diff --git a/DEPS b/DEPS
index f08ae70..4bad310 100644
--- a/DEPS
+++ b/DEPS
@@ -316,11 +316,11 @@
   # 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': '2eaa4a2641b0d19b79d02a83d1683e60894a6179',
+  'v8_revision': '0eb99a5fd27ab7a29e4d8bc54b5f7bd97012c7c0',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '36ae4553287d44e82080c486adae52da7865daa8',
+  'angle_revision': '219f7762e54ba3653d67a605dcba270f14f50467',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -363,7 +363,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
-  'freetype_revision': '9a2d6d97b2d8a5d22d02948b783df12b764afa2d',
+  'freetype_revision': '982bc83849966554f850fbc91405883a2a0de895',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # 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 devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '3586c7113a54ede17dc840ba4213a90823e56756',
+  'devtools_frontend_revision': 'c8712a9d7df87cdcf0536f3aa3495b75cc6d707f',
   # 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.
@@ -427,7 +427,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': '30d2bfb2ecc261e55b1c329b039cb233678ae126',
+  'dawn_revision': 'b476146a257fbb8ee3b3a4982e16404fc335aa19',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -831,7 +831,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    '71700ce427b7af336a88a02a0767b1ee1af7512b',
+    '6c89ab97e91680ad99a18c4763e0c7815d4a30ba',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -986,7 +986,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'w_WvxAtkTYqygcFc1DtLkvJlGU0WRsUg71SxSvIp-cEC',
+          'version': 'UhN_2VJ25wg9QmMGNFfBe-A-S0N2DsHIgxyHYusxnCYC',
       },
     ],
     'condition': 'checkout_android',
@@ -1202,7 +1202,7 @@
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'fac063701741add8c5af364fb8cfbbf13e5bdc98',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '5d8ddfde5f0b4f9892d87404f14b3a7c48547020',
     'condition': 'checkout_src_internal',
   },
 
@@ -1818,7 +1818,7 @@
       'dep_type': 'cipd',
   },
 
-  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@36da75a01950ce86a9525f7c080359710c0ee6b4',
+  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@7e651e5917e3e8a7eadf8ee002291e4b85caaa56',
 
   'src/third_party/vulkan_memory_allocator':
     Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + '56300b29fbfcc693ee6609ddad3fdd5b7a449a21',
@@ -1858,7 +1858,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '680c654441704480e9756124770dd683a32d13d1',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'cb3f740525bca608b44fb2a5af2e8ee0190a789c',
+    Var('webrtc_git') + '/src.git' + '@' + '6f170a05dc27b0add7d9f351585b96e644382b1c',
 
   # 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.
@@ -2025,7 +2025,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': 'z8QzE_ywxGHggqzrCvZjSQbFEYhTeOsDHkADFFozVc8C',
+        'version': '7pRCUCi-rbKicyrTuwvChRxijVPZGUel3I7KuO1nwHsC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -3873,7 +3873,7 @@
 
   'src/ash/webui/conch': {
       'url': Var('chrome_git') + '/ash/webui/conch.git' + '@' +
-        '6e3f1d19bc845e70d07ed85628e7bcc19a57b2f0',
+        '33b50544ebbc3b6ae3aeeb4fabfbe2570dfa247e',
       'condition': 'checkout_src_internal and checkout_chromeos',
   },
 
@@ -4132,7 +4132,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        '7414643e72f711bd1d0e4e20a0de078a26b791d1',
+        '31db9b52cb0b5f645f5f7cce78e3cd4863d81d4c',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
index 339c359..df16010 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -656,6 +656,8 @@
                 "Enables new optimized implementation of SpdyHeadersToHttpResponse. No behavior"
                         + " change."),
         Flag.baseFeature(
+                NetFeatures.ENABLE_IP_PROTECTION_PROXY, "Enables IP Protection on WebView."),
+        Flag.baseFeature(
                 "MojoFixAssociatedHandleLeak",
                 "Holdback for a bugfix which may have improved WebView stability."),
         Flag.baseFeature("MojoIpcz"),
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 6525a32..8484eac3 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -825,6 +825,8 @@
     "login/ui/auth_factor_model.h",
     "login/ui/auth_icon_view.cc",
     "login/ui/auth_icon_view.h",
+    "login/ui/auth_panel_debug_view.cc",
+    "login/ui/auth_panel_debug_view.h",
     "login/ui/bottom_status_indicator.cc",
     "login/ui/bottom_status_indicator.h",
     "login/ui/disabled_auth_message_view.cc",
diff --git a/ash/accessibility/accessibility_controller.cc b/ash/accessibility/accessibility_controller.cc
index c3fff2d..804a638a 100644
--- a/ash/accessibility/accessibility_controller.cc
+++ b/ash/accessibility/accessibility_controller.cc
@@ -2713,12 +2713,12 @@
       active_user_prefs_->GetInteger(prefs::kAccessibilityCaretBlinkInterval));
   auto* native_theme_dark = ui::NativeTheme::GetInstanceForDarkUI();
   native_theme_dark->set_caret_blink_interval(caret_blink_interval);
-  native_theme_dark->NotifyOnNativeThemeUpdated();
   auto* native_theme_web = ui::NativeTheme::GetInstanceForWeb();
   native_theme_web->set_caret_blink_interval(caret_blink_interval);
-  native_theme_web->NotifyOnNativeThemeUpdated();
   auto* native_theme = ui::NativeTheme::GetInstanceForNativeUi();
   native_theme->set_caret_blink_interval(caret_blink_interval);
+  native_theme_dark->NotifyOnNativeThemeUpdated();
+  native_theme_web->NotifyOnNativeThemeUpdated();
   native_theme->NotifyOnNativeThemeUpdated();
 }
 
diff --git a/ash/assistant/ui/assistant_web_container_view.cc b/ash/assistant/ui/assistant_web_container_view.cc
index ba1c6b8e..912a9f95 100644
--- a/ash/assistant/ui/assistant_web_container_view.cc
+++ b/ash/assistant/ui/assistant_web_container_view.cc
@@ -81,7 +81,8 @@
 
 AssistantWebContainerView::~AssistantWebContainerView() = default;
 
-gfx::Size AssistantWebContainerView::CalculatePreferredSize() const {
+gfx::Size AssistantWebContainerView::CalculatePreferredSize(
+    const views::SizeBounds& available_size) const {
   const int non_client_frame_view_height =
       views::GetCaptionButtonLayoutSize(
           views::CaptionButtonLayoutSize::kNonBrowserCaption)
diff --git a/ash/assistant/ui/assistant_web_container_view.h b/ash/assistant/ui/assistant_web_container_view.h
index e7813fe..5b6279a 100644
--- a/ash/assistant/ui/assistant_web_container_view.h
+++ b/ash/assistant/ui/assistant_web_container_view.h
@@ -41,7 +41,8 @@
   }
 
   // views::WidgetDelegateView:
-  gfx::Size CalculatePreferredSize() const override;
+  gfx::Size CalculatePreferredSize(
+      const views::SizeBounds& available_size) const override;
   void ChildPreferredSizeChanged(views::View* child) override;
   views::ClientView* CreateClientView(views::Widget* widget) override;
   void OnThemeChanged() override;
diff --git a/ash/assistant/ui/main_stage/assistant_footer_view.cc b/ash/assistant/ui/main_stage/assistant_footer_view.cc
index 582aeab..0a3c261d 100644
--- a/ash/assistant/ui/main_stage/assistant_footer_view.cc
+++ b/ash/assistant/ui/main_stage/assistant_footer_view.cc
@@ -53,7 +53,8 @@
   AssistantState::Get()->RemoveObserver(this);
 }
 
-gfx::Size AssistantFooterView::CalculatePreferredSize() const {
+gfx::Size AssistantFooterView::CalculatePreferredSize(
+    const views::SizeBounds& available_size) const {
   return gfx::Size(INT_MAX, GetHeightForWidth(INT_MAX));
 }
 
diff --git a/ash/assistant/ui/main_stage/assistant_footer_view.h b/ash/assistant/ui/main_stage/assistant_footer_view.h
index 406dd94..86fa602 100644
--- a/ash/assistant/ui/main_stage/assistant_footer_view.h
+++ b/ash/assistant/ui/main_stage/assistant_footer_view.h
@@ -38,7 +38,8 @@
   ~AssistantFooterView() override;
 
   // views::View:
-  gfx::Size CalculatePreferredSize() const override;
+  gfx::Size CalculatePreferredSize(
+      const views::SizeBounds& available_size) const override;
   int GetHeightForWidth(int width) const override;
 
   // AssistantStateObserver:
diff --git a/ash/assistant/ui/main_stage/assistant_onboarding_view.cc b/ash/assistant/ui/main_stage/assistant_onboarding_view.cc
index 6281ecf..efdac9f 100644
--- a/ash/assistant/ui/main_stage/assistant_onboarding_view.cc
+++ b/ash/assistant/ui/main_stage/assistant_onboarding_view.cc
@@ -129,7 +129,8 @@
     AssistantSuggestionsController::Get()->GetModel()->RemoveObserver(this);
 }
 
-gfx::Size AssistantOnboardingView::CalculatePreferredSize() const {
+gfx::Size AssistantOnboardingView::CalculatePreferredSize(
+    const views::SizeBounds& available_size) const {
   return gfx::Size(INT_MAX, GetHeightForWidth(INT_MAX));
 }
 
diff --git a/ash/assistant/ui/main_stage/assistant_onboarding_view.h b/ash/assistant/ui/main_stage/assistant_onboarding_view.h
index c58d663..092e4d8 100644
--- a/ash/assistant/ui/main_stage/assistant_onboarding_view.h
+++ b/ash/assistant/ui/main_stage/assistant_onboarding_view.h
@@ -40,7 +40,8 @@
   ~AssistantOnboardingView() override;
 
   // views::View:
-  gfx::Size CalculatePreferredSize() const override;
+  gfx::Size CalculatePreferredSize(
+      const views::SizeBounds& available_size) const override;
   void ChildPreferredSizeChanged(views::View* child) override;
   void OnThemeChanged() override;
 
diff --git a/ash/assistant/ui/main_stage/assistant_opt_in_view.cc b/ash/assistant/ui/main_stage/assistant_opt_in_view.cc
index dccfb52..0bd626e 100644
--- a/ash/assistant/ui/main_stage/assistant_opt_in_view.cc
+++ b/ash/assistant/ui/main_stage/assistant_opt_in_view.cc
@@ -68,7 +68,8 @@
   ~AssistantOptInContainer() override = default;
 
   // views::View:
-  gfx::Size CalculatePreferredSize() const override {
+  gfx::Size CalculatePreferredSize(
+      const views::SizeBounds& available_size) const override {
     const int preferred_width = views::View::CalculatePreferredSize().width();
     return gfx::Size(preferred_width, GetHeightForWidth(preferred_width));
   }
diff --git a/ash/assistant/ui/main_stage/assistant_progress_indicator.cc b/ash/assistant/ui/main_stage/assistant_progress_indicator.cc
index 9e719f2..0db2248 100644
--- a/ash/assistant/ui/main_stage/assistant_progress_indicator.cc
+++ b/ash/assistant/ui/main_stage/assistant_progress_indicator.cc
@@ -78,7 +78,8 @@
 
 AssistantProgressIndicator::~AssistantProgressIndicator() = default;
 
-gfx::Size AssistantProgressIndicator::CalculatePreferredSize() const {
+gfx::Size AssistantProgressIndicator::CalculatePreferredSize(
+    const views::SizeBounds& available_size) const {
   const int preferred_width = views::View::CalculatePreferredSize().width();
   return gfx::Size(preferred_width, GetHeightForWidth(preferred_width));
 }
diff --git a/ash/assistant/ui/main_stage/assistant_progress_indicator.h b/ash/assistant/ui/main_stage/assistant_progress_indicator.h
index eecaff76..4917f81 100644
--- a/ash/assistant/ui/main_stage/assistant_progress_indicator.h
+++ b/ash/assistant/ui/main_stage/assistant_progress_indicator.h
@@ -25,7 +25,8 @@
   ~AssistantProgressIndicator() override;
 
   // views::View:
-  gfx::Size CalculatePreferredSize() const override;
+  gfx::Size CalculatePreferredSize(
+      const views::SizeBounds& available_size) const override;
   int GetHeightForWidth(int width) const override;
   void AddedToWidget() override;
   void RemovedFromWidget() override;
diff --git a/ash/assistant/ui/main_stage/assistant_query_view.cc b/ash/assistant/ui/main_stage/assistant_query_view.cc
index d76ab7b96..315099c 100644
--- a/ash/assistant/ui/main_stage/assistant_query_view.cc
+++ b/ash/assistant/ui/main_stage/assistant_query_view.cc
@@ -56,7 +56,8 @@
 
 AssistantQueryView::~AssistantQueryView() = default;
 
-gfx::Size AssistantQueryView::CalculatePreferredSize() const {
+gfx::Size AssistantQueryView::CalculatePreferredSize(
+    const views::SizeBounds& available_size) const {
   return gfx::Size(kMaxWidthDip, GetHeightForWidth(kMaxWidthDip));
 }
 
diff --git a/ash/assistant/ui/main_stage/assistant_query_view.h b/ash/assistant/ui/main_stage/assistant_query_view.h
index f17d45a1..0f89e20 100644
--- a/ash/assistant/ui/main_stage/assistant_query_view.h
+++ b/ash/assistant/ui/main_stage/assistant_query_view.h
@@ -31,7 +31,8 @@
   ~AssistantQueryView() override;
 
   // views::View:
-  gfx::Size CalculatePreferredSize() const override;
+  gfx::Size CalculatePreferredSize(
+      const views::SizeBounds& available_size) const override;
   int GetHeightForWidth(int width) const override;
   void OnThemeChanged() override;
 
diff --git a/ash/assistant/ui/main_stage/assistant_zero_state_view.cc b/ash/assistant/ui/main_stage/assistant_zero_state_view.cc
index db2812c..e990ddc 100644
--- a/ash/assistant/ui/main_stage/assistant_zero_state_view.cc
+++ b/ash/assistant/ui/main_stage/assistant_zero_state_view.cc
@@ -74,8 +74,10 @@
     AssistantUiController::Get()->GetModel()->RemoveObserver(this);
 }
 
-gfx::Size AssistantZeroStateView::CalculatePreferredSize() const {
-  return gfx::Size(INT_MAX, GetHeightForWidth(INT_MAX));
+gfx::Size AssistantZeroStateView::CalculatePreferredSize(
+    const views::SizeBounds& available_size) const {
+  return gfx::Size(
+      INT_MAX, GetLayoutManager()->GetPreferredHeightForWidth(this, INT_MAX));
 }
 
 void AssistantZeroStateView::ChildPreferredSizeChanged(views::View* child) {
diff --git a/ash/assistant/ui/main_stage/assistant_zero_state_view.h b/ash/assistant/ui/main_stage/assistant_zero_state_view.h
index 32d95439b..64b7c43 100644
--- a/ash/assistant/ui/main_stage/assistant_zero_state_view.h
+++ b/ash/assistant/ui/main_stage/assistant_zero_state_view.h
@@ -38,7 +38,8 @@
   ~AssistantZeroStateView() override;
 
   // views::View:
-  gfx::Size CalculatePreferredSize() const override;
+  gfx::Size CalculatePreferredSize(
+      const views::SizeBounds& available_size) const override;
   void ChildPreferredSizeChanged(views::View* child) override;
   void OnBoundsChanged(const gfx::Rect& prev_bounds) override;
 
diff --git a/ash/assistant/ui/main_stage/chip_view.cc b/ash/assistant/ui/main_stage/chip_view.cc
index 93d55a99..9381d19 100644
--- a/ash/assistant/ui/main_stage/chip_view.cc
+++ b/ash/assistant/ui/main_stage/chip_view.cc
@@ -102,8 +102,10 @@
 
 ChipView::~ChipView() = default;
 
-gfx::Size ChipView::CalculatePreferredSize() const {
-  const int preferred_width = views::View::CalculatePreferredSize().width();
+gfx::Size ChipView::CalculatePreferredSize(
+    const views::SizeBounds& available_size) const {
+  const int preferred_width =
+      views::View::CalculatePreferredSize(available_size).width();
   return gfx::Size(preferred_width, GetHeightForWidth(preferred_width));
 }
 
diff --git a/ash/assistant/ui/main_stage/chip_view.h b/ash/assistant/ui/main_stage/chip_view.h
index a04ca68e..572a750 100644
--- a/ash/assistant/ui/main_stage/chip_view.h
+++ b/ash/assistant/ui/main_stage/chip_view.h
@@ -27,7 +27,8 @@
   ~ChipView() override;
 
   // views::View:
-  gfx::Size CalculatePreferredSize() const override;
+  gfx::Size CalculatePreferredSize(
+      const views::SizeBounds& available_size) const override;
   int GetHeightForWidth(int width) const override;
   void ChildVisibilityChanged(views::View* child) override;
   bool OnKeyPressed(const ui::KeyEvent& event) override;
diff --git a/ash/in_session_auth/auth_dialog_contents_view.cc b/ash/in_session_auth/auth_dialog_contents_view.cc
index 7fd2c5d4..ca327e62 100644
--- a/ash/in_session_auth/auth_dialog_contents_view.cc
+++ b/ash/in_session_auth/auth_dialog_contents_view.cc
@@ -207,8 +207,12 @@
   }
 
   // views::View:
-  gfx::Size CalculatePreferredSize() const override {
-    gfx::Size size = views::View::CalculatePreferredSize();
+  gfx::Size CalculatePreferredSize(
+      const views::SizeBounds& available_size) const override {
+    views::SizeBounds content_available_size(available_size);
+    content_available_size.set_width(kFingerprintViewWidthDp);
+    gfx::Size size =
+        views::View::CalculatePreferredSize(content_available_size);
     size.set_width(kFingerprintViewWidthDp);
     return size;
   }
diff --git a/ash/login/ui/auth_panel_debug_view.cc b/ash/login/ui/auth_panel_debug_view.cc
new file mode 100644
index 0000000..bfa132e
--- /dev/null
+++ b/ash/login/ui/auth_panel_debug_view.cc
@@ -0,0 +1,153 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/login/ui/auth_panel_debug_view.h"
+
+#include <memory>
+#include <string>
+
+#include "ash/accessibility/accessibility_controller.h"
+#include "ash/keyboard/ui/keyboard_ui_controller.h"
+#include "ash/login/ui/non_accessible_view.h"
+#include "ash/strings/grit/ash_strings.h"
+#include "ash/style/ash_color_id.h"
+#include "ash/style/ash_color_provider.h"
+#include "base/functional/bind.h"
+#include "base/notimplemented.h"
+#include "chromeos/ash/components/auth_panel/impl/auth_factor_store.h"
+#include "chromeos/ash/components/auth_panel/impl/auth_panel.h"
+#include "chromeos/ash/components/auth_panel/impl/auth_panel_event_dispatcher.h"
+#include "chromeos/ash/components/auth_panel/impl/factor_auth_view_factory.h"
+#include "chromeos/ash/components/osauth/public/auth_hub.h"
+#include "chromeos/ash/components/osauth/public/common_types.h"
+#include "components/account_id/account_id.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/models/image_model.h"
+#include "ui/chromeos/resources/grit/ui_chromeos_resources.h"
+#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
+#include "ui/compositor/layer.h"
+#include "ui/views/background.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/fill_layout.h"
+#include "ui/views/layout/flex_layout.h"
+#include "ui/views/layout/layout_types.h"
+#include "ui/views/vector_icons.h"
+
+namespace ash {
+
+namespace {
+
+// TODO(b/304754895): move the pin request view shared constants to
+// ash/login/ui/login_constants.h
+// Minimum inset (= back button inset).
+constexpr int kAuthPanelDebugViewWidthDp = 500;
+constexpr int kAuthPanelDebugViewHeightDp = 400;
+
+}  // namespace
+
+AuthPanelDebugView::AuthPanelDebugView(const AccountId& account_id) {
+  //  MODAL_TYPE_SYSTEM is used to get a semi-transparent background behind the
+  //  local authentication request view, when it is used directly on a widget.
+  //  The overlay consumes all the inputs from the user, so that they can only
+  //  interact with the local authentication request view while it is visible.
+  // SetModalType(ui::MODAL_TYPE_SYSTEM);
+  // SetButtons(ui::DIALOG_BUTTON_NONE);
+  // Main view contains all other views aligned vertically and centered.
+
+  SetLayoutManager(std::make_unique<views::FlexLayout>())
+      ->SetOrientation(views::LayoutOrientation::kVertical)
+      .SetMainAxisAlignment(views::LayoutAlignment::kCenter)
+      .SetCrossAxisAlignment(views::LayoutAlignment::kCenter)
+      .SetCollapseMargins(false);
+
+  ui::ColorId background_color_id = cros_tokens::kCrosSysSystemBaseElevated;
+  SetBackground(views::CreateThemedSolidBackground(background_color_id));
+
+  auto* auth_hub = AuthHub::Get();
+
+  auto continuation =
+      base::BindOnce(&AuthHub::StartAuthentication, base::Unretained(auth_hub),
+                     account_id, AuthPurpose::kLogin, this);
+
+  auth_hub->EnsureInitialized(std::move(continuation));
+}
+
+AuthPanelDebugView::~AuthPanelDebugView() = default;
+
+gfx::Size AuthPanelDebugView::CalculatePreferredSize() const {
+  return GetAuthPanelDebugViewSize();
+}
+
+void AuthPanelDebugView::UpdatePreferredSize() {
+  SetPreferredSize(CalculatePreferredSize());
+  if (GetWidget()) {
+    GetWidget()->CenterWindow(GetPreferredSize());
+  }
+}
+
+gfx::Size AuthPanelDebugView::GetAuthPanelDebugViewSize() const {
+  return gfx::Size(kAuthPanelDebugViewWidthDp, kAuthPanelDebugViewHeightDp);
+}
+
+void AuthPanelDebugView::OnEndAuthentication() {
+  LOG(ERROR) << "AuthPanelDebugView::OnEndAuthentication";
+  NOTIMPLEMENTED();
+}
+
+void AuthPanelDebugView::OnAuthPanelPreferredSizeChanged() {
+  LOG(ERROR) << "AuthPanelDebugView::OnAuthPanelPreferredSizeChanged";
+  NOTIMPLEMENTED();
+}
+
+void AuthPanelDebugView::OnUserAuthAttemptRejected() {
+  LOG(ERROR) << "AuthPanelDebugView::OnUserAuthAttemptRejected";
+  NOTIMPLEMENTED();
+}
+
+void AuthPanelDebugView::OnUserAuthAttemptConfirmed(
+    AuthHubConnector* connector,
+    raw_ptr<AuthFactorStatusConsumer>& out_consumer) {
+  LOG(ERROR) << "AuthPanelDebugView::OnUserAuthAttemptConfirmed";
+  // AddAuthPanel
+  auto* auth_panel = AddChildView(std::make_unique<AuthPanel>(
+      std::make_unique<FactorAuthViewFactory>(),
+      std::make_unique<AuthFactorStoreFactory>(),
+      std::make_unique<AuthPanelEventDispatcherFactory>(),
+      base::BindOnce(&AuthPanelDebugView::OnEndAuthentication,
+                     weak_ptr_factory_.GetWeakPtr()),
+      base::BindRepeating(&AuthPanelDebugView::OnAuthPanelPreferredSizeChanged,
+                          weak_ptr_factory_.GetWeakPtr()),
+      connector));
+  auth_panel->SetBackground(views::CreateThemedRoundedRectBackground(
+      cros_tokens::kCrosSysSystemBase, 8));
+  LOG(ERROR) << "auth panel visible: " << auth_panel->GetVisible();
+  LOG(ERROR) << "auth panel visible bounds: "
+             << auth_panel->GetVisibleBounds().ToString();
+  out_consumer = auth_panel;
+  SetPreferredSize(GetAuthPanelDebugViewSize());
+}
+
+void AuthPanelDebugView::OnAccountNotFound() {
+  LOG(ERROR) << "AuthPanelDebugView::OnAccountNotFound";
+  NOTIMPLEMENTED();
+}
+
+void AuthPanelDebugView::OnUserAuthAttemptCancelled() {
+  LOG(ERROR) << "AuthPanelDebugView::OnUserAuthAttemptCancelled";
+  NOTIMPLEMENTED();
+}
+
+void AuthPanelDebugView::OnFactorAttemptFailed(AshAuthFactor factor) {
+  LOG(ERROR) << "AuthPanelDebugView::OnFactorAttemptFailed";
+  NOTIMPLEMENTED();
+}
+
+void AuthPanelDebugView::OnUserAuthSuccess(AshAuthFactor factor,
+                                           const AuthProofToken& token) {
+  LOG(ERROR) << "AuthPanelDebugView::OnUserAuthSuccess";
+  NOTIMPLEMENTED();
+}
+
+}  // namespace ash
diff --git a/ash/login/ui/auth_panel_debug_view.h b/ash/login/ui/auth_panel_debug_view.h
new file mode 100644
index 0000000..d11782a
--- /dev/null
+++ b/ash/login/ui/auth_panel_debug_view.h
@@ -0,0 +1,64 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_LOGIN_UI_AUTH_PANEL_DEBUG_VIEW_H_
+#define ASH_LOGIN_UI_AUTH_PANEL_DEBUG_VIEW_H_
+
+#include "ash/ash_export.h"
+#include "base/functional/callback_helpers.h"
+#include "base/memory/raw_ptr.h"
+#include "base/scoped_observation.h"
+#include "chromeos/ash/components/cryptohome/auth_factor.h"
+#include "chromeos/ash/components/osauth/public/auth_attempt_consumer.h"
+#include "components/account_id/account_id.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/views/view.h"
+
+namespace ash {
+
+class ASH_EXPORT AuthPanelDebugView : public views::View,
+                                      public AuthAttemptConsumer {
+ public:
+  // Creates local authentication request view that will enable the user to
+  // authenticate with a local authentication.
+  AuthPanelDebugView(const AccountId& account_id);
+
+  AuthPanelDebugView(const AuthPanelDebugView&) = delete;
+  AuthPanelDebugView& operator=(const AuthPanelDebugView&) = delete;
+
+  ~AuthPanelDebugView() override;
+
+  // AuthAttemptConsumer:
+  void OnUserAuthAttemptRejected() override;
+  void OnUserAuthAttemptConfirmed(
+      AuthHubConnector* connector,
+      raw_ptr<AuthFactorStatusConsumer>& out_consumer) override;
+  void OnAccountNotFound() override;
+  void OnUserAuthAttemptCancelled() override;
+  void OnFactorAttemptFailed(AshAuthFactor factor) override;
+  void OnUserAuthSuccess(AshAuthFactor factor,
+                         const AuthProofToken& token) override;
+
+  gfx::Size CalculatePreferredSize() const override;
+
+ private:
+  // Closes the view.
+  void OnClose();
+
+  // Updates view's preferred size.
+  void UpdatePreferredSize();
+
+  void OnEndAuthentication();
+
+  void OnAuthPanelPreferredSizeChanged();
+
+  // Returns the view dimensions.
+  gfx::Size GetAuthPanelDebugViewSize() const;
+
+  base::WeakPtrFactory<AuthPanelDebugView> weak_ptr_factory_{this};
+};
+
+}  // namespace ash
+
+#endif  // ASH_LOGIN_UI_AUTH_PANEL_DEBUG_VIEW_H_
diff --git a/ash/login/ui/lock_debug_view.cc b/ash/login/ui/lock_debug_view.cc
index 081ab8d..d9e4c88 100644
--- a/ash/login/ui/lock_debug_view.cc
+++ b/ash/login/ui/lock_debug_view.cc
@@ -16,6 +16,7 @@
 #include "ash/detachable_base/detachable_base_pairing_status.h"
 #include "ash/ime/ime_controller_impl.h"
 #include "ash/login/login_screen_controller.h"
+#include "ash/login/ui/auth_panel_debug_view.h"
 #include "ash/login/ui/local_authentication_request_controller_impl.h"
 #include "ash/login/ui/lock_contents_view.h"
 #include "ash/login/ui/lock_contents_view_test_api.h"
@@ -27,6 +28,7 @@
 #include "ash/public/cpp/kiosk_app_menu.h"
 #include "ash/public/cpp/login/local_authentication_request_controller.h"
 #include "ash/public/cpp/login_types.h"
+#include "ash/public/cpp/shell_window_ids.h"
 #include "ash/public/cpp/smartlock_state.h"
 #include "ash/public/cpp/style/dark_light_mode_controller.h"
 #include "ash/shelf/login_shelf_view.h"
@@ -52,6 +54,7 @@
 #include "ui/views/controls/scrollbar/overlay_scroll_bar.h"
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/view.h"
+#include "ui/views/widget/widget.h"
 
 namespace ash {
 namespace {
@@ -216,6 +219,7 @@
       const DebugDataDispatcherTransformer&) = delete;
 
   ~DebugDataDispatcherTransformer() override {
+    auth_panel_debug_widget_ = nullptr;
     root_dispatcher_->RemoveObserver(this);
   }
 
@@ -401,6 +405,35 @@
         std::move(user_context));
   }
 
+  // Activates AuthPanel for the user at |user_index|.
+  void AuthPanelRequestForUserIndex(size_t user_index) {
+    if (auth_panel_debug_widget_) {
+      LOG(ERROR) << "AuthPanelDebugWidget still exists.";
+      return;
+    }
+    auto delegate = std::make_unique<views::DialogDelegate>();
+    delegate->SetButtons(ui::DIALOG_BUTTON_NONE);
+    delegate->SetModalType(ui::MODAL_TYPE_SYSTEM);
+    delegate->SetOwnedByWidget(true);
+    delegate->SetCloseCallback(
+        base::BindOnce(&LockDebugView::DebugDataDispatcherTransformer::
+                           OnAuthPanelDebugWidgetClose,
+                       base::Unretained(this)));
+
+    DCHECK(user_index >= 0 && user_index < debug_users_.size());
+    UserMetadata* debug_user = &debug_users_[user_index];
+    const AccountId account_id = debug_user->account_id;
+    delegate->SetContentsView(std::make_unique<AuthPanelDebugView>(account_id));
+
+    auth_panel_debug_widget_ = views::DialogDelegate::CreateDialogWidget(
+        std::move(delegate),
+        /*context=*/nullptr,
+        /*parent=*/
+        Shell::GetPrimaryRootWindow()->GetChildById(
+            kShellWindowId_LockSystemModalContainer));
+    auth_panel_debug_widget_->Show();
+  }
+
   // Cycles fingerprint state for the user at |user_index|.
   void CycleFingerprintStateForUserIndex(size_t user_index) {
     DCHECK(user_index >= 0 && user_index < debug_users_.size());
@@ -632,6 +665,8 @@
         show_full_management_disclosure);
   }
 
+  void OnAuthPanelDebugWidgetClose() { auth_panel_debug_widget_ = nullptr; }
+
  private:
   // The debug overlay UI takes ground-truth data from |root_dispatcher_|,
   // applies a series of transformations to it, and exposes it to the UI via
@@ -654,6 +689,8 @@
   // Called when a new user list has been received.
   base::RepeatingClosure on_users_received_;
 
+  raw_ptr<views::Widget> auth_panel_debug_widget_ = nullptr;
+
   // Called for testing functions not belonging to the login data dispatcher.
   // In such a case, we want to bypass the event handling mechanism and do
   // direct calls to the lock screen. We need either an instance of
@@ -1249,6 +1286,12 @@
                             base::Unretained(debug_data_dispatcher_.get()), i),
         row);
 
+    AddButton("Show AuthPanel",
+              base::BindRepeating(
+                  &DebugDataDispatcherTransformer::AuthPanelRequestForUserIndex,
+                  base::Unretained(debug_data_dispatcher_.get()), i),
+              row);
+
     AddButton("Show local authentication request",
               base::BindRepeating(
                   &DebugDataDispatcherTransformer::AuthRequestForUserIndex,
diff --git a/ash/login/ui/lock_debug_view.h b/ash/login/ui/lock_debug_view.h
index 3e7cd73..4a772678 100644
--- a/ash/login/ui/lock_debug_view.h
+++ b/ash/login/ui/lock_debug_view.h
@@ -103,7 +103,7 @@
                                 views::Button::PressedCallback callback,
                                 views::View* container);
 
-  raw_ptr<LockContentsView> lock_ = nullptr;
+  raw_ptr<LockContentsView, DanglingUntriaged> lock_ = nullptr;
 
   // Debug container which holds the entire debug UI.
   raw_ptr<views::View> container_ = nullptr;
@@ -129,7 +129,8 @@
   // Debug dispatcher and cached data for the UI.
   std::unique_ptr<DebugDataDispatcherTransformer> const debug_data_dispatcher_;
   // Reference to the detachable base model passed to (and owned by) lock_.
-  raw_ptr<DebugLoginDetachableBaseModel> debug_detachable_base_model_ = nullptr;
+  raw_ptr<DebugLoginDetachableBaseModel, DanglingUntriaged>
+      debug_detachable_base_model_ = nullptr;
   size_t num_system_info_clicks_ = 0u;
   LoginScreenController::ForceFailAuth force_fail_auth_ =
       LoginScreenController::ForceFailAuth::kOff;
diff --git a/ash/strings/ash_strings_id.xtb b/ash/strings/ash_strings_id.xtb
index 79b2bb28..70b4b7a 100644
--- a/ash/strings/ash_strings_id.xtb
+++ b/ash/strings/ash_strings_id.xtb
@@ -162,6 +162,7 @@
 <translation id="1569384531973824928">Tindakan ini akan mengizinkan akses untuk semua aplikasi serta situs yang memiliki izin kamera dan mikrofon. Anda mungkin perlu memuat ulang halaman web atau memulai ulang aplikasi.</translation>
 <translation id="1571697193564730395">Alihkan mode Jangan Ganggu. <ph name="STATE_TEXT" /></translation>
 <translation id="1576623706766186887">Perkecil saat kaca pembesar diaktifkan</translation>
+<translation id="1582946770779745370">Dasbor Game tersedia. Tekan <ph name="LAUNCHER_KEY_NAME" /> + Shift + Escape, lalu <ph name="LAUNCHER_KEY_NAME" /> + g kapan saja untuk membuka</translation>
 <translation id="1586324912145647027">Membuka desktop 1 sampai 8</translation>
 <translation id="158838227375272121">Situs Google Classroom</translation>
 <translation id="1589090746204042747">Akses semua aktivitas Anda di sesi ini</translation>
diff --git a/ash/strings/ash_strings_ms.xtb b/ash/strings/ash_strings_ms.xtb
index 3885e7e7..fbfb5a5f 100644
--- a/ash/strings/ash_strings_ms.xtb
+++ b/ash/strings/ash_strings_ms.xtb
@@ -2124,6 +2124,7 @@
 <translation id="954052413789300507">Ruang tidak mencukupi untuk <ph name="FILENAME" />. Kosongkan ruang.</translation>
 <translation id="954520015070501466">30 min</translation>
 <translation id="956452277966142925">Tetapan papan pemuka permainan</translation>
+<translation id="961856697154696964">Padamkan data semakan imbas</translation>
 <translation id="974545358917229949">Memaparkan <ph name="RESULT_COUNT" /> hasil carian untuk <ph name="QUERY" /></translation>
 <translation id="981011780479609956">Tiada tarikh tamat</translation>
 <translation id="98120814841227350">Pergi ke bahagian hujung dokumen</translation>
diff --git a/ash/strings/ash_strings_ne.xtb b/ash/strings/ash_strings_ne.xtb
index 6db55d07..be518f5 100644
--- a/ash/strings/ash_strings_ne.xtb
+++ b/ash/strings/ash_strings_ne.xtb
@@ -1770,7 +1770,7 @@
 <translation id="7886169021410746335">गोपनीयतासम्बन्धी सेटिङहरूको समायोजन गर्नुहोस्</translation>
 <translation id="7886277072580235377">तपाईं साइन आउट हुँदा तपाईंको इन्टरनेट सत्र खाली गरिने छ। <ph name="LEARN_MORE" /></translation>
 <translation id="788781083998633524">इमेल पठाउनुहोस्</translation>
-<translation id="7893503627044934815">मलाई यो फाइल नदेखाइयोस्</translation>
+<translation id="7893503627044934815">मलाई यो फाइल नदेखाउनुहोस्</translation>
 <translation id="7893547474469215105">शिरोबिन्दुको परिभाषा दिइयोस्</translation>
 <translation id="7895348134893321514">Tote</translation>
 <translation id="7896681766480521542">कुनै कार्य हाल्नुहोस्</translation>
@@ -2072,7 +2072,7 @@
 <translation id="9072519059834302790">ब्याट्री पूरै सकिन <ph name="TIME_LEFT" /> बाँकी छ।</translation>
 <translation id="9074432941673450836">तपाईंले <ph name="PRODUCT_NAME" /> मा गर्नु पर्ने सबै कार्य गर्न एपहरू प्रयोग गर्नुहोस्। तपाईं लन्चरमा आफ्ना एपहरू भेट्टाउन सक्नुहुन्छ। तपाईं किबोर्डमा रहेको लन्चर की (सिफ्ट कीको माथिपट्टि) पनि थिच्न सक्नुहुन्छ।</translation>
 <translation id="9074739597929991885">ब्लुटुथ</translation>
-<translation id="9077515519330855811">मिडिया नियन्त्रण सुविधाहरू, अहिले <ph name="MEDIA_TITLE" /> बजिरहेको छ</translation>
+<translation id="9077515519330855811">मिडिया कन्ट्रोल, अहिले <ph name="MEDIA_TITLE" /> बजिरहेको छ</translation>
 <translation id="9079731690316798640">Wi-Fi: <ph name="ADDRESS" /></translation>
 <translation id="9080073830732419341">क्यामेरा सिरानको बायाँ कुनामा स्न्याप गरियो</translation>
 <translation id="9080132581049224423">गृहपृष्ठमा जान माथितिर स्वाइप गर्नुहोस्</translation>
diff --git a/ash/webui/camera_app_ui/resources/eslint_plugin/index.js b/ash/webui/camera_app_ui/resources/eslint_plugin/index.js
index 6f33a319..e061e7f 100644
--- a/ash/webui/camera_app_ui/resources/eslint_plugin/index.js
+++ b/ash/webui/camera_app_ui/resources/eslint_plugin/index.js
@@ -101,7 +101,8 @@
           if (!verifyTodo(commentValue)) {
             context.report({
               node: comment,
-              message: `Use: TODO(ldap) / TODO(b/123) / TODO(crbug.com/123)`,
+              message: `Use: TODO(ldap) / TODO(b/123456789) /` +
+                  ` TODO(crbug.com/123456789)`,
             });
           }
         }
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_ka.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_ka.xtb
index 0c50b46..105e5b12 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_ka.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_ka.xtb
@@ -32,6 +32,7 @@
 <translation id="2175927920773552910">QR კოდი</translation>
 <translation id="2244252133441425811">ვიდეოს კ/წმ ამომრჩევის ჩართვა</translation>
 <translation id="2271433936731426666">სრულზომიანი ვიდეოსნეპშოტის გადაღების დაშვება</translation>
+<translation id="2281736597583450397">მიიღეთ უფრო მკვეთი დეტალები გაძლიერებული მასშტაბირებით</translation>
 <translation id="2320741269052147773">მარცხნივ პანირება</translation>
 <translation id="2360840973209616515">კამერის აპს მართავს თქვენი ადმინისტრატორი.
         დეტალური ინფორმაციისთვის მიმართეთ ადმინისტრატორს.</translation>
@@ -118,6 +119,7 @@
 თუ თქვენი გამოხმაურება გამოსახულების ან ვიდეოს ხარისხს ეხება, მაგალითის სახით დაურთეთ ფოტო ან ვიდეო და აღწერეთ პრობლემა (მაგალითად, ფოტო ზედმეტად მუქია ან ობიექტი არ არის მოქცეული ფოკუსში).</translation>
 <translation id="6519884562954018934"><ph name="WIFINAME" />-თან შეერთება</translation>
 <translation id="6527303717912515753">გაზიარება</translation>
+<translation id="6586509689874700895">პირველ რიგში, გასადიდებლად დააჭირეთ <ph name="BUTTON_NAME" />-ს. შემდეგ კი გადაიღეთ ფოტო და გაძლიერებულ დეტალებს ნახავთ.</translation>
 <translation id="6617916774429601017">ყველა გარჩევადობის ჩვენება</translation>
 <translation id="6631515515009660915">არეკვლის გამორთვა</translation>
 <translation id="6652737148136672975">გადაიტანეთ კუთხის პოზიცია ისრებიანი კლავიშების მეშვეობით</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_lo.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_lo.xtb
index caa0052..2da0c8d5 100644
--- a/ash/webui/camera_app_ui/resources/strings/camera_strings_lo.xtb
+++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_lo.xtb
@@ -32,6 +32,7 @@
 <translation id="2175927920773552910">ລະຫັດ QR</translation>
 <translation id="2244252133441425811">ເປີດການນຳໃຊ້ຕົວເລືອກ FPS ວິດີໂອ</translation>
 <translation id="2271433936731426666">ເປີດການນຳໃຊ້ສະແນັບຊັອດວິດີໂອຂະໜາດເຕັມ</translation>
+<translation id="2281736597583450397">ຮັບລາຍລະອຽດທີ່ຄົມຊັດຂຶ້ນດ້ວຍການຊູມທີ່ປັບປຸງໃຫ້ດີຂຶ້ນ</translation>
 <translation id="2320741269052147773">ເລືອນໄປຊ້າຍ</translation>
 <translation id="2360840973209616515">ແອັບກ້ອງຖ່າຍຮູບຖືກຈັດການໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ.
         ສຳລັບລາຍລະອຽດ, ໃຫ້ຕິດຕໍ່ຫາຜູ້ເບິ່ງແຍງລະບົບ.</translation>
@@ -118,6 +119,7 @@
 ຖ້າຄຳຕິຊົມຂອງທ່ານກ່ຽວກັບຄຸນນະພາບຮູບ ຫຼື ວິດີໂອ, ກະລຸນາແນບຮູບ ຫຼື ວິດີໂອຕົວຢ່າງມານຳ ແລະ ໃຫ້ລາຍລະອຽດວ່າມີຫຍັງຜິດພາດ. (ຕົວຢ່າງ: ຮູບມືດເກີນໄປ ຫຼື ຮູບເປົ້າໝາຍບໍ່ຢູ່ໃນໂຟກັສ.)</translation>
 <translation id="6519884562954018934">ເຂົ້າຮ່ວມ <ph name="WIFINAME" /></translation>
 <translation id="6527303717912515753">ແຊຣ໌</translation>
+<translation id="6586509689874700895">ທຳອິດ, ໃຫ້ກົດ <ph name="BUTTON_NAME" /> ເພື່ອຊູມເຂົ້າ. ຈາກນັ້ນ, ຫຼັງຈາກທີ່ທ່ານຖ່າຍຮູບ, ທ່ານຈະເຫັນລາຍລະອຽດທີ່ປັບປຸງໃຫ້ດີຂຶ້ນ.</translation>
 <translation id="6617916774429601017">ສະແດງຄວາມລະອຽດທັງໝົດ</translation>
 <translation id="6631515515009660915">ປິດການສະທ້ອນແລ້ວ</translation>
 <translation id="6652737148136672975">ຍ້າຍຕຳແໜ່ງມຸມດ້ວຍປຸ່ມລູກສອນ</translation>
diff --git a/ash/webui/conch b/ash/webui/conch
index 6e3f1d1..33b5054 160000
--- a/ash/webui/conch
+++ b/ash/webui/conch
@@ -1 +1 @@
-Subproject commit 6e3f1d19bc845e70d07ed85628e7bcc19a57b2f0
+Subproject commit 33b50544ebbc3b6ae3aeeb4fabfbe2570dfa247e
diff --git a/base/allocator/miracle_parameter.h b/base/allocator/miracle_parameter.h
index d894e1a..68716789 100644
--- a/base/allocator/miracle_parameter.h
+++ b/base/allocator/miracle_parameter.h
@@ -14,7 +14,7 @@
 // dependency cycle of (base->miracle_parameter->base).
 // Eventually the miracle_parameter component will have a public interface in
 // //base/ and this could be removed.
-// TODO(crbug.com/1475915): remove miracle_parameter from
+// TODO(crbug.com/40279826): remove miracle_parameter from
 // //base/allocator/.
 
 namespace base {
diff --git a/base/allocator/partition_allocator/src/partition_alloc/address_space_randomization_unittest.cc b/base/allocator/partition_allocator/src/partition_alloc/address_space_randomization_unittest.cc
index 9b9edd95..f817670 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/address_space_randomization_unittest.cc
+++ b/base/allocator/partition_allocator/src/partition_alloc/address_space_randomization_unittest.cc
@@ -253,7 +253,8 @@
 #undef TEST_RANDOM_BIT
 
 // Checks that we can actually map memory in the requested range.
-// TODO(crbug.com/1318466): Extend to all operating systems once they are fixed.
+// TODO(crbug.com/40222892): Extend to all operating systems once they are
+// fixed.
 #if BUILDFLAG(IS_MAC)
 TEST(PartitionAllocAddressSpaceRandomizationTest, CanMapInAslrRange) {
   int tries = 0;
diff --git a/base/allocator/partition_allocator/src/partition_alloc/page_allocator_unittest.cc b/base/allocator/partition_allocator/src/partition_alloc/page_allocator_unittest.cc
index abbcfb9..5932bdc 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/page_allocator_unittest.cc
+++ b/base/allocator/partition_allocator/src/partition_alloc/page_allocator_unittest.cc
@@ -140,7 +140,7 @@
   EXPECT_FALSE(ReserveAddressSpace(EasyAllocSize()));
 }
 
-// TODO(crbug.com/765801): Test failed on chromium.win/Win10 Tests x64.
+// TODO(crbug.com/41344946): Test failed on chromium.win/Win10 Tests x64.
 #if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS)
 #define MAYBE_ReserveAddressSpace DISABLED_ReserveAddressSpace
 #else
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_unittest.cc b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_unittest.cc
index 2f83d90c..b60e04c 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_unittest.cc
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_unittest.cc
@@ -509,7 +509,7 @@
   };
 
   void DoReturnNullTest(size_t alloc_size, ReturnNullTestMode mode) {
-    // TODO(crbug.com/678782): Where necessary and possible, disable the
+    // TODO(crbug.com/41293809): Where necessary and possible, disable the
     // platform's OOM-killing behavior. OOM-killing makes this test flaky on
     // low-memory devices.
     if (!IsLargeMemoryDevice()) {
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ref_unittest.cc b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ref_unittest.cc
index 3d87d892..03bcdbf 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ref_unittest.cc
+++ b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ref_unittest.cc
@@ -7,7 +7,7 @@
 #include <functional>
 #include <type_traits>
 
-// TODO(crbug.com/957519): including logging.h is required because of the
+// TODO(crbug.com/41455655): including logging.h is required because of the
 // raw_ptr_traits definition that actually requires all types pointed with
 // raw_ptr to be defined.
 #include "base/logging.h"
diff --git a/base/android/java/src/org/chromium/base/CommandLine.java b/base/android/java/src/org/chromium/base/CommandLine.java
index f1eec40c..2ff05ff 100644
--- a/base/android/java/src/org/chromium/base/CommandLine.java
+++ b/base/android/java/src/org/chromium/base/CommandLine.java
@@ -432,7 +432,7 @@
 
         @Override
         protected void destroy() {
-            // TODO(https://crbug.com/771205): Downgrade this to an assert once we have eliminated
+            // TODO(crbug.com/40542965): Downgrade this to an assert once we have eliminated
             // tests that do this.
             throw new IllegalStateException("Can't destroy native command line after startup");
         }
diff --git a/base/android/java/src/org/chromium/base/FileUtils.java b/base/android/java/src/org/chromium/base/FileUtils.java
index 9ea6289..43b4ab3 100644
--- a/base/android/java/src/org/chromium/base/FileUtils.java
+++ b/base/android/java/src/org/chromium/base/FileUtils.java
@@ -150,11 +150,12 @@
 
     /**
      * Returns a URI that points at the file.
+     *
      * @param file File to get a URI for.
      * @return URI that points at that file, either as a content:// URI or a file:// URI.
      */
     public static Uri getUriForFile(File file) {
-        // TODO(crbug/709584): Uncomment this when http://crbug.com/709584 has been fixed.
+        // TODO(crbug.com/40514633): Uncomment this when http://crbug.com/709584 has been fixed.
         // assert !ThreadUtils.runningOnUiThread();
         Uri uri = null;
 
diff --git a/base/android/java/src/org/chromium/base/PathUtils.java b/base/android/java/src/org/chromium/base/PathUtils.java
index 19acf90..b48ca1b 100644
--- a/base/android/java/src/org/chromium/base/PathUtils.java
+++ b/base/android/java/src/org/chromium/base/PathUtils.java
@@ -92,7 +92,7 @@
         }
     }
 
-    // TODO(crbug.com/1512123): Merge the Chrome and WebView implementations
+    // TODO(crbug.com/41484704): Merge the Chrome and WebView implementations
     // of isPathUnderAppDir into one.
     @RequiresApi(Build.VERSION_CODES.N)
     public static boolean isPathUnderAppDir(String path, Context context) {
@@ -264,7 +264,7 @@
     @SuppressWarnings("unused")
     @CalledByNative
     public static @NonNull String getDownloadsDirectory() {
-        // TODO(crbug.com/508615): Move calls to getDownloadsDirectory() to background thread.
+        // TODO(crbug.com/41187555): Move calls to getDownloadsDirectory() to background thread.
         try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                 // https://developer.android.com/preview/privacy/scoped-storage
diff --git a/base/android/java/src/org/chromium/base/memory/MemoryPurgeManager.java b/base/android/java/src/org/chromium/base/memory/MemoryPurgeManager.java
index 185e8705..b346ea3 100644
--- a/base/android/java/src/org/chromium/base/memory/MemoryPurgeManager.java
+++ b/base/android/java/src/org/chromium/base/memory/MemoryPurgeManager.java
@@ -33,7 +33,7 @@
 
     // Arbitrary delay, a few minutes is what is used for background renderer purge, and 5 minutes
     // for freezing.
-    // TODO(crbug.com/1356242): Should ideally be tuned according to the distribution of background
+    // TODO(crbug.com/40860286): Should ideally be tuned according to the distribution of background
     // time residency.
     @VisibleForTesting static final long PURGE_DELAY_MS = 4 * 60 * 1000;
     private static final long NEVER = -1;
diff --git a/base/check.h b/base/check.h
index d0081be4..6e1691c 100644
--- a/base/check.h
+++ b/base/check.h
@@ -185,7 +185,7 @@
 // if (a == 1)
 //   CHECK(Foo());
 //
-// TODO(crbug.com/1380930): Remove the const bool when the blink-gc plugin has
+// TODO(crbug.com/40244950): Remove the const bool when the blink-gc plugin has
 // been updated to accept `if (LIKELY(!field_))` as well as `if (!field_)`.
 #define LOGGING_CHECK_FUNCTION_IMPL(check_stream, condition)              \
   switch (0)                                                              \
diff --git a/base/debug/allocation_trace.h b/base/debug/allocation_trace.h
index 034174a..f0bddd9 100644
--- a/base/debug/allocation_trace.h
+++ b/base/debug/allocation_trace.h
@@ -117,7 +117,7 @@
   //
   // The value is mutable since pre C++20 there is no const getter in
   // atomic_flag. All ways to get the value involve setting it.
-  // TODO(https://crbug.com/1284275): Remove mutable and make IsRecording() use
+  // TODO(crbug.com/42050406): Remove mutable and make IsRecording() use
   // atomic_flag::test();
   mutable std::atomic_flag is_recording_ = ATOMIC_FLAG_INIT;
 };
diff --git a/base/debug/stack_trace.h b/base/debug/stack_trace.h
index c3dc1a1..fae5c87f 100644
--- a/base/debug/stack_trace.h
+++ b/base/debug/stack_trace.h
@@ -68,7 +68,7 @@
  public:
   // LINT.IfChange(max_stack_frames)
 #if BUILDFLAG(IS_ANDROID)
-  // TODO(https://crbug.com/925525): Testing indicates that Android has issues
+  // TODO(crbug.com/41437515): Testing indicates that Android has issues
   // with a larger value here, so leave Android at 62.
   static constexpr size_t kMaxTraces = 62;
 #else
diff --git a/base/functional/unretained_traits.h b/base/functional/unretained_traits.h
index 116a74f0..6882ca1 100644
--- a/base/functional/unretained_traits.h
+++ b/base/functional/unretained_traits.h
@@ -89,7 +89,7 @@
 //
 // to make this easier to land without potentially breaking the tree.
 //
-// TODO(https://crbug.com/1392872): Enable this on all platforms, then in
+// TODO(crbug.com/40247956): Enable this on all platforms, then in
 // official builds, and then in non-test code as well.
 #if defined(FORCE_UNRETAINED_COMPLETENESS_CHECKS_FOR_TESTS) || \
     (!defined(UNIT_TEST) && !defined(OFFICIAL_BUILD) &&        \
diff --git a/base/memory/platform_shared_memory_region.h b/base/memory/platform_shared_memory_region.h
index 191af0e..ba8e8120 100644
--- a/base/memory/platform_shared_memory_region.h
+++ b/base/memory/platform_shared_memory_region.h
@@ -95,7 +95,7 @@
     //
     // This is only used to support sandbox_ipc_linux.cc, and should not be used
     // anywhere else in chrome. This is restricted via AllowCreateExecutable.
-    // TODO(crbug.com/982879): remove this when NaCl is unshipped.
+    // TODO(crbug.com/41470149): remove this when NaCl is unshipped.
     //
     // Returns an invalid ScopedFD if the call fails.
     static ScopedFD CreateFD(size_t size);
diff --git a/base/metrics/statistics_recorder_starvation_unittest.cc b/base/metrics/statistics_recorder_starvation_unittest.cc
index b1e879eb..6b596f0 100644
--- a/base/metrics/statistics_recorder_starvation_unittest.cc
+++ b/base/metrics/statistics_recorder_starvation_unittest.cc
@@ -237,7 +237,7 @@
 // StatisticsRecorder. When switching to a Read/Write lock (see crbug/1123627),
 // we encountered such a starvation issue, where a thread trying to write to the
 // internal map was starved out for 10+ seconds by readers on iOS.
-// TODO(crbug.com/1516818): StatisticsRecorderNoStarvation continuously emits a
+// TODO(crbug.com/41489801): StatisticsRecorderNoStarvation continuously emits a
 // new histogram which can cause the app memory footprint to grow unbounded and
 // watchdog kill the unit test on iOS devices.
 TEST_P(StatisticsRecorderStarvationTest, StatisticsRecorderNoStarvation) {
diff --git a/base/no_destructor.h b/base/no_destructor.h
index 8a431ba4..9c035c1b 100644
--- a/base/no_destructor.h
+++ b/base/no_destructor.h
@@ -122,7 +122,7 @@
   alignas(T) char storage_[sizeof(T)];
 
 #if defined(LEAK_SANITIZER)
-  // TODO(https://crbug.com/812277): This is a hack to work around the fact
+  // TODO(crbug.com/40562930): This is a hack to work around the fact
   // that LSan doesn't seem to treat NoDestructor as a root for reachability
   // analysis. This means that code like this:
   //   static base::NoDestructor<std::vector<int>> v({1, 2, 3});
diff --git a/base/notreached.h b/base/notreached.h
index c35804d..94264904 100644
--- a/base/notreached.h
+++ b/base/notreached.h
@@ -10,7 +10,7 @@
 #include "base/dcheck_is_on.h"
 #include "base/logging_buildflags.h"
 
-// TODO(crbug.com/1520664): Remove once NOTIMPLEMENTED() call sites include
+// TODO(crbug.com/41493641): Remove once NOTIMPLEMENTED() call sites include
 // base/notimplemented.h.
 #include "base/notimplemented.h"
 
diff --git a/base/sampling_heap_profiler/sampling_heap_profiler_unittest.cc b/base/sampling_heap_profiler/sampling_heap_profiler_unittest.cc
index 3e827da1..2e07a61 100644
--- a/base/sampling_heap_profiler/sampling_heap_profiler_unittest.cc
+++ b/base/sampling_heap_profiler/sampling_heap_profiler_unittest.cc
@@ -245,7 +245,7 @@
 
 // Platform TLS: alloc+free[ns]: 22.184  alloc[ns]: 8.910  free[ns]: 13.274
 // thread_local: alloc+free[ns]: 18.353  alloc[ns]: 5.021  free[ns]: 13.331
-// TODO(crbug.com/1117342) Disabled on Mac
+// TODO(crbug.com/40145097) Disabled on Mac
 #if BUILDFLAG(IS_MAC)
 #define MAYBE_MANUAL_SamplerMicroBenchmark DISABLED_MANUAL_SamplerMicroBenchmark
 #else
diff --git a/base/strings/escape.cc b/base/strings/escape.cc
index c241ec6..54a8c250 100644
--- a/base/strings/escape.cc
+++ b/base/strings/escape.cc
@@ -539,7 +539,7 @@
   // before FeatureList initialization. In that case, fallback to the feature's
   // default state.
   //
-  // TODO(crbug.com/1321924): Cleanup this feature.
+  // TODO(crbug.com/40224104): Cleanup this feature.
   const bool optimize_data_urls_feature_is_enabled =
       base::FeatureList::GetInstance()
           ? base::FeatureList::IsEnabled(features::kOptimizeDataUrls)
diff --git a/base/task/sequence_manager/thread_controller.cc b/base/task/sequence_manager/thread_controller.cc
index 0ffe47a..4b85506c 100644
--- a/base/task/sequence_manager/thread_controller.cc
+++ b/base/task/sequence_manager/thread_controller.cc
@@ -143,13 +143,13 @@
 #if BUILDFLAG(ENABLE_BASE_TRACING)
   perfetto_track_.emplace(
       reinterpret_cast<uint64_t>(this),
-      // TODO(crbug.com/1006541): Replace with ThreadTrack::Current() after SDK
+      // TODO(crbug.com/42050015): Replace with ThreadTrack::Current() after SDK
       // migration.
       // In the non-SDK version, ThreadTrack::Current() returns a different
       // track id on some platforms (for example Mac OS), which results in
       // async tracks not being associated with their thread.
       perfetto::ThreadTrack::ForThread(base::PlatformThread::CurrentId()));
-  // TODO(1006541): Use Perfetto library to name this Track.
+  // TODO(crbug.com/42050015): Use Perfetto library to name this Track.
   // auto desc = perfetto_track_->Serialize();
   // desc.set_name(JoinString({"MessagePumpPhases", thread_name}, " "));
   // perfetto::internal::TrackEventDataSource::SetTrackDescriptor(
@@ -553,8 +553,8 @@
   if (is_tracing_enabled) {
     if (!was_tracing_enabled_) {
       // The first event name on the track hackily names the track...
-      // TODO(1006541): Use the Perfetto library to properly name this Track in
-      // EnableRecording above.
+      // TODO(crbug.com/42050015): Use the Perfetto library to properly name
+      // this Track in EnableRecording above.
       TRACE_EVENT_INSTANT(TRACE_DISABLED_BY_DEFAULT("base"),
                           "MessagePumpPhases", *perfetto_track_,
                           last_phase_end_ - Seconds(1));
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc b/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc
index 17673f3..e4489af 100644
--- a/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc
+++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc
@@ -97,7 +97,7 @@
   }
 };
 
-// TODO(crbug.com/901373): Deduplicate FakeTaskRunners.
+// TODO(crbug.com/40600768): Deduplicate FakeTaskRunners.
 class FakeTaskRunner : public SingleThreadTaskRunner {
  public:
   bool PostDelayedTask(const Location& from_here,
diff --git a/base/test/ios/wait_util.h b/base/test/ios/wait_util.h
index 91790965..5665bf65 100644
--- a/base/test/ios/wait_util.h
+++ b/base/test/ios/wait_util.h
@@ -32,7 +32,7 @@
 
 // Constant for timeout while waiting for clear browsing data. It seems this
 // can take a very long time on the bots when running simulators in parallel.
-// TODO(crbug.com/993513): Investigate why this is sometimes very slow.
+// TODO(crbug.com/41475878): Investigate why this is sometimes very slow.
 constexpr TimeDelta kWaitForClearBrowsingDataTimeout = Seconds(45);
 
 // Constant for timeout while waiting for cookies operations to complete.
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc
index d6def8e..66fac98 100644
--- a/base/test/test_suite.cc
+++ b/base/test/test_suite.cc
@@ -578,7 +578,7 @@
 #if BUILDFLAG(DCHECK_IS_CONFIGURABLE)
   // Default the configurable DCHECK level to FATAL when running death tests'
   // child process, so that they behave as expected.
-  // TODO(crbug.com/1057995): Remove this in favor of the codepath in
+  // TODO(crbug.com/40120934): Remove this in favor of the codepath in
   // FeatureList::SetInstance() when/if OnTestStart() TestEventListeners
   // are fixed to be invoked in the child process as expected.
   if (command_line->HasSwitch("gtest_internal_run_death_test"))
diff --git a/base/test/test_timeouts.cc b/base/test/test_timeouts.cc
index 66e53f1..2abfc7b 100644
--- a/base/test/test_timeouts.cc
+++ b/base/test/test_timeouts.cc
@@ -24,7 +24,7 @@
      defined(ADDRESS_SANITIZER)) &&                   \
     BUILDFLAG(IS_CHROMEOS_ASH)
 // History of this value:
-// 1) TODO(crbug.com/1058022): reduce the multiplier back to 2x.
+// 1) TODO(crbug.com/40120948): reduce the multiplier back to 2x.
 // 2) A number of tests on ChromeOS run very close to the base limit, so
 // ChromeOS gets 3x. TODO(b:318608561) Reduce back to 3x once OOBE load time is
 // lower.
diff --git a/base/test/trace_event_analyzer.cc b/base/test/trace_event_analyzer.cc
index ca34d905..e0d1415 100644
--- a/base/test/trace_event_analyzer.cc
+++ b/base/test/trace_event_analyzer.cc
@@ -173,7 +173,7 @@
   }
 
   // For each argument, copy the type and create a trace_analyzer::TraceValue.
-  // TODO(crbug.com/1303874): Add BINARY and LIST arg types if needed.
+  // TODO(crbug.com/40826205): Add BINARY and LIST arg types if needed.
   if (maybe_args) {
     for (auto pair : *maybe_args) {
       switch (pair.second.type()) {
diff --git a/base/timer/timer.h b/base/timer/timer.h
index b34be71..b9f83e43 100644
--- a/base/timer/timer.h
+++ b/base/timer/timer.h
@@ -163,7 +163,7 @@
   virtual void Reset();
 
   // DEPRECATED. Call Stop() instead.
-  // TODO(1262205): Remove this method and all callers.
+  // TODO(crbug.com/40202541): Remove this method and all callers.
   void AbandonAndStop();
 
   TimeTicks desired_run_time() const {
diff --git a/base/trace_event/base_tracing.h b/base/trace_event/base_tracing.h
index c33b7730..f3ed650a 100644
--- a/base/trace_event/base_tracing.h
+++ b/base/trace_event/base_tracing.h
@@ -14,7 +14,7 @@
 
 #if BUILDFLAG(ENABLE_BASE_TRACING)
 // Update the check in //base/PRESUBMIT.py when adding new headers here.
-// TODO(crbug/1006541): Switch to perfetto for trace event implementation.
+// TODO(crbug.com/42050015): Switch to perfetto for trace event implementation.
 #include "base/trace_event/heap_profiler.h"               // nogncheck
 #include "base/trace_event/interned_args_helper.h"        // nogncheck
 #include "base/trace_event/memory_allocator_dump_guid.h"  // nogncheck
diff --git a/base/trace_event/typed_macros.h b/base/trace_event/typed_macros.h
index 3268118..e2a2510 100644
--- a/base/trace_event/typed_macros.h
+++ b/base/trace_event/typed_macros.h
@@ -28,7 +28,7 @@
 // implementation of trace macros.
 // [1] https://perfetto.dev/docs/instrumentation/track-events
 // [2] //third_party/perfetto/include/perfetto/tracing/track_event.h
-// TODO(crbug/1006541): Replace this file with the Perfetto client library.
+// TODO(crbug.com/42050015): Replace this file with the Perfetto client library.
 
 // Typed event macros:
 //
diff --git a/build/android/chromium_annotations.flags b/build/android/chromium_annotations.flags
index aaedafd..99a670b1 100644
--- a/build/android/chromium_annotations.flags
+++ b/build/android/chromium_annotations.flags
@@ -60,9 +60,17 @@
 }
 
 # Mark fields with this to help R8 figure out that they cannot be null.
--assumenosideeffects class ** {
+# Use assumevalues in addition to assumenosideeffects block because Google3 proguard cannot parse
+# assumenosideeffects blocks which overwrite return value.
+-assumevalues class ** {
   @org.chromium.build.annotations.AssumeNonNull *** *(...) return _NONNULL_;
 }
 -assumenosideeffects class ** {
+  @org.chromium.build.annotations.AssumeNonNull *** *(...);
+}
+-assumevalues class ** {
   @org.chromium.build.annotations.AssumeNonNull *** * return _NONNULL_;
 }
+-assumenosideeffects class ** {
+  @org.chromium.build.annotations.AssumeNonNull *** *;
+}
diff --git a/build/android/gyp/compile_java.py b/build/android/gyp/compile_java.py
index b39b826..30a82eb 100755
--- a/build/android/gyp/compile_java.py
+++ b/build/android/gyp/compile_java.py
@@ -64,7 +64,7 @@
     'ToStringReturnsNull',
     # If possible, this should be automatically fixed if turned on:
     'MalformedInlineTag',
-    # TODO(crbug.com/834807): Follow steps in bug
+    # TODO(crbug.com/41384359): Follow steps in bug
     'DoubleBraceInitialization',
     # TODO(crbug.com/834790): Follow steps in bug.
     'CatchAndPrintStackTrace',
diff --git a/build/android/gyp/util/java_cpp_utils.py b/build/android/gyp/util/java_cpp_utils.py
index 46f05f6..c42eeea 100644
--- a/build/android/gyp/util/java_cpp_utils.py
+++ b/build/android/gyp/util/java_cpp_utils.py
@@ -65,7 +65,7 @@
   return package, class_name
 
 
-# TODO(crbug.com/937282): Work will be needed if we want to annotate specific
+# TODO(crbug.com/40616187): Work will be needed if we want to annotate specific
 # constants in the file to be parsed.
 class CppConstantParser:
   """Parses C++ constants, retaining their comments.
diff --git a/build/android/pylib/android/logcat_symbolizer.py b/build/android/pylib/android/logcat_symbolizer.py
index 84d812ca6..61fd5111 100644
--- a/build/android/pylib/android/logcat_symbolizer.py
+++ b/build/android/pylib/android/logcat_symbolizer.py
@@ -65,7 +65,7 @@
       # crash log inside the logcat and pass only the crash log to the script,
       # because we don't want to lose other information in the logcat that,
       # if passed to the stack script, will just be ignored by it.
-      # TODO(crbug.com/755225): Rewrite the logic here.
+      # TODO(crbug.com/41339210): Rewrite the logic here.
       outside_of_crash_log = True
       in_lower_half_crash = False
       data_to_symbolize = []
diff --git a/build/chromeos/test_runner.py b/build/chromeos/test_runner.py
index 4936891..260b978 100755
--- a/build/chromeos/test_runner.py
+++ b/build/chromeos/test_runner.py
@@ -837,7 +837,7 @@
   # certain libraries need to be pushed to the device. It looks for the args via
   # an env var. To trigger the default deploying behavior, give it a dummy set
   # of args.
-  # TODO(crbug.com/823996): Make the GN-dependent deps controllable via cmd
+  # TODO(crbug.com/40567963): Make the GN-dependent deps controllable via cmd
   # line args.
   if not env.get('GN_ARGS'):
     env['GN_ARGS'] = 'enable_nacl = true'
diff --git a/build/config/arm.gni b/build/config/arm.gni
index 5b404c1..21fc25c6 100644
--- a/build/config/arm.gni
+++ b/build/config/arm.gni
@@ -41,7 +41,7 @@
 
   # For lacros build, we use ARM v8 by default.
   if (is_chromeos_lacros && arm_arch == "") {
-    # TODO(crbug.com/1467681) Enable i8mm and dotprod instructions for ffmpeg
+    # TODO(crbug.com/40276884) Enable i8mm and dotprod instructions for ffmpeg
     # if ever we update to a version of arm that supports these instructions.
     arm_version = 8
     arm_arch = "armv8-a+crc"
diff --git a/build/config/chrome_build.gni b/build/config/chrome_build.gni
index 4100059f..cd12d2f 100644
--- a/build/config/chrome_build.gni
+++ b/build/config/chrome_build.gni
@@ -41,7 +41,7 @@
 declare_args() {
   # Whether to apply size->speed trade-offs to the secondary toolchain.
   # Relevant only for 64-bit target_cpu.
-  is_high_end_android_secondary_toolchain = is_high_end_android
+  is_high_end_android_secondary_toolchain = false
 }
 
 assert(!is_chrome_for_testing || !is_chrome_branded,
diff --git a/build/config/clang/BUILD.gn b/build/config/clang/BUILD.gn
index 498b3ebe..8cbeb6e 100644
--- a/build/config/clang/BUILD.gn
+++ b/build/config/clang/BUILD.gn
@@ -49,7 +49,7 @@
       "-Xclang",
       "disable-check-raw-ptr-to-stack-allocated-error",
 
-      # TODO(https://crbug.com/1504043): Remove when raw_ptr check has been
+      # TODO(crbug.com/40944547): Remove when raw_ptr check has been
       # enabled for the dawn repo.
       "-Xclang",
       "-plugin-arg-find-bad-constructs",
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 5a03a71b..5940c9a1 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -1926,7 +1926,7 @@
 
       if (!is_nacl) {
         cflags_cc += [
-          # TODO(https://crbug.com/1513724): Fix and re-enable.
+          # TODO(crbug.com/41486292): Fix and re-enable.
           "-Wno-c++11-narrowing-const-reference",
         ]
       }
@@ -2539,7 +2539,7 @@
 # instead of code size. This config is exactly the same as "optimize_max"
 # except that we use -O3 instead of -O2 on non-IRT platforms.
 #
-# TODO(crbug.com/621335) - rework how all of these configs are related
+# TODO(crbug.com/41259697) - rework how all of these configs are related
 # so that we don't need this disclaimer.
 config("optimize_speed") {
   if (is_nacl && is_nacl_irt) {
diff --git a/build/config/compiler/pgo/BUILD.gn b/build/config/compiler/pgo/BUILD.gn
index d047c7e..afa4aa2 100644
--- a/build/config/compiler/pgo/BUILD.gn
+++ b/build/config/compiler/pgo/BUILD.gn
@@ -17,6 +17,12 @@
   # are not required to be defined when we're not actually using PGO.
   if (chrome_pgo_phase == 1 && is_clang && !is_nacl && is_a_target_toolchain) {
     cflags = [ "-fprofile-generate" ]
+    if (temporal_pgo_profile) {
+      cflags += [
+        "-mllvm",
+        "-pgo-temporal-instrumentation",
+      ]
+    }
     if (!is_win) {
       # Windows directly calls link.exe instead of the compiler driver when
       # linking, and embeds the path to the profile runtime library as
diff --git a/build/config/compiler/pgo/pgo.gni b/build/config/compiler/pgo/pgo.gni
index 008a5752..d9a74fe 100644
--- a/build/config/compiler/pgo/pgo.gni
+++ b/build/config/compiler/pgo/pgo.gni
@@ -34,4 +34,7 @@
 
   # When using chrome_pgo_phase = 2, read profile data from this path.
   pgo_data_path = ""
+
+  # Whether to enable temporal pgo or not (experimental).
+  temporal_pgo_profile = false
 }
diff --git a/build/fuchsia/test/compatible_utils.py b/build/fuchsia/test/compatible_utils.py
index b59fbbd..bc4ce2e 100644
--- a/build/fuchsia/test/compatible_utils.py
+++ b/build/fuchsia/test/compatible_utils.py
@@ -31,7 +31,7 @@
     When running unattended, confirmation prompts and the like are suppressed.
     """
 
-    # TODO(crbug/1401387): Change to mixin based approach.
+    # TODO(crbug.com/40884247): Change to mixin based approach.
     return 'SWARMING_SERVER' in os.environ
 
 
diff --git a/build/lacros/lacros_resource_sizes.py b/build/lacros/lacros_resource_sizes.py
index bcb471f1..23ce0d0 100755
--- a/build/lacros/lacros_resource_sizes.py
+++ b/build/lacros/lacros_resource_sizes.py
@@ -310,7 +310,7 @@
     tracked_groups.append(
         _Group(paths=['nacl_helper_bootstrap'],
                title='File: nacl_helper_bootstrap'))
-  # TODO(https://crbug.com/1356761): remove the following part once nacl files
+  # TODO(crbug.com/40236427): remove the following part once nacl files
   # are available.
   elif args.arch == 'arm64':
     tracked_groups.remove(
diff --git a/cc/mojo_embedder/viz_layer_context.cc b/cc/mojo_embedder/viz_layer_context.cc
index 8b74d2cab..cac7ca5 100644
--- a/cc/mojo_embedder/viz_layer_context.cc
+++ b/cc/mojo_embedder/viz_layer_context.cc
@@ -33,7 +33,7 @@
 }
 
 void VizLayerContext::Commit(const CommitState& state) {
-  // TODO(https://crbug.com/1431762): Push actual commit data. For now we only
+  // TODO(crbug.com/40902503): Push actual commit data. For now we only
   // update basic parameters required for any LayerTreeHost drawing.
   auto update = viz::mojom::LayerTreeUpdate::New();
   update->device_viewport = state.device_viewport_rect;
diff --git a/cc/paint/paint_op_buffer.h b/cc/paint/paint_op_buffer.h
index f0e673b7..d707d64 100644
--- a/cc/paint/paint_op_buffer.h
+++ b/cc/paint/paint_op_buffer.h
@@ -157,7 +157,7 @@
     // e.g. in the case of UI.
     bool is_privileged = false;
     // The HDR headroom to apply when deserializing.
-    // TODO(https://crbug.com/1483235): Move this to playback instead of
+    // TODO(crbug.com/40281980): Move this to playback instead of
     // deserialization.
     float hdr_headroom = 1.f;
     SharedImageProvider* shared_image_provider = nullptr;
diff --git a/cc/raster/categorized_worker_pool.cc b/cc/raster/categorized_worker_pool.cc
index 201abcc..317bd1e 100644
--- a/cc/raster/categorized_worker_pool.cc
+++ b/cc/raster/categorized_worker_pool.cc
@@ -219,7 +219,7 @@
       std::end(kBackgroundThreadPriorityCategories)};
 
   base::SimpleThread::Options thread_options;
-// TODO(1326996): Figure out whether !IS_MAC can be lifted here.
+// TODO(crbug.com/40226019): Figure out whether !IS_MAC can be lifted here.
 #if !BUILDFLAG(IS_MAC)
   thread_options.thread_type = base::ThreadType::kBackground;
 #endif
diff --git a/cc/trees/layer_tree_host_unittest_picture.cc b/cc/trees/layer_tree_host_unittest_picture.cc
index f1ba03c..91955c77 100644
--- a/cc/trees/layer_tree_host_unittest_picture.cc
+++ b/cc/trees/layer_tree_host_unittest_picture.cc
@@ -569,7 +569,7 @@
 
 // Multi-thread only because in single thread you can't pinch zoom on the
 // compositor thread.
-// TODO(https://crbug.com/997866): Flaky on several platforms.
+// TODO(crbug.com/41478255): Flaky on several platforms.
 // MULTI_THREAD_TEST_F(LayerTreeHostPictureTestRSLLMembershipWithScale);
 
 class LayerTreeHostPictureTestForceRecalculateScales
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc
index fd4bd5e..f11d49a 100644
--- a/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -1368,7 +1368,7 @@
 };
 
 // TODO(crbug.com/1201662): Flaky on Fuchsia, ChromeOS, and Linux.
-// TODO(crbug.com/1522172): Flaky on Windows ASAN.
+// TODO(crbug.com/41495136): Flaky on Windows ASAN.
 #if !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_CHROMEOS) && \
     !BUILDFLAG(IS_LINUX) && !(BUILDFLAG(IS_WIN) && defined(ADDRESS_SANITIZER))
 MULTI_THREAD_TEST_F(LayerTreeHostScrollTestImplOnlyScrollSnap);
diff --git a/cc/trees/local_layer_context.cc b/cc/trees/local_layer_context.cc
index 6b9399d..f205a14 100644
--- a/cc/trees/local_layer_context.cc
+++ b/cc/trees/local_layer_context.cc
@@ -54,7 +54,7 @@
 }
 
 void LocalLayerContext::Commit(const CommitState& state) {
-  // TODO(https://crbug.com/1431762): Actually update the tree contents.
+  // TODO(crbug.com/40902503): Actually update the tree contents.
   host_->SetViewportRectAndScale(state.device_viewport_rect,
                                  state.device_scale_factor,
                                  state.local_surface_id_from_parent);
diff --git a/cc/trees/local_layer_context.h b/cc/trees/local_layer_context.h
index 18a0745..d659767 100644
--- a/cc/trees/local_layer_context.h
+++ b/cc/trees/local_layer_context.h
@@ -89,7 +89,7 @@
   const raw_ptr<MutatorHost> mutator_host_;
 
   // The concrete LayerTreeHost which the client is controlling.
-  // TODO(https://crbug.com/1431762): Own and manage a LayerTreeHostImpl
+  // TODO(crbug.com/40902503): Own and manage a LayerTreeHostImpl
   // directly instead of proxying through a single-threaded LayerTreeHost.
   const LayerListSettings layer_list_settings_;
   std::unique_ptr<LayerTreeHost> host_;
diff --git a/chrome/VERSION b/chrome/VERSION
index 4ba5ee2..2e2dc96e 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=126
 MINOR=0
-BUILD=6434
+BUILD=6435
 PATCH=0
diff --git a/chrome/android/expectations/monochrome_64_32_public_bundle.proguard_flags.expected b/chrome/android/expectations/monochrome_64_32_public_bundle.proguard_flags.expected
index f3ae530e..4f092f9 100644
--- a/chrome/android/expectations/monochrome_64_32_public_bundle.proguard_flags.expected
+++ b/chrome/android/expectations/monochrome_64_32_public_bundle.proguard_flags.expected
@@ -137,12 +137,20 @@
 }
 
 # Mark fields with this to help R8 figure out that they cannot be null.
--assumenosideeffects class ** {
+# Use assumevalues in addition to assumenosideeffects block because Google3 proguard cannot parse
+# assumenosideeffects blocks which overwrite return value.
+-assumevalues class ** {
   @org.chromium.build.annotations.AssumeNonNull *** *(...) return _NONNULL_;
 }
 -assumenosideeffects class ** {
+  @org.chromium.build.annotations.AssumeNonNull *** *(...);
+}
+-assumevalues class ** {
   @org.chromium.build.annotations.AssumeNonNull *** * return _NONNULL_;
 }
+-assumenosideeffects class ** {
+  @org.chromium.build.annotations.AssumeNonNull *** *;
+}
 
 # File: ../../base/android/proguard/chromium_apk.flags
 # Copyright 2016 The Chromium Authors
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryViewBridge.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryViewBridge.java
index 92dfd07..63608d3 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryViewBridge.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryViewBridge.java
@@ -23,18 +23,17 @@
 import org.chromium.ui.base.WindowAndroid;
 import org.chromium.url.GURL;
 
-/**
- * JNI call glue for AutofillExternalDelagate C++ and Java objects.
- * This provides an alternative UI for Autofill suggestions, and replaces AutofillPopupBridge when
- * --enable-autofill-keyboard-accessory-view is passed on the command line.
- */
+import java.util.Arrays;
+import java.util.List;
+
+/** JNI call glue between C++ (AutofillKeyboardAccessoryViewImpl) and Java objects. */
 @JNINamespace("autofill")
 public class AutofillKeyboardAccessoryViewBridge implements AutofillDelegate {
     private long mNativeAutofillKeyboardAccessory;
     private @Nullable ObservableSupplier<ManualFillingComponent> mManualFillingComponentSupplier;
     private @Nullable ManualFillingComponent mManualFillingComponent;
     private @Nullable Context mContext;
-    private final PropertyProvider<AutofillSuggestion[]> mChipProvider =
+    private final PropertyProvider<List<AutofillSuggestion>> mChipProvider =
             new PropertyProvider<>(AccessoryAction.AUTOFILL_SUGGESTION);
     private final Callback<ManualFillingComponent> mFillingComponentObserver =
             this::connectToFillingComponent;
@@ -118,7 +117,7 @@
     @CalledByNative
     private void dismiss() {
         if (mManualFillingComponentSupplier != null) {
-            mChipProvider.notifyObservers(new AutofillSuggestion[0]);
+            mChipProvider.notifyObservers(List.of());
             mManualFillingComponentSupplier.removeObserver(mFillingComponentObserver);
         }
         dismissed();
@@ -127,11 +126,13 @@
 
     /**
      * Shows an Autofill view with specified suggestions.
+     *
      * @param suggestions Autofill suggestions to be displayed.
      */
     @CalledByNative
-    private void show(AutofillSuggestion[] suggestions) {
-        mChipProvider.notifyObservers(suggestions);
+    private void show(@JniType("std::vector") Object[] suggestions) {
+        mChipProvider.notifyObservers(
+                (List<AutofillSuggestion>) (List<?>) Arrays.asList(suggestions));
     }
 
     @CalledByNative
@@ -145,14 +146,9 @@
                 () -> this.onDeletionDialogClosed(/* confirmed= */ false));
     }
 
-    @CalledByNative
-    private static AutofillSuggestion[] createAutofillSuggestionArray(int size) {
-        return new AutofillSuggestion[size];
-    }
-
     /**
-     * @param array AutofillSuggestion array that should get a new suggestion added.
-     * @param index Index in the array where to place a new suggestion.
+     * Creates an Autofill suggestion.
+     *
      * @param label Suggested text. The text that's going to be filled in the focused field, with a
      *     few exceptions:
      *     <ul>
@@ -171,11 +167,10 @@
      *     suggestion.
      * @param customIconUrl The url used to fetch the custom icon to be displayed in the autofill
      *     suggestion chip.
+     * @return an AutofillSuggestion containing the above information.
      */
     @CalledByNative
-    private static void addToAutofillSuggestionArray(
-            AutofillSuggestion[] array,
-            int index,
+    private static AutofillSuggestion createAutofillSuggestion(
             @JniType("std::u16string") String label,
             @JniType("std::u16string") String sublabel,
             int iconId,
@@ -184,24 +179,24 @@
             @JniType("std::string") String featureForIPH,
             GURL customIconUrl) {
         int drawableId = iconId == 0 ? DropdownItem.NO_ICON : iconId;
-        array[index] =
-                new AutofillSuggestion.Builder()
-                        .setLabel(label)
-                        .setSubLabel(sublabel)
-                        .setIconId(drawableId)
-                        .setIsIconAtStart(false)
-                        .setPopupItemId(popupItemId)
-                        .setIsDeletable(isDeletable)
-                        .setIsMultiLineLabel(false)
-                        .setIsBoldLabel(false)
-                        .setFeatureForIPH(featureForIPH)
-                        .setCustomIconUrl(customIconUrl)
-                        .build();
+        return new AutofillSuggestion.Builder()
+                .setLabel(label)
+                .setSubLabel(sublabel)
+                .setIconId(drawableId)
+                .setIsIconAtStart(false)
+                .setPopupItemId(popupItemId)
+                .setIsDeletable(isDeletable)
+                .setIsMultiLineLabel(false)
+                .setIsBoldLabel(false)
+                .setFeatureForIPH(featureForIPH)
+                .setCustomIconUrl(customIconUrl)
+                .build();
     }
 
     /**
      * Used to register the filling component that receives and renders the autofill suggestions.
      * Noop if the component hasn't changed or became null.
+     *
      * @param fillingComponent The {@link ManualFillingComponent} displaying suggestions as chips.
      */
     private void connectToFillingComponent(@Nullable ManualFillingComponent fillingComponent) {
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingCoordinator.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingCoordinator.java
index 6b2cc0e..07410c2 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingCoordinator.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingCoordinator.java
@@ -28,13 +28,14 @@
 import org.chromium.ui.DropdownPopupWindow;
 import org.chromium.ui.base.WindowAndroid;
 
+import java.util.List;
+
 /**
  * Handles requests to the manual UI for filling passwords, payments and other user data. Ideally,
  * the caller has no access to Keyboard accessory or sheet and is only interacting with this
- * component.
- * For that, it facilitates the communication between {@link KeyboardAccessoryCoordinator} and
- * {@link AccessorySheetCoordinator} to add and trigger surfaces that may assist users while filling
- * fields.
+ * component. For that, it facilitates the communication between {@link
+ * KeyboardAccessoryCoordinator} and {@link AccessorySheetCoordinator} to add and trigger surfaces
+ * that may assist users while filling fields.
  */
 class ManualFillingCoordinator implements ManualFillingComponent {
     private final ManualFillingMediator mMediator = new ManualFillingMediator();
@@ -157,7 +158,8 @@
 
     @Override
     public void registerAutofillProvider(
-            PropertyProvider<AutofillSuggestion[]> autofillProvider, AutofillDelegate delegate) {
+            PropertyProvider<List<AutofillSuggestion>> autofillProvider,
+            AutofillDelegate delegate) {
         mMediator.registerAutofillProvider(autofillProvider, delegate);
     }
 
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java
index bd87e17d..b65f95b2 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMediator.java
@@ -80,6 +80,7 @@
 import org.chromium.ui.mojom.VirtualKeyboardMode;
 
 import java.util.HashSet;
+import java.util.List;
 
 /**
  * This part of the manual filling component manages the state of the manual filling flow depending
@@ -321,7 +322,8 @@
     }
 
     void registerAutofillProvider(
-            PropertyProvider<AutofillSuggestion[]> autofillProvider, AutofillDelegate delegate) {
+            PropertyProvider<List<AutofillSuggestion>> autofillProvider,
+            AutofillDelegate delegate) {
         if (!isInitialized()) return;
         if (mKeyboardAccessory == null) return;
         mKeyboardAccessory.registerAutofillProvider(autofillProvider, delegate);
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryCoordinator.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryCoordinator.java
index cdaab7a..835a805 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryCoordinator.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryCoordinator.java
@@ -39,6 +39,8 @@
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.modelutil.RecyclerViewAdapter;
 
+import java.util.List;
+
 /**
  * Creates and owns all elements which are part of the keyboard accessory component. It's part of
  * the controller but will mainly forward events (like adding a tab, or showing the accessory) to
@@ -246,14 +248,15 @@
     }
 
     /**
-     * Registers a Provider.Observer to the given Provider. The
-     * new observer will render chips into the accessory bar for every new suggestion and call the
-     * given {@link AutofillDelegate} when the user interacts with a chip.
-     * @param provider A {@link Provider<AutofillSuggestion[]>}.
+     * Registers a Provider.Observer to the given Provider. The new observer will render chips into
+     * the accessory bar for every new suggestion and call the given {@link AutofillDelegate} when
+     * the user interacts with a chip.
+     *
+     * @param provider A {@link Provider<List<AutofillSuggestion>>}.
      * @param delegate A {@link AutofillDelegate}.
      */
     public void registerAutofillProvider(
-            Provider<AutofillSuggestion[]> provider, AutofillDelegate delegate) {
+            Provider<List<AutofillSuggestion>> provider, AutofillDelegate delegate) {
         provider.addObserver(mMediator.createAutofillSuggestionsObserver(delegate));
     }
 
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java
index 87739b0..bbf3565 100644
--- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java
+++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java
@@ -86,12 +86,13 @@
      * Creates an observer object that refreshes the accessory bar items when a connected provider
      * notifies it about new {@link AutofillSuggestion}s. It ensures the delegate receives
      * interactions with the view representing a suggestion.
+     *
      * @param delegate A {@link AutofillDelegate}.
      * @return A {@link Provider.Observer} accepting only {@link AutofillSuggestion}s.
      */
-    Provider.Observer<AutofillSuggestion[]> createAutofillSuggestionsObserver(
+    Provider.Observer<List<AutofillSuggestion>> createAutofillSuggestionsObserver(
             AutofillDelegate delegate) {
-        return (@AccessoryAction int typeId, AutofillSuggestion[] suggestions) -> {
+        return (@AccessoryAction int typeId, List<AutofillSuggestion> suggestions) -> {
             assert typeId == AccessoryAction.AUTOFILL_SUGGESTION
                     : "Autofill suggestions observer received wrong data: " + typeId;
             List<BarItem> retainedItems = collectItemsToRetain(AccessoryAction.AUTOFILL_SUGGESTION);
@@ -167,10 +168,10 @@
     }
 
     private List<AutofillBarItem> toBarItems(
-            AutofillSuggestion[] suggestions, AutofillDelegate delegate) {
-        List<AutofillBarItem> barItems = new ArrayList<>(suggestions.length);
-        for (int position = 0; position < suggestions.length; ++position) {
-            AutofillSuggestion suggestion = suggestions[position];
+            List<AutofillSuggestion> suggestions, AutofillDelegate delegate) {
+        List<AutofillBarItem> barItems = new ArrayList<>(suggestions.size());
+        for (int position = 0; position < suggestions.size(); ++position) {
+            AutofillSuggestion suggestion = suggestions.get(position);
             if (!shouldShowSuggestion(suggestion)) continue;
             barItems.add(new AutofillBarItem(suggestion, createAutofillAction(delegate, position)));
         }
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java
index cd48f89..c8e1913 100644
--- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java
+++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java
@@ -63,6 +63,8 @@
 import org.chromium.ui.modelutil.PropertyObservable.PropertyObserver;
 import org.chromium.ui.test.util.modelutil.FakeViewProvider;
 
+import java.util.List;
+
 /** Controller tests for the keyboard accessory component. */
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(
@@ -195,7 +197,7 @@
     public void testSortsActionsBasedOnType() {
         PropertyProvider<Action[]> generationProvider =
                 new PropertyProvider<>(GENERATE_PASSWORD_AUTOMATIC);
-        PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
+        PropertyProvider<List<AutofillSuggestion>> autofillSuggestionProvider =
                 new PropertyProvider<>(AUTOFILL_SUGGESTION);
         PropertyProvider<Action[]> credManProvider =
                 new PropertyProvider<>(CREDMAN_CONDITIONAL_UI_REENTRY);
@@ -222,8 +224,7 @@
                         .build();
         Action generationAction = new Action(GENERATE_PASSWORD_AUTOMATIC, (a) -> {});
         Action credManAction = new Action(CREDMAN_CONDITIONAL_UI_REENTRY, (a) -> {});
-        autofillSuggestionProvider.notifyObservers(
-                new AutofillSuggestion[] {suggestion1, suggestion2});
+        autofillSuggestionProvider.notifyObservers(List.of(suggestion1, suggestion2));
         generationProvider.notifyObservers(new Action[] {generationAction});
         credManProvider.notifyObservers(new Action[] {credManAction});
 
@@ -246,7 +247,7 @@
 
     @Test
     public void testChangesCaptionIdForCredManEntry() {
-        PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
+        PropertyProvider<List<AutofillSuggestion>> autofillSuggestionProvider =
                 new PropertyProvider<>(AUTOFILL_SUGGESTION);
         PropertyProvider<Action[]> credManProvider =
                 new PropertyProvider<>(CREDMAN_CONDITIONAL_UI_REENTRY);
@@ -261,7 +262,7 @@
                         .setPopupItemId(PopupItemId.WEBAUTHN_CREDENTIAL)
                         .build();
         Action credManAction = new Action(CREDMAN_CONDITIONAL_UI_REENTRY, (a) -> {});
-        autofillSuggestionProvider.notifyObservers(new AutofillSuggestion[] {suggestion});
+        autofillSuggestionProvider.notifyObservers(List.of(suggestion));
         credManProvider.notifyObservers(new Action[] {credManAction});
 
         assertThat(mModel.get(BAR_ITEMS).size(), is(3));
@@ -276,7 +277,7 @@
     public void testMovesTabSwitcherToEnd() {
         PropertyProvider<Action[]> generationProvider =
                 new PropertyProvider<>(GENERATE_PASSWORD_AUTOMATIC);
-        PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
+        PropertyProvider<List<AutofillSuggestion>> autofillSuggestionProvider =
                 new PropertyProvider<>(AUTOFILL_SUGGESTION);
 
         mCoordinator.registerActionProvider(generationProvider);
@@ -286,8 +287,7 @@
         AutofillSuggestion suggestion1 = builder.setLabel("kayseri").build();
         AutofillSuggestion suggestion2 = builder.setLabel("spor").build();
         Action generationAction = new Action(GENERATE_PASSWORD_AUTOMATIC, (a) -> {});
-        autofillSuggestionProvider.notifyObservers(
-                new AutofillSuggestion[] {suggestion1, suggestion2});
+        autofillSuggestionProvider.notifyObservers(List.of(suggestion1, suggestion2));
         generationProvider.notifyObservers(new Action[] {generationAction});
 
         // Autofill suggestions should always come last, independent of when they were added.
@@ -306,7 +306,7 @@
     public void testDeletingActionsAffectsOnlyOneType() {
         PropertyProvider<Action[]> generationProvider =
                 new PropertyProvider<>(GENERATE_PASSWORD_AUTOMATIC);
-        PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
+        PropertyProvider<List<AutofillSuggestion>> autofillSuggestionProvider =
                 new PropertyProvider<>(AUTOFILL_SUGGESTION);
 
         mCoordinator.registerActionProvider(generationProvider);
@@ -321,18 +321,17 @@
                         .setFeatureForIPH("")
                         .build();
         Action generationAction = new Action(GENERATE_PASSWORD_AUTOMATIC, (a) -> {});
-        autofillSuggestionProvider.notifyObservers(
-                new AutofillSuggestion[] {suggestion, suggestion});
+        autofillSuggestionProvider.notifyObservers(List.of(suggestion, suggestion));
         generationProvider.notifyObservers(new Action[] {generationAction});
         assertThat(mModel.get(BAR_ITEMS).size(), is(4));
 
         // Drop all Autofill suggestions. Only the generation action should remain.
-        autofillSuggestionProvider.notifyObservers(new AutofillSuggestion[0]);
+        autofillSuggestionProvider.notifyObservers(List.of());
         assertThat(mModel.get(BAR_ITEMS).size(), is(2));
         assertThat(mModel.get(BAR_ITEMS).get(0).getAction(), is(generationAction));
 
         // Readd an Autofill suggestion and drop the generation. Only the suggestion should remain.
-        autofillSuggestionProvider.notifyObservers(new AutofillSuggestion[] {suggestion});
+        autofillSuggestionProvider.notifyObservers(List.of(suggestion));
         generationProvider.notifyObservers(new Action[0]);
         assertThat(mModel.get(BAR_ITEMS).size(), is(2));
         assertThat(mModel.get(BAR_ITEMS).get(0), instanceOf(AutofillBarItem.class));
@@ -361,7 +360,7 @@
 
     @Test
     public void testCreatesAddressItemWithIPH() {
-        PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
+        PropertyProvider<List<AutofillSuggestion>> autofillSuggestionProvider =
                 new PropertyProvider<>(AUTOFILL_SUGGESTION);
         AutofillSuggestion addressSuggestion =
                 new AutofillSuggestion.Builder()
@@ -373,7 +372,7 @@
                         .build();
         mCoordinator.registerAutofillProvider(autofillSuggestionProvider, mMockAutofillDelegate);
         autofillSuggestionProvider.notifyObservers(
-                new AutofillSuggestion[] {addressSuggestion, addressSuggestion, addressSuggestion});
+                List.of(addressSuggestion, addressSuggestion, addressSuggestion));
 
         // assertThat(getAutofillItemAt(0).getFeatureForIPH(), is(nullValue()));
         // mCoordinator.prepareUserEducation();
@@ -386,7 +385,7 @@
 
     @Test
     public void testCreatesPaymentItemWithIPH() {
-        PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
+        PropertyProvider<List<AutofillSuggestion>> autofillSuggestionProvider =
                 new PropertyProvider<>(AUTOFILL_SUGGESTION);
         AutofillSuggestion paymentSuggestion =
                 new AutofillSuggestion.Builder()
@@ -398,7 +397,7 @@
                         .build();
         mCoordinator.registerAutofillProvider(autofillSuggestionProvider, mMockAutofillDelegate);
         autofillSuggestionProvider.notifyObservers(
-                new AutofillSuggestion[] {paymentSuggestion, paymentSuggestion, paymentSuggestion});
+                List.of(paymentSuggestion, paymentSuggestion, paymentSuggestion));
 
         // assertThat(getAutofillItemAt(0).getFeatureForIPH(), is(nullValue()));
         // mCoordinator.prepareUserEducation();
@@ -411,7 +410,7 @@
 
     @Test
     public void testIPHFeatureSetForAutofillSuggestion() {
-        PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
+        PropertyProvider<List<AutofillSuggestion>> autofillSuggestionProvider =
                 new PropertyProvider<>(AUTOFILL_SUGGESTION);
         AutofillSuggestion paymentSuggestion =
                 new AutofillSuggestion.Builder()
@@ -424,7 +423,7 @@
                         .build();
         mCoordinator.registerAutofillProvider(autofillSuggestionProvider, mMockAutofillDelegate);
         autofillSuggestionProvider.notifyObservers(
-                new AutofillSuggestion[] {paymentSuggestion, paymentSuggestion, paymentSuggestion});
+                List.of(paymentSuggestion, paymentSuggestion, paymentSuggestion));
 
         // assertThat(getAutofillItemAt(0).getFeatureForIPH(), is(nullValue()));
         // mCoordinator.prepareUserEducation();
@@ -439,7 +438,7 @@
 
     @Test
     public void testCreatesIPHForSecondPasswordItem() {
-        PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
+        PropertyProvider<List<AutofillSuggestion>> autofillSuggestionProvider =
                 new PropertyProvider<>(AUTOFILL_SUGGESTION);
         AutofillSuggestion passwordSuggestion1 =
                 new AutofillSuggestion.Builder()
@@ -459,9 +458,7 @@
                         .build();
         mCoordinator.registerAutofillProvider(autofillSuggestionProvider, mMockAutofillDelegate);
         autofillSuggestionProvider.notifyObservers(
-                new AutofillSuggestion[] {
-                    passwordSuggestion1, passwordSuggestion2, passwordSuggestion2
-                });
+                List.of(passwordSuggestion1, passwordSuggestion2, passwordSuggestion2));
 
         // assertThat(getAutofillItemAt(0).getFeatureForIPH(), is(nullValue()));
         // mCoordinator.prepareUserEducation();
@@ -474,7 +471,7 @@
 
     @Test
     public void testCreatesAddressItemWithExternallyProvidedIPH() {
-        PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
+        PropertyProvider<List<AutofillSuggestion>> autofillSuggestionProvider =
                 new PropertyProvider<>(AUTOFILL_SUGGESTION);
         AutofillSuggestion addressSuggestion =
                 new AutofillSuggestion.Builder()
@@ -489,7 +486,7 @@
 
         mCoordinator.registerAutofillProvider(autofillSuggestionProvider, mMockAutofillDelegate);
         autofillSuggestionProvider.notifyObservers(
-                new AutofillSuggestion[] {addressSuggestion, addressSuggestion, addressSuggestion});
+                List.of(addressSuggestion, addressSuggestion, addressSuggestion));
 
         // assertThat(getAutofillItemAt(0).getFeatureForIPH(), is(nullValue()));
         // mCoordinator.prepareUserEducation();
@@ -568,16 +565,15 @@
 
     @Test
     public void testModelChangesUpdatesTheContentDescription() {
-        PropertyProvider<AutofillSuggestion[]> autofillSuggestionProvider =
+        PropertyProvider<List<AutofillSuggestion>> autofillSuggestionProvider =
                 new PropertyProvider<>(AUTOFILL_SUGGESTION);
 
         mCoordinator.registerAutofillProvider(autofillSuggestionProvider, mMockAutofillDelegate);
-        autofillSuggestionProvider.notifyObservers(
-                new AutofillSuggestion[] {mock(AutofillSuggestion.class)});
+        autofillSuggestionProvider.notifyObservers(List.of(mock(AutofillSuggestion.class)));
 
         assertThat(mModel.get(HAS_SUGGESTIONS), is(true));
 
-        autofillSuggestionProvider.notifyObservers(new AutofillSuggestion[] {});
+        autofillSuggestionProvider.notifyObservers(List.of());
         assertThat(mModel.get(HAS_SUGGESTIONS), is(false));
     }
 
diff --git a/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponent.java b/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponent.java
index fcb7bf0..bd2d5a7 100644
--- a/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponent.java
+++ b/chrome/android/features/keyboard_accessory/public/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingComponent.java
@@ -26,11 +26,13 @@
 import org.chromium.ui.DropdownPopupWindow;
 import org.chromium.ui.base.WindowAndroid;
 
+import java.util.List;
+
 /** This component handles the new, non-popup filling UI. */
 public interface ManualFillingComponent extends BackPressHandler {
     /**
-     * Observers are added with {@link #addObserver} and removed with {@link #removeObserver}.
-     * They are notified when the {@link ManualFillingComponent} is destroyed.
+     * Observers are added with {@link #addObserver} and removed with {@link #removeObserver}. They
+     * are notified when the {@link ManualFillingComponent} is destroyed.
      */
     interface Observer {
         /** Called if the ManualFillingComponent is destroyed. */
@@ -160,14 +162,16 @@
     /**
      * Registers a provider, to provide autofill suggestions for the keyboard accessory bar. Call
      * {@link PropertyProvider#notifyObservers(Object)} to fill or update the suggestions.
+     *
      * @param autofillProvider The {@link PropertyProvider} providing autofill suggestions.
      * @param delegate The {@link AutofillDelegate} to call for interaction with the suggestions.
      */
     void registerAutofillProvider(
-            PropertyProvider<AutofillSuggestion[]> autofillProvider, AutofillDelegate delegate);
+            PropertyProvider<List<AutofillSuggestion>> autofillProvider, AutofillDelegate delegate);
 
     /**
      * Signals that the accessory has permission to show.
+     *
      * @param waitForKeyboard signals if the keyboard is requested.
      */
     void show(boolean waitForKeyboard);
diff --git a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ms.xtb b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ms.xtb
index 93714088..ae64927 100644
--- a/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ms.xtb
+++ b/chrome/android/features/tab_ui/java/strings/translations/android_chrome_tab_ui_strings_ms.xtb
@@ -88,6 +88,7 @@
 <translation id="6421412308143682486">{INCOGNITO_TABS_COUNT,plural, =1{Anda boleh menemukan tab anda yang ditutup dalam tab Terbaharu ini dalam bahagian menu utama Chrome. Tab Inkognito anda tidak akan tersedia.}other{Anda boleh menemukan tab anda yang ditutup dalam tab Terbaharu ini dalam bahagian menu utama Chrome. # tab Inkognito anda tidak akan tersedia.}}</translation>
 <translation id="6422650314852876533">{TABS_COUNT,plural, =1{<ph name="TABS_COUNT_ONE" /> tab}other{<ph name="TABS_COUNT_MANY" /> tab}}</translation>
 <translation id="6549021453810473782">Lihat maklumat kedai</translation>
+<translation id="6557858706263317126">+<ph name="HIDDEN_TABS_COUNT" /></translation>
 <translation id="6562820390860419811">Alihkan tab ke kiri</translation>
 <translation id="6615455863669487791">Tunjukkan kepada saya</translation>
 <translation id="661742612106409204">Anda boleh menemukan tab anda yang ditutup dalam tab Terbaharu ini dalam bahagian menu utama Chrome.</translation>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
index 6890fdad..e3169b3b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
@@ -1050,10 +1050,6 @@
     /** Returns true if a badge (i.e. a red-dot) should be shown on the menu item icon. */
     protected boolean shouldShowBadgeOnMenuItemIcon(MenuItem item) {
         if (item.getItemId() == R.id.preferences_id) {
-            if (!ChromeFeatureList.isEnabled(
-                    ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)) {
-                return false;
-            }
             // Theoretically mTabModelSelector could return a stub model.
             Profile profile = mTabModelSelector.getCurrentModel().getProfile();
             if (profile == null) {
@@ -1075,10 +1071,6 @@
      */
     protected String getContentDescription(MenuItem item) {
         if (item.getItemId() == R.id.preferences_id) {
-            if (!ChromeFeatureList.isEnabled(
-                    ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)) {
-                return null;
-            }
             // Theoretically mTabModelSelector could return a stub model.
             Profile profile = mTabModelSelector.getCurrentModel().getProfile();
             if (profile == null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/BrowsingHistoryBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/history/BrowsingHistoryBridge.java
index 7d0817472..2e45234 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/BrowsingHistoryBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/BrowsingHistoryBridge.java
@@ -77,7 +77,7 @@
     }
 
     @Override
-    public void getAllAppIds() {
+    public void queryApps() {
         BrowsingHistoryBridgeJni.get()
                 .getAllAppIds(
                         mNativeHistoryBridge, BrowsingHistoryBridge.this, new ArrayList<String>());
@@ -88,11 +88,6 @@
         items.add(appId);
     }
 
-    @CalledByNative
-    public void onQueryAppIdComplete(List<String> items) {
-        // TODO: Notify the app ID query complete event.
-    }
-
     @Override
     public void getLastVisitToHostBeforeRecentNavigations(
             String hostName, Callback<Long> callback) {
@@ -159,6 +154,11 @@
     }
 
     @CalledByNative
+    public void onQueryAppsComplete(List<String> items) {
+        if (mObserver != null) mObserver.onQueryAppsComplete(items);
+    }
+
+    @CalledByNative
     public void onRemoveComplete() {
         mRemovingItems = false;
         if (mHasPendingRemoveRequest) removeItems();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java
index c09864b..229c8c7c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java
@@ -6,6 +6,7 @@
 
 import android.content.Intent;
 import android.os.Bundle;
+import android.view.ViewGroup;
 
 import org.chromium.base.IntentUtils;
 import org.chromium.chrome.browser.IntentHandler;
@@ -14,10 +15,12 @@
 import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.profiles.ProfileProvider;
+import org.chromium.components.browser_ui.bottomsheet.ManagedBottomSheetController;
 
 /** Activity for displaying the browsing history manager. */
 public class HistoryActivity extends SnackbarActivity {
     private HistoryManager mHistoryManager;
+    private ManagedBottomSheetController mBottomSheetController;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -35,23 +38,32 @@
         Profile profile = getProfileProvider().getOriginalProfile();
         HistoryUmaRecorder historyUmaRecorder =
                 appSpecificHistory ? new AppHistoryUmaRecorder() : new HistoryUmaRecorder();
+        boolean showAppFilter = !appSpecificHistory;
         mHistoryManager =
                 new HistoryManager(
                         this,
                         true,
                         getSnackbarManager(),
                         ProfileProvider.getOrCreateProfile(getProfileProvider(), isIncognito),
+                        () -> mBottomSheetController,
                         /* Supplier<Tab>= */ null,
                         new BrowsingHistoryBridge(profile),
                         historyUmaRecorder,
                         clientPackageName,
                         shouldShowClearData,
-                        appSpecificHistory);
-        setContentView(mHistoryManager.getView());
+                        appSpecificHistory,
+                        showAppFilter);
+        ViewGroup contentView = mHistoryManager.getView();
+        setContentView(contentView);
+        if (showAppFilter) createBottomSheetController(contentView);
         BackPressHelper.create(
                 this, getOnBackPressedDispatcher(), mHistoryManager, SecondaryActivity.HISTORY);
     }
 
+    private void createBottomSheetController(ViewGroup contentView) {
+        // TODO: Create bottomsheet controller for HistoryActivity.
+    }
+
     @Override
     protected void onDestroy() {
         mHistoryManager.onDestroyed();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java
index df26c23..7d772a7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryAdapter.java
@@ -50,6 +50,7 @@
     private HeaderItem mClearBrowsingDataButtonHeaderItem;
     private HeaderItem mHistoryOpenInChromeHeaderItem;
     private HeaderItem mAppFilterHeaderItem;
+    private ChipView mAppFilterChip;
 
     // Footers
     private MoreProgressButton mMoreProgressButton;
@@ -66,8 +67,9 @@
     private boolean mClearBrowsingDataButtonVisible;
     private String mQueryText = EMPTY_QUERY;
     private String mHostName;
-    private String mAppId; // Not used if null i.e. query all entries regardless of app ID
 
+    // ID of the App currently chosen for app filtering. If null, ignored when querying history.
+    private String mAppId;
     private boolean mDisableScrollToLoadForTest;
 
     public HistoryAdapter(HistoryContentManager manager, HistoryProvider provider) {
@@ -107,6 +109,10 @@
         setHeaders();
     }
 
+    void queryApps() {
+        mHistoryProvider.queryApps();
+    }
+
     @Override
     public void onAttachedToRecyclerView(RecyclerView recyclerView) {
         // This adapter should only ever be attached to one RecyclerView.
@@ -151,9 +157,6 @@
         onSearchStart();
         mClearOnNextQueryComplete = true;
         mHistoryProvider.queryHistory(mQueryText, mAppId);
-        // TODO: Query all the app IDs to initialize app filter button.
-        //       mHistoryProvider.getAllAppIds()
-
     }
 
     /** Called when a search is ended. */
@@ -243,8 +246,8 @@
             clear(true);
             mClearOnNextQueryComplete = false;
         }
-
-        if (!mAreHeadersInitialized && items.size() > 0 && !mIsSearching) {
+        if (!mAreHeadersInitialized && items.size() > 0 && !mIsSearching
+                || mIsSearching && mManager.showAppFilter()) {
             setHeaders();
             mAreHeadersInitialized = true;
         }
@@ -279,6 +282,13 @@
     }
 
     @Override
+    public void onQueryAppsComplete(List<String> items) {
+        // Querying apps was completed after the search mode is entered. Enable the filter button.
+        boolean hasAppToShow = mManager.buildAppInfoList(items);
+        if (hasAppToShow && mIsSearching) mAppFilterChip.setEnabled(true);
+    }
+
+    @Override
     protected BasicViewHolder createFooter(ViewGroup parent) {
         // Create the same frame layout as place holder for more footer items.
         return createHeader(parent);
@@ -381,12 +391,11 @@
                 (ViewGroup)
                         LayoutInflater.from(mManager.getContext())
                                 .inflate(R.layout.app_history_filter, parent, true);
-        ChipView appFilterChip =
+        mAppFilterChip =
                 (ChipView) historyAppFilterContainer.findViewById(R.id.app_history_filter_chip);
-        appFilterChip.setOnClickListener(v -> mManager.onAppFilterClicked());
-        // TODO(jinsukkim) the button text should become the app label when a filter is selected.
-        appFilterChip.getPrimaryTextView().setText(R.string.history_filter_by_app);
-        appFilterChip.addDropdownIcon();
+        mAppFilterChip.setOnClickListener(v -> mManager.onAppFilterClicked());
+        mAppFilterChip.getPrimaryTextView().setText(R.string.history_filter_by_app);
+        mAppFilterChip.addDropdownIcon();
         return historyAppFilterContainer;
     }
 
@@ -431,11 +440,14 @@
     }
 
     /** Pass header items to {@link #setHeaders(HeaderItem...)} as parameters. */
-    void setHeaders() {
+    private void setHeaders() {
         ArrayList<HeaderItem> args = new ArrayList<>();
         if (mIsSearching) {
-            if (HistoryManager.isAppSpecificHistoryEnabled()) {
+            if (mManager.showAppFilter()) {
                 args.add(mAppFilterHeaderItem);
+                // Query for apps list could be still pending. Keep the button disabled until
+                // the result is ready.
+                mAppFilterChip.setEnabled(mManager.hasFilterList());
             }
         } else {
             if (mPrivacyDisclaimersVisible) {
@@ -551,4 +563,8 @@
     MoreProgressButton getMoreProgressButtonForTest() {
         return mMoreProgressButton;
     }
+
+    ChipView getAppFilterButtonForTest() {
+        return mAppFilterChip;
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryContentManager.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryContentManager.java
index ff4ce88..10d9f79 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryContentManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryContentManager.java
@@ -11,6 +11,8 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.provider.Browser;
 import android.view.ContextThemeWrapper;
@@ -31,7 +33,7 @@
 import org.chromium.chrome.browser.ActivityUtils;
 import org.chromium.chrome.browser.IntentHandler;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.history.AppFilterCoordinator.AppInfo;
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.preferences.PrefChangeRegistrar;
 import org.chromium.chrome.browser.preferences.PrefChangeRegistrar.PrefObserver;
@@ -42,6 +44,7 @@
 import org.chromium.chrome.browser.tab.TabLaunchType;
 import org.chromium.chrome.browser.tabmodel.document.ChromeAsyncTabLauncher;
 import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
+import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.browser_ui.util.ConversionUtils;
 import org.chromium.components.browser_ui.widget.selectable_list.SelectableItemViewHolder;
 import org.chromium.components.browser_ui.widget.selectable_list.SelectionDelegate;
@@ -87,9 +90,6 @@
         /** Called after a user clicks the open full Chrome history button. */
         void onOpenFullChromeHistoryClicked();
 
-        /** Called after a user clicks the filter by app button. */
-        default void onAppFilterClicked() {}
-
         /** Called to notify when the user's sign in or pref state has changed. */
         void onUserAccountStateChanged();
 
@@ -116,6 +116,10 @@
     private final boolean mIsScrollToLoadDisabled;
     private final boolean mShouldShowClearDataIfAvailable;
     private final String mHostName;
+    private final Runnable mHideSoftKeyboard;
+    private final boolean mShowAppFilter;
+    private final List<AppInfo> mAppInfoList = new ArrayList<>();
+    private final Supplier<BottomSheetController> mBottomSheetController;
     private final Supplier<Tab> mTabSupplier;
     private HistoryAdapter mHistoryAdapter;
     private RecyclerView mRecyclerView;
@@ -125,6 +129,8 @@
     private boolean mLaunchedForApp;
     private PrefChangeRegistrar mPrefChangeRegistrar;
     private String mAppId;
+    private AppFilterCoordinator mAppFilterSheet;
+    private AppInfo mCurrentApp;
 
     /**
      * Creates a new HistoryContentManager.
@@ -157,15 +163,21 @@
             boolean shouldShowClearDataIfAvailable,
             @Nullable String hostName,
             @Nullable SelectionDelegate<HistoryItem> selectionDelegate,
+            @Nullable Supplier<BottomSheetController> bottomSheetController,
             @Nullable Supplier<Tab> tabSupplier,
+            @Nullable Runnable hideSoftKeyboard,
             HistoryProvider historyProvider,
             String appId,
-            boolean launchedForApp) {
+            boolean launchedForApp,
+            boolean showAppFilter) {
         mActivity = activity;
         mObserver = observer;
         mIsSeparateActivity = isSeparateActivity;
         mIsIncognito = profile.isOffTheRecord();
         mProfile = profile;
+        mBottomSheetController = bottomSheetController;
+        mHideSoftKeyboard = hideSoftKeyboard;
+        mShowAppFilter = showAppFilter;
         mShouldShowPrivacyDisclaimers = shouldShowPrivacyDisclaimers;
         mShouldShowClearDataIfAvailable = shouldShowClearDataIfAvailable;
         mHostName = hostName;
@@ -265,7 +277,49 @@
         mHistoryAdapter.startLoadingItems();
     }
 
-    /** @return The RecyclerView for this HistoryContentManager. */
+    /** Query all app IDs from the history database if required. */
+    void maybeQueryApps() {
+        if (!showAppFilter()) return;
+
+        // TODO: Measure the time to get the query result.
+        mHistoryAdapter.queryApps();
+    }
+
+    /**
+     * Build a list of {@link AppInfo} using the app query result.
+     *
+     * @param appIds List of app IDs found from the history database.
+     * @return {@code true} if we have non-empty list of the apps to show.
+     */
+    boolean buildAppInfoList(List<String> appIds) {
+        mAppInfoList.clear();
+        PackageManager pm = mActivity.getPackageManager();
+        for (String appId : appIds) {
+            try {
+                var icon = pm.getApplicationIcon(appId);
+                var appInfo = pm.getApplicationInfo(appId, PackageManager.GET_META_DATA);
+                var label = pm.getApplicationLabel(appInfo);
+                mAppInfoList.add(new AppInfo(appId, icon, label));
+            } catch (NameNotFoundException e) {
+                // Can happen if the corresponding app was uninstalled, or unavailable for any
+                // reason. Filter it out for now. TODO: Consider keeping it with a default app
+                // icon + label.
+            }
+        }
+        return hasFilterList();
+    }
+
+    /**
+     * @return Whether there is apps to show in the filter UI. Could be false if the query is not
+     *     completed or the result indeed is empty.
+     */
+    boolean hasFilterList() {
+        return !mAppInfoList.isEmpty();
+    }
+
+    /**
+     * @return The RecyclerView for this HistoryContentManager.
+     */
     public RecyclerView getRecyclerView() {
         return mRecyclerView;
     }
@@ -370,7 +424,14 @@
      * @return True if history UI was launched for the app-specific mode.
      */
     boolean launchedForApp() {
-        return ChromeFeatureList.sAppSpecificHistory.isEnabled() && mLaunchedForApp;
+        return HistoryManager.isAppSpecificHistoryEnabled() && mLaunchedForApp;
+    }
+
+    /**
+     * @return True if history page needs to show app filter UI.
+     */
+    boolean showAppFilter() {
+        return HistoryManager.isAppSpecificHistoryEnabled() && mShowAppFilter;
     }
 
     /** returns whether the info header will be available for user upon request. */
@@ -543,7 +604,11 @@
 
     /** Called after a user clicks the filter by app button. */
     void onAppFilterClicked() {
-        mObserver.onAppFilterClicked();
+        // Search mode starts with the soft keyboard open. Hide it first for the sheet
+        // to appear at the bottom as expected.
+        mHideSoftKeyboard.run();
+
+        // TODO: Open app filter sheet.
     }
 
     /** Removes the list header. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
index 2e349fd0..015a1aa 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
@@ -38,8 +38,8 @@
 import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar;
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager.SnackbarController;
+import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.browser_ui.settings.SettingsLauncher;
-import org.chromium.components.browser_ui.widget.chips.ChipView;
 import org.chromium.components.browser_ui.widget.gesture.BackPressHandler;
 import org.chromium.components.browser_ui.widget.selectable_list.SelectableListLayout;
 import org.chromium.components.browser_ui.widget.selectable_list.SelectableListToolbar.SearchDelegate;
@@ -115,6 +115,8 @@
      *     the main Chrome activity.
      * @param snackbarManager The {@link SnackbarManager} used to display snackbars.
      * @param profile The profile launching History.
+     * @param bottomSheetController Supplier of {@link BottomSheetController} to show app filter
+     *     sheet in.
      * @param tabSupplier Supplies the current tab, null if the history UI will be shown in a
      *     separate activity.
      * @param historyProvider Provider of methods for querying and managing browsing history.
@@ -122,6 +124,7 @@
      * @param clientPackageName Package name of the client the history UI is launched on top of.
      * @param shouldShowClearData Whether the 'Clear browsing data' button should be shown.
      * @param launchedForApp Whether history UI is launched for app-specific history.
+     * @param showAppFilter Whether history page will show app filter UI.
      */
     @SuppressWarnings("unchecked") // mSelectableListLayout
     public HistoryManager(
@@ -129,12 +132,14 @@
             boolean isSeparateActivity,
             @NonNull SnackbarManager snackbarManager,
             @NonNull Profile profile,
+            @Nullable Supplier<BottomSheetController> bottomSheetController,
             @Nullable Supplier<Tab> tabSupplier,
             HistoryProvider historyProvider,
             @NonNull HistoryUmaRecorder umaRecorder,
             @Nullable String clientPackageName,
             boolean shouldShowClearData,
-            boolean launchedForApp) {
+            boolean launchedForApp,
+            boolean showAppFilter) {
         mActivity = activity;
         mIsSeparateActivity = isSeparateActivity;
         mSnackbarManager = snackbarManager;
@@ -179,10 +184,13 @@
                         shouldShowClearData,
                         /* hostName= */ null,
                         mSelectionDelegate,
+                        bottomSheetController,
                         tabSupplier,
+                        () -> mToolbar.hideKeyboard(),
                         historyProvider,
                         clientPackageName,
-                        launchedForApp);
+                        launchedForApp,
+                        showAppFilter);
         mSelectableListLayout.initializeRecyclerView(
                 mContentManager.getAdapter(), mContentManager.getRecyclerView());
 
@@ -228,11 +236,12 @@
                 .addObserver((x) -> onBackPressStateChanged());
 
         onBackPressStateChanged(); // Initialize back press State.
+        mContentManager.maybeQueryApps();
     }
 
     /**
      * @return Whether the history manager UI is displayed in a separate activity than the main
-     *         Chrome activity.
+     *     Chrome activity.
      */
     public boolean isDisplayedInSeparateActivity() {
         return mIsSeparateActivity;
@@ -527,13 +536,6 @@
         mUmaRecorder.recordOpenFullHistory();
     }
 
-    @Override
-    public void onAppFilterClicked() {
-        ChipView chip = (ChipView) mActivity.findViewById(R.id.app_history_filter_chip);
-        chip.setSelected(true);
-        chip.setIcon(R.drawable.ic_check_googblue_24dp, true);
-    }
-
     // HistoryContentManager.Observer
     @Override
     public void onUserAccountStateChanged() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryPage.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryPage.java
index 4ebb2f0..37268d9e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryPage.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryPage.java
@@ -14,6 +14,7 @@
 import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
 import org.chromium.chrome.browser.ui.native_page.BasicNativePage;
 import org.chromium.chrome.browser.ui.native_page.NativePageHost;
+import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.embedder_support.util.UrlConstants;
 
 /** Native page for managing browsing history. */
@@ -23,13 +24,15 @@
 
     /**
      * Create a new instance of the history page.
-     * @param activity The {@link Activity} used to get context and instantiate the
-     *                 {@link HistoryManager}.
+     *
+     * @param activity The {@link Activity} used to get context and instantiate the {@link
+     *     HistoryManager}.
      * @param host A NativePageHost to load URLs.
      * @param snackbarManager The {@link SnackbarManager} used to display snackbars.
      * @param profile The Profile of the current tab.
+     * @param bottomSheetController {@link BottomSheetController} object.
      * @param tabSupplier Supplies the current tab, null if the history UI will be shown in a
-     *                    separate activity.
+     *     separate activity.
      * @param url The URL used to address the HistoryPage.
      */
     public HistoryPage(
@@ -37,6 +40,7 @@
             NativePageHost host,
             SnackbarManager snackbarManager,
             Profile profile,
+            BottomSheetController bottomSheetController,
             Supplier<Tab> tabSupplier,
             String url) {
         super(host);
@@ -50,12 +54,14 @@
                         /* isSeparateActivity= */ false,
                         snackbarManager,
                         profile,
+                        () -> bottomSheetController,
                         tabSupplier,
                         new BrowsingHistoryBridge(profile.getOriginalProfile()),
                         new HistoryUmaRecorder(),
                         null,
                         /* shouldShowClearData= */ true,
-                        /* launchedForApp= */ false);
+                        /* launchedForApp= */ false,
+                        /* showAppFilter= */ true);
         mTitle = host.getContext().getResources().getString(R.string.menu_history);
 
         initWithView(mHistoryManager.getView());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryProvider.java
index 816171c8..69f872e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryProvider.java
@@ -32,9 +32,17 @@
         /**
          * Called after querying history to indicate whether other forms of browsing history were
          * found.
+         *
          * @param hasOtherForms Whether other forms of browsing history were found.
          */
         void hasOtherFormsOfBrowsingData(boolean hasOtherForms);
+
+        /**
+         * Called after {@link BrowsingHistoryBridge#getAllAppIds()} is complete.
+         *
+         * @param items The list of app IDs.
+         */
+        void onQueryAppsComplete(List<String> items);
     }
 
     /** Sets the {@link BrowsingHistoryObserver} to be notified of browsing history events. */
@@ -65,7 +73,7 @@
     void queryHistoryContinuation();
 
     /** Fetches all the app IDs used in the database. */
-    void getAllAppIds();
+    void queryApps();
 
     /**
      * Gets the last time any webpage on the given host was visited, excluding the last navigation
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java
index 2c4084c..8221678 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java
@@ -251,6 +251,7 @@
                     new TabShim(tab, mBrowserControlsManager, mTabModelSelector),
                     mSnackbarManagerSupplier.get(),
                     tab.getProfile(),
+                    mBottomSheetController,
                     mCurrentTabSupplier,
                     url);
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoHistoryController.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoHistoryController.java
index 08f4e59..a2bcb78 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoHistoryController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoHistoryController.java
@@ -92,10 +92,13 @@
                         /* shouldShowClearDataIfAvailable= */ false,
                         mHost,
                         /* selectionDelegate= */ null,
+                        /* bottomSheetController= */ null,
                         mTabSupplier,
+                        /* hideSoftKeyboard= */ null,
                         new BrowsingHistoryBridge(profile),
                         null,
-                        /* launchedForApp= */ false);
+                        /* launchedForApp= */ false,
+                        /* showAppFilter= */ false);
         mContentManager.startLoadingItems();
         return mContentManager.getRecyclerView();
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncErrorNotifier.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncErrorNotifier.java
index 8c9f735c..e36505a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncErrorNotifier.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/SyncErrorNotifier.java
@@ -17,7 +17,6 @@
 import org.chromium.base.Promise;
 import org.chromium.base.ThreadUtils;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.notifications.NotificationConstants;
 import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
 import org.chromium.chrome.browser.notifications.NotificationWrapperBuilderFactory;
@@ -174,16 +173,6 @@
             return NotificationState.HIDDEN;
         }
 
-        if (!mSyncService.isSyncFeatureEnabled()
-                && !ChromeFeatureList.isEnabled(
-                        ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)) {
-            // Error notifications are only currently shown to syncing users, even though passphrase
-            // and trusted vault key errors still apply to signed-in users.
-            // They are shown to signed-in users as well if SyncShowIdentityErrorsForSignedInUsers
-            // feature flag is enabled.
-            return NotificationState.HIDDEN;
-        }
-
         if (mSyncService.isPassphraseRequiredForPreferredDataTypes()
                 && !mSyncService.isPassphrasePromptMutedForCurrentProductVersion()) {
             return NotificationState.REQUIRE_PASSPHRASE;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/IdentityErrorCardPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/IdentityErrorCardPreference.java
index 6be8983..4ec42e7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/IdentityErrorCardPreference.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/IdentityErrorCardPreference.java
@@ -15,7 +15,6 @@
 
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.sync.SyncServiceFactory;
 import org.chromium.chrome.browser.sync.settings.SyncSettingsUtils.ErrorCardDetails;
@@ -126,8 +125,6 @@
     }
 
     private boolean shouldShowErrorCard() {
-        return mIdentityError != SyncError.NO_ERROR
-                && ChromeFeatureList.isEnabled(
-                        ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS);
+        return mIdentityError != SyncError.NO_ERROR;
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SignInPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SignInPreference.java
index 1c8f24553..b4a3f7d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SignInPreference.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/SignInPreference.java
@@ -229,9 +229,8 @@
         setIcon(profileData.getImage());
         setViewEnabledAndShowAlertIcon(
                 /* enabled= */ true,
-                /* alertIconVisible= */ ChromeFeatureList.isEnabled(
-                                ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
-                        && SyncSettingsUtils.getIdentityError(mProfile) != SyncError.NO_ERROR);
+                /* alertIconVisible= */ SyncSettingsUtils.getIdentityError(mProfile)
+                        != SyncError.NO_ERROR);
         setOnPreferenceClickListener(null);
 
         mWasGenericSigninPromoDisplayed = false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessage.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessage.java
index ea60016..88270cba 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessage.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessage.java
@@ -23,7 +23,6 @@
 import org.chromium.base.UnownedUserDataKey;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
 import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
@@ -454,17 +453,11 @@
     }
 
     private static @SyncError int getError(Profile profile) {
-        // Check if there is an identity error.
-        final boolean hasSyncConsent =
-                IdentityServicesProvider.get()
+        return IdentityServicesProvider.get()
                         .getIdentityManager(profile)
-                        .hasPrimaryAccount(ConsentLevel.SYNC);
-        if (!hasSyncConsent
-                && ChromeFeatureList.isEnabled(
-                        ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)) {
-            return SyncSettingsUtils.getIdentityError(profile);
-        }
-        return SyncSettingsUtils.getSyncError(profile);
+                        .hasPrimaryAccount(ConsentLevel.SYNC)
+                ? SyncSettingsUtils.getSyncError(profile)
+                : SyncSettingsUtils.getIdentityError(profile);
     }
 
     @VisibleForTesting
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java
index e25897e..b049bc80 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/TabbedAppMenuTest.java
@@ -445,7 +445,6 @@
     @Test
     @LargeTest
     @Feature({"Browser", "Main", "RenderTest"})
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSettingsMenuItem_NoBadgeShownForNotSignedInUsers() throws IOException {
         View view = getSettingsMenuItemView();
         Assert.assertNull(view.findViewById(R.id.menu_item_text).getContentDescription());
@@ -455,7 +454,6 @@
     @Test
     @LargeTest
     @Feature({"Browser", "Main", "RenderTest"})
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSettingsMenuItem_BadgeShownForSignedInUsersOnIdentityError()
             throws IOException {
         TestThreadUtils.runOnUiThreadBlocking(() -> mAppMenuHandler.hideAppMenu());
@@ -484,7 +482,6 @@
     @Test
     @LargeTest
     @Feature({"Browser", "Main", "RenderTest"})
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSettingsMenuItem_NoBadgeShownForSignedInUsersIfNoError() throws IOException {
         TestThreadUtils.runOnUiThreadBlocking(() -> mAppMenuHandler.hideAppMenu());
         // Sign in and wait for sync machinery to be active.
@@ -499,7 +496,6 @@
     @Test
     @LargeTest
     @Feature({"Browser", "Main", "RenderTest"})
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSettingsMenuItem_BadgeShownForSyncingUsersOnSyncError() throws IOException {
         TestThreadUtils.runOnUiThreadBlocking(() -> mAppMenuHandler.hideAppMenu());
         FakeSyncServiceImpl fakeSyncService =
@@ -526,7 +522,6 @@
     @Test
     @LargeTest
     @Feature({"Browser", "Main", "RenderTest"})
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSettingsMenuItem_NoBadgeShownForSyncingUsersIfNoError() throws IOException {
         TestThreadUtils.runOnUiThreadBlocking(() -> mAppMenuHandler.hideAppMenu());
         // Sign in and wait for sync machinery to be active.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java
index e572ba3..2ff4238f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java
@@ -41,7 +41,6 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
-import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Features;
 import org.chromium.base.test.util.Features.DisableFeatures;
 import org.chromium.base.test.util.Features.EnableFeatures;
@@ -74,6 +73,8 @@
 import org.chromium.components.omnibox.OmniboxSuggestionType;
 import org.chromium.components.omnibox.action.OmniboxActionJni;
 import org.chromium.components.omnibox.action.OmniboxPedalId;
+import org.chromium.components.prefs.PrefService;
+import org.chromium.components.user_prefs.UserPrefs;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.modaldialog.DialogDismissalCause;
 import org.chromium.ui.test.util.DisableAnimationsTestRule;
@@ -214,8 +215,15 @@
 
     @Test
     @MediumTest
-    @DisabledTest(message = "b/333905073")
-    public void testManagePasswords() throws InterruptedException {
+    public void testManagePasswordsNoUpmFlow() throws InterruptedException {
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> {
+                    PrefService prefService = UserPrefs.get(sActivityTestRule.getProfile(false));
+                    prefService.setInteger(
+                            "passwords_use_upm_local_and_separate_stores",
+                            /*UseUpmLocalAndSeparateStoresState = Off*/ 0);
+                });
+
         setSuggestions(createPedalSuggestion(OmniboxPedalId.MANAGE_PASSWORDS));
         clickOnPedalToSettings(() -> mOmniboxUtils.clickOnAction(0, 0), PasswordSettings.class);
         verify(mOmniboxActionJni, times(1))
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
index be61e11..f9461b7 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
@@ -379,7 +379,6 @@
     // Tests that no alert icon is visible if there are no identity errors.
     @Test
     @SmallTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSigninRowShowsNoAlertWhenNoIdentityErrors() {
         // Sign-in and open settings.
         mSyncTestRule.setUpAccountAndSignInForTesting();
@@ -393,7 +392,6 @@
     // an identity error.
     @Test
     @SmallTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSigninRowShowsNoAlertForIdentityErrorsForSyncingUsers() {
         FakeSyncServiceImpl fakeSyncService =
                 TestThreadUtils.runOnUiThreadBlockingNoException(
@@ -416,7 +414,6 @@
     // signed-in non-syncing user.
     @Test
     @SmallTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSigninRowShowsAlertForIdentityErrors() {
         FakeSyncServiceImpl fakeSyncService =
                 TestThreadUtils.runOnUiThreadBlockingNoException(
@@ -438,7 +435,6 @@
     @Test
     @LargeTest
     @Feature({"RenderTest"})
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testRenderOnIdentityErrorForSignedInUsers() throws IOException {
         FakeSyncServiceImpl fakeSyncService =
                 TestThreadUtils.runOnUiThreadBlockingNoException(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInIntegrationTest.java
index 5632180465..26a5ffcd 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInIntegrationTest.java
@@ -128,7 +128,7 @@
                 HistoryOptInMode.REQUIRED);
 
         verifyCollapsedBottomSheetAndSignin(accountInfo);
-        acceptHistorySyncAndVerifyFlowCompletion();
+        acceptHistorySyncAndVerifyFlowCompletion(/* checkDialogRoot= */ false);
     }
 
     @Test
@@ -158,20 +158,8 @@
                 WithAccountSigninMode.DEFAULT_ACCOUNT_BOTTOM_SHEET,
                 HistoryOptInMode.REQUIRED);
 
-        // Verify that the history opt-in dialog is shown and accept.
-        onViewWaiting(withId(R.id.history_sync_illustration), /* checkRootDialog= */ true)
-                .check(matches(isDisplayed()));
-        onViewWaiting(
-                        allOf(withId(R.id.button_primary), isCompletelyDisplayed()),
-                        /* checkRootDialog= */ true)
-                .perform(click());
-
-        // Verify signin and history sync state.
+        acceptHistorySyncAndVerifyFlowCompletion(/* checkDialogRoot= */ true);
         assertNotNull(mSigninTestRule.getPrimaryAccount(ConsentLevel.SIGNIN));
-        SyncTestUtil.waitForHistorySyncEnabled();
-
-        // Verify that the flow completion callback, which finishes the activity, is called.
-        ApplicationTestUtils.waitForActivityState(mActivity, Stage.DESTROYED);
     }
 
     @Test
@@ -210,7 +198,7 @@
                 HistoryOptInMode.OPTIONAL);
 
         verifyCollapsedBottomSheetAndSignin(accountInfo);
-        acceptHistorySyncAndVerifyFlowCompletion();
+        acceptHistorySyncAndVerifyFlowCompletion(/* checkDialogRoot= */ false);
     }
 
     @Test
@@ -384,12 +372,11 @@
                 HistoryOptInMode.REQUIRED);
 
         verifyNoAccountBottomSheetAndSignin();
-        acceptHistorySyncAndVerifyFlowCompletion();
+        acceptHistorySyncAndVerifyFlowCompletion(/* checkDialogRoot= */ false);
     }
 
     @Test
     @MediumTest
-    @DisabledTest(message = "https://crbug.com/335867572")
     public void testWithNoAccount_instantSignin_requiredHistorySync() {
         CoreAccountInfo accountInfo = AccountManagerTestRule.TEST_ACCOUNT_1;
         mSigninTestRule.setResultForNextAddAccountFlow(Activity.RESULT_OK, accountInfo.getEmail());
@@ -399,7 +386,7 @@
                 WithAccountSigninMode.DEFAULT_ACCOUNT_BOTTOM_SHEET,
                 HistoryOptInMode.REQUIRED);
 
-        acceptHistorySyncAndVerifyFlowCompletion();
+        acceptHistorySyncAndVerifyFlowCompletion(/* checkDialogRoot= */ true);
     }
 
     @Test
@@ -461,10 +448,23 @@
         mSigninTestRule.waitForSignin(accountInfo);
     }
 
-    private void acceptHistorySyncAndVerifyFlowCompletion() {
+    // `checkDialogRoot` should be set to true for tests that fail due to Espresso using the wrong
+    // root view for dialogs on API30+ (Mostly when the dialog appears without the bottom sheet
+    // being shown before).
+    // See https://crbug.com/332025155.
+    private void acceptHistorySyncAndVerifyFlowCompletion(boolean checkDialogRoot) {
         // Verify that the history opt-in dialog is shown and accept.
-        onView(withId(R.id.history_sync_illustration)).check(matches(isDisplayed()));
-        onView(allOf(withId(R.id.button_primary), isCompletelyDisplayed())).perform(click());
+        if (checkDialogRoot) {
+            onViewWaiting(withId(R.id.history_sync_illustration), /* checkRootDialog= */ true)
+                    .check(matches(isDisplayed()));
+            onViewWaiting(
+                            allOf(withId(R.id.button_primary), isCompletelyDisplayed()),
+                            /* checkRootDialog= */ true)
+                    .perform(click());
+        } else {
+            onView(withId(R.id.history_sync_illustration)).check(matches(isDisplayed()));
+            onView(allOf(withId(R.id.button_primary), isCompletelyDisplayed())).perform(click());
+        }
 
         // Verify history sync state.
         SyncTestUtil.waitForHistorySyncEnabled();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java
index 07d7baa..450e6ec 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SyncConsentFragmentTest.java
@@ -1280,6 +1280,92 @@
 
     @Test
     @LargeTest
+    @EnableFeatures(SigninFeatures.MINOR_MODE_RESTRICTIONS_FOR_HISTORY_SYNC_OPT_IN)
+    public void testSignedInWithMinorModeRequiredRecordsCancelButtonClicked() throws IOException {
+        mChromeActivityTestRule.startMainActivityOnBlankPage();
+        CoreAccountInfo accountInfo =
+                mSigninTestRule.addAccount(
+                        AccountManagerTestRule.TEST_ACCOUNT_EMAIL, MINOR_MODE_REQUIRED);
+
+        mSigninTestRule.waitForSeeding();
+        SigninTestUtil.signin(accountInfo);
+        mSyncConsentActivity = waitForSyncConsentActivity(accountInfo);
+
+        HistogramWatcher histogramWatcher =
+                HistogramWatcher.newSingleRecordWatcher(
+                        "Signin.SyncButtons.Clicked",
+                        MinorModeHelper.SyncButtonClicked.SYNC_CANCEL_EQUAL_WEIGHTED);
+        onViewWaiting(withText(R.string.signin_sync_decline_button)).perform(click());
+        histogramWatcher.assertExpected();
+    }
+
+    @Test
+    @LargeTest
+    @EnableFeatures(SigninFeatures.MINOR_MODE_RESTRICTIONS_FOR_HISTORY_SYNC_OPT_IN)
+    public void testSignedInWithMinorModeNotRequiredRecordsCancelButtonClicked()
+            throws IOException {
+        mChromeActivityTestRule.startMainActivityOnBlankPage();
+        CoreAccountInfo accountInfo =
+                mSigninTestRule.addAccount(
+                        AccountManagerTestRule.TEST_ACCOUNT_EMAIL, MINOR_MODE_NOT_REQUIRED);
+
+        mSigninTestRule.waitForSeeding();
+        SigninTestUtil.signin(accountInfo);
+        mSyncConsentActivity = waitForSyncConsentActivity(accountInfo);
+
+        HistogramWatcher histogramWatcher =
+                HistogramWatcher.newSingleRecordWatcher(
+                        "Signin.SyncButtons.Clicked",
+                        MinorModeHelper.SyncButtonClicked.SYNC_CANCEL_NOT_EQUAL_WEIGHTED);
+        onViewWaiting(withText(R.string.signin_sync_decline_button)).perform(click());
+        histogramWatcher.assertExpected();
+    }
+
+    @Test
+    @LargeTest
+    @EnableFeatures(SigninFeatures.MINOR_MODE_RESTRICTIONS_FOR_HISTORY_SYNC_OPT_IN)
+    public void testSignedInWithMinorModeRequiredRecordsAcceptButtonClicked() throws IOException {
+        mChromeActivityTestRule.startMainActivityOnBlankPage();
+        CoreAccountInfo accountInfo =
+                mSigninTestRule.addAccount(
+                        AccountManagerTestRule.TEST_ACCOUNT_EMAIL, MINOR_MODE_REQUIRED);
+
+        mSigninTestRule.waitForSeeding();
+        SigninTestUtil.signin(accountInfo);
+        mSyncConsentActivity = waitForSyncConsentActivity(accountInfo);
+
+        HistogramWatcher histogramWatcher =
+                HistogramWatcher.newSingleRecordWatcher(
+                        "Signin.SyncButtons.Clicked",
+                        MinorModeHelper.SyncButtonClicked.SYNC_OPT_IN_EQUAL_WEIGHTED);
+        onViewWaiting(withText(R.string.signin_accept_button)).perform(click());
+        histogramWatcher.assertExpected();
+    }
+
+    @Test
+    @LargeTest
+    @EnableFeatures(SigninFeatures.MINOR_MODE_RESTRICTIONS_FOR_HISTORY_SYNC_OPT_IN)
+    public void testSignedInWithMinorModeNotRequiredRecordsAcceptButtonClicked()
+            throws IOException {
+        mChromeActivityTestRule.startMainActivityOnBlankPage();
+        CoreAccountInfo accountInfo =
+                mSigninTestRule.addAccount(
+                        AccountManagerTestRule.TEST_ACCOUNT_EMAIL, MINOR_MODE_NOT_REQUIRED);
+
+        mSigninTestRule.waitForSeeding();
+        SigninTestUtil.signin(accountInfo);
+        mSyncConsentActivity = waitForSyncConsentActivity(accountInfo);
+
+        HistogramWatcher histogramWatcher =
+                HistogramWatcher.newSingleRecordWatcher(
+                        "Signin.SyncButtons.Clicked",
+                        MinorModeHelper.SyncButtonClicked.SYNC_OPT_IN_NOT_EQUAL_WEIGHTED);
+        onViewWaiting(withText(R.string.signin_accept_button)).perform(click());
+        histogramWatcher.assertExpected();
+    }
+
+    @Test
+    @LargeTest
     @Feature("RenderTest")
     @EnableFeatures(SigninFeatures.MINOR_MODE_RESTRICTIONS_FOR_HISTORY_SYNC_OPT_IN)
     public void testSignedInWithMinorModeRequiredHasEqualButtons() throws IOException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java
index 876c2ed..cfe77416 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java
@@ -50,8 +50,6 @@
 import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.base.test.util.DoNotBatch;
 import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.Features.DisableFeatures;
-import org.chromium.base.test.util.Features.EnableFeatures;
 import org.chromium.base.test.util.HistogramWatcher;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
@@ -324,7 +322,6 @@
 
     @Test
     @SmallTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testIdentityErrorCardShownForSignedInUsers() {
         // Fake an identity error.
         overrideSyncService().setRequiresClientUpgrade(true);
@@ -345,29 +342,6 @@
 
     @Test
     @SmallTest
-    @DisableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
-    public void testIdentityErrorCardNotShownIfFeatureDisabled() {
-        // Fake an identity error.
-        overrideSyncService().setRequiresClientUpgrade(true);
-
-        // Expect no records.
-        HistogramWatcher watchIdentityErrorCardShownHistogram =
-                HistogramWatcher.newBuilder()
-                        .expectNoRecords("Sync.IdentityErrorCard.ClientOutOfDate")
-                        .build();
-
-        // Sign in and open settings.
-        mSyncTestRule.setUpAccountAndSignInForTesting();
-        mSettingsActivityTestRule.startSettingsActivity();
-
-        onViewWaiting(allOf(is(mSettingsActivityTestRule.getFragment().getView()), isDisplayed()));
-        onView(withId(R.id.identity_error_card)).check(doesNotExist());
-        watchIdentityErrorCardShownHistogram.assertExpected();
-    }
-
-    @Test
-    @SmallTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testIdentityErrorCardNotShownIfNoError() {
         // Sign in and open settings.
         mSyncTestRule.setUpAccountAndSignInForTesting();
@@ -379,7 +353,6 @@
 
     @Test
     @SmallTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testIdentityErrorCardNotShownForSyncingUsers() {
         // Fake an identity error.
         overrideSyncService().setRequiresClientUpgrade(true);
@@ -401,7 +374,6 @@
 
     @Test
     @SmallTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testIdentityErrorCardDynamicallyShownOnError() {
         FakeSyncServiceImpl fakeSyncService = overrideSyncService();
 
@@ -435,7 +407,6 @@
 
     @Test
     @SmallTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testIdentityErrorCardDynamicallyHidden() {
         FakeSyncServiceImpl fakeSyncService = overrideSyncService();
         // Fake an identity error.
@@ -471,7 +442,6 @@
 
     @Test
     @LargeTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testActionForAuthError() throws Exception {
         FakeSyncServiceImpl fakeSyncService = overrideSyncService();
         fakeSyncService.setAuthError(GoogleServiceAuthError.State.INVALID_GAIA_CREDENTIALS);
@@ -506,7 +476,6 @@
 
     @Test
     @LargeTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testActionForPassphraseRequired() throws Exception {
         mSyncTestRule.getFakeServerHelper().setCustomPassphraseNigori("passphrase");
 
@@ -553,7 +522,6 @@
 
     @Test
     @LargeTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testActionForClientOutdatedError() throws Exception {
         overrideSyncService().setRequiresClientUpgrade(true);
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/IdentityErrorCardPreferenceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/IdentityErrorCardPreferenceTest.java
index 1192a95e..400fa70d5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/IdentityErrorCardPreferenceTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/IdentityErrorCardPreferenceTest.java
@@ -21,8 +21,6 @@
 
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.Features.EnableFeatures;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
 import org.chromium.chrome.browser.sync.settings.AccountManagementFragment;
@@ -38,7 +36,6 @@
 /** Test suite for IdentityErrorCardPreference */
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-@EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
 public class IdentityErrorCardPreferenceTest {
     public final SettingsActivityTestRule<AccountManagementFragment> mSettingsActivityTestRule =
             new SettingsActivityTestRule<>(AccountManagementFragment.class);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessageTest.java
index db44c729..32adda0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessageTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/ui/SyncErrorMessageTest.java
@@ -30,12 +30,9 @@
 import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.base.test.util.DoNotBatch;
 import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.Features.DisableFeatures;
-import org.chromium.base.test.util.Features.EnableFeatures;
 import org.chromium.base.test.util.HistogramWatcher;
 import org.chromium.base.test.util.Matchers;
 import org.chromium.chrome.browser.SyncFirstSetupCompleteSource;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.sync.FakeSyncServiceImpl;
 import org.chromium.chrome.browser.sync.SyncTestRule;
@@ -266,7 +263,6 @@
 
     @Test
     @LargeTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSyncErrorMessageShownForAuthErrorForSignedInUsers() throws Exception {
         HistogramWatcher watchIdentityErrorMessageShownHistogram =
                 HistogramWatcher.newSingleRecordWatcher(
@@ -287,7 +283,6 @@
 
     @Test
     @LargeTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSyncErrorMessageShownForPassphraseRequiredForSignedInUsers() throws Exception {
         HistogramWatcher watchIdentityErrorMessageShownHistogram =
                 HistogramWatcher.newSingleRecordWatcher(
@@ -309,7 +304,6 @@
 
     @Test
     @LargeTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSyncErrorMessageShownForClientOutOfDateForSignedInUsers() throws Exception {
         HistogramWatcher watchIdentityErrorMessageShownHistogram =
                 HistogramWatcher.newSingleRecordWatcher(
@@ -329,7 +323,6 @@
 
     @Test
     @LargeTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSyncErrorMessageShownForTrustedVaultKeyRequiredForSignedInUsers()
             throws Exception {
         HistogramWatcher watchIdentityErrorMessageShownHistogram =
@@ -352,7 +345,6 @@
 
     @Test
     @LargeTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSyncErrorMessageShownForTrustedVaultRecoverabilityDegradedForSignedInUsers()
             throws Exception {
         HistogramWatcher watchIdentityErrorMessageShownHistogram =
@@ -375,7 +367,6 @@
 
     @Test
     @LargeTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSyncErrorMessageNotShownWhenNoErrorForSignedInUsers() throws Exception {
         // Sign in.
         mSyncTestRule.setUpAccountAndSignInForTesting();
@@ -390,27 +381,7 @@
 
     @Test
     @LargeTest
-    @DisableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
-    public void testSyncErrorMessageNotShownForAuthErrorForSignedInUsersIfFeatureDisabled()
-            throws Exception {
-        HistogramWatcher watchIdentityErrorMessageShownHistogram =
-                HistogramWatcher.newBuilder()
-                        .expectNoRecords("Sync.IdentityErrorMessage.AuthError")
-                        .build();
-
-        // Sign in.
-        mSyncTestRule.setUpAccountAndSignInForTesting();
-        mFakeSyncServiceImpl.setAuthError(GoogleServiceAuthError.State.INVALID_GAIA_CREDENTIALS);
-
-        mSyncTestRule.loadUrl(UrlConstants.VERSION_URL);
-        verifyHasNeverShownMessage();
-        watchIdentityErrorMessageShownHistogram.assertExpected();
-    }
-
-    @Test
-    @LargeTest
     @Feature("RenderTest")
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSyncErrorMessageForAuthErrorViewForSignedInUsers() throws IOException {
         SyncErrorMessage.setMessageDispatcherForTesting(null);
         // Sign in.
@@ -426,7 +397,6 @@
     @Test
     @LargeTest
     @Feature("RenderTest")
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSyncErrorMessageForPassphraseRequiredViewForSignedInUsers() throws IOException {
         SyncErrorMessage.setMessageDispatcherForTesting(null);
         // Sign in.
@@ -443,7 +413,6 @@
     @Test
     @LargeTest
     @Feature("RenderTest")
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testSyncErrorMessageForClientOutOfDateViewForSignedInUsers() throws IOException {
         SyncErrorMessage.setMessageDispatcherForTesting(null);
         // Sign in.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateUnitTest.java
index f50ad6bd..3034eb87 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateUnitTest.java
@@ -254,8 +254,6 @@
         setShoppingListEligible(false);
         setShoppingListEligible(false);
         mTestValues.addFeatureFlagOverride(ChromeFeatureList.PWA_UNIVERSAL_INSTALL_UI, false);
-        mTestValues.addFeatureFlagOverride(
-                ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS, false);
         FeatureList.setTestValues(mTestValues);
     }
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/history/HistoryUITest.java b/chrome/android/junit/src/org/chromium/chrome/browser/history/HistoryUITest.java
index dd7e8f2e..5dfe6ae9 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/history/HistoryUITest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/history/HistoryUITest.java
@@ -86,6 +86,7 @@
 import org.chromium.ui.base.TestActivity;
 import org.chromium.url.GURL;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
 
@@ -108,6 +109,7 @@
     private StubbedHistoryProvider mHistoryProvider;
     private HistoryAdapter mAdapter;
     private HistoryManager mHistoryManager;
+    private HistoryContentManager mContentManager;
     private RecyclerView mRecyclerView;
     private Activity mActivity;
 
@@ -166,14 +168,17 @@
                         true,
                         mSnackbarManager,
                         mProfile,
+                        /* bottomSheetController= */ null,
                         /* Supplier<Tab>= */ null,
                         mHistoryProvider,
                         new HistoryUmaRecorder(),
                         null,
                         true,
-                        false);
-        mAdapter = mHistoryManager.getContentManagerForTests().getAdapter();
-        mRecyclerView = mHistoryManager.getContentManagerForTests().getRecyclerView();
+                        false,
+                        ChromeFeatureList.isEnabled(ChromeFeatureList.APP_SPECIFIC_HISTORY));
+        mContentManager = mHistoryManager.getContentManagerForTests();
+        mAdapter = mContentManager.getAdapter();
+        mRecyclerView = mContentManager.getRecyclerView();
 
         // Layout the recycler view with ample height so that we can measure how much height it
         // needs to fully display its initial set of items.
@@ -445,6 +450,32 @@
         Assert.assertTrue(mAdapter.hasListHeader());
     }
 
+    @EnableFeatures(ChromeFeatureList.APP_SPECIFIC_HISTORY)
+    @Config(sdk = VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @Test
+    @SmallTest
+    public void testSearch_AppFilterChipEnabledWithNonEmptyAppResult() {
+        Assert.assertTrue(mHistoryProvider.isQueryAppsTriggered());
+        mAdapter.setClearBrowsingDataButtonVisibilityForTest(false);
+        mAdapter.setPrivacyDisclaimer();
+        Assert.assertFalse(mAdapter.hasListHeader());
+        performMenuAction(R.id.search_menu_id);
+
+        // Verify the button starts disabled.
+        Assert.assertFalse(mAdapter.getAppFilterButtonForTest().isEnabled());
+
+        // Verify the button remains disabled if the query app result is empty.
+        var result = new ArrayList<String>();
+        mAdapter.onQueryAppsComplete(result);
+        Assert.assertFalse(mAdapter.getAppFilterButtonForTest().isEnabled());
+
+        // Verify the button becomes enabled if the app result is non-empty.
+        result.add("org.chromium.chrome.ernie");
+        result.add("org.chromium.chrome.bert");
+        mAdapter.onQueryAppsComplete(result);
+        Assert.assertFalse(mAdapter.getAppFilterButtonForTest().isEnabled());
+    }
+
     @Test
     @SmallTest
     public void testSearchViewDismissedByBackPress() {
@@ -606,12 +637,14 @@
                         true,
                         mSnackbarManager,
                         mProfile,
+                        /* bottomSheetController= */ null,
                         /* Supplier<Tab>= */ null,
                         mHistoryProvider,
                         new HistoryUmaRecorder(),
                         null,
                         true,
-                        true);
+                        true,
+                        false);
         final HistoryManagerToolbar toolbar = mHistoryManager.getToolbarForTests();
         Assert.assertNull(toolbar.getItemById(R.id.close_menu_id));
         Assert.assertEquals(
@@ -627,12 +660,14 @@
                         true,
                         mSnackbarManager,
                         mProfile,
+                        /* bottomSheetController= */ null,
                         /* Supplier<Tab>= */ null,
                         mHistoryProvider,
                         new HistoryUmaRecorder(),
                         null,
                         true,
-                        true);
+                        true,
+                        false);
         InfoHeaderPref headerPref = mHistoryManager.getInfoHeaderPrefForTests();
         Assert.assertFalse(headerPref.isVisible());
         HistoryManagerToolbar toolbar = mHistoryManager.getToolbarForTests();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/sync/SyncErrorNotifierTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/sync/SyncErrorNotifierTest.java
index bda6091f..72534316 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/sync/SyncErrorNotifierTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/sync/SyncErrorNotifierTest.java
@@ -31,10 +31,7 @@
 import org.chromium.base.Promise;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Features;
-import org.chromium.base.test.util.Features.DisableFeatures;
-import org.chromium.base.test.util.Features.EnableFeatures;
 import org.chromium.chrome.R;
-import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.components.browser_ui.notifications.NotificationManagerProxy;
 import org.chromium.components.browser_ui.notifications.NotificationWrapper;
 import org.chromium.components.signin.base.CoreAccountInfo;
@@ -250,7 +247,6 @@
 
     @Test
     @SmallTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testPassphraseNotificationForSignedInUsers() {
         when(mSyncService.getAccountInfo())
                 .thenReturn(CoreAccountInfo.createFromEmailAndGaiaId("a@b.com", "gaiaId"));
@@ -292,28 +288,6 @@
 
     @Test
     @SmallTest
-    @DisableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
-    public void testNoNotificationForSignedInUsersIfFeatureDisabled() {
-        when(mSyncService.getAccountInfo())
-                .thenReturn(CoreAccountInfo.createFromEmailAndGaiaId("a@b.com", "gaiaId"));
-        when(mSyncService.isSyncFeatureEnabled()).thenReturn(false);
-        when(mSyncService.isEngineInitialized()).thenReturn(true);
-        when(mSyncService.isEncryptEverythingEnabled()).thenReturn(true);
-        when(mSyncService.isPassphraseRequiredForPreferredDataTypes()).thenReturn(true);
-        when(mSyncService.isPassphrasePromptMutedForCurrentProductVersion()).thenReturn(false);
-        when(mSyncService.isTrustedVaultKeyRequiredForPreferredDataTypes()).thenReturn(false);
-
-        SyncErrorNotifier notifier =
-                new SyncErrorNotifier(mNotificationManagerProxy, mSyncService, mTrustedVaultClient);
-        notifier.syncStateChanged();
-
-        verify(mNotificationManagerProxy, Mockito.times(0)).cancel(anyInt());
-        verify(mNotificationManagerProxy, Mockito.times(0)).notify(any());
-    }
-
-    @Test
-    @SmallTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testTrustedVaultNotificationForPasswordsForSignedInUsers() {
         when(mSyncService.getAccountInfo())
                 .thenReturn(CoreAccountInfo.createFromEmailAndGaiaId("a@b.com", "gaiaId"));
@@ -374,7 +348,6 @@
 
     @Test
     @SmallTest
-    @EnableFeatures(ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS)
     public void testTrustedVaultNotificationForEverythingForSignedInUsers() {
         when(mSyncService.getAccountInfo())
                 .thenReturn(CoreAccountInfo.createFromEmailAndGaiaId("a@b.com", "gaiaId"));
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java
index 6cba2307..93dbb79 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegateUnitTest.java
@@ -97,13 +97,8 @@
 
 /** Unit tests for {@link TabbedAppMenuPropertiesDelegate}. */
 @RunWith(BaseRobolectricTestRunner.class)
-@EnableFeatures({
-    UiAccessibilityFeatures.START_SURFACE_ACCESSIBILITY_CHECK
-})
-@DisableFeatures({
-    ChromeFeatureList.SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS,
-    ChromeFeatureList.PWA_UNIVERSAL_INSTALL_UI
-})
+@EnableFeatures({UiAccessibilityFeatures.START_SURFACE_ACCESSIBILITY_CHECK})
+@DisableFeatures({ChromeFeatureList.PWA_UNIVERSAL_INSTALL_UI})
 public class TabbedAppMenuPropertiesDelegateUnitTest {
     // Constants defining flags that determines multi-window menu items visibility.
     private static final boolean TAB_M = true; // multiple tabs
diff --git a/chrome/app/resources/chromium_strings_id.xtb b/chrome/app/resources/chromium_strings_id.xtb
index e9e380d..9562c41 100644
--- a/chrome/app/resources/chromium_strings_id.xtb
+++ b/chrome/app/resources/chromium_strings_id.xtb
@@ -175,6 +175,7 @@
 <translation id="4095980151185649725">{COUNT,plural, =1{Organisasi akan otomatis menutup Chromium jika tidak digunakan selama 1 menit. Data penjelajahan akan dihapus. Data ini dapat mencakup histori, isi otomatis, dan download.}other{Organisasi akan otomatis menutup Chromium jika tidak digunakan selama # menit. Data penjelajahan akan dihapus. Data ini dapat mencakup histori, isi otomatis, dan download.}}</translation>
 <translation id="4118474109249235144">Mode Samaran Chromium</translation>
 <translation id="4148957013307229264">Memasang...</translation>
+<translation id="4149336151887611710">Organisasi Anda dapat melihat dan mengelola data penjelajahan di profil kerja Anda, seperti bookmark, histori, dan sandi. Organisasi Anda tidak dapat melihat data penjelajahan di profil Chromium pribadi.</translation>
 <translation id="419998258129752635"><ph name="PAGE_TITLE" /> - Login Jaringan - Chromium</translation>
 <translation id="421369550622382712">Temukan aplikasi, game, ekstensi, dan tema yang hebat untuk Chromium.</translation>
 <translation id="4216212958613226427">Bahasa ini digunakan untuk menampilkan UI Chromium</translation>
@@ -403,6 +404,7 @@
 <translation id="7867198900892795913">Chromium tidak dapat diupdate ke versi terbaru, sehingga Anda tidak mendapatkan perbaikan keamanan dan fitur baru.</translation>
 <translation id="7872446069773932638">Mendownload ... <ph name="SECONDS" /> detik lagi</translation>
 <translation id="7877292582355102282"><ph name="BEGIN_BOLD" />Cara Anda dapat mengelola data Anda:<ph name="END_BOLD" /> Untuk melindungi privasi Anda, kami otomatis menghapus minat yang tersimpan lebih dari 4 minggu. Saat Anda terus menjelajah, minat dapat kembali muncul di daftar. Atau Anda dapat menghapus minat yang tidak perlu dipertimbangkan oleh Chromium.</translation>
+<translation id="7888981273428720788">Setel Chromium sebagai browser default</translation>
 <translation id="7937630085815544518">Anda telah masuk ke Chromium sebagai <ph name="USER_EMAIL_ADDRESS" />. Gunakan akun yang sama untuk masuk kembali.</translation>
 <translation id="7975919845073681630">Ini adalah pemasangan Chromium sekunder, dan tidak dapat digunakan sebagai browser default.</translation>
 <translation id="7997934263947464652">Ekstensi, aplikasi, dan tema dari sumber tidak dikenal dapat membahayakan perangkat Anda. Chromium merekomendasikan hanya menginstal ekstensi, aplikasi, dan tema dari <ph name="IDS_EXTENSION_WEB_STORE_TITLE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_ms.xtb b/chrome/app/resources/chromium_strings_ms.xtb
index 4d2407d..eb79d15 100644
--- a/chrome/app/resources/chromium_strings_ms.xtb
+++ b/chrome/app/resources/chromium_strings_ms.xtb
@@ -42,6 +42,7 @@
 <translation id="1779356040007214683">Untuk menjadikan Chromium lebih selamat, kami melumpuhkan beberapa sambungan yang tidak disenaraikan dalam <ph name="IDS_EXTENSION_WEB_STORE_TITLE" /> dan mungkin telah ditambahkan tanpa pengetahuan anda.</translation>
 <translation id="1808667845054772817">Pasang semula Chromium</translation>
 <translation id="1820835682567584003">Chromium cuba <ph name="AUTHENTICATION_PURPOSE" /></translation>
+<translation id="18552579716432081">Untuk memadamkan data semakan imbas daripada peranti ini dan menyimpan data semakan imbas tersebut dalam Google Account anda, <ph name="BEGIN_LINK" />log keluar dari Chromium<ph name="END_LINK" />.</translation>
 <translation id="185970820835152459">Anda boleh mengurus Google Account anda yang dilog masuk. Google Account anda digunakan untuk penyemak imbas Chromium, Play Store, Gmail dan pelbagai lagi. Jika anda ingin menambah akaun untuk orang lain, seperti ahli keluarga, tambahkan sahaja orang baharu pada <ph name="DEVICE_TYPE" /> anda. <ph name="LINK_BEGIN" />Ketahui lebih lanjut<ph name="LINK_END" /></translation>
 <translation id="1863308913976887472">Laman boleh menyimpan maklumat tentang minat anda menggunakan Chromium. Contohnya, jika anda melawat laman untuk membeli kasut untuk maraton, laman tersebut mungkin mentakrifkan minat anda sebagai larian maraton. Kemudian, jika anda melawati laman lain untuk mendaftar perlumbaan, laman tersebut boleh memaparkan kepada anda iklan kasut untuk berlari berdasarkan minat anda.</translation>
 <translation id="1881322772814446296">Anda log masuk menggunakan akaun yang terurus dan memberikan pentadbirnya kawalan ke atas profil Chromium anda. Data Chromium anda, seperti apl, penanda halaman, sejarah, kata laluan dan tetapan anda yang lain akan terikat kepada <ph name="USER_NAME" /> secara kekal. Anda akan dapat memadamkan data ini melalui Papan Pemuka Google Account, tetapi anda tidak akan dapat mengaitkan data ini dengan akaun lain. Anda boleh memilih untuk membuat profil baharu untuk mengasingkan data Chromium anda yang sedia ada. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/generated_resources_af.xtb b/chrome/app/resources/generated_resources_af.xtb
index 730b0e1..899bcae 100644
--- a/chrome/app/resources/generated_resources_af.xtb
+++ b/chrome/app/resources/generated_resources_af.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Wysig lêers</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Kan nie lêer oopmaak nie}other{Kan nie lêers oopmaak nie}}</translation>
 <translation id="1282311502488501110">Moenie aanmeld nie</translation>
-<translation id="1282465000333679776">Deel stelseloudio</translation>
 <translation id="1283126956823499975">Iets het skeefgeloop met die opstel van die toestel</translation>
 <translation id="1284277788676816155">Moenie toelaat om data te stoor nie</translation>
 <translation id="1285320974508926690">Moet nooit hierdie werf vertaal nie</translation>
@@ -1062,7 +1061,6 @@
 <translation id="1781502536226964113">Maak nuwe oortjie-bladsy oop</translation>
 <translation id="1781553166608855614">Gesproke taal</translation>
 <translation id="1781771911845953849">Rekeninge en sinkronisering</translation>
-<translation id="1781979858217752599">Deel vensteroudio</translation>
 <translation id="1782101999402987960">Jou administrateur blokkeer opdaterings</translation>
 <translation id="1782196717298160133">Vind tans jou foon</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 nota}other{# notas}}</translation>
@@ -1627,7 +1625,6 @@
 <translation id="2187895286714876935">Bedienersertifikaat-invoerfout</translation>
 <translation id="2187906491731510095">Uitbreidings is opgedateer</translation>
 <translation id="2188881192257509750">Maak <ph name="APPLICATION" /> oop</translation>
-<translation id="2189787291884708275">Deel oortjie-oudio</translation>
 <translation id="2190069059097339078">Wi-Fi-eiebewyshaler</translation>
 <translation id="219008588003277019">Plaaslike kliënt-module: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(leeg)</translation>
@@ -5301,6 +5298,7 @@
 <translation id="4998430619171209993">Aan</translation>
 <translation id="4999804342505941663">Skakel Moenie Steur Nie aan</translation>
 <translation id="5001526427543320409">Derdepartywebkoekies</translation>
+<translation id="5003993274120026347">Volgende sin</translation>
 <translation id="5005498671520578047">Kopieer wagwoord</translation>
 <translation id="5006118752738286774">2 jaar gelede</translation>
 <translation id="5006218871145547804">Android-program-ADB in Crostini</translation>
@@ -9225,6 +9223,7 @@
 <translation id="8033958968890501070">Uittelling</translation>
 <translation id="8035059678007243127">Incognito-terug-vorentoe-kasgegeue-bladsy: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Help om outovul te verbeter</translation>
+<translation id="8036504271468642248">Vorige sin</translation>
 <translation id="8037117027592400564">Lees alle teks uitgespreek met gesintetiseerde spraak</translation>
 <translation id="8037357227543935929">Vra (verstek)</translation>
 <translation id="803771048473350947">Lêer</translation>
diff --git a/chrome/app/resources/generated_resources_am.xtb b/chrome/app/resources/generated_resources_am.xtb
index 1eac02f..c3fa3b5e 100644
--- a/chrome/app/resources/generated_resources_am.xtb
+++ b/chrome/app/resources/generated_resources_am.xtb
@@ -383,7 +383,6 @@
 <translation id="1280965841156951489">ፋይሎችን አርትዕ</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ፋይልን መክፈት አልተቻለም}one{ፋይልን መክፈት አልተቻለም}other{ፋይሎችን መክፈት አልተቻለም}}</translation>
 <translation id="1282311502488501110">በመለያ አይግቡ</translation>
-<translation id="1282465000333679776">የስርዓት ኦዲዮን ያጋሩ</translation>
 <translation id="1283126956823499975">መሣሪያውን በማዘጋጀት ላይ የሆነ ስህተት ተከስቷል</translation>
 <translation id="1284277788676816155">ውሂብ ለማስቀመጥ አይፍቀዱ</translation>
 <translation id="1285320974508926690">ይህን ጣቢያ በጭራሽ አትተርጉም</translation>
@@ -1059,7 +1058,6 @@
 <translation id="1781502536226964113">የአዲስ ትር ገፅ ክፈት</translation>
 <translation id="1781553166608855614">የሚነገረው ቋንቋ</translation>
 <translation id="1781771911845953849">መለያዎች እና ማስመር</translation>
-<translation id="1781979858217752599">የመስኮት ኦዲዮን አጋራ</translation>
 <translation id="1782101999402987960">ዝማኔዎች በአስተዳዳሪዎ ታግደዋል</translation>
 <translation id="1782196717298160133">የእርስዎን ስልክ ማግኘት</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 ማስታወሻ፦}one{# ማስታወሻ}other{# ማስታወሻዎች}}</translation>
@@ -1623,7 +1621,6 @@
 <translation id="2187895286714876935">የአገልጋይ ዕውቅና ማረጋገጫ ስህተት</translation>
 <translation id="2187906491731510095">ቅጥያዎች ተዘምነዋል</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> ክፈት</translation>
-<translation id="2189787291884708275">የትር ኦዲዮን አጋራ</translation>
 <translation id="2190069059097339078">WiFi አሳማኝ ምስክርነቶችን አግኝ</translation>
 <translation id="219008588003277019">የውስጥ ተገልጋይ ሞዱል፦ <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(ባዶ)</translation>
@@ -5292,6 +5289,7 @@
 <translation id="4998430619171209993">አብራ</translation>
 <translation id="4999804342505941663">አትረብሽን አብራ</translation>
 <translation id="5001526427543320409">የሦስተኛ ወገን ኩኪዎች</translation>
+<translation id="5003993274120026347">ቀጣይ ዓረፍተ ነገር</translation>
 <translation id="5005498671520578047">የይለፍ ቃል ቅዳ</translation>
 <translation id="5006118752738286774">ከ2 ዓመቶች በፊት</translation>
 <translation id="5006218871145547804">የCrostini Android መተግበሪያ ADB</translation>
@@ -9224,6 +9222,7 @@
 <translation id="8033958968890501070">ጊዜው አልቋል</translation>
 <translation id="8035059678007243127">ማንነት የማያሳውቅ የጀርባ/ፊት መሸጎጫ ገፅ፦ <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">ራስ-ሙላን ለማሻሻል ያግዙ</translation>
+<translation id="8036504271468642248">ቀዳሚ ዓረፍተ ነገር</translation>
 <translation id="8037117027592400564">ተሰብስቦ በተሰራ ንግግር አማካኝነት ሁሉንም የተነገሩ ጽሑፎች ያነብባል</translation>
 <translation id="8037357227543935929">ጠይቅ (ነባሪ)</translation>
 <translation id="803771048473350947">ፋይል</translation>
diff --git a/chrome/app/resources/generated_resources_ar.xtb b/chrome/app/resources/generated_resources_ar.xtb
index 5168715..16113d93 100644
--- a/chrome/app/resources/generated_resources_ar.xtb
+++ b/chrome/app/resources/generated_resources_ar.xtb
@@ -386,7 +386,6 @@
 <translation id="1280965841156951489">تعديل الملفات</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{يتعذّر فتح الملف.}zero{يتعذّر فتح الملفات.}two{يتعذّر فتح الملفين.}few{يتعذّر فتح الملفات.}many{يتعذّر فتح الملفات.}other{يتعذّر فتح الملفات.}}</translation>
 <translation id="1282311502488501110">عدم تسجيل الدخول</translation>
-<translation id="1282465000333679776">مشاركة صوت النظام</translation>
 <translation id="1283126956823499975">حدث خطأ أثناء إعداد الجهاز</translation>
 <translation id="1284277788676816155">عدم السماح بحفظ البيانات</translation>
 <translation id="1285320974508926690">عدم ترجمة هذا الموقع مطلقًا</translation>
@@ -541,6 +540,7 @@
 <translation id="1410797069449661718">الانتقال إلى علامة التبويب الأولى</translation>
 <translation id="1410806973194718079">يتعذّر التحقّق من السياسات.</translation>
 <translation id="1411400282355634827">هل تريد إعادة ضبط جميع أذونات الأجهزة التي تتضمّن بلوتوث؟</translation>
+<translation id="141163372431617064">عدم السماح للمواقع الإلكترونية بقفل المؤشر</translation>
 <translation id="1414315029670184034">عدم السماح للمواقع الإلكترونية باستخدام الكاميرا</translation>
 <translation id="1414648216875402825">إنك تُجري تحديثًا لإصدار غير ثابت من <ph name="PRODUCT_NAME" /> والذي يشتمل على ميزات قيد التقدم. لذا قد تحدث أعطال وأخطاء غير متوقعة. يُرجى المتابعة مع توخّي الحذر.</translation>
 <translation id="1415708812149920388">تم رفض الإذن بالاطّلاع على الحافظة</translation>
@@ -1053,7 +1053,6 @@
 <translation id="1781502536226964113">فتح صفحة علامة التبويب الجديدة</translation>
 <translation id="1781553166608855614">لغة التحدّث</translation>
 <translation id="1781771911845953849">الحسابات والمزامنة</translation>
-<translation id="1781979858217752599">مشاركة صوت النافذة</translation>
 <translation id="1782101999402987960">لقد حظر المشرف التحديثات.</translation>
 <translation id="1782196717298160133">العثور على هاتفك</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{ملاحظة واحدة}zero{# ملاحظة}two{ملاحظتان}few{# ملاحظات}many{# ملاحظة}other{# ملاحظة}}</translation>
@@ -1375,6 +1374,7 @@
 <translation id="2010501376126504057">الأجهزة المتوافقة</translation>
 <translation id="201217432804812273">تفعيل خيار "حفظ المجموعة"</translation>
 <translation id="2012935757369720523">حذف الملف</translation>
+<translation id="2013467735169740431">السماح للمواقع الإلكترونية بطلب قفل لوحة المفاتيح</translation>
 <translation id="2013550551806600826">لتجربة هذه الميزة بنفسك، فعِّل هذا الإعداد أو أوقِفه ثم مرِّر بإصبعين على لوحة اللمس في منطقة الاختبار. يمكنك أيضًا العثور على هذه الميزة لاحقًا في الإعدادات &gt; الجهاز &gt; الماوس ولوحة اللمس.</translation>
 <translation id="2015232545623037616">‏جهاز الكمبيوتر الشخصي وجهاز Chromecast متصلان بشبكة Wi-Fi واحدة</translation>
 <translation id="2016473077102413275">لن تعمل الميزات التي تحتاج إلى استخدام الصور.</translation>
@@ -1618,7 +1618,6 @@
 <translation id="2187895286714876935">خط استيراد شهادة الخادم</translation>
 <translation id="2187906491731510095">تم تحديث الإضافات.</translation>
 <translation id="2188881192257509750">فتح <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">مشاركة صوت علامة التبويب</translation>
 <translation id="2190069059097339078">‏أداة الحصول على بيانات اعتماد WiFi</translation>
 <translation id="219008588003277019">وحدة البرنامج العميل الأصلي: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(فارغ)</translation>
@@ -2201,6 +2200,7 @@
 <translation id="2613535083491958306">سيتمكّن <ph name="ORIGIN" /> من تعديل <ph name="FILENAME" />.</translation>
 <translation id="2613747923081026172">إنشاء مجموعة</translation>
 <translation id="2615159404909536465">{FILE_COUNT,plural, =1{فتح وتعديل ملف <ph name="FILE1" /> في هذه الإضافة}zero{فتح وتعديل الملفات <ph name="FILE1" />، … في هذه الإضافة}two{فتح وتعديل الملفَين <ph name="FILE1" />، … في هذه الإضافة}few{فتح وتعديل الملفات <ph name="FILE1" />، … في هذه الإضافة}many{فتح وتعديل الملفات <ph name="FILE1" />، … في هذه الإضافة}other{فتح وتعديل الملفات <ph name="FILE1" />، … في هذه الإضافة}}</translation>
+<translation id="2615927647449180540">المواقع الإلكترونية التي لا يُسمح لها بقفل المؤشر</translation>
 <translation id="2616366145935564096">قراءة بياناتك وتغييرها في <ph name="WEBSITE_1" /></translation>
 <translation id="2618797463720777311">إعداد ميزة "المشاركة عن قرب"</translation>
 <translation id="2619340799655338321">تشغيل/إيقاف مؤقت</translation>
@@ -3067,6 +3067,7 @@
 <translation id="3293644607209440645">إرسال هذه الصفحة</translation>
 <translation id="32939749466444286">‏يتعذَّر بدء حاوية نظام التشغيل Linux. يُرجى إعادة المحاولة.</translation>
 <translation id="3294437725009624529">ضيف</translation>
+<translation id="3294484594253557399">تستخدِم المواقع الإلكترونية قفل المؤشر لإخفاء مؤشر الماوس ومنعه من الظهور خارج صفحاتها.</translation>
 <translation id="3294686910656423119">إحصاءات الاستخدام وتقارير الأعطال</translation>
 <translation id="3295241308788901889">يجري بث علامة تبويب.</translation>
 <translation id="3297105622164376095">مواقع إلكترونية يُسمح لها بعرض الطلبات بتسجيل الدخول في الخدمات التابعة لجهات خارجية</translation>
@@ -4136,6 +4137,7 @@
 <translation id="4094647278880271855">أنت تستخدم متغير بيئة غير معتمد: <ph name="BAD_VAR" />. وسيؤثر ذلك سلبًا على الثبات والأمان.</translation>
 <translation id="4095264805865317199">فتح واجهة مستخدم لتفعيل شبكة الجوّال</translation>
 <translation id="4095425503313512126">تصفَّح وابحث بشكل أسرع.</translation>
+<translation id="4095483462103784441">إنشاء مجموعة علامات تبويب جديدة</translation>
 <translation id="4095507791297118304">شاشة أساسية</translation>
 <translation id="4096421352214844684">يمكنك الاتصال تلقائيًا بنقطة الاتصال على هاتفك.</translation>
 <translation id="4096797685681362305">تم الاطّلاع عليه في الأسبوع الماضي.</translation>
@@ -5046,6 +5048,7 @@
 <translation id="4819323978093861656">{0,plural, =0{‏سيتم إغلاق كل نوافذ Chrome الآن.}=1{‏سيتم إغلاق كل نوافذ Chrome بعد ثانية واحدة.}two{‏سيتم إغلاق كل نوافذ Chrome بعد ثانيتَين.}few{‏سيتم إغلاق كل نوافذ Chrome بعد # ثوانٍ.}many{‏سيتم إغلاق كل نوافذ Chrome بعد # ثانية.}other{‏سيتم إغلاق كل نوافذ Chrome بعد # ثانية.}}</translation>
 <translation id="4819607494758673676">‏إشعارات "مساعد Google"</translation>
 <translation id="4819818293886748542">الحصول على رابط أداة الدعم</translation>
+<translation id="4820082996741546682">المواقع الإلكترونية التي يُسمح لها بقفل لوحة المفاتيح</translation>
 <translation id="4820236583224459650">ضبط كتذكرة نشطة</translation>
 <translation id="4820795723433418303">استخدام مفاتيح الوظائف كبديل لمفاتيح الصف العلوي</translation>
 <translation id="4821935166599369261">&amp;التوصيف مفعّل</translation>
@@ -5122,6 +5125,7 @@
 <translation id="4872192066608821120">‏لاستيراد كلمات مرور، اختَر أحد ملفات CSV.</translation>
 <translation id="4872212987539553601">ضبط إعدادات عملية "التشفير على الجهاز فقط"</translation>
 <translation id="4873312501243535625">مدقق ملف الوسائط</translation>
+<translation id="4874705075711349931">تستخدِم المواقع الإلكترونية قفل لوحة المفاتيح للوصول إلى إدخالات لوحة المفاتيح التي كان سيتعامل معها المتصفّح أو نظام التشغيل.</translation>
 <translation id="4876273079589074638">ساعد مهندسينا في تحري هذا العطل وإصلاحه. واسرد الخطوات الدقيقة إذا كان ذلك ممكنًا. لا توجد تفاصيل صغيرة جدًا!</translation>
 <translation id="4876305945144899064">ليس هناك اسم مستخدم</translation>
 <translation id="4876327226315760474">هذا يعني أنّ ميزات الموقع الإلكتروني يُفترض أن تعمل على النحو المتوقَّع، ولكن قد تكون الحماية أثناء التصفّح أقلّ.</translation>
@@ -5281,6 +5285,7 @@
 <translation id="4998430619171209993">مفعّل</translation>
 <translation id="4999804342505941663">تفعيل وضع "عدم الإزعاج"</translation>
 <translation id="5001526427543320409">ملفات تعريف الارتباط التابعة لجهات خارجية</translation>
+<translation id="5003993274120026347">الجملة التالية</translation>
 <translation id="5005498671520578047">نسخ كلمة المرور</translation>
 <translation id="5006118752738286774">قبل عامين</translation>
 <translation id="5006218871145547804">‏أداة ADB في تطبيق Android لنظام التشغيل Crostini</translation>
@@ -6339,6 +6344,7 @@
 <translation id="583431638776747">لم يكن الموقع الإلكتروني متاحًا.</translation>
 <translation id="5834581999798853053">تتبقى <ph name="TIME" /> دقيقة تقريبًا</translation>
 <translation id="5835360478055379192">{NUM_EXTENSION,plural, =1{‏الإضافة التي لديها إمكانية الوصول إلى أجهزة HID: <ph name="EXTENSION1" />}=2{الإضافات التي لديها إمكانية الوصول إلى الأجهزة: <ph name="EXTENSION1" /> و<ph name="EXTENSION2" />}zero{الإضافات التي لديها إمكانية الوصول إلى الأجهزة: <ph name="EXTENSION1" /> و<ph name="EXTENSION2" /> و{3} إضافة أخرى}few{الإضافات التي لديها إمكانية الوصول إلى الأجهزة: <ph name="EXTENSION1" /> و<ph name="EXTENSION2" /> و{3} إضافات أخرى}many{الإضافات التي لديها إمكانية الوصول إلى الأجهزة: <ph name="EXTENSION1" /> و<ph name="EXTENSION2" /> و{3} إضافة أخرى}other{الإضافات التي لديها إمكانية الوصول إلى الأجهزة: <ph name="EXTENSION1" /> و<ph name="EXTENSION2" /> و{3} إضافة أخرى}}</translation>
+<translation id="5835714760577949748">المواقع الإلكترونية التي لا يُسمح لها بقفل لوحة المفاتيح</translation>
 <translation id="583673505367439042">السماح للمواقع الإلكترونية بطلب تعديل الملفات والمجلدات على جهازك</translation>
 <translation id="5836999627049108525">لغة النص المطلوب ترجمته</translation>
 <translation id="583756221537636748">الحافظة</translation>
@@ -8883,6 +8889,7 @@
 
 
 <ph name="EXTENSION_NAME" /></translation>
+<translation id="7788948939674438635">عدم السماح للمواقع الإلكترونية بقفل لوحة المفاتيح</translation>
 <translation id="7789963078219276159">تم تغيير خلفية الصفحة الرئيسية إلى <ph name="CATEGORY" />.</translation>
 <translation id="7790689625219600437">‏التعرّف البصري على الأحرف (OCR) في ملفات PDF</translation>
 <translation id="7791269138074599214">أسلوب الإدخال</translation>
@@ -9212,6 +9219,7 @@
 <translation id="8033958968890501070">انتهاء المهلة</translation>
 <translation id="8035059678007243127">الصفحة المخزّنة من خلال ميزة "التخزين المؤقت للصفحات" في وضع "التصفّح المتخفي": <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">المساعدة على تحسين ميزة "الملء التلقائي"</translation>
+<translation id="8036504271468642248">الجملة السابقة</translation>
 <translation id="8037117027592400564">قراءة جميع النصوص المنطوقة باستخدام الكلام المركب</translation>
 <translation id="8037357227543935929">الطلب (تلقائي)</translation>
 <translation id="803771048473350947">ملف</translation>
@@ -9910,6 +9918,7 @@
 <translation id="8561206103590473338">فيل</translation>
 <translation id="8561565784790166472">يُرجى المتابعة مع توخّي الحذر</translation>
 <translation id="8561853412914299728"><ph name="TAB_TITLE" /> <ph name="EMOJI_PLAYING" /></translation>
+<translation id="8562115322675481339">إنشاء مجموعة علامات تبويب جديدة</translation>
 <translation id="8563043098557365232">السماح لخدمات النظام فقط</translation>
 <translation id="8564220755011656606">يتعذّر الوصول إلى الميكروفون</translation>
 <translation id="8565650234829130278">محاولة الرجوع إلى الإصدار السابق من التطبيق.</translation>
@@ -10398,6 +10407,7 @@
 <translation id="8930622219860340959">شبكة لاسلكية</translation>
 <translation id="8931076093143205651">‏يمكنك إرسال بيانات الاستخدام والتشخيص. يمكنك المساعدة في تحسين تجربة نظام التشغيل Android من خلال إرسال بيانات استخدام التطبيق وبيانات الجهاز وبيانات التشخيص تلقائيًا إلى Google. وسيساعد ذلك في تعزيز استقرار النظام والتطبيقات وإجراء المزيد من التحسينات. وسيستفيد أيضًا مطوّرو التطبيقات والشركاء في Google، مثل مطوّري البرامج المتوافقة مع Android، من بعض البيانات المجمّعة. ويفرض المالك هذا الإعداد. قد يختار المالك إرسال بيانات الاستخدام والتشخيص لهذا الجهاز إلى Google. في حال تفعيل إعداد "النشاط الإضافي على الويب وفي التطبيقات"، قد يتم حفظ هذه البيانات في حسابك على Google.</translation>
 <translation id="8931475688782629595">إدارة البيانات المتزامنة</translation>
+<translation id="8931479761457920281">المواقع الإلكترونية التي يُسمح لها بقفل المؤشر</translation>
 <translation id="8931713990831679796">هذه الطابعات متصلة وجاهزة للاستخدام. عليك حفظها في ملفك الشخصي للوصول إليها بسهولة.</translation>
 <translation id="8932654652795262306">تفاصيل عن ميزة "التوصيل الفوري"</translation>
 <translation id="893298445929867520">تم إخفاء سلّات التسوّق، وستظهر من جديد عند إجرائك لأي تغييرات.</translation>
@@ -10868,6 +10878,7 @@
 <translation id="978146274692397928">العرض الأولي لعلامات الترقيم هو عرض بالكامل</translation>
 <translation id="978978324795544535">انقر مرّتين على أي عنصر ثم انقر مع الاستمرار عليه ثم اسحبه لنقله.</translation>
 <translation id="97905529126098460">سيتم إغلاق هذه النافذة بعد اكتمال عملية الإلغاء.</translation>
+<translation id="979345485590886759">السماح للمواقع الإلكترونية بطلب قفل مؤشر الماوس</translation>
 <translation id="980731642137034229">زر قائمة الإجراءات</translation>
 <translation id="981121421437150478">بلا اتصال</translation>
 <translation id="983192555821071799">إغلاق جميع علامات التبويب</translation>
diff --git a/chrome/app/resources/generated_resources_as.xtb b/chrome/app/resources/generated_resources_as.xtb
index 45d7739..8903f07 100644
--- a/chrome/app/resources/generated_resources_as.xtb
+++ b/chrome/app/resources/generated_resources_as.xtb
@@ -385,7 +385,6 @@
 <translation id="1280965841156951489">ফাইলসমূহ সম্পাদনা কৰক</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ফাইল খুলিব নোৱাৰি}one{ফাইলসমূহ খুলিব নোৱাৰি}other{ফাইলসমূহ খুলিব নোৱাৰি}}</translation>
 <translation id="1282311502488501110">ছাইন ইন নকৰিব</translation>
-<translation id="1282465000333679776">ছিষ্টেমৰ অডিঅ’ শ্বেয়াৰ কৰক</translation>
 <translation id="1283126956823499975">ডিভাইচটো ছেট আপ কৰোঁতে কিবা ভুল হৈছে</translation>
 <translation id="1284277788676816155">ডেটা ছেভ কৰিবলৈ অনুমতি নিদিব</translation>
 <translation id="1285320974508926690">এই ছাইটটো কেতিয়াও অনুবাদ নকৰিব</translation>
@@ -1060,7 +1059,6 @@
 <translation id="1781502536226964113">নতুন টেবৰ পৃষ্ঠাটো খোলক</translation>
 <translation id="1781553166608855614">কথিত ভাষা</translation>
 <translation id="1781771911845953849">একাউণ্ট আৰু ছিংক</translation>
-<translation id="1781979858217752599">ৱিণ্ড’ৰ অডিঅ’ শ্বেয়াৰ কৰক</translation>
 <translation id="1782101999402987960">আপোনাৰ প্ৰশাসকে আপডে’টসমূহ অৱৰোধ কৰিছে</translation>
 <translation id="1782196717298160133">আপোনাৰ ফ’নটো বিচাৰি থকা হৈছে</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{১ টা টোকা}one{# টা টোকা}other{# টা টোকা}}</translation>
@@ -1625,7 +1623,6 @@
 <translation id="2187895286714876935">ছাৰ্ভাৰৰ প্ৰমাণপত্ৰ আমদানি কৰাত আসোঁৱাহ</translation>
 <translation id="2187906491731510095">এক্সটেনশ্বন আপডে'ট কৰা হৈছে</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> খোলক</translation>
-<translation id="2189787291884708275">টেব অডিঅ’ শ্বেয়াৰ কৰক</translation>
 <translation id="2190069059097339078">ৱাই ফাইৰ ক্ৰেডেনশ্বিয়েলসমূহ সংগ্ৰহকাৰী</translation>
 <translation id="219008588003277019">স্থানীয় ক্লাইণ্টৰ মডিউল: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(খালী)</translation>
@@ -5298,6 +5295,7 @@
 <translation id="4998430619171209993">অন আছে</translation>
 <translation id="4999804342505941663">অসুবিধা নিদিব অন কৰক</translation>
 <translation id="5001526427543320409">তৃতীয় পক্ষৰ কুকি</translation>
+<translation id="5003993274120026347">পৰৱৰ্তী বাক্য</translation>
 <translation id="5005498671520578047">পাছৱর্ডটোৰ প্ৰতিলিপি কৰক</translation>
 <translation id="5006118752738286774">২ বছৰ পূৰ্বে</translation>
 <translation id="5006218871145547804">Crostini Android এপৰ ADB</translation>
@@ -9223,6 +9221,7 @@
 <translation id="8033958968890501070">সময় উকলিছে</translation>
 <translation id="8035059678007243127">বেক-ফৰৱাৰ্ড কেশ্বত থকা ইনক’গনিট’ পৃষ্ঠা: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">স্বয়ংক্ৰিয়ভাৱে পূৰ কৰা সুবিধাটো উন্নত কৰাত সহায় কৰক</translation>
+<translation id="8036504271468642248">পূৰ্বৱৰ্তী বাক্য</translation>
 <translation id="8037117027592400564">সংশ্লেষিত কথন ব্যৱহাৰ কৰি কোৱা সকলো পাঠ পঢ়ক</translation>
 <translation id="8037357227543935929">সোধক (ডিফ'ল্ট)</translation>
 <translation id="803771048473350947">ফাইল</translation>
diff --git a/chrome/app/resources/generated_resources_az.xtb b/chrome/app/resources/generated_resources_az.xtb
index ed2a248..a7df8b1 100644
--- a/chrome/app/resources/generated_resources_az.xtb
+++ b/chrome/app/resources/generated_resources_az.xtb
@@ -380,7 +380,6 @@
 <translation id="1280965841156951489">Faylları redaktə edin</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Faylı açmaq olmur}other{Faylları açmaq olmur}}</translation>
 <translation id="1282311502488501110">Daxil olmayın</translation>
-<translation id="1282465000333679776">Sistem audiosunu paylaşın</translation>
 <translation id="1283126956823499975">Cihazı ayarlayarkən xəta oldu</translation>
 <translation id="1284277788676816155">Datanı saxlamağa icazə verməyin</translation>
 <translation id="1285320974508926690">Bu saytı heç vaxt tərcümə etməyin</translation>
@@ -1047,7 +1046,6 @@
 <translation id="1781502536226964113">Yeni Tab səhifəsini açın</translation>
 <translation id="1781553166608855614">Danışıq dili</translation>
 <translation id="1781771911845953849">Hesablar və sinxronizasiya</translation>
-<translation id="1781979858217752599">Pəncərə audiosunu paylaşın</translation>
 <translation id="1782101999402987960">Güncəlləmələr administratorunuz tərəfindən bloklanır</translation>
 <translation id="1782196717298160133">Telefonunuz tapılır</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 Qeyd}other{# Qeyd}}</translation>
@@ -1611,7 +1609,6 @@
 <translation id="2187895286714876935">Server Sertifikatını İmport Xətası</translation>
 <translation id="2187906491731510095">Artırmalar yeniləndi</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> tətbiqini açın</translation>
-<translation id="2189787291884708275">Tab audiosunu paylaşın</translation>
 <translation id="2190069059097339078">WiFi Kredensial Alan</translation>
 <translation id="219008588003277019">Native Klient modulu: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(boş)</translation>
@@ -5282,6 +5279,7 @@
 <translation id="4998430619171209993">Aktiv</translation>
 <translation id="4999804342505941663">"Narahat Etməyin" rejimini aktiv edin</translation>
 <translation id="5001526427543320409">Üçüncü tərəf kukiləri</translation>
+<translation id="5003993274120026347">Növbəti cümlə</translation>
 <translation id="5005498671520578047">Parolu kopyalayın</translation>
 <translation id="5006118752738286774">2 il öncə</translation>
 <translation id="5006218871145547804">Crostini Android tətbiqi üzrə ADB</translation>
@@ -9203,6 +9201,7 @@
 <translation id="8033958968890501070">Vaxtın bitməsi</translation>
 <translation id="8035059678007243127">Anonim Geri/İrəli Keşlənmiş Səhifə: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Avto doldurmanı təkmilləşdirməyə yardım edin</translation>
+<translation id="8036504271468642248">Əvvəlki cümlə</translation>
 <translation id="8037117027592400564">Sintetik nitq işlədərək bütün mətni oxuyun</translation>
 <translation id="8037357227543935929">Soruşun (defolt)</translation>
 <translation id="803771048473350947">Fayl</translation>
diff --git a/chrome/app/resources/generated_resources_be.xtb b/chrome/app/resources/generated_resources_be.xtb
index a7b7249..309e5c43 100644
--- a/chrome/app/resources/generated_resources_be.xtb
+++ b/chrome/app/resources/generated_resources_be.xtb
@@ -385,7 +385,6 @@
 <translation id="1280965841156951489">Змяніць файлы</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Не ўдаецца адкрыць файл}one{Не ўдаецца адкрыць файлы}few{Не ўдаецца адкрыць файлы}many{Не ўдаецца адкрыць файлы}other{Не ўдаецца адкрыць файлы}}</translation>
 <translation id="1282311502488501110">Не ўваходзіць</translation>
-<translation id="1282465000333679776">Абагульваць аўдыя сістэмы</translation>
 <translation id="1283126956823499975">Пры наладжванні прылады адбылася памылка</translation>
 <translation id="1284277788676816155">Не дазваляць захоўваць даныя</translation>
 <translation id="1285320974508926690">Ніколі не перакладаць гэты сайт</translation>
@@ -1054,7 +1053,6 @@
 <translation id="1781502536226964113">Адкрыць старонку новай укладкі</translation>
 <translation id="1781553166608855614">Мова вуснага маўлення</translation>
 <translation id="1781771911845953849">Уліковыя запісы і сінхранізацыя</translation>
-<translation id="1781979858217752599">Абагульваць аўдыя з акна</translation>
 <translation id="1782101999402987960">Абнаўленні заблакіраваны вашым адміністратарам</translation>
 <translation id="1782196717298160133">Ідзе пошук тэлефона</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 нататка}one{# нататка}few{# нататкі}many{# нататак}other{# нататкі}}</translation>
@@ -1616,7 +1614,6 @@
 <translation id="2187895286714876935">Памылка імпарту сертыфіката сервера</translation>
 <translation id="2187906491731510095">Пашырэнні абноўлены</translation>
 <translation id="2188881192257509750">Адкрыць <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Абагульваць аўдыя з укладкі</translation>
 <translation id="2190069059097339078">Сродак атрымання ўліковых даных Wi-Fi</translation>
 <translation id="219008588003277019">Модуль Native Client: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(пуста)</translation>
@@ -5284,6 +5281,7 @@
 <translation id="4998430619171209993">Уключана</translation>
 <translation id="4999804342505941663">Уключыць рэжым "Не турбаваць"</translation>
 <translation id="5001526427543320409">Староннія файлы cookie</translation>
+<translation id="5003993274120026347">Наступны сказ</translation>
 <translation id="5005498671520578047">Капіраваць пароль</translation>
 <translation id="5006118752738286774">2 гады таму</translation>
 <translation id="5006218871145547804">ADB у праграмах для Android у Crostini</translation>
@@ -9212,6 +9210,7 @@
 <translation id="8033958968890501070">Час скончыўся</translation>
 <translation id="8035059678007243127">Старонка ў рэжыме інкогніта, захаваная ў кэшы пераходу назад і наперад: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Дапамагчы палепшыць функцыю аўтазапаўнення</translation>
+<translation id="8036504271468642248">Папярэдні сказ</translation>
 <translation id="8037117027592400564">Чытаць увесь тэкст, выкарыстоўваючы сінтэзатар маўлення</translation>
 <translation id="8037357227543935929">Запытаць (стандартна)</translation>
 <translation id="803771048473350947">Файл</translation>
diff --git a/chrome/app/resources/generated_resources_bg.xtb b/chrome/app/resources/generated_resources_bg.xtb
index 88b445a..3f7e74e 100644
--- a/chrome/app/resources/generated_resources_bg.xtb
+++ b/chrome/app/resources/generated_resources_bg.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Редактиране на файловете</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Файлът не може да се отвори}other{Файловете не могат да се отворят}}</translation>
 <translation id="1282311502488501110">Без влизане в профила</translation>
-<translation id="1282465000333679776">Споделяне на системния звук</translation>
 <translation id="1283126956823499975">Нещо се обърка при настройването на устройството</translation>
 <translation id="1284277788676816155">Забраняване на запазването на данни</translation>
 <translation id="1285320974508926690">Този сайт да не се превежда никога</translation>
@@ -1058,7 +1057,6 @@
 <translation id="1781502536226964113">Да се отваря нов раздел в браузъра</translation>
 <translation id="1781553166608855614">Език на говора</translation>
 <translation id="1781771911845953849">Профили и синхронизиране</translation>
-<translation id="1781979858217752599">Споделяне на звука в прозореца</translation>
 <translation id="1782101999402987960">Актуализациите са блокирани от администратора ви</translation>
 <translation id="1782196717298160133">Намиране на телефона ви</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 бележка}other{# бележки}}</translation>
@@ -1623,7 +1621,6 @@
 <translation id="2187895286714876935">Грешка при импортирането на сертификат на сървър</translation>
 <translation id="2187906491731510095">Разширенията бяха актуализирани</translation>
 <translation id="2188881192257509750">Отваряне на <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Споделяне на звука в раздела</translation>
 <translation id="2190069059097339078">Получаване на идентификационни данни за Wi-Fi</translation>
 <translation id="219008588003277019">Модул в клиента за директно изпълнение: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(празно)</translation>
@@ -5298,6 +5295,7 @@
 <translation id="4998430619171209993">Включено</translation>
 <translation id="4999804342505941663">Включване на режима „Не безпокойте“</translation>
 <translation id="5001526427543320409">„Бисквитки“ на трети страни</translation>
+<translation id="5003993274120026347">Следващо изречение</translation>
 <translation id="5005498671520578047">Копиране на паролата</translation>
 <translation id="5006118752738286774">Преди 2 години</translation>
 <translation id="5006218871145547804">Отстраняване на грешки в приложения за Android през ADB за Crostini</translation>
@@ -9224,6 +9222,7 @@
 <translation id="8033958968890501070">Времето за изчакване изтече</translation>
 <translation id="8035059678007243127">Страница в режим „инкогнито“, съхранена в кеша за назад/напред: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Помогнете за подобряването на автоматичното попълване</translation>
+<translation id="8036504271468642248">Предишно изречение</translation>
 <translation id="8037117027592400564">Четене на целия текст, произнесен посредством синтезирания говор</translation>
 <translation id="8037357227543935929">Извеждане на запитване (по подразбиране)</translation>
 <translation id="803771048473350947">Файл</translation>
diff --git a/chrome/app/resources/generated_resources_bn.xtb b/chrome/app/resources/generated_resources_bn.xtb
index cb2c720..3ec376bf 100644
--- a/chrome/app/resources/generated_resources_bn.xtb
+++ b/chrome/app/resources/generated_resources_bn.xtb
@@ -385,7 +385,6 @@
 <translation id="1280965841156951489">ফাইল এডিট করতে পারবে</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ফাইল খোলা যাচ্ছে না}one{ফাইল খোলা যাচ্ছে না}other{ফাইল খোলা যাচ্ছে না}}</translation>
 <translation id="1282311502488501110">সাইন-ইন করতে চাই না</translation>
-<translation id="1282465000333679776">সিস্টেম অডিও শেয়ার করুন</translation>
 <translation id="1283126956823499975">এই ডিভাইস সেট-আপ করার সময় কিছু সমস্যা হয়েছে</translation>
 <translation id="1284277788676816155">ডেটা সেভ করার অনুমতি দেবেন না</translation>
 <translation id="1285320974508926690">কখনই এই সাইটটিকে অনুবাদ করবেন না</translation>
@@ -1063,7 +1062,6 @@
 <translation id="1781502536226964113">নতুন ট্যাব পৃষ্ঠাটি খুলুন</translation>
 <translation id="1781553166608855614">টেক্সট-টু-স্পিচ</translation>
 <translation id="1781771911845953849">অ্যাকাউন্ট এবং সিঙ্ক</translation>
-<translation id="1781979858217752599">উইন্ডো অডিও শেয়ার করুন</translation>
 <translation id="1782101999402987960">আপনার অ্যাডমিনিস্ট্রেটর আপডেটগুলি ব্লক করেছেন</translation>
 <translation id="1782196717298160133">আপনার ফোন খোঁজা হচ্ছে</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{১টি নোট}one{#টি নোট}other{#টি নোট}}</translation>
@@ -1628,7 +1626,6 @@
 <translation id="2187895286714876935">সার্ভার সার্টিফিকেট আমদানি করতে সমস্যা</translation>
 <translation id="2187906491731510095">এক্সটেনশনগুলি আপডেট করা হয়েছে</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> খুলুন</translation>
-<translation id="2189787291884708275">ট্যাব অডিও শেয়ার করুন</translation>
 <translation id="2190069059097339078">ওয়াই-ফাই সার্টিফিকেট সংগ্রহকারী</translation>
 <translation id="219008588003277019">স্থানীয় গ্রাহক মডিউল: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(খালি)</translation>
@@ -5303,6 +5300,7 @@
 <translation id="4998430619171209993">চালু করা আছে</translation>
 <translation id="4999804342505941663">'বিরক্ত করবে না' মোড চালু করুন</translation>
 <translation id="5001526427543320409">থার্ড-পার্টি কুকি</translation>
+<translation id="5003993274120026347">পরের বাক্য</translation>
 <translation id="5005498671520578047">পাসওয়ার্ড কপি করুন</translation>
 <translation id="5006118752738286774">২ বছর আগে</translation>
 <translation id="5006218871145547804">Crostini Android অ্যাপ ADB</translation>
@@ -9231,6 +9229,7 @@
 <translation id="8033958968890501070">সময় শেষ হয়ে গেছে</translation>
 <translation id="8035059678007243127">ব্যাক-ফরোয়ার্ড ক্যাশেতে স্টোর করা ছদ্মবেশী পেজ: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">'অটোফিল' ফিচার উন্নত করতে সাহায্য করুন</translation>
+<translation id="8036504271468642248">আগের বাক্য</translation>
 <translation id="8037117027592400564">সিন্থেসাইজড স্পিচ ব্যবহার করে কথিত সব পাঠ্য পড়ুন</translation>
 <translation id="8037357227543935929">জিজ্ঞাসা করুন (ডিফল্ট)</translation>
 <translation id="803771048473350947">ফাইল</translation>
diff --git a/chrome/app/resources/generated_resources_bs.xtb b/chrome/app/resources/generated_resources_bs.xtb
index 640a8793..cda2124 100644
--- a/chrome/app/resources/generated_resources_bs.xtb
+++ b/chrome/app/resources/generated_resources_bs.xtb
@@ -386,7 +386,6 @@
 <translation id="1280965841156951489">Uredi fajlove</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Nije moguće otvoriti fajl}one{Nije moguće otvoriti fajlove}few{Nije moguće otvoriti fajlove}other{Nije moguće otvoriti fajlove}}</translation>
 <translation id="1282311502488501110">Nemoj se prijaviti</translation>
-<translation id="1282465000333679776">Dijeli sistemski zvuk</translation>
 <translation id="1283126956823499975">Došlo je do greške prilikom postavljanja uređaja</translation>
 <translation id="1284277788676816155">Nemoj dozvoliti pohranjivanje podataka</translation>
 <translation id="1285320974508926690">Nikada ne prevodi ovu web lokaciju</translation>
@@ -1061,7 +1060,6 @@
 <translation id="1781502536226964113">Otvori na stranici u novoj kartici</translation>
 <translation id="1781553166608855614">Jezik govora</translation>
 <translation id="1781771911845953849">Računi i sinhronizacija</translation>
-<translation id="1781979858217752599">Dijeli zvuk prozora</translation>
 <translation id="1782101999402987960">Vaš administrator je blokirao ažuriranja</translation>
 <translation id="1782196717298160133">Pronalaženje vašeg telefona</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 bilješka}one{# bilješka}few{# bilješke}other{# bilješki}}</translation>
@@ -1626,7 +1624,6 @@
 <translation id="2187895286714876935">Greška pri uvozu potvrde za server</translation>
 <translation id="2187906491731510095">Ekstenzije su ažurirane</translation>
 <translation id="2188881192257509750">Otvori <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Dijeli zvuk kartice</translation>
 <translation id="2190069059097339078">Preuzimanje akreditiva za WiFi</translation>
 <translation id="219008588003277019">Modul izvornog klijenta: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(prazno)</translation>
@@ -5300,6 +5297,7 @@
 <translation id="4998430619171209993">Uključeno</translation>
 <translation id="4999804342505941663">Uključi funkciju Ne ometaj</translation>
 <translation id="5001526427543320409">Kolačići treće strane</translation>
+<translation id="5003993274120026347">Sljedeća rečenica</translation>
 <translation id="5005498671520578047">Kopiranje lozinke</translation>
 <translation id="5006118752738286774">Prije 2 godine</translation>
 <translation id="5006218871145547804">ADB Android aplikacija na Crostiniju</translation>
@@ -9229,6 +9227,7 @@
 <translation id="8033958968890501070">Vrijeme je isteklo</translation>
 <translation id="8035059678007243127">Keširana verzija cijele stranice anonimnog načina rada: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Pomozite nam da poboljšamo automatsko popunjavanje</translation>
+<translation id="8036504271468642248">Prethodna rečenica</translation>
 <translation id="8037117027592400564">Čitaj naglas sav tekst koristeći sintetizirani glas</translation>
 <translation id="8037357227543935929">Pitaj (zadano)</translation>
 <translation id="803771048473350947">Fajl</translation>
diff --git a/chrome/app/resources/generated_resources_ca.xtb b/chrome/app/resources/generated_resources_ca.xtb
index a70d38d..ceb99e5 100644
--- a/chrome/app/resources/generated_resources_ca.xtb
+++ b/chrome/app/resources/generated_resources_ca.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">Edita els fitxers</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{No es pot obrir el fitxer}other{No es poden obrir els fitxers}}</translation>
 <translation id="1282311502488501110">No iniciïs la sessió</translation>
-<translation id="1282465000333679776">Comparteix l'àudio del sistema</translation>
 <translation id="1283126956823499975">S'ha produït un error en configurar el dispositiu</translation>
 <translation id="1284277788676816155">No permetis que es desin dades</translation>
 <translation id="1285320974508926690">No tradueixis mai aquest lloc</translation>
@@ -1051,7 +1050,6 @@
 <translation id="1781502536226964113">Obre la pàgina Pestanya nova</translation>
 <translation id="1781553166608855614">Idioma parlat</translation>
 <translation id="1781771911845953849">Comptes i sincronització</translation>
-<translation id="1781979858217752599">Comparteix l'àudio de la finestra</translation>
 <translation id="1782101999402987960">El teu administrador ha bloquejat les actualitzacions</translation>
 <translation id="1782196717298160133">S'està cercant el telèfon</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 nota}other{# notes}}</translation>
@@ -1615,7 +1613,6 @@
 <translation id="2187895286714876935">Error d'importació del certificat del servidor</translation>
 <translation id="2187906491731510095">S'han actualitzat les extensions</translation>
 <translation id="2188881192257509750">Obre <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Comparteix l'àudio de la pestanya</translation>
 <translation id="2190069059097339078">Mètode d'obtenció de credencials de la Wi-Fi</translation>
 <translation id="219008588003277019">Mòdul de client nadiu: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(buit)</translation>
@@ -5284,6 +5281,7 @@
 <translation id="4998430619171209993">Activat</translation>
 <translation id="4999804342505941663">Activa el mode No molestis</translation>
 <translation id="5001526427543320409">Galetes de tercers</translation>
+<translation id="5003993274120026347">Frase següent</translation>
 <translation id="5005498671520578047">Copia la contrasenya</translation>
 <translation id="5006118752738286774">Fa 2 anys</translation>
 <translation id="5006218871145547804">ADB d'aplicacions d'Android a Crostini</translation>
@@ -9208,6 +9206,7 @@
 <translation id="8033958968890501070">Temps d'espera esgotat</translation>
 <translation id="8035059678007243127">Pàgina d'incògnit desada a la memòria cau endavant/enrere: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Ajuda a millorar la funció Emplenament automàtic</translation>
+<translation id="8036504271468642248">Frase anterior</translation>
 <translation id="8037117027592400564">Llegeix tot el text en veu alta mitjançant una síntesi de veu</translation>
 <translation id="8037357227543935929">Pregunta (opció predeterminada)</translation>
 <translation id="803771048473350947">Fitxer</translation>
diff --git a/chrome/app/resources/generated_resources_cs.xtb b/chrome/app/resources/generated_resources_cs.xtb
index 3b255a3..81a084a5 100644
--- a/chrome/app/resources/generated_resources_cs.xtb
+++ b/chrome/app/resources/generated_resources_cs.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Upravit soubory</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Soubor nelze otevřít}few{Soubory nelze otevřít}many{Soubory nelze otevřít}other{Soubory nelze otevřít}}</translation>
 <translation id="1282311502488501110">Nepřihlašovat se</translation>
-<translation id="1282465000333679776">Sdílet systémový zvuk</translation>
 <translation id="1283126956823499975">Při nastavování zařízení se něco pokazilo</translation>
 <translation id="1284277788676816155">Nepovolovat ukládání dat</translation>
 <translation id="1285320974508926690">Tento web nikdy nepřekládat</translation>
@@ -1053,7 +1052,6 @@
 <translation id="1781502536226964113">Otevřít stránku Nová karta</translation>
 <translation id="1781553166608855614">Mluvený jazyk</translation>
 <translation id="1781771911845953849">Účty a synchronizace</translation>
-<translation id="1781979858217752599">Sdílet zvuk v okně</translation>
 <translation id="1782101999402987960">Administrátor blokuje aktualizace</translation>
 <translation id="1782196717298160133">Nalezení telefonu</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 poznámka}few{# poznámky}many{# poznámky}other{# poznámek}}</translation>
@@ -1617,7 +1615,6 @@
 <translation id="2187895286714876935">Chyba při importu certifikátu serveru</translation>
 <translation id="2187906491731510095">Rozšíření byla aktualizována</translation>
 <translation id="2188881192257509750">Spustit aplikaci <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Sdílet zvuk z karty</translation>
 <translation id="2190069059097339078">Nástroj na získávání identifikačních údajů sítí Wi-Fi</translation>
 <translation id="219008588003277019">Modul nativního klienta: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(prázdné)</translation>
@@ -5286,6 +5283,7 @@
 <translation id="4998430619171209993">Zapnuto</translation>
 <translation id="4999804342505941663">Zapnout režim Nerušit</translation>
 <translation id="5001526427543320409">Soubory cookie třetích stran</translation>
+<translation id="5003993274120026347">Další věta</translation>
 <translation id="5005498671520578047">Kopírování hesla</translation>
 <translation id="5006118752738286774">Před 2 roky</translation>
 <translation id="5006218871145547804">ADB aplikací Android pro Crostini</translation>
@@ -9211,6 +9209,7 @@
 <translation id="8033958968890501070">Vypršel časový limit</translation>
 <translation id="8035059678007243127">Mezipaměť pro přechod zpět nebo vpřed na anonymní stránce: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Pomozte zlepšovat automatické vyplňování</translation>
+<translation id="8036504271468642248">Předchozí věta</translation>
 <translation id="8037117027592400564">Číst veškerý text vyslovovaný pomocí syntetické řeči</translation>
 <translation id="8037357227543935929">Zeptat se (výchozí)</translation>
 <translation id="803771048473350947">Soubor</translation>
diff --git a/chrome/app/resources/generated_resources_cy.xtb b/chrome/app/resources/generated_resources_cy.xtb
index b79776f..327d228 100644
--- a/chrome/app/resources/generated_resources_cy.xtb
+++ b/chrome/app/resources/generated_resources_cy.xtb
@@ -388,7 +388,6 @@
 <translation id="1280965841156951489">Golygu ffeiliau</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Methu ag agor y ffeil}zero{Methu ag agor y ffeiliau}two{Methu ag agor y ffeiliau}few{Methu ag agor y ffeiliau}many{Methu ag agor y ffeiliau}other{Methu ag agor y ffeiliau}}</translation>
 <translation id="1282311502488501110">Peidio â Mewngofnodi</translation>
-<translation id="1282465000333679776">Rhannu sain y system</translation>
 <translation id="1283126956823499975">Aeth rhywbeth o'i le gyda gosod y ddyfais</translation>
 <translation id="1284277788676816155">Peidio â chaniatáu cadw data</translation>
 <translation id="1285320974508926690">Peidio byth â chyfieithu'r wefan hon</translation>
@@ -1065,7 +1064,6 @@
 <translation id="1781502536226964113">Agorwch y dudalen Tab Newydd</translation>
 <translation id="1781553166608855614">Iaith ar lafar</translation>
 <translation id="1781771911845953849">Cyfrifon a chysoni</translation>
-<translation id="1781979858217752599">Rhannu sain y ffenestr</translation>
 <translation id="1782101999402987960">Mae diweddariadau yn cael eu rhwystro gan eich gweinyddwr</translation>
 <translation id="1782196717298160133">Wrthi'n dod o hyd i'ch ffôn</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 Nodyn}zero{# Nodyn}two{# Nodyn}few{# Nodyn}many{# Nodyn}other{# Nodyn}}</translation>
@@ -1630,7 +1628,6 @@
 <translation id="2187895286714876935">Gwall wrth Fewnforio Tystysgrif y Gweinydd</translation>
 <translation id="2187906491731510095">Diweddarwyd yr estyniadau</translation>
 <translation id="2188881192257509750">Agor <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Rhannu sain y tab</translation>
 <translation id="2190069059097339078">Casglwr Cymwysterau Wi-Fi</translation>
 <translation id="219008588003277019">Modiwl Cleient Brodorol: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(gwag)</translation>
@@ -5304,6 +5301,7 @@
 <translation id="4998430619171209993">Ymlaen</translation>
 <translation id="4999804342505941663">Troi Peidiwch ag Aflonyddu Ymlaen</translation>
 <translation id="5001526427543320409">Cwcis trydydd parti</translation>
+<translation id="5003993274120026347">Brawddeg nesaf</translation>
 <translation id="5005498671520578047">Copïo'r cyfrinair</translation>
 <translation id="5006118752738286774">2 flynedd yn ôl</translation>
 <translation id="5006218871145547804">ADB Ap Android Crostini</translation>
@@ -9234,6 +9232,7 @@
 <translation id="8033958968890501070">Terfyn amser</translation>
 <translation id="8035059678007243127">Tudalen Anhysbys yn y Storfa Yn ôl/Ymlaen: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Helpwch i Wella Awtolenwi</translation>
+<translation id="8036504271468642248">Brawddeg flaenorol</translation>
 <translation id="8037117027592400564">Darllen yr holl destun a siaredir gan ddefnyddio lleferydd sydd wedi'i syntheseiddio</translation>
 <translation id="8037357227543935929">Yn gofyn (Diofyn)</translation>
 <translation id="803771048473350947">Ffeil</translation>
diff --git a/chrome/app/resources/generated_resources_da.xtb b/chrome/app/resources/generated_resources_da.xtb
index 2e7e884..63372c7 100644
--- a/chrome/app/resources/generated_resources_da.xtb
+++ b/chrome/app/resources/generated_resources_da.xtb
@@ -385,7 +385,6 @@
 <translation id="1280965841156951489">Rediger filer</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Filen kan ikke åbnes}one{Filen kan ikke åbnes}other{Filerne kan ikke åbnes}}</translation>
 <translation id="1282311502488501110">Log ikke ind</translation>
-<translation id="1282465000333679776">Del systemlyd</translation>
 <translation id="1283126956823499975">Noget gik galt under konfigurationen af enheden</translation>
 <translation id="1284277788676816155">Tillad ikke, at data gemmes</translation>
 <translation id="1285320974508926690">Oversæt aldrig dette website</translation>
@@ -1063,7 +1062,6 @@
 <translation id="1781502536226964113">Åbn siden Ny fane</translation>
 <translation id="1781553166608855614">Talt sprog</translation>
 <translation id="1781771911845953849">Konti og synkronisering</translation>
-<translation id="1781979858217752599">Del lyd fra vindue</translation>
 <translation id="1782101999402987960">Opdateringer blokeres af din administrator</translation>
 <translation id="1782196717298160133">Sådan finder du din telefon</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 note}one{# note}other{# noter}}</translation>
@@ -1628,7 +1626,6 @@
 <translation id="2187895286714876935">Fejl ved import af servercertifikat</translation>
 <translation id="2187906491731510095">Udvidelserne er opdateret</translation>
 <translation id="2188881192257509750">Åbn <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Del fanelyd</translation>
 <translation id="2190069059097339078">Hentning af Wi-Fi-loginoplysninger</translation>
 <translation id="219008588003277019">Native Client-modul: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(tom)</translation>
@@ -5302,6 +5299,7 @@
 <translation id="4998430619171209993">Til</translation>
 <translation id="4999804342505941663">Aktivér Forstyr ikke</translation>
 <translation id="5001526427543320409">Tredjepartscookies</translation>
+<translation id="5003993274120026347">Næste sætning</translation>
 <translation id="5005498671520578047">Kopiér adgangskode</translation>
 <translation id="5006118752738286774">For 2 år siden</translation>
 <translation id="5006218871145547804">Adb til Android-apps i Crostini</translation>
@@ -9228,6 +9226,7 @@
 <translation id="8033958968890501070">Timeout</translation>
 <translation id="8035059678007243127">Inkognitoside i back/forward-cache: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Hjælp med at forbedre Autofyld</translation>
+<translation id="8036504271468642248">Forrige sætning</translation>
 <translation id="8037117027592400564">Læs hele teksten højt ved hjælp af talesyntese</translation>
 <translation id="8037357227543935929">Spørg (standardindstilling)</translation>
 <translation id="803771048473350947">Fil</translation>
diff --git a/chrome/app/resources/generated_resources_de.xtb b/chrome/app/resources/generated_resources_de.xtb
index fca2e13..af704c8 100644
--- a/chrome/app/resources/generated_resources_de.xtb
+++ b/chrome/app/resources/generated_resources_de.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">Dateien bearbeiten</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Datei kann nicht geöffnet werden}other{Dateien können nicht geöffnet werden}}</translation>
 <translation id="1282311502488501110">Nicht anmelden</translation>
-<translation id="1282465000333679776">Audio des Systems teilen</translation>
 <translation id="1283126956823499975">Bei der Einrichtung des Geräts ist ein Fehler aufgetreten</translation>
 <translation id="1284277788676816155">Speichern von Daten nicht genehmigen</translation>
 <translation id="1285320974508926690">Diese Website nie übersetzen</translation>
@@ -1048,7 +1047,6 @@
 <translation id="1781502536226964113">„Neuer Tab“-Seite öffnen</translation>
 <translation id="1781553166608855614">Gesprochene Sprache</translation>
 <translation id="1781771911845953849">Konten und Synchronisierung</translation>
-<translation id="1781979858217752599">Audio des Fensters teilen</translation>
 <translation id="1782101999402987960">Updates werden von deinem Administrator blockiert</translation>
 <translation id="1782196717298160133">Mein Telefon finden</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 Hinweis}other{# Hinweise}}</translation>
@@ -1612,7 +1610,6 @@
 <translation id="2187895286714876935">Fehler beim Importieren des Serverzertifikats</translation>
 <translation id="2187906491731510095">Erweiterungen wurden aktualisiert</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> öffnen</translation>
-<translation id="2189787291884708275">Audio des Tabs teilen</translation>
 <translation id="2190069059097339078">WLAN-Anmeldedaten-Abruf</translation>
 <translation id="219008588003277019">Natives Client-Modul: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(leer)</translation>
@@ -5282,6 +5279,7 @@
 <translation id="4998430619171209993">An</translation>
 <translation id="4999804342505941663">„Bitte nicht stören“ aktivieren</translation>
 <translation id="5001526427543320409">Drittanbieter-Cookies</translation>
+<translation id="5003993274120026347">Nächster Satz</translation>
 <translation id="5005498671520578047">Passwort kopieren</translation>
 <translation id="5006118752738286774">Vor 2 Jahren</translation>
 <translation id="5006218871145547804">Android-App-ADB für Crostini</translation>
@@ -9204,6 +9202,7 @@
 <translation id="8033958968890501070">Zeitüberschreitung</translation>
 <translation id="8035059678007243127">Inkognito-Seite im Back-Forward-Cache: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Hilf mit, Autofill zu verbessern</translation>
+<translation id="8036504271468642248">Vorheriger Satz</translation>
 <translation id="8037117027592400564">Alle mit künstlicher Sprachausgabe gesprochenen Texte lesen</translation>
 <translation id="8037357227543935929">Nachfragen (Standard)</translation>
 <translation id="803771048473350947">Datei</translation>
diff --git a/chrome/app/resources/generated_resources_el.xtb b/chrome/app/resources/generated_resources_el.xtb
index 32cc38d..df5243d 100644
--- a/chrome/app/resources/generated_resources_el.xtb
+++ b/chrome/app/resources/generated_resources_el.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Επεξεργασία αρχείων</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Δεν είναι δυνατό το άνοιγμα του αρχείου}other{Δεν είναι δυνατό το άνοιγμα των αρχείων}}</translation>
 <translation id="1282311502488501110">Να μην γίνει σύνδεση</translation>
-<translation id="1282465000333679776">Κοινοποίηση ήχου συστήματος</translation>
 <translation id="1283126956823499975">Προέκυψε πρόβλημα με τη ρύθμιση της συσκευής</translation>
 <translation id="1284277788676816155">Να μην επιτρέπεται η αποθήκευση δεδομένων</translation>
 <translation id="1285320974508926690">Να μην γίνεται ποτέ μετάφραση αυτού του ιστότοπου</translation>
@@ -1062,7 +1061,6 @@
 <translation id="1781502536226964113">Ανοίξτε τη σελίδα νέας καρτέλας</translation>
 <translation id="1781553166608855614">Γλώσσα ομιλίας</translation>
 <translation id="1781771911845953849">Λογαριασμοί και συγχρονισμός</translation>
-<translation id="1781979858217752599">Κοινοποίηση ήχου παραθύρου</translation>
 <translation id="1782101999402987960">Οι ενημερώσεις έχουν αποκλειστεί από τον διαχειριστή σας</translation>
 <translation id="1782196717298160133">Εύρεση του τηλεφώνου σας</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 σημείωση}other{# σημειώσεις}}</translation>
@@ -1627,7 +1625,6 @@
 <translation id="2187895286714876935">Σφάλμα εισαγωγής του πιστοποιητικού διακομιστή  </translation>
 <translation id="2187906491731510095">Οι επεκτάσεις ενημερώθηκαν</translation>
 <translation id="2188881192257509750">Άνοιγμα <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Κοινοποίηση ήχου καρτέλας</translation>
 <translation id="2190069059097339078">Εργαλείο λήψης διαπιστευτηρίων Wi-Fi</translation>
 <translation id="219008588003277019">Λειτουργική μονάδα Native Client: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(κενό)</translation>
@@ -5301,6 +5298,7 @@
 <translation id="4998430619171209993">Ενεργό</translation>
 <translation id="4999804342505941663">Ενεργοποίηση λειτουργίας Μην ενοχλείτε</translation>
 <translation id="5001526427543320409">Cookie τρίτου μέρους</translation>
+<translation id="5003993274120026347">Επόμενη πρόταση</translation>
 <translation id="5005498671520578047">Αντιγραφή κωδικού πρόσβασης</translation>
 <translation id="5006118752738286774">Πριν από 2 χρόνια</translation>
 <translation id="5006218871145547804">ADB εφαρμογής Android Crostini</translation>
@@ -9227,6 +9225,7 @@
 <translation id="8033958968890501070">Λήξη ορίου χρόνου</translation>
 <translation id="8035059678007243127">Σελίδα ανώνυμης περιήγησης αποθηκευμένη στην κρυφή μνήμη πίσω-εμπρός: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Συμβάλετε στη βελτίωση της αυτόματης συμπλήρωσης</translation>
+<translation id="8036504271468642248">Προηγούμενη πρόταση</translation>
 <translation id="8037117027592400564">Ανάγνωση όλου του κειμένου που εκφωνείται με χρήση ομιλίας σύνθεσης</translation>
 <translation id="8037357227543935929">Να γίνεται ερώτηση (προεπιλογή)</translation>
 <translation id="803771048473350947">Αρχείο</translation>
diff --git a/chrome/app/resources/generated_resources_en-GB.xtb b/chrome/app/resources/generated_resources_en-GB.xtb
index 0460f78..403795fa 100644
--- a/chrome/app/resources/generated_resources_en-GB.xtb
+++ b/chrome/app/resources/generated_resources_en-GB.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Edit files</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Can't open file}other{Can't open files}}</translation>
 <translation id="1282311502488501110">Don't sign in</translation>
-<translation id="1282465000333679776">Share system audio</translation>
 <translation id="1283126956823499975">Something went wrong with setting up the device</translation>
 <translation id="1284277788676816155">Don’t allow to save data</translation>
 <translation id="1285320974508926690">Never translate this site</translation>
@@ -1062,7 +1061,6 @@
 <translation id="1781502536226964113">Open the New Tab page</translation>
 <translation id="1781553166608855614">Spoken language</translation>
 <translation id="1781771911845953849">Accounts and sync</translation>
-<translation id="1781979858217752599">Share window audio</translation>
 <translation id="1782101999402987960">Updates are blocked by your administrator</translation>
 <translation id="1782196717298160133">Finding your phone</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 note}other{# notes}}</translation>
@@ -1627,7 +1625,6 @@
 <translation id="2187895286714876935">Server Certificate Import Error</translation>
 <translation id="2187906491731510095">Extensions updated</translation>
 <translation id="2188881192257509750">Open <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Share tab audio</translation>
 <translation id="2190069059097339078">Wi-Fi Credentials Getter</translation>
 <translation id="219008588003277019">Native Client module: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(empty)</translation>
@@ -5301,6 +5298,7 @@
 <translation id="4998430619171209993">On</translation>
 <translation id="4999804342505941663">Turn on Do Not Disturb</translation>
 <translation id="5001526427543320409">Third-party cookies</translation>
+<translation id="5003993274120026347">Next sentence</translation>
 <translation id="5005498671520578047">Copy password</translation>
 <translation id="5006118752738286774">2 years ago</translation>
 <translation id="5006218871145547804">Crostini Android app ADB</translation>
@@ -9226,6 +9224,7 @@
 <translation id="8033958968890501070">Time out</translation>
 <translation id="8035059678007243127">Incognito back-forward cached page: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Help improve auto-fill</translation>
+<translation id="8036504271468642248">Previous sentence</translation>
 <translation id="8037117027592400564">Read all text spoken using synthesised speech</translation>
 <translation id="8037357227543935929">Ask (default)</translation>
 <translation id="803771048473350947">File</translation>
diff --git a/chrome/app/resources/generated_resources_es-419.xtb b/chrome/app/resources/generated_resources_es-419.xtb
index d7880102..57f0390 100644
--- a/chrome/app/resources/generated_resources_es-419.xtb
+++ b/chrome/app/resources/generated_resources_es-419.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">Editar archivos</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{No se puede abrir el archivo}other{No se pueden abrir los archivos}}</translation>
 <translation id="1282311502488501110">No acceder</translation>
-<translation id="1282465000333679776">Compartir el audio del sistema</translation>
 <translation id="1283126956823499975">Se produjo un error cuando se configuraba el dispositivo</translation>
 <translation id="1284277788676816155">No permitir que se guarden los datos</translation>
 <translation id="1285320974508926690">Nunca traducir este sitio</translation>
@@ -1048,7 +1047,6 @@
 <translation id="1781502536226964113">Abrir la página Nueva pestaña</translation>
 <translation id="1781553166608855614">Idioma de voz</translation>
 <translation id="1781771911845953849">Cuentas y sincronización</translation>
-<translation id="1781979858217752599">Compartir el audio de la ventana</translation>
 <translation id="1782101999402987960">Tu administrador bloqueó las actualizaciones</translation>
 <translation id="1782196717298160133">Buscando el teléfono</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 nota}other{# notas}}</translation>
@@ -1612,7 +1610,6 @@
 <translation id="2187895286714876935">Error en el servidor de importación de certificado</translation>
 <translation id="2187906491731510095">Se actualizaron las extensiones</translation>
 <translation id="2188881192257509750">Abrir <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Compartir audio de la pestaña</translation>
 <translation id="2190069059097339078">Captador de credenciales de Wi-Fi</translation>
 <translation id="219008588003277019">Módulo Native Client: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(vacío)</translation>
@@ -5282,6 +5279,7 @@
 <translation id="4998430619171209993">Sí</translation>
 <translation id="4999804342505941663">Activar No interrumpir</translation>
 <translation id="5001526427543320409">Cookies de terceros</translation>
+<translation id="5003993274120026347">Oración siguiente</translation>
 <translation id="5005498671520578047">Copiar contraseña</translation>
 <translation id="5006118752738286774">Hace 2 años</translation>
 <translation id="5006218871145547804">ADB de apps para Android en Crostini</translation>
@@ -9207,6 +9205,7 @@
 <translation id="8033958968890501070">Se agotó el tiempo de espera</translation>
 <translation id="8035059678007243127">Página de incógnito en la Memoria caché atrás/adelante: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Ayuda a mejorar Autocompletar</translation>
+<translation id="8036504271468642248">Oración anterior</translation>
 <translation id="8037117027592400564">Leer todo el texto hablado con la síntesis de voz</translation>
 <translation id="8037357227543935929">Preguntar (predeterminado)</translation>
 <translation id="803771048473350947">Archivo</translation>
diff --git a/chrome/app/resources/generated_resources_es.xtb b/chrome/app/resources/generated_resources_es.xtb
index d5698cc..ac2b0538 100644
--- a/chrome/app/resources/generated_resources_es.xtb
+++ b/chrome/app/resources/generated_resources_es.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">Editar archivos</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{No se puede abrir el archivo}other{No se pueden abrir los archivos}}</translation>
 <translation id="1282311502488501110">No iniciar sesión</translation>
-<translation id="1282465000333679776">Compartir audio del sistema</translation>
 <translation id="1283126956823499975">Se ha producido un error al configurar el dispositivo</translation>
 <translation id="1284277788676816155">No permitir que guarde datos</translation>
 <translation id="1285320974508926690">No traducir nunca este sitio</translation>
@@ -1051,7 +1050,6 @@
 <translation id="1781502536226964113">Abrir la página Nueva pestaña</translation>
 <translation id="1781553166608855614">Idioma hablado</translation>
 <translation id="1781771911845953849">Cuentas y sincronización</translation>
-<translation id="1781979858217752599">Compartir audio de la ventana</translation>
 <translation id="1782101999402987960">Tu administrador ha bloqueado las actualizaciones</translation>
 <translation id="1782196717298160133">Buscando teléfono</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 nota}other{# notas}}</translation>
@@ -1615,7 +1613,6 @@
 <translation id="2187895286714876935">Error de importación del certificado de servidor</translation>
 <translation id="2187906491731510095">Se han actualizado las extensiones</translation>
 <translation id="2188881192257509750">Abrir <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Compartir audio de la pestaña</translation>
 <translation id="2190069059097339078">Aplicación para obtener credenciales Wi-Fi</translation>
 <translation id="219008588003277019">Módulo cliente nativo: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(vacío)</translation>
@@ -5284,6 +5281,7 @@
 <translation id="4998430619171209993">Activado</translation>
 <translation id="4999804342505941663">Activar No molestar</translation>
 <translation id="5001526427543320409">Cookies de terceros</translation>
+<translation id="5003993274120026347">Siguiente frase</translation>
 <translation id="5005498671520578047">Copiar contraseña</translation>
 <translation id="5006118752738286774">Hace 2 años</translation>
 <translation id="5006218871145547804">ADB de aplicaciones Android en Crostini</translation>
@@ -9209,6 +9207,7 @@
 <translation id="8033958968890501070">Tiempo de espera agotado</translation>
 <translation id="8035059678007243127">Página de incógnito almacenada en la caché de páginas completas: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Ayuda a mejorar Autocompletar</translation>
+<translation id="8036504271468642248">Frase anterior</translation>
 <translation id="8037117027592400564">Leer todo el texto hablado con la conversión de texto a voz</translation>
 <translation id="8037357227543935929">Preguntar (predeterminado)</translation>
 <translation id="803771048473350947">Archivo</translation>
diff --git a/chrome/app/resources/generated_resources_et.xtb b/chrome/app/resources/generated_resources_et.xtb
index f34eb71c6..e073e0b 100644
--- a/chrome/app/resources/generated_resources_et.xtb
+++ b/chrome/app/resources/generated_resources_et.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Muuda faile</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Faili avamine ei õnnestunud}other{Failide avamine ei õnnestunud}}</translation>
 <translation id="1282311502488501110">Ära logi sisse</translation>
-<translation id="1282465000333679776">Jaga süsteemi heli</translation>
 <translation id="1283126956823499975">Seadme seadistamisel läks midagi valesti</translation>
 <translation id="1284277788676816155">Ära luba andmeid salvestada</translation>
 <translation id="1285320974508926690">Ära kunagi seda saiti tõlgi</translation>
@@ -1054,7 +1053,6 @@
 <translation id="1781502536226964113">Ava uus vaheleht</translation>
 <translation id="1781553166608855614">Kõnesünteesi keel</translation>
 <translation id="1781771911845953849">Kontod ja sünkroonimine</translation>
-<translation id="1781979858217752599">Jaga akna heli</translation>
 <translation id="1782101999402987960">Administraator on värskendused blokeerinud</translation>
 <translation id="1782196717298160133">Teie telefoni otsimine</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 märkus}other{# märkust}}</translation>
@@ -1618,7 +1616,6 @@
 <translation id="2187895286714876935">Serveri sertifikaadi impordi viga</translation>
 <translation id="2187906491731510095">Laiendused on värskendatud</translation>
 <translation id="2188881192257509750">Ava <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Jaga vahelehe heli</translation>
 <translation id="2190069059097339078">WiFi mandaadi hankija</translation>
 <translation id="219008588003277019">Omakliendi moodul: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(tühi)</translation>
@@ -5291,6 +5288,7 @@
 <translation id="4998430619171209993">Sees</translation>
 <translation id="4999804342505941663">Lülita režiim Mitte segada sisse</translation>
 <translation id="5001526427543320409">Kolmanda osapoole küpsisefailid</translation>
+<translation id="5003993274120026347">Järgmine lause</translation>
 <translation id="5005498671520578047">Parooli kopeerimine</translation>
 <translation id="5006118752738286774">2 aastat tagasi</translation>
 <translation id="5006218871145547804">Crostini Androidi rakenduse ADB</translation>
@@ -9216,6 +9214,7 @@
 <translation id="8033958968890501070">Ajalõpp</translation>
 <translation id="8035059678007243127">Vahemälu tagasi-edasiliikumiseks inkognito lehel: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Aidake automaattäitefunktsiooni täiustada</translation>
+<translation id="8036504271468642248">Eelmine lause</translation>
 <translation id="8037117027592400564">Kogu kõnesünteesil põhineva teksti lugemine</translation>
 <translation id="8037357227543935929">Küsi (vaikimisi)</translation>
 <translation id="803771048473350947">Fail</translation>
diff --git a/chrome/app/resources/generated_resources_eu.xtb b/chrome/app/resources/generated_resources_eu.xtb
index 764d4b4..4706e13 100644
--- a/chrome/app/resources/generated_resources_eu.xtb
+++ b/chrome/app/resources/generated_resources_eu.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">Editatu fitxategiak</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Ezin da ireki fitxategia}other{Ezin dira ireki fitxategiak}}</translation>
 <translation id="1282311502488501110">Ez hasi saioa</translation>
-<translation id="1282465000333679776">Partekatu sistemaren audioa</translation>
 <translation id="1283126956823499975">Arazoren bat izan da gailua konfiguratzean</translation>
 <translation id="1284277788676816155">Ez eman datuak gordetzeko baimenik</translation>
 <translation id="1285320974508926690">Ez itzuli inoiz webgune hau</translation>
@@ -1051,7 +1050,6 @@
 <translation id="1781502536226964113">Ireki fitxa berriaren orria</translation>
 <translation id="1781553166608855614">Hitz egiteko hizkuntza</translation>
 <translation id="1781771911845953849">Kontuak eta sinkronizazioa</translation>
-<translation id="1781979858217752599">Partekatu leihoaren audioa</translation>
 <translation id="1782101999402987960">Administratzaileak blokeatu egin ditu eguneratzeak</translation>
 <translation id="1782196717298160133">Telefonoa bilatzen</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 ohar}other{# ohar}}</translation>
@@ -1615,7 +1613,6 @@
 <translation id="2187895286714876935">Errore bat gertatu da zerbitzariaren ziurtagiria inportatzean</translation>
 <translation id="2187906491731510095">Eguneratu dira luzapenak</translation>
 <translation id="2188881192257509750">Ireki <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Partekatu fitxaren audioa</translation>
 <translation id="2190069059097339078">Wi-Fi kredentzialen lortzailea</translation>
 <translation id="219008588003277019">Bezero natiboaren modulua: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(hutsik)</translation>
@@ -5285,6 +5282,7 @@
 <translation id="4998430619171209993">Aktibatuta</translation>
 <translation id="4999804342505941663">Aktibatu ez molestatzeko modua</translation>
 <translation id="5001526427543320409">Hirugarrenen cookieak</translation>
+<translation id="5003993274120026347">Hurrengo esaldia</translation>
 <translation id="5005498671520578047">Kopiatu pasahitza</translation>
 <translation id="5006118752738286774">Duela 2 urte</translation>
 <translation id="5006218871145547804">Crostini-ren Android-erako aplikazioen ADB</translation>
@@ -9204,6 +9202,7 @@
 <translation id="8033958968890501070">Gainditu egin da denbora-muga</translation>
 <translation id="8035059678007243127">Aurreko orria cachean gordetzeko eginbidean gordetako ezkutuko moduko orria: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Lagundu betetze automatikoa hobetzen</translation>
+<translation id="8036504271468642248">Aurreko esaldia</translation>
 <translation id="8037117027592400564">Irakurri testu idatzi guztiak ahots sintetizatua erabilita</translation>
 <translation id="8037357227543935929">Galdetu (lehenetsia)</translation>
 <translation id="803771048473350947">Fitxategia</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb
index e50bf6d..e2c7ec30 100644
--- a/chrome/app/resources/generated_resources_fa.xtb
+++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -385,7 +385,6 @@
 <translation id="1280965841156951489">ویرایش فایل‌ها</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{فایل باز نمی‌شود}one{فایل باز نمی‌شود}other{فایل‌ها باز نمی‌شود}}</translation>
 <translation id="1282311502488501110">وارد سیستم نشود</translation>
-<translation id="1282465000333679776">هم‌رسانی صدای سیستم</translation>
 <translation id="1283126956823499975">هنگام راه‌اندازی دستگاه مشکلی پیش آمد</translation>
 <translation id="1284277788676816155">ذخیره کردن داده مجاز نیست</translation>
 <translation id="1285320974508926690">این سایت هرگز ترجمه نشود</translation>
@@ -1060,7 +1059,6 @@
 <translation id="1781502536226964113">باز کردن صفحه «برگه جدید»</translation>
 <translation id="1781553166608855614">زبان گفتار</translation>
 <translation id="1781771911845953849">حساب‌ها و همگام‌سازی</translation>
-<translation id="1781979858217752599">هم‌رسانی صدای پنجره</translation>
 <translation id="1782101999402987960">سرپرست شما به‌روزرسانی‌ها را مسدود کرده است</translation>
 <translation id="1782196717298160133">در حال پیدا کردن تلفن خودتان</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{یک یادداشت}one{# یادداشت}other{# یادداشت}}</translation>
@@ -1624,7 +1622,6 @@
 <translation id="2187895286714876935">خطای وارد کردن مجوز سرور</translation>
 <translation id="2187906491731510095">افزونه‌ها به‌روزرسانی شدند</translation>
 <translation id="2188881192257509750">باز کردن <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">هم‌رسانی صدای برگه</translation>
 <translation id="2190069059097339078">‏گیرنده اعتبارنامه‌های WiFi</translation>
 <translation id="219008588003277019">‏ماژول Native Client: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(خالی)</translation>
@@ -5298,6 +5295,7 @@
 <translation id="4998430619171209993">روشن</translation>
 <translation id="4999804342505941663">روشن کردن «مزاحم نشوید»</translation>
 <translation id="5001526427543320409">کوکی‌های شخص ثالث</translation>
+<translation id="5003993274120026347">جمله بعدی</translation>
 <translation id="5005498671520578047">کپی گذرواژه</translation>
 <translation id="5006118752738286774">۲ سال قبل</translation>
 <translation id="5006218871145547804">‏پُل اشکال‌زدایی برنامه Android در Crostini</translation>
@@ -7312,7 +7310,7 @@
 <translation id="6586099239452884121">مرور به عنوان مهمان</translation>
 <translation id="6586213706115310390">‏با گفتن «OK Google» به «دستیار» دسترسی یابید.</translation>
 <translation id="6586451623538375658">جابجایی دکمه اصلی ماوس</translation>
-<translation id="6588043302623806746">‏استفاده از DNS ایمن</translation>
+<translation id="6588043302623806746">استفاده از ساناد امن</translation>
 <translation id="659005207229852190">«بررسی ایمنی» کامل شده است.</translation>
 <translation id="6590458744723262880">تغییر نام پوشه</translation>
 <translation id="6592267180249644460">‏زمان ثبت گزارش WebRTC ‏<ph name="WEBRTC_LOG_CAPTURE_TIME" /></translation>
@@ -9224,6 +9222,7 @@
 <translation id="8033958968890501070">پایان درنگ</translation>
 <translation id="8035059678007243127">صفحه ناشناس ذخیره‌شده در حافظه پنهان عقب-جلو: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">کمک به بهبود «تکمیل خودکار»</translation>
+<translation id="8036504271468642248">جمله قبلی</translation>
 <translation id="8037117027592400564">خواندن همه نوشتار با استفاده از گفتار تجزیه و تحلیل شده</translation>
 <translation id="8037357227543935929">درخواست (پیش‌فرض)</translation>
 <translation id="803771048473350947">فایل</translation>
diff --git a/chrome/app/resources/generated_resources_fi.xtb b/chrome/app/resources/generated_resources_fi.xtb
index 0dc2cbc3..17c303f 100644
--- a/chrome/app/resources/generated_resources_fi.xtb
+++ b/chrome/app/resources/generated_resources_fi.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Muokkaa tiedostoja</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Tiedostoa ei voi avata}other{Tiedostoja ei voi avata}}</translation>
 <translation id="1282311502488501110">Älä kirjaudu sisään</translation>
-<translation id="1282465000333679776">Jaa järjestelmän audio</translation>
 <translation id="1283126956823499975">Jotain meni pieleen laitteen käyttöönotossa</translation>
 <translation id="1284277788676816155">Älä salli datan tallentamista</translation>
 <translation id="1285320974508926690">Älä käännä tätä sivustoa</translation>
@@ -1061,7 +1060,6 @@
 <translation id="1781502536226964113">Avaa Uusi välilehti -sivu</translation>
 <translation id="1781553166608855614">Puheen kieli</translation>
 <translation id="1781771911845953849">Tilit ja synkronointi</translation>
-<translation id="1781979858217752599">Jaa ikkunan audio</translation>
 <translation id="1782101999402987960">Järjestelmänvalvoja on estänyt päivitykset</translation>
 <translation id="1782196717298160133">Etsitään puhelintasi</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 muistiinpano}other{# muistiinpanoa}}</translation>
@@ -1626,7 +1624,6 @@
 <translation id="2187895286714876935">Palvelimen varmenteen tuontivirhe</translation>
 <translation id="2187906491731510095">Laajennukset päivitetty</translation>
 <translation id="2188881192257509750">Avaa <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Jaa välilehden audio</translation>
 <translation id="2190069059097339078">Wi-Fi-tunnuksien hakija</translation>
 <translation id="219008588003277019">Asiakasmoduuli: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(tyhjä)</translation>
@@ -5297,6 +5294,7 @@
 <translation id="4998430619171209993">Päällä</translation>
 <translation id="4999804342505941663">Laita Älä häiritse ‑tila päälle</translation>
 <translation id="5001526427543320409">Kolmannen osapuolen evästeet</translation>
+<translation id="5003993274120026347">Seuraava lause</translation>
 <translation id="5005498671520578047">Kopioi salasana</translation>
 <translation id="5006118752738286774">2 vuotta sitten</translation>
 <translation id="5006218871145547804">Crostinin Android-sovellusten ADB</translation>
@@ -9221,6 +9219,7 @@
 <translation id="8033958968890501070">Aikakatkaisu</translation>
 <translation id="8035059678007243127">Siirtymisvälimuistissa oleva incognito-sivu: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Auta parantamaan automaattista täyttöä</translation>
+<translation id="8036504271468642248">Edellinen lause</translation>
 <translation id="8037117027592400564">Käyttää kaikkea puhesynteesin avulla luettua tekstiä</translation>
 <translation id="8037357227543935929">Kysy (oletus)</translation>
 <translation id="803771048473350947">Tiedosto</translation>
diff --git a/chrome/app/resources/generated_resources_fil.xtb b/chrome/app/resources/generated_resources_fil.xtb
index 1ecba56..88b7f0e7 100644
--- a/chrome/app/resources/generated_resources_fil.xtb
+++ b/chrome/app/resources/generated_resources_fil.xtb
@@ -387,7 +387,6 @@
 <translation id="1280965841156951489">I-edit ang mga file</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Hindi mabuksan ang file}one{Hindi mabuksan ang mga file}other{Hindi mabuksan ang mga file}}</translation>
 <translation id="1282311502488501110">Huwag Mag-sign In</translation>
-<translation id="1282465000333679776">Ibahagi ang audio ng system</translation>
 <translation id="1283126956823499975">Nagkaproblema sa pag-set up ng device</translation>
 <translation id="1284277788676816155">Huwag payagang i-save ang data</translation>
 <translation id="1285320974508926690">Huwag isalin kailanman ang site na ito</translation>
@@ -1066,7 +1065,6 @@
 <translation id="1781502536226964113">Buksan ang page ng Bagong Tab</translation>
 <translation id="1781553166608855614">Sinasalitang wika</translation>
 <translation id="1781771911845953849">Mga account at pag-sync</translation>
-<translation id="1781979858217752599">Ibahagi ang audio ng window</translation>
 <translation id="1782101999402987960">Bina-block ang mga update ng iyong administrator</translation>
 <translation id="1782196717298160133">Hinahanap ang iyong telepono</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 Paalala}one{# Paalala}other{# na Paalala}}</translation>
@@ -1632,7 +1630,6 @@
 <translation id="2187895286714876935">Error sa Pag-import ng Certificate ng Server</translation>
 <translation id="2187906491731510095">Na-update ang mga extension</translation>
 <translation id="2188881192257509750">Buksan ang <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Ibahagi ang audio ng tab</translation>
 <translation id="2190069059097339078">Pangkuha ng mga Kredensyal ng WiFi</translation>
 <translation id="219008588003277019">Module ng Native Client: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(walang laman)</translation>
@@ -5326,6 +5323,7 @@
 <translation id="4998430619171209993">Naka-on</translation>
 <translation id="4999804342505941663">I-on ang Huwag Istorbohin</translation>
 <translation id="5001526427543320409">Mga third-party na cookie</translation>
+<translation id="5003993274120026347">Susunod na pangungusap</translation>
 <translation id="5005498671520578047">Kopyahin password</translation>
 <translation id="5006118752738286774">2 taon ang nakalipas</translation>
 <translation id="5006218871145547804">ADB ng Android app sa Crostini</translation>
@@ -9277,6 +9275,7 @@
 <translation id="8033958968890501070">Time out</translation>
 <translation id="8035059678007243127">Back/Forward Cached na Page ng Incognito: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Tumulong na Pahusayin ang Autofill</translation>
+<translation id="8036504271468642248">Nakaraang pangungusap</translation>
 <translation id="8037117027592400564">Basahin ang lahat ng binigkas na text gamit ang naka-synthesize na pagsasalita</translation>
 <translation id="8037357227543935929">Magtanong (default)</translation>
 <translation id="803771048473350947">File</translation>
diff --git a/chrome/app/resources/generated_resources_fr-CA.xtb b/chrome/app/resources/generated_resources_fr-CA.xtb
index 6a7a59d..cb6ce923 100644
--- a/chrome/app/resources/generated_resources_fr-CA.xtb
+++ b/chrome/app/resources/generated_resources_fr-CA.xtb
@@ -383,7 +383,6 @@
 <translation id="1280965841156951489">Modifier les fichiers</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Impossible d'ouvrir le fichier}one{Impossible d'ouvrir le fichier}other{Impossible d'ouvrir les fichiers}}</translation>
 <translation id="1282311502488501110">Ne pas se connecter</translation>
-<translation id="1282465000333679776">Partager l'audio du système</translation>
 <translation id="1283126956823499975">Un problème est survenu lors de la configuration de l'appareil</translation>
 <translation id="1284277788676816155">Ne pas autoriser l'enregistrement des données</translation>
 <translation id="1285320974508926690">Ne jamais traduire ce site</translation>
@@ -1052,7 +1051,6 @@
 <translation id="1781502536226964113">Ouvrir la page Nouvel onglet</translation>
 <translation id="1781553166608855614">Langue parlée</translation>
 <translation id="1781771911845953849">Comptes et synchronisation</translation>
-<translation id="1781979858217752599">Partager le son de la fenêtre</translation>
 <translation id="1782101999402987960">Les mises à jour sont bloquées par votre administrateur</translation>
 <translation id="1782196717298160133">Rechercher votre téléphone</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 remarque}one{# remarques}other{# remarques}}</translation>
@@ -1616,7 +1614,6 @@
 <translation id="2187895286714876935">Erreur d'importation du certificat serveur</translation>
 <translation id="2187906491731510095">Extensions mises à jour</translation>
 <translation id="2188881192257509750">Ouvrir l'application <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Partager l'audio de l'onglet</translation>
 <translation id="2190069059097339078">Acquéreur d'authentifiant Wi-Fi</translation>
 <translation id="219008588003277019">Module de client natif : <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(vide)</translation>
@@ -5288,6 +5285,7 @@
 <translation id="4998430619171209993">Activé</translation>
 <translation id="4999804342505941663">Activer la fonctionnalité Ne pas déranger</translation>
 <translation id="5001526427543320409">Témoins tiers</translation>
+<translation id="5003993274120026347">Phrase suivante</translation>
 <translation id="5005498671520578047">Copier mot de passe</translation>
 <translation id="5006118752738286774">Il y a 2 ans</translation>
 <translation id="5006218871145547804">Pont interappareil d'applications Android pour Crostini</translation>
@@ -9213,6 +9211,7 @@
 <translation id="8033958968890501070">Délai dépassé</translation>
 <translation id="8035059678007243127">Page de navigation privée de la mise en cache complète bidirectionnelle : <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Aidez-nous à améliorer le remplissage automatique</translation>
+<translation id="8036504271468642248">Phrase précédente</translation>
 <translation id="8037117027592400564">Lire tout le texte énoncé à l'aide de la synthèse vocale</translation>
 <translation id="8037357227543935929">Demander (par défaut)</translation>
 <translation id="803771048473350947">Fichier</translation>
diff --git a/chrome/app/resources/generated_resources_fr.xtb b/chrome/app/resources/generated_resources_fr.xtb
index 55b31947..4c95d9a5 100644
--- a/chrome/app/resources/generated_resources_fr.xtb
+++ b/chrome/app/resources/generated_resources_fr.xtb
@@ -383,7 +383,6 @@
 <translation id="1280965841156951489">Modifier les fichiers</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Impossible d'ouvrir le fichier}one{Impossible d'ouvrir le fichier}other{Impossible d'ouvrir les fichiers}}</translation>
 <translation id="1282311502488501110">Ne pas se connecter</translation>
-<translation id="1282465000333679776">Partager l'audio du système</translation>
 <translation id="1283126956823499975">Un problème est survenu lors de la configuration de l'appareil</translation>
 <translation id="1284277788676816155">Ne pas autoriser l'enregistrement des données</translation>
 <translation id="1285320974508926690">Ne jamais traduire ce site</translation>
@@ -1052,7 +1051,6 @@
 <translation id="1781502536226964113">Ouvrir la page "Nouvel onglet"</translation>
 <translation id="1781553166608855614">Langue parlée</translation>
 <translation id="1781771911845953849">Comptes et synchronisation</translation>
-<translation id="1781979858217752599">Partager l'audio de la fenêtre</translation>
 <translation id="1782101999402987960">Les mises à jour ont été bloquées par votre administrateur</translation>
 <translation id="1782196717298160133">Rechercher votre téléphone</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 note}one{# note}other{# notes}}</translation>
@@ -1616,7 +1614,6 @@
 <translation id="2187895286714876935">Erreur d'importation du certificat serveur</translation>
 <translation id="2187906491731510095">Extensions mises à jour</translation>
 <translation id="2188881192257509750">Ouvrir <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Partager l'audio de l'onglet</translation>
 <translation id="2190069059097339078">Obtention des identifiants Wi-Fi</translation>
 <translation id="219008588003277019">Module Native Client : <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(vide)</translation>
@@ -5286,6 +5283,7 @@
 <translation id="4998430619171209993">Activé</translation>
 <translation id="4999804342505941663">Activer le mode Ne pas déranger</translation>
 <translation id="5001526427543320409">Cookies tiers</translation>
+<translation id="5003993274120026347">Phrase suivante</translation>
 <translation id="5005498671520578047">Copier mot de passe</translation>
 <translation id="5006118752738286774">Il y a 2 ans</translation>
 <translation id="5006218871145547804">ADB pour les applications Android sur Crostini</translation>
@@ -9214,6 +9212,7 @@
 <translation id="8033958968890501070">Délai dépassé</translation>
 <translation id="8035059678007243127">Page de navigation privée en cache amélioré : <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Aidez-nous à améliorer la saisie automatique</translation>
+<translation id="8036504271468642248">Phrase précédente</translation>
 <translation id="8037117027592400564">Accéder à l'ensemble du texte énoncé à l'aide de la synthèse vocale</translation>
 <translation id="8037357227543935929">Demander (par défaut)</translation>
 <translation id="803771048473350947">Fichier</translation>
diff --git a/chrome/app/resources/generated_resources_gl.xtb b/chrome/app/resources/generated_resources_gl.xtb
index b719de8ac..642ab8ad 100644
--- a/chrome/app/resources/generated_resources_gl.xtb
+++ b/chrome/app/resources/generated_resources_gl.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">Editar ficheiros</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Non se pode abrir o ficheiro}other{Non se pode abrir o ficheiros}}</translation>
 <translation id="1282311502488501110">Non iniciar sesión</translation>
-<translation id="1282465000333679776">Compartir audio do sistema</translation>
 <translation id="1283126956823499975">Produciuse un erro ao configurar o dispositivo</translation>
 <translation id="1284277788676816155">Non permitir gardar datos</translation>
 <translation id="1285320974508926690">Non traducir nunca este sitio</translation>
@@ -1050,7 +1049,6 @@
 <translation id="1781502536226964113">Abrir a páxina da pestana nova</translation>
 <translation id="1781553166608855614">Idioma falado</translation>
 <translation id="1781771911845953849">Contas e sincronización</translation>
-<translation id="1781979858217752599">Compartir audio da ventá</translation>
 <translation id="1782101999402987960">O teu administrador bloquea as actualizacións</translation>
 <translation id="1782196717298160133">Buscando o teu teléfono</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 nota}other{# notas}}</translation>
@@ -1614,7 +1612,6 @@
 <translation id="2187895286714876935">Erro de importación do certificado do servidor</translation>
 <translation id="2187906491731510095">Actualizáronse as extensións</translation>
 <translation id="2188881192257509750">Abrir <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Compartir audio da pestana</translation>
 <translation id="2190069059097339078">Método de obtención de credenciais de wifi</translation>
 <translation id="219008588003277019">Módulo de cliente nativo: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(baleiro)</translation>
@@ -5287,6 +5284,7 @@
 <translation id="4998430619171209993">Si</translation>
 <translation id="4999804342505941663">Activar modo Non molestar</translation>
 <translation id="5001526427543320409">Cookies de terceiros</translation>
+<translation id="5003993274120026347">Frase seguinte</translation>
 <translation id="5005498671520578047">Copiar contrasinal</translation>
 <translation id="5006118752738286774">Hai 2 anos</translation>
 <translation id="5006218871145547804">ADB para aplicacións para Android en Crostini</translation>
@@ -9207,6 +9205,7 @@
 <translation id="8033958968890501070">Tempo de espera esgotado</translation>
 <translation id="8035059678007243127">Páxina de incógnito almacenada na memoria caché de páxinas anteriores e seguintes: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Axuda a mellorar a función Autocompletar</translation>
+<translation id="8036504271468642248">Frase anterior</translation>
 <translation id="8037117027592400564">Ler o texto falado coa síntese de voz</translation>
 <translation id="8037357227543935929">Preguntar (predeterminado)</translation>
 <translation id="803771048473350947">Ficheiro</translation>
diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb
index 17976be..7c00bde4 100644
--- a/chrome/app/resources/generated_resources_gu.xtb
+++ b/chrome/app/resources/generated_resources_gu.xtb
@@ -383,7 +383,6 @@
 <translation id="1280965841156951489">ફાઇલોમાં ફેરફાર કરો</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ફાઇલ ખોલી શકાતી નથી}one{ફાઇલો ખોલી શકાતી નથી}other{ફાઇલો ખોલી શકાતી નથી}}</translation>
 <translation id="1282311502488501110">સાઇન ઇન કરશો નહીં</translation>
-<translation id="1282465000333679776">સિસ્ટમ ઑડિયો શેર કરો</translation>
 <translation id="1283126956823499975">ડિવાઇસનું સેટઅપ કરવામાં કંઈક ખોટું થયું</translation>
 <translation id="1284277788676816155">ડેટા સાચવવાની મંજૂરી આપશો નહીં</translation>
 <translation id="1285320974508926690">આ સાઇટનો ક્યારેય અનુવાદ કરશો નહીં</translation>
@@ -1048,7 +1047,6 @@
 <translation id="1781502536226964113">નવું ટૅબ પેજ ખોલો</translation>
 <translation id="1781553166608855614">બોલવામાં આવેલી ભાષા</translation>
 <translation id="1781771911845953849">એકાઉન્ટ અને સિંક</translation>
-<translation id="1781979858217752599">વિન્ડો ઑડિયો શેર કરો</translation>
 <translation id="1782101999402987960">તમારા વ્યવસ્થાપક દ્વારા અપડેટ બ્લૉક કરવામાં આવી છે</translation>
 <translation id="1782196717298160133">તમારો ફોન શોધી રહ્યું છે</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 નોંધ}one{# નોંધ}other{# નોંધ}}</translation>
@@ -1612,7 +1610,6 @@
 <translation id="2187895286714876935">સર્વર પ્રમાણપત્ર આયાત કરવામાં ભૂલ</translation>
 <translation id="2187906491731510095">એક્સ્ટેંશન અપડેટ કર્યા</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> ખોલો</translation>
-<translation id="2189787291884708275">ટૅબનો ઑડિયો શેર કરો</translation>
 <translation id="2190069059097339078">WiFi ઓળખપત્રો બનાવનાર</translation>
 <translation id="219008588003277019">મૂળ ક્લાયંટ મોડ્યુલ: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(ખાલી)</translation>
@@ -5283,6 +5280,7 @@
 <translation id="4998430619171209993">ચાલુ</translation>
 <translation id="4999804342505941663">'ખલેલ પાડશો નહીં' સુવિધા ચાલુ કરો</translation>
 <translation id="5001526427543320409">ત્રીજા પક્ષની કુકી</translation>
+<translation id="5003993274120026347">આગલું વાક્ય</translation>
 <translation id="5005498671520578047">પાસવર્ડની કૉપિ કરો</translation>
 <translation id="5006118752738286774">2 વર્ષ પહેલાં</translation>
 <translation id="5006218871145547804">Crostini Android ઍપ ADB</translation>
@@ -9206,6 +9204,7 @@
 <translation id="8033958968890501070">સમયસમાપ્તિ</translation>
 <translation id="8035059678007243127">બૅક/ફૉરવર્ડ કૅશ મેમરીમાં સ્ટોર કરેલું છૂપું પેજ: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">ઑટોમૅટિક રીતે ભરવાની સુવિધા બહેતર બનાવવાની રીત</translation>
+<translation id="8036504271468642248">પહેલાંનું વાક્ય</translation>
 <translation id="8037117027592400564">સિન્થેસાઇઝ કરેલ વાણીનો ઉપયોગ કરીને બધી બોલાયેલ ટેક્સ્ટને વાંચો</translation>
 <translation id="8037357227543935929">પૂછો (ડિફૉલ્ટ)</translation>
 <translation id="803771048473350947">ફાઇલ</translation>
diff --git a/chrome/app/resources/generated_resources_hi.xtb b/chrome/app/resources/generated_resources_hi.xtb
index ad9288c..d3a1303 100644
--- a/chrome/app/resources/generated_resources_hi.xtb
+++ b/chrome/app/resources/generated_resources_hi.xtb
@@ -385,7 +385,6 @@
 <translation id="1280965841156951489">फ़ाइलों में बदलाव करें</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{फ़ाइल खोली नहीं जा सकती}one{फ़ाइल खोली नहीं जा सकती}other{फ़ाइलें खोली नहीं जा सकतीं}}</translation>
 <translation id="1282311502488501110">साइन इन न करें</translation>
-<translation id="1282465000333679776">सिस्टम ऑडियो शेयर करें</translation>
 <translation id="1283126956823499975">डिवाइस को सेट अप करने के दौरान कोई गड़बड़ी हुई</translation>
 <translation id="1284277788676816155">साइट को डेटा सेव करने की अनुमति न दें</translation>
 <translation id="1285320974508926690">कभी भी इस साइट का अनुवाद न करें</translation>
@@ -1062,7 +1061,6 @@
 <translation id="1781502536226964113">'नया टैब' पेज खोलें</translation>
 <translation id="1781553166608855614">लिखाई को बोली में बदलने से जुड़ी सेटिंग पर जाएं</translation>
 <translation id="1781771911845953849">खाते और सिंक</translation>
-<translation id="1781979858217752599">विंडो ऑडियो शेयर करें</translation>
 <translation id="1782101999402987960">आपके एडमिन ने अपडेट ब्लॉक कर दिए हैं</translation>
 <translation id="1782196717298160133">आपका फ़ोन ढूंढा जा रहा है</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 नोट}one{# नोट}other{# नोट}}</translation>
@@ -1625,7 +1623,6 @@
 <translation id="2187895286714876935">सर्वर प्रमाणपत्र आयात गड़बड़ी</translation>
 <translation id="2187906491731510095">एक्सटेंशन अपडेट किए गए</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> खोलें</translation>
-<translation id="2189787291884708275">टैब ऑडियो शेयर करें</translation>
 <translation id="2190069059097339078">वाई-फ़ाई क्रेडेंशियल प्राप्‍तकर्ता</translation>
 <translation id="219008588003277019">नेटिव क्लाइंट मॉड्यूल: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(खाली)</translation>
@@ -5293,6 +5290,7 @@
 <translation id="4998430619171209993">चालू है</translation>
 <translation id="4999804342505941663">'परेशान न करें' सुविधा चालू करें</translation>
 <translation id="5001526427543320409">तीसरे पक्ष की कुकी</translation>
+<translation id="5003993274120026347">अगले वाक्य पर जाएं</translation>
 <translation id="5005498671520578047">पासवर्ड कॉपी करें</translation>
 <translation id="5006118752738286774">दो साल पहले</translation>
 <translation id="5006218871145547804">Crostini में Android ऐप्लिकेशन ADB की सेटिंग</translation>
@@ -9209,6 +9207,7 @@
 <translation id="8033958968890501070">समय खत्म</translation>
 <translation id="8035059678007243127">बैक/फ़ॉरवर्ड कैश मेमोरी में सेव किया गया गुप्त पेज: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">अपने-आप जानकारी भरने की सुविधा को बेहतर बनाने में मदद करें</translation>
+<translation id="8036504271468642248">पिछले वाक्य पर जाएं</translation>
 <translation id="8037117027592400564">संश्लेषित बोली का उपयोग करके बोला गया सभी लेख पढ़ें</translation>
 <translation id="8037357227543935929">पूछें (डिफ़ॉल्ट)</translation>
 <translation id="803771048473350947">फ़ाइल</translation>
diff --git a/chrome/app/resources/generated_resources_hr.xtb b/chrome/app/resources/generated_resources_hr.xtb
index 3a704e3..7f19c895 100644
--- a/chrome/app/resources/generated_resources_hr.xtb
+++ b/chrome/app/resources/generated_resources_hr.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Uredi datoteke</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Datoteka se ne može otvoriti}one{Datoteke se ne mogu otvoriti}few{Datoteke se ne mogu otvoriti}other{Datoteke se ne mogu otvoriti}}</translation>
 <translation id="1282311502488501110">Ne prijavljuj se</translation>
-<translation id="1282465000333679776">Dijeli zvuk sustava</translation>
 <translation id="1283126956823499975">Nešto nije u redu s postavljanjem uređaja</translation>
 <translation id="1284277788676816155">Nemoj dopustiti spremanje podataka</translation>
 <translation id="1285320974508926690">Nikad nemoj prevoditi ovu web-lokaciju</translation>
@@ -1053,7 +1052,6 @@
 <translation id="1781502536226964113">Otvori stranicu Nova kartica</translation>
 <translation id="1781553166608855614">Govorni jezik</translation>
 <translation id="1781771911845953849">Računi i sinkronizacija</translation>
-<translation id="1781979858217752599">Dijeli zvuk prozora</translation>
 <translation id="1782101999402987960">Administrator je blokirao ažuriranja</translation>
 <translation id="1782196717298160133">Pronalaženje vašeg telefona</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 bilješka}one{# bilješka}few{# bilješke}other{# bilješki}}</translation>
@@ -1617,7 +1615,6 @@
 <translation id="2187895286714876935">Pogreška pri uvozu Certifikata poslužitelja</translation>
 <translation id="2187906491731510095">Proširenja ažurirana</translation>
 <translation id="2188881192257509750">Otvori aplikaciju <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Dijeli zvuk kartice</translation>
 <translation id="2190069059097339078">Dohvaćanje vjerodajnica za Wi-Fi</translation>
 <translation id="219008588003277019">Modul Native Client: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(prazno)</translation>
@@ -5288,6 +5285,7 @@
 <translation id="4998430619171209993">Uključeno</translation>
 <translation id="4999804342505941663">Uključi opciju Ne uznemiravaj</translation>
 <translation id="5001526427543320409">Kolačići trećih strana</translation>
+<translation id="5003993274120026347">Sljedeća rečenica</translation>
 <translation id="5005498671520578047">Kopiranje zaporke</translation>
 <translation id="5006118752738286774">Prije dvije godine</translation>
 <translation id="5006218871145547804">Crostinijev ADB za Android aplikacije</translation>
@@ -9214,6 +9212,7 @@
 <translation id="8033958968890501070">Vrijeme je isteklo</translation>
 <translation id="8035059678007243127">Anonimno predmemorirana posjećena stranica: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Pomozite poboljšati automatsko popunjavanje</translation>
+<translation id="8036504271468642248">Prethodna rečenica</translation>
 <translation id="8037117027592400564">čitati sve tekstove izgovorene sintetiziranim govorom</translation>
 <translation id="8037357227543935929">Pitaj (zadano)</translation>
 <translation id="803771048473350947">Datoteka</translation>
diff --git a/chrome/app/resources/generated_resources_hu.xtb b/chrome/app/resources/generated_resources_hu.xtb
index c4464d53..a29fc6e 100644
--- a/chrome/app/resources/generated_resources_hu.xtb
+++ b/chrome/app/resources/generated_resources_hu.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Fájlok szerkesztése</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Nem lehet megnyitni a fájlt}other{Nem lehet megnyitni a fájlokat}}</translation>
 <translation id="1282311502488501110">Bejelentkezés leállítása</translation>
-<translation id="1282465000333679776">A rendszer hangjának megosztása</translation>
 <translation id="1283126956823499975">Hiba történt az eszköz beállítása során</translation>
 <translation id="1284277788676816155">Az adatok mentésének tiltása</translation>
 <translation id="1285320974508926690">Ezt a webhelyet soha ne fordítsa le</translation>
@@ -1062,7 +1061,6 @@
 <translation id="1781502536226964113">Új lap oldal megnyitása</translation>
 <translation id="1781553166608855614">Beszélt nyelv</translation>
 <translation id="1781771911845953849">Fiókok és szinkronizálás</translation>
-<translation id="1781979858217752599">Az ablak hangjának megosztása</translation>
 <translation id="1782101999402987960">A frissítéseket tiltja a rendszergazda</translation>
 <translation id="1782196717298160133">Telefon megtalálása</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 jegyzet}other{# jegyzet}}</translation>
@@ -1626,7 +1624,6 @@
 <translation id="2187895286714876935">Hiba a szervertanúsítvány importálásánál</translation>
 <translation id="2187906491731510095">Bővítmények frissítve</translation>
 <translation id="2188881192257509750">A(z) <ph name="APPLICATION" /> megnyitása</translation>
-<translation id="2189787291884708275">A lap hangjának megosztása</translation>
 <translation id="2190069059097339078">Wi-Fi hitelesítési adatok lekérője</translation>
 <translation id="219008588003277019">Natív kliensmodul: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(üres)</translation>
@@ -5299,6 +5296,7 @@
 <translation id="4998430619171209993">Be</translation>
 <translation id="4999804342505941663">A Ne zavarjanak mód bekapcsolása</translation>
 <translation id="5001526427543320409">Harmadik felektől származó cookie-k</translation>
+<translation id="5003993274120026347">Következő mondat</translation>
 <translation id="5005498671520578047">Jelszó másolása</translation>
 <translation id="5006118752738286774">2 éve</translation>
 <translation id="5006218871145547804">ADB crostinis Android-alkalmazáshoz</translation>
@@ -9224,6 +9222,7 @@
 <translation id="8033958968890501070">Időtúllépés</translation>
 <translation id="8035059678007243127">Előre-vissza gyorsítótárazott inkognitóoldal: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Segítsen az Automatikus kitöltés fejlesztésében</translation>
+<translation id="8036504271468642248">Előző mondat</translation>
 <translation id="8037117027592400564">Az összes szöveg felolvasása szintetizált beszéddel kimondva</translation>
 <translation id="8037357227543935929">Kérdezzen rá (alapértelmezés szerint)</translation>
 <translation id="803771048473350947">Fájl</translation>
diff --git a/chrome/app/resources/generated_resources_hy.xtb b/chrome/app/resources/generated_resources_hy.xtb
index c8bf3a8..87b320f 100644
--- a/chrome/app/resources/generated_resources_hy.xtb
+++ b/chrome/app/resources/generated_resources_hy.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Փոփոխել ֆայլերը</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Հնարավոր չէ բացել ֆայլը}one{Հնարավոր չէ բացել ֆայլը}other{Հնարավոր չէ բացել ֆայլերը}}</translation>
 <translation id="1282311502488501110">Մուտք չգործել</translation>
-<translation id="1282465000333679776">Հասանելի դարձնել համակարգի աուդիո բովանդակությունը</translation>
 <translation id="1283126956823499975">Սարքը կարգավորելիս սխալ առաջացավ</translation>
 <translation id="1284277788676816155">Չթույլատրել տվյալներ պահել</translation>
 <translation id="1285320974508926690">Երբեք չթարգմանել այս կայքը</translation>
@@ -1053,7 +1052,6 @@
 <translation id="1781502536226964113">Բացել նոր ներդիրի էջով</translation>
 <translation id="1781553166608855614">Հնչեցման լեզուն</translation>
 <translation id="1781771911845953849">Հաշիվներ և համաժամացում</translation>
-<translation id="1781979858217752599">Հասանելի դարձնել պատուհանի աուդիո բովանդակությունը</translation>
 <translation id="1782101999402987960">Ադմինիստրատորն արգելափակում է թարմացումները</translation>
 <translation id="1782196717298160133">Ձեր հեռախոսը որոնվում է</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 նշում}one{# նշում}other{# նշում}}</translation>
@@ -1617,7 +1615,6 @@
 <translation id="2187895286714876935">Սերվերի վկայագրի ներմուծման սխալ</translation>
 <translation id="2187906491731510095">Ընդլայնումները թարմացվել են</translation>
 <translation id="2188881192257509750">Բացել <ph name="APPLICATION" /> հավելվածը</translation>
-<translation id="2189787291884708275">Հասանելի դարձնել ներդիրի աուդիո բովանդակությունը</translation>
 <translation id="2190069059097339078">WiFi հավատարմագրերի կորզիչ</translation>
 <translation id="219008588003277019">Native Client մոդուլ` <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(դատարկ)</translation>
@@ -5284,6 +5281,7 @@
 <translation id="4998430619171209993">Միացված է</translation>
 <translation id="4999804342505941663">Միացնել «Չանհանգստացնել» ռեժիմը</translation>
 <translation id="5001526427543320409">Երրորդ կողմի քուքիներ</translation>
+<translation id="5003993274120026347">Հաջորդ նախադասությունը</translation>
 <translation id="5005498671520578047">Պատճենել գաղտնաբառը</translation>
 <translation id="5006118752738286774">2 տարի առաջ</translation>
 <translation id="5006218871145547804">Android-ի համար հավելվածների ADB գործիք Crostini-ում</translation>
@@ -9205,6 +9203,7 @@
 <translation id="8033958968890501070">Ժամանակը սպառվել է</translation>
 <translation id="8035059678007243127">Հետադարձ քեշի էջ ինկոգնիտո ռեժիմում՝ <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Օգնեք բարելավել ինքնալրացման գործառույթը</translation>
+<translation id="8036504271468642248">Նախորդ նախադասությունը</translation>
 <translation id="8037117027592400564">Տեքստի ընթերցում սինթեզված խոսքի միջոցով</translation>
 <translation id="8037357227543935929">Հարցնել (կանխադրված)</translation>
 <translation id="803771048473350947">Ֆայլ</translation>
diff --git a/chrome/app/resources/generated_resources_id.xtb b/chrome/app/resources/generated_resources_id.xtb
index a9c7b62cb..c20f4f37 100644
--- a/chrome/app/resources/generated_resources_id.xtb
+++ b/chrome/app/resources/generated_resources_id.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Edit file</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Tidak dapat membuka file}other{Tidak dapat membuka file}}</translation>
 <translation id="1282311502488501110">Jangan Login</translation>
-<translation id="1282465000333679776">Bagikan audio sistem</translation>
 <translation id="1283126956823499975">Terjadi error saat menyiapkan perangkat</translation>
 <translation id="1284277788676816155">Jangan izinkan penyimpanan data</translation>
 <translation id="1285320974508926690">Jangan pernah terjemahkan situs ini</translation>
@@ -1062,7 +1061,6 @@
 <translation id="1781502536226964113">Buka halaman Tab Baru</translation>
 <translation id="1781553166608855614">Bahasa lisan</translation>
 <translation id="1781771911845953849">Akun dan sinkronisasi</translation>
-<translation id="1781979858217752599">Bagikan audio jendela</translation>
 <translation id="1782101999402987960">Update diblokir oleh administrator Anda</translation>
 <translation id="1782196717298160133">Menemukan ponsel Anda</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 Catatan}other{# Catatan}}</translation>
@@ -1125,6 +1123,7 @@
 <translation id="1823768272150895732">Font</translation>
 <translation id="1823781806707127806">Tambahkan data penjelajahan yang sudah ada ke profil terkelola</translation>
 <translation id="18245044880483936">Data cadangan tidak akan mengurangi kuota penyimpanan Drive anak Anda.</translation>
+<translation id="1824870205483790748">Sematkan Grup ke Kolom Bookmark</translation>
 <translation id="1825073796163165618">Aktifkan link</translation>
 <translation id="1825565032302550710">Port harus antara 1024 dan 65535</translation>
 <translation id="182577151972096764">resep yang dilihat baru-baru ini</translation>
@@ -1147,6 +1146,7 @@
 <translation id="1834503245783133039">Download tidak berhasil: <ph name="FILE_NAME" /></translation>
 <translation id="1835261175655098052">Mengupgrade Linux</translation>
 <translation id="1835612721186505600">Mengizinkan akses untuk aplikasi dan situs yang memiliki izin kamera</translation>
+<translation id="1837441256780906162">Microsoft OneDrive menolak permintaan tersebut. Coba lagi nanti.</translation>
 <translation id="1838374766361614909">Hapus penelusuran</translation>
 <translation id="1839021455997460752">Alamat email Anda</translation>
 <translation id="1839540115464516994">Tampilkan di <ph name="LOCATION" /></translation>
@@ -1625,7 +1625,6 @@
 <translation id="2187895286714876935">Kesalahan Impor Sertifikat Server</translation>
 <translation id="2187906491731510095">Ekstensi diupdate</translation>
 <translation id="2188881192257509750">Buka <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Bagikan audio tab</translation>
 <translation id="2190069059097339078">Pembuka Kredensial Wi-Fi</translation>
 <translation id="219008588003277019">Modul Klien Asli: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(kosong)</translation>
@@ -1649,6 +1648,7 @@
 <translation id="2204387456724731099">Pilihan ini tidak dapat diterjemahkan</translation>
 <translation id="2207116775853792104">Simpan ekstensi ini</translation>
 <translation id="2210462644007531147">Tidak dapat menyelesaikan penginstalan</translation>
+<translation id="2211043920024403606">Informasi profil</translation>
 <translation id="2211245494465528624">Kelola opsi sinkronisasi</translation>
 <translation id="2214018885812055163">Folder bersama</translation>
 <translation id="2214893006758804920">{LINE_COUNT,plural, =1{&lt;1 baris tidak ditampilkan&gt;}other{&lt;<ph name="NUMBER_OF_LINES" /> baris tidak ditampilkan&gt;}}</translation>
@@ -2868,6 +2868,11 @@
 <translation id="311394601889664316">Jangan izinkan situs mengedit file atau folder di perangkat Anda</translation>
 <translation id="3115147772012638511">Menunggu cache...</translation>
 <translation id="3115580024857770654">Ciutkan semua</translation>
+<translation id="3115728370128632723">Menjadikan web berfungsi lebih baik untuk Anda, berarti:
+      &lt;ul&gt;
+        &lt;li&gt;Menjaga keamanan Anda saat menjelajah, dan&lt;/li&gt;
+        &lt;li&gt;Mendukung ekosistem berkembang yang menjaga web tetap aman, terbuka, cepat, dan gratis&lt;/li&gt;
+      &lt;/ul&gt;</translation>
 <translation id="3115743155098198207">Kelola bahasa Akun Google</translation>
 <translation id="3117362587799608430">Dok tidak sepenuhnya kompatibel</translation>
 <translation id="3117791853215125017">{COUNT,plural, =1{Gagal mengirim <ph name="ATTACHMENTS" /> ke <ph name="DEVICE_NAME" />}other{Gagal mengirim <ph name="ATTACHMENTS" /> ke <ph name="DEVICE_NAME" />}}</translation>
@@ -3689,6 +3694,7 @@
 <translation id="3760460896538743390">Periksa Halaman Latar &amp;Belakang</translation>
 <translation id="37613671848467444">Buka di &amp;Jendela Samaran</translation>
 <translation id="3761556954875533505">Izinkan situs mengedit file?</translation>
+<translation id="3761733456040768239">Tindakan lainnya untuk <ph name="CARD_DESCRIPTION" />, CVC disimpan</translation>
 <translation id="3763433740586298940">Anda dapat memblokir situs yang tidak diinginkan. Chrome juga otomatis menghapus situs dari daftar yang tersimpan lebih dari 30 hari.</translation>
 <translation id="3763549179847864476">Tombol kembali Panduan Privasi</translation>
 <translation id="3764314093345384080">Detail informasi build</translation>
@@ -5292,6 +5298,7 @@
 <translation id="4998430619171209993">Aktif</translation>
 <translation id="4999804342505941663">Aktifkan Jangan Ganggu</translation>
 <translation id="5001526427543320409">Cookie pihak ketiga</translation>
+<translation id="5003993274120026347">Kalimat berikutnya</translation>
 <translation id="5005498671520578047">Salin sandi</translation>
 <translation id="5006118752738286774">2 tahun lalu</translation>
 <translation id="5006218871145547804">ADB aplikasi Android Crostini</translation>
@@ -5719,6 +5726,7 @@
 <translation id="5344128444027639014"><ph name="BATTERY_PERCENTAGE" />% (Kanan)</translation>
 <translation id="534449933710420173">Folder tanpa nama</translation>
 <translation id="5345916423802287046">Mulai aplikasi saat login</translation>
+<translation id="5347920333985823270">Chrome mendukung web gratis</translation>
 <translation id="5350293332385664455">Nonaktifkan Asisten Google</translation>
 <translation id="535123479159372765">Teks disalin dari perangkat lain</translation>
 <translation id="5352033265844765294">Penyetempelan Waktu</translation>
@@ -5911,6 +5919,7 @@
 <translation id="5493792505296048976">layar aktif</translation>
 <translation id="5494016731375030300">Tab yang Baru Ditutup</translation>
 <translation id="5494362494988149300">Buka Setelah &amp;Selesai</translation>
+<translation id="5494843939447324326">Chrome memberi Anda pilihan</translation>
 <translation id="5494920125229734069">Pilih semua</translation>
 <translation id="5495466433285976480">Hal ini akan menghapus semua pengguna lokal, file, data, dan setelan lain setelah Anda memulai ulang lagi. Semua pengguna perlu masuk kembali.</translation>
 <translation id="5495597166260341369">Biarkan layar tetap menyala</translation>
@@ -5968,6 +5977,12 @@
 <translation id="5542132724887566711">Profil</translation>
 <translation id="5542750926112347543">Cookie dari <ph name="DOMAIN" /> diblokir</translation>
 <translation id="5542949973455282971">Menghubungkan ke <ph name="CARRIER_NAME" /></translation>
+<translation id="5543901591855628053">Iklan sangat penting bagi banyak bisnis online. Iklan membantu membuat konten tetap gratis secara online, yang membantu memastikan siapa saja dapat mengakses konten. Chrome mengembangkan cara agar situs dapat menampilkan iklan yang dipersonalisasi kepada Anda sekaligus melindungi privasi Anda.  Iklan yang berfungsi dengan efektif akan memberikan manfaat bagi semua orang di web, karena saat Anda melihat iklan:
+      &lt;ul&gt;
+        &lt;li&gt;Anda mungkin menemukan sesuatu yang baru atau menarik&lt;/li&gt;
+        &lt;li&gt;Pengiklan mungkin menemukan pelanggan baru&lt;/li&gt;
+        &lt;li&gt;Situs yang Anda kunjungi menghasilkan uang dengan menghosting iklan&lt;/li&gt;
+      &lt;/ul&gt;</translation>
 <translation id="5543983818738093899">Memeriksa status...</translation>
 <translation id="5544482392629385159">Perangkat <ph name="DEVICE_INDEX" /> dari <ph name="DEVICE_COUNT" />, <ph name="DEVICE_NAME" /></translation>
 <translation id="554517701842997186">Perender</translation>
@@ -6066,6 +6081,7 @@
 <translation id="5616571005307953937">Terlama</translation>
 <translation id="5616726534702877126">Tetapkan ukuran</translation>
 <translation id="561698261642843490">Tutup Firefox</translation>
+<translation id="5616991717083739666">Sematkan grup ke kolom bookmark</translation>
 <translation id="5620163320393916465">Tidak ada sandi yang tersimpan</translation>
 <translation id="5620540760831960151">Daftar ini dipengaruhi oleh <ph name="BEGIN_LINK1" />{BrowserSwitcherUrlList}<ph name="END_LINK1" />
           , <ph name="BEGIN_LINK2" />{BrowserSwitcherExternalSitelistUrl}<ph name="END_LINK2" />, 
@@ -6758,6 +6774,7 @@
 <translation id="6154240335466762404">Hapus semua port</translation>
 <translation id="615436196126345398">Protokol</translation>
 <translation id="6154739047827675957">Penyiapan OneDrive gagal</translation>
+<translation id="6154820449290823443">Kelola akses dan blokir aplikasi di Chromebook ini.</translation>
 <translation id="6155141482566063812">Tab background membagikan layar Anda</translation>
 <translation id="6156323911414505561">Tampilkan kolom bookmark</translation>
 <translation id="6156863943908443225">Cache skrip</translation>
@@ -6847,6 +6864,7 @@
 <translation id="6226777517901268232">File kunci pribadi (opsional)</translation>
 <translation id="6227002569366039565">Tekan |<ph name="ACCELERATOR" />| untuk memfokuskan balon ini, lalu tekan lagi untuk memfokuskan elemen yang ditunjuk.</translation>
 <translation id="6227280783235722609">ekstensi</translation>
+<translation id="622902691730729894">Lepaskan pin grup dari kolom bookmark</translation>
 <translation id="6229062790325126537">Reset ApnMigrator</translation>
 <translation id="6229849828796482487">Putuskan koneksi jaringan Wi-Fi</translation>
 <translation id="6231782223312638214">Disarankan</translation>
@@ -7681,6 +7699,7 @@
 <translation id="686831807558000905">Jangan login</translation>
 <translation id="686839242150793617">Diizinkan masuk ke mode picture-in-picture secara otomatis</translation>
 <translation id="6868934826811377550">Lihat Detail</translation>
+<translation id="6869093950561306644">Untuk memastikan perangkat ini dapat digunakan dengan aman, organisasi Anda mungkin perlu melihat informasi tentang sistem operasi, browser, dan setelannya, serta software apa yang diinstal di perangkat.</translation>
 <translation id="6871644448911473373">Penanggap OCSP: <ph name="LOCATION" /></translation>
 <translation id="6873571253135628430">Ubah izin situs</translation>
 <translation id="6876155724392614295">Sepeda</translation>
@@ -9204,6 +9223,7 @@
 <translation id="8033958968890501070">Waktu habis</translation>
 <translation id="8035059678007243127">Halaman Samaran yang Disimpan di Back/Forward Cache: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Bantu Tingkatkan Isi Otomatis</translation>
+<translation id="8036504271468642248">Kalimat sebelumnya</translation>
 <translation id="8037117027592400564">Membaca semua teks yang diucapkan menggunakan ucapan yang disintesis</translation>
 <translation id="8037357227543935929">Tanyakan (default)</translation>
 <translation id="803771048473350947">File</translation>
@@ -10266,6 +10286,7 @@
 <translation id="8838601485495657486">Buram</translation>
 <translation id="8838770651474809439">Hamburger</translation>
 <translation id="8838778928843281408">Kelola ponsel</translation>
+<translation id="8838841425230629509">Lepaskan Pin Grup dari Kolom Bookmark</translation>
 <translation id="883924185304953854">Telusuri pakai gambar</translation>
 <translation id="8841786407272321022">Sandi hanya disimpan di perangkat ini. Untuk menyimpan sandi baru di Akun Google Anda, update layanan Google Play.</translation>
 <translation id="8841843049738266382">Membaca dan mengubah pengguna yang diizinkan</translation>
@@ -10274,6 +10295,7 @@
 <translation id="8846132060409673887">Membaca produsen dan model komputer ini</translation>
 <translation id="8846163936679269230">Reset profil eSIM</translation>
 <translation id="8846239054091760429">Audio mono, pengaktifan, Teks Otomatis, dan lainnya</translation>
+<translation id="8847459600640933659">Pendapatan iklan juga mendukung banyak produk dan layanan gratis dari Google, seperti Chrome, Gmail, Maps, dan YouTube.</translation>
 <translation id="8847988622838149491">USB</translation>
 <translation id="8849001918648564819">Tersembunyi</translation>
 <translation id="8849219423513870962">Batalkan penghapusan profil eSIM bernama <ph name="PROFILE_NAME" /></translation>
diff --git a/chrome/app/resources/generated_resources_is.xtb b/chrome/app/resources/generated_resources_is.xtb
index f570321..84ff9386 100644
--- a/chrome/app/resources/generated_resources_is.xtb
+++ b/chrome/app/resources/generated_resources_is.xtb
@@ -385,7 +385,6 @@
 <translation id="1280965841156951489">Breyta skrám</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Ekki er hægt að opna skrána}one{Ekki er hægt að opna skrárnar}other{Ekki er hægt að opna skrárnar}}</translation>
 <translation id="1282311502488501110">Ekki skrá inn</translation>
-<translation id="1282465000333679776">Deila hljóði kerfis</translation>
 <translation id="1283126956823499975">Eitthvað fór úrskeiðis við uppsetningu tækisins</translation>
 <translation id="1284277788676816155">Ekki leyfa vistun gagna</translation>
 <translation id="1285320974508926690">Aldrei þýða þetta vefsvæði</translation>
@@ -1063,7 +1062,6 @@
 <translation id="1781502536226964113">Opna síðu nýrra flipa</translation>
 <translation id="1781553166608855614">Talað tungumál</translation>
 <translation id="1781771911845953849">Reikningar og samstilling</translation>
-<translation id="1781979858217752599">Deila hljóði glugga</translation>
 <translation id="1782101999402987960">Stjórnandi hefur lokað á uppfærslur</translation>
 <translation id="1782196717298160133">Leit að síma</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 glósa}one{# glósa}other{# glósur}}</translation>
@@ -1628,7 +1626,6 @@
 <translation id="2187895286714876935">Villa við innflutning á vottorði þjóns</translation>
 <translation id="2187906491731510095">Viðbætur uppfærðar</translation>
 <translation id="2188881192257509750">Opna <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Deila hljóði flipa</translation>
 <translation id="2190069059097339078">Niðurhal Wi-Fi skilríkja</translation>
 <translation id="219008588003277019">Eining sérforritaðs biðlara: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(autt)</translation>
@@ -5302,6 +5299,7 @@
 <translation id="4998430619171209993">Kveikt</translation>
 <translation id="4999804342505941663">Kveikja á „Ónáðið ekki“</translation>
 <translation id="5001526427543320409">Fótspor þriðju aðila</translation>
+<translation id="5003993274120026347">Næsta setning</translation>
 <translation id="5005498671520578047">Afrita aðgangsorð</translation>
 <translation id="5006118752738286774">fyrir 2 árum</translation>
 <translation id="5006218871145547804">ADB Android forrita í Crostini</translation>
@@ -9227,6 +9225,7 @@
 <translation id="8033958968890501070">Tímamörk</translation>
 <translation id="8035059678007243127">Huliðssíða í skyndiminni til baka / áfram: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Hjálpaðu til við að bæta sjálfvirka útfyllingu</translation>
+<translation id="8036504271468642248">Fyrri setning</translation>
 <translation id="8037117027592400564">Lesa allan talaðan texta með talgervli</translation>
 <translation id="8037357227543935929">Spyrja (sjálfgefið)</translation>
 <translation id="803771048473350947">Skrá</translation>
diff --git a/chrome/app/resources/generated_resources_it.xtb b/chrome/app/resources/generated_resources_it.xtb
index d19e3d8..4a6385a 100644
--- a/chrome/app/resources/generated_resources_it.xtb
+++ b/chrome/app/resources/generated_resources_it.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">Modifica file</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Impossibile aprire il file}other{Impossibile aprire i file}}</translation>
 <translation id="1282311502488501110">Non accedere</translation>
-<translation id="1282465000333679776">Condividi audio di sistema</translation>
 <translation id="1283126956823499975">Si è verificato un problema durante la configurazione del dispositivo</translation>
 <translation id="1284277788676816155">Non consentire il salvataggio dei dati</translation>
 <translation id="1285320974508926690">Non tradurre mai questo sito</translation>
@@ -1051,7 +1050,6 @@
 <translation id="1781502536226964113">Apri la pagina Nuova scheda</translation>
 <translation id="1781553166608855614">Lingua parlata</translation>
 <translation id="1781771911845953849">Account e sincronizzazioni</translation>
-<translation id="1781979858217752599">Condividi audio finestra</translation>
 <translation id="1782101999402987960">Gli aggiornamenti sono stati bloccati dall'amministratore</translation>
 <translation id="1782196717298160133">Ricerca del tuo telefono</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 nota}other{# note}}</translation>
@@ -1615,7 +1613,6 @@
 <translation id="2187895286714876935">Errore di importazione del certificato del server</translation>
 <translation id="2187906491731510095">Estensioni aggiornate</translation>
 <translation id="2188881192257509750">Apri <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Condividi l'audio della scheda</translation>
 <translation id="2190069059097339078">WiFi Credentials Getter</translation>
 <translation id="219008588003277019">Modulo Native Client: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(vuoto)</translation>
@@ -5284,6 +5281,7 @@
 <translation id="4998430619171209993">On</translation>
 <translation id="4999804342505941663">Attiva Non disturbare</translation>
 <translation id="5001526427543320409">Cookie di terze parti</translation>
+<translation id="5003993274120026347">Frase successiva</translation>
 <translation id="5005498671520578047">Copia password</translation>
 <translation id="5006118752738286774">2 anni fa</translation>
 <translation id="5006218871145547804">ADB app Android su Crostini</translation>
@@ -9206,6 +9204,7 @@
 <translation id="8033958968890501070">Timeout</translation>
 <translation id="8035059678007243127">Pagina in incognito memorizzata nella cache back-forward: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Contribuisci a migliorare la compilazione automatica</translation>
+<translation id="8036504271468642248">Frase precedente</translation>
 <translation id="8037117027592400564">Lettura di tutto il testo pronunciato utilizzando la sintesi vocale</translation>
 <translation id="8037357227543935929">Chiedi (predefinita)</translation>
 <translation id="803771048473350947">Archivio</translation>
diff --git a/chrome/app/resources/generated_resources_iw.xtb b/chrome/app/resources/generated_resources_iw.xtb
index 9972b5b..4a581c1 100644
--- a/chrome/app/resources/generated_resources_iw.xtb
+++ b/chrome/app/resources/generated_resources_iw.xtb
@@ -385,7 +385,6 @@
 <translation id="1280965841156951489">אישור לערוך קבצים</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{לא ניתן לפתוח את הקובץ}one{לא ניתן לפתוח את הקבצים}two{לא ניתן לפתוח את הקבצים}other{לא ניתן לפתוח את הקבצים}}</translation>
 <translation id="1282311502488501110">אני לא רוצה להיכנס</translation>
-<translation id="1282465000333679776">שיתוף האודיו של המערכת</translation>
 <translation id="1283126956823499975">משהו השתבש בהגדרת המכשיר</translation>
 <translation id="1284277788676816155">אין לאפשר שמירת נתונים</translation>
 <translation id="1285320974508926690">איני רוצה לקבל תרגום של אתר זה</translation>
@@ -1059,7 +1058,6 @@
 <translation id="1781502536226964113">ייפתח דף 'כרטיסייה חדשה'</translation>
 <translation id="1781553166608855614">שפה מדוברת</translation>
 <translation id="1781771911845953849">חשבונות וסנכרון</translation>
-<translation id="1781979858217752599">שיתוף האודיו מהחלון</translation>
 <translation id="1782101999402987960">העדכונים חסומים על ידי מנהל המערכת</translation>
 <translation id="1782196717298160133">מתבצע חיפוש של הטלפון שלך</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{הערה אחת}one{# הערות}two{# הערות}other{# הערות}}</translation>
@@ -1624,7 +1622,6 @@
 <translation id="2187895286714876935">שגיאת ייבוא של אישור שרת</translation>
 <translation id="2187906491731510095">התוספים עודכנו</translation>
 <translation id="2188881192257509750">פתיחת <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">שיתוף האודיו מהכרטיסייה</translation>
 <translation id="2190069059097339078">‏מאחזר פרטי כניסה ל-Wi-Fi</translation>
 <translation id="219008588003277019">‏Native Client מודול: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(ריק)</translation>
@@ -5299,6 +5296,7 @@
 <translation id="4998430619171209993">מופעל</translation>
 <translation id="4999804342505941663">הפעלת המצב 'נא לא להפריע'</translation>
 <translation id="5001526427543320409">‏קובצי cookie של צד שלישי</translation>
+<translation id="5003993274120026347">המשפט הבא</translation>
 <translation id="5005498671520578047">העתקת הסיסמה</translation>
 <translation id="5006118752738286774">לפני שנתיים</translation>
 <translation id="5006218871145547804">‏ADB עבור אפליקציות ל-Android ב-Crostini</translation>
@@ -9222,6 +9220,7 @@
 <translation id="8033958968890501070">הזמן שהוקצב תם</translation>
 <translation id="8035059678007243127">הדף האנונימי השמור במטמון לדף הקודם/הבא: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">עזרה בשיפור של המילוי האוטומטי</translation>
+<translation id="8036504271468642248">המשפט הקודם</translation>
 <translation id="8037117027592400564">קריאת כל הטקסט הנאמר באמצעות דיבור מסונתז</translation>
 <translation id="8037357227543935929">לשאול (ברירת מחדל)</translation>
 <translation id="803771048473350947">קובץ</translation>
diff --git a/chrome/app/resources/generated_resources_ja.xtb b/chrome/app/resources/generated_resources_ja.xtb
index bc3a9c1..e5d4615 100644
--- a/chrome/app/resources/generated_resources_ja.xtb
+++ b/chrome/app/resources/generated_resources_ja.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">ファイルを編集</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ファイルを開けません}other{ファイルを開けません}}</translation>
 <translation id="1282311502488501110">ログインしない</translation>
-<translation id="1282465000333679776">システムの音声を共有</translation>
 <translation id="1283126956823499975">デバイスの設定中にエラーが発生しました</translation>
 <translation id="1284277788676816155">データの保存を許可しない</translation>
 <translation id="1285320974508926690">このサイトは翻訳しない</translation>
@@ -1050,7 +1049,6 @@
 <translation id="1781502536226964113">新しいタブ ページを開く</translation>
 <translation id="1781553166608855614">音声の言語</translation>
 <translation id="1781771911845953849">アカウントと同期</translation>
-<translation id="1781979858217752599">ウィンドウの音声を共有</translation>
 <translation id="1782101999402987960">更新は管理者によりブロックされています</translation>
 <translation id="1782196717298160133">スマートフォンを検出中</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 件のメモ}other{# 件のメモ}}</translation>
@@ -1612,7 +1610,6 @@
 <translation id="2187895286714876935">サーバー証明書インポート エラー</translation>
 <translation id="2187906491731510095">拡張機能が更新されました</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> を開く</translation>
-<translation id="2189787291884708275">タブの音声を共有</translation>
 <translation id="2190069059097339078">WiFi 認証情報の取得機能</translation>
 <translation id="219008588003277019">ネイティブ クライアント モジュール: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(なし)</translation>
@@ -5275,6 +5272,7 @@
 <translation id="4998430619171209993">オン</translation>
 <translation id="4999804342505941663">サイレント モードをオンにする</translation>
 <translation id="5001526427543320409">サードパーティ Cookie</translation>
+<translation id="5003993274120026347">次の文</translation>
 <translation id="5005498671520578047">パスワードのコピー</translation>
 <translation id="5006118752738286774">2 年前</translation>
 <translation id="5006218871145547804">Crostini Android アプリ ADB</translation>
@@ -9193,6 +9191,7 @@
 <translation id="8033958968890501070">タイムアウト</translation>
 <translation id="8035059678007243127">バックフォワード キャッシュのシークレット ページ: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">自動入力の改善にご協力ください</translation>
+<translation id="8036504271468642248">前の文</translation>
 <translation id="8037117027592400564">合成音声で読み上げたすべてのテキストの読み取り</translation>
 <translation id="8037357227543935929">確認(デフォルト)</translation>
 <translation id="803771048473350947">ファイル</translation>
diff --git a/chrome/app/resources/generated_resources_ka.xtb b/chrome/app/resources/generated_resources_ka.xtb
index 8bdee6f..50f0201 100644
--- a/chrome/app/resources/generated_resources_ka.xtb
+++ b/chrome/app/resources/generated_resources_ka.xtb
@@ -15,6 +15,7 @@
 <translation id="1006873397406093306">ამ გაფართოებას შეუძლია საიტებზე თქვენი მონაცემების წაკითხვა და შეცვლა. თქვენ შეგიძლიათ გააკონტროლოთ, თუ რომელ საიტებზე ექნება მას წვდომა.</translation>
 <translation id="1007057452468855774">Google Play Store-ის ჩართვა</translation>
 <translation id="1008186147501209563">სანიშნეების ექსპორტი</translation>
+<translation id="1008209036711323236">ამიტომაც Chrome გეგმავს, გამოყენებიდან ამოიღოს „მესამე მხარის“ ქუქი-ჩანაწერები, როგორც კი დაამუშავებს კონკურენტთა საკითხებს <ph name="BEGIN_LINK" />გაერთიანებული სამეფოს კონკურენციისა და ბაზრების უწყება (CMA)<ph name="END_LINK" />.</translation>
 <translation id="1008261151167010035"><ph name="BRAND" /> დაიმახსოვრებს სისტემაში შესვლის ხერხს და ავტომატურად შეგიყვანთ სისტემაში, როცა ეს შესაძლებელია. გამორთვის შემთხვევაში, ყოველ ჯერზე საჭირო იქნება თქვენი დასტური.</translation>
 <translation id="1008544602823861396">ვერ გამოიყენებს თქვენს ინფორმაციას შემდეგ საიტზე:</translation>
 <translation id="1008557486741366299">ახლა არა</translation>
@@ -382,7 +383,6 @@
 <translation id="1280965841156951489">ფაილების რედაქტირება</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ფაილის გახსნა ვერ ხერხდება}other{ფაილების გახსნა ვერ ხერხდება}}</translation>
 <translation id="1282311502488501110">არ მსურს შესვლა</translation>
-<translation id="1282465000333679776">სისტემის აუდიოს გაზიარება</translation>
 <translation id="1283126956823499975">ამ მოწყობილობის დაყენებისას წარმოიქმნა შეფერხება</translation>
 <translation id="1284277788676816155">მონაცემთა შენახვის აკრძალვა</translation>
 <translation id="1285320974508926690">არასდროს გადათარგმნო ეს საიტი</translation>
@@ -866,6 +866,7 @@
     <ph name="BEGIN_PARAGRAPH2" />ამ სერვისის გამორთვა შეგიძლიათ პარამეტრებიდან.<ph name="END_PARAGRAPH2" /></translation>
 <translation id="1637224376458524414">მიიღეთ ეს სანიშნე თქვენს iPhone-ზე</translation>
 <translation id="1637765355341780467">თქვენი პროფილის გახსნისას შეფერხება წარმოიქმნა. ზოგიერთი ფუნქცია შეიძლება მიუწვდომელი იყოს.</translation>
+<translation id="1637830036924985819">ზოგჯერ საიტები ქუქი-ჩანაწერებს არამიზნობრივად იყენებს</translation>
 <translation id="1639239467298939599">იტვირთება</translation>
 <translation id="1640235262200048077"><ph name="IME_NAME" /> ჯერ არ მუშაობს Linux აპებში</translation>
 <translation id="1640283014264083726">PKCS #1 MD4 RSA დაშიფვრით</translation>
@@ -1029,6 +1030,7 @@
 <translation id="1767508543310534319">პუნქტუაციის ექო</translation>
 <translation id="1768212860412467516">გამოგვეხმაურეთ, როგორია <ph name="EXPERIMENT_NAME" />.</translation>
 <translation id="1769104665586091481">გახსენით ბმულები ახალ &amp;ფანჯარაში</translation>
+<translation id="1769157454356586138">სკანირება ვერ მოხერხდა. ეს ფაილი დაბლოკილია თქვენი ადმინისტრატორის მიერ</translation>
 <translation id="1770407692401984718">ჩავლებით გადმოიტანეთ სურათი აქ ან</translation>
 <translation id="177053719077591686">Android აპების სარეზერვო ასლების შექმნა Google Drive-ზე.</translation>
 <translation id="1771075623623424448">ბრაუზერის მოწყობილობის ჟურნალის გვერდს ეძებთ? მოინახულეთ<ph name="BEGIN_LINK" /><ph name="CHROME_DEVICE_LOG_LINK" /><ph name="END_LINK" />.</translation>
@@ -1051,7 +1053,6 @@
 <translation id="1781502536226964113">ახალი ჩანართის გვერდის გახსნა</translation>
 <translation id="1781553166608855614">გახმოვანების ენა</translation>
 <translation id="1781771911845953849">ანგარიშები და სინქრონიზაცია</translation>
-<translation id="1781979858217752599">ფანჯრის აუდიოს გაზიარება</translation>
 <translation id="1782101999402987960">განახლებები დაბლოკილია თქვენი ადმინისტრატორის მიერ</translation>
 <translation id="1782196717298160133">თქვენი ტელეფონის ძებნა</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 ჩანიშვნა}other{# ჩანიშვნა}}</translation>
@@ -1615,7 +1616,6 @@
 <translation id="2187895286714876935">სერვერის სერტიფიკატის იმპორტის შეცდომა</translation>
 <translation id="2187906491731510095">გაფართოებები განახლდა</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" />-ის გახსნა</translation>
-<translation id="2189787291884708275">ჩანართის აუდიოს გაზიარება</translation>
 <translation id="2190069059097339078">WiFi-ს ავტორიზაციის მონაცემების მიმღები</translation>
 <translation id="219008588003277019">საკუთარი კლიენტის მოდული: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(ცარიელი)</translation>
@@ -2116,6 +2116,7 @@
 <translation id="2542050502251273923">დააყენებს ქსელთან კავშირის მენეჯერისა და სხვა სერვისების შეცდომების გამართვის დონეს ff_debug-ის მეშვეობით.</translation>
 <translation id="2543780089903485983">{NUM_SUB_APP_INSTALLS,plural, =1{ნებართვები, რომლებსაც „<ph name="APP_NAME" />“-ისთვის დაუშვებთ, დაშვებული იქნება ამ აპისთვისაც. <ph name="MANAGE_LINK" />}other{ნებართვები, რომლებსაც „<ph name="APP_NAME" />“-ისთვის დაუშვებთ, დაშვებული იქნება ამ აპებისთვისაც. <ph name="MANAGE_LINK" />}}</translation>
 <translation id="2544352060595557290">ეს ჩანართი</translation>
+<translation id="2545743249923338554">ახალი ჩანართები</translation>
 <translation id="2546302722632337735">ვებსაიტებისთვის იდენტიფიკატორების გამოყენების აკრძალვა დაცული კონტენტის დაკვრის მიზნით</translation>
 <translation id="2546991196809436099">გაადიდეთ მასშტაბი, ეკრანზე არსებული ერთეულები რომ გაადიდოთ. ლუპის ჩასართავად ან გამოსართავად გამოიყენეთ კლავიშთა კომბინაცია Search + Ctrl + M.</translation>
 <translation id="2548347166720081527"><ph name="PERMISSION" /> დაშვებულია</translation>
@@ -2670,6 +2671,7 @@
 <translation id="2967926928600500959">ამ წესების შესატყვისი URL-ები იძულებით გაიხსნება კონკრეტულ ბრაუზერში.</translation>
 <translation id="2969411787010981955">მონაცემები ექსპორტირებულია არჩეულ მდებარეობაზე</translation>
 <translation id="2970766364519518369">არჩეული კონტაქტები შეძლებენ კონტენტის თქვენთვის გაზიარებას, როცა ისინი ახლოს იქნებიან. ამ ტიპის მოთხოვნები უნდა დაამტკიცოთ, თუმცა <ph name="USER_EMAIL" />-ში შესული მოწყობილობების დამტკიცება არ დაგჭირდებათ.</translation>
+<translation id="2971514543824815520">კურსორის ცვლილება რომ ამოქმედდეს, შეიძლება აპების გადატვირთვა დაგჭირდეთ</translation>
 <translation id="2972557485845626008">მიკროპროგრამა</translation>
 <translation id="2972581237482394796">&amp;გამეორება</translation>
 <translation id="2973324205039581528">საიტის დადუმება</translation>
@@ -2786,6 +2788,7 @@
 <translation id="3046910703532196514">ვებგვერდო, მთლიანი</translation>
 <translation id="304747341537320566">მეტყველების მოდულები</translation>
 <translation id="3048336643003835855">HID მოწყობილობები, რომელთა მომწოდებელია <ph name="VENDOR_ID" /></translation>
+<translation id="3048742847101793553">თქვენმა ორგანიზაციამ დაბლოკა ეს ფაილი, რადგან სკანირება ვერ მოხერხდა.</translation>
 <translation id="3048917188684939573">ტრანსლირებისა და მოწყობილობათა ჟურნალები</translation>
 <translation id="3051250416341590778">ჩვენების ზომა</translation>
 <translation id="3053013834507634016">სერტიფიკატის გასაღების გამოყენება</translation>
@@ -2866,6 +2869,7 @@
 <translation id="3117791853215125017">{COUNT,plural, =1{<ph name="ATTACHMENTS" /> <ph name="DEVICE_NAME" />-ს ვერ გაეგზავნა}other{<ph name="ATTACHMENTS" /> <ph name="DEVICE_NAME" />-ს ვერ გაეგზავნა}}</translation>
 <translation id="3118319026408854581"><ph name="PRODUCT_NAME" /> დახმარება</translation>
 <translation id="3118748462829336648">გვერდითი პანელის გახსნა</translation>
+<translation id="3119743309973425629">ტექსტის კურსორის ციმციმის სიხშირე</translation>
 <translation id="3119948370277171654">რა ტიპის კონტენტის/URL-ის ტრანსლირებას ახორციელებდით?</translation>
 <translation id="3122464029669770682">CPU</translation>
 <translation id="3122496702278727796">მონაცემების დირექტორია ვერ შეიქმნა</translation>
@@ -3720,6 +3724,7 @@
 <translation id="3783889407390048282">თქვენს Android-ზე წვდომა რომ არ დაკარგოთ, გაათავისუფლეთ მეხსიერება.</translation>
 <translation id="3785308913036335955">პროგრამების მალსახმობის ჩვენება</translation>
 <translation id="3785727820640310185">ამ საიტისთვის შენახული პაროლები</translation>
+<translation id="3785748905555897481">PIN წარმატებით შეიცვალა</translation>
 <translation id="3786224729726357296">საიტის მონაცემებისა და ნებართვების წაშლა <ph name="SITE" />-ისთვის</translation>
 <translation id="3786834302860277193">ხაზგასმის ჩვენება შედგენილი ტექსტისთვის</translation>
 <translation id="3787434344076711519">ველოდებით თარგმნის დასრულებას</translation>
@@ -4381,6 +4386,7 @@
 <translation id="428963538941819373">ამ საიტებს შეუძლია გამოიყენონ მათ მიერ თქვენ შესახებ შენახული ინფორმაცია, როცა <ph name="HOST" />-ს ათვალიერებთ</translation>
 <translation id="4289732974614035569">აირჩიეთ PIN-კოდი</translation>
 <translation id="4290791284969893584">გვერდის დახურვის შემდეგ, თქვენ მიერ დაყენებული ამოცანები, შესაძლოა, არ დასრულდეს</translation>
+<translation id="4290898381118933198">გადაფურცლეთ გვერდებს შორის ნავიგაციისთვის</translation>
 <translation id="4291265871880246274">სისტემაში შესვლის დიალოგი</translation>
 <translation id="429234155571566255">ბოლო დროს ნანახი ეს რეცეპტები</translation>
 <translation id="429312253194641664">საიტზე გაშვებულია მედია-კონტენტი</translation>
@@ -5285,6 +5291,7 @@
 <translation id="4998430619171209993">ჩართული</translation>
 <translation id="4999804342505941663">„არ შემაწუხოთ“ რეჟიმის ჩართვა</translation>
 <translation id="5001526427543320409">მესამე მხარის ქუქი-ჩანაწერები</translation>
+<translation id="5003993274120026347">შემდეგი წინადადება</translation>
 <translation id="5005498671520578047">პაროლის კოპირება</translation>
 <translation id="5006118752738286774">2 წლის წინ</translation>
 <translation id="5006218871145547804">Crostini-ს Android აპის ADB</translation>
@@ -5359,6 +5366,7 @@
 <translation id="5063480226653192405">გამოყენება</translation>
 <translation id="5065775832226780415">Smart Lock</translation>
 <translation id="5066100345385738837">მართეთ დაცული DNS ChromeOS-ის პარამეტრებიდან</translation>
+<translation id="5066534201484101197">საზღვრის მიღმა გადაადგილდით გვერდებს შორის ნავიგაციისთვის</translation>
 <translation id="5067399438976153555">ყოველთვის ჩართული</translation>
 <translation id="5067867186035333991">იკითხეთ, თუ <ph name="HOST" />-ს სურს თქვენს მიკროფონზე წვდომა</translation>
 <translation id="5068553687099139861">პაროლების ჩვენება</translation>
@@ -9207,6 +9215,7 @@
 <translation id="8033958968890501070">დრო ამოიწურა</translation>
 <translation id="8035059678007243127">ქეშირებული ინკოგნიტო გვერდი უკან-წინ გადასვლის შესაძლებლობით: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">დაგვეხმარეთ, გავაუმჯობესოთ ავტომატური შევსება</translation>
+<translation id="8036504271468642248">წინა წინადადება</translation>
 <translation id="8037117027592400564">წარმოთქმული ტექსტის წაკითხვა სინთეზირებული მეტყველების გამოყენებით</translation>
 <translation id="8037357227543935929">შეკითხვა (ნაგულისხმევი)</translation>
 <translation id="803771048473350947">ფაილი</translation>
@@ -9522,6 +9531,12 @@
 <translation id="826905130698769948">კლიენტის სერტიფიკატი არასწორია</translation>
 <translation id="8270320981823560179">Drive</translation>
 <translation id="82706708334564640">ბოლოდროინდელი ჩამოტვირთვის ისტორია</translation>
+<translation id="8270946420566049889">Chrome შეგიძლიათ მოირგოთ ისე, როგორც გსურთ:
+      &lt;ul&gt;
+        &lt;li&gt;&lt;em&gt;ყველაფერი საუკეთესო Google-ისგან&lt;/em&gt; მათთვის, ვისაც ეს სურს. მაგალითად, Chrome-ის ნაგულისხმევ საძიებო სისტემად შეგიძლიათ დააყენოთ Google Search, ასევე, ისარგებლოთ Google პაროლების მმართველით, რომ თქვენი ყველა პაროლი ხელმისაწვდომი გქონდეთ ნებისმიერ მოწყობილობაზე. &lt;/li&gt;
+        &lt;li&gt;&lt;em&gt;გააზრებული არჩევანი&lt;/em&gt;: Chrome პარამეტრებთან დაკავშირებით გთავაზობთ არჩევანსა და მართვის საშუალებებს, ასევე, ინფორმაციას, რომელიც აწონ-დაწონილი გადაწყვეტილებების მიღებაში დაგეხმარებათ.&lt;/li&gt;
+        &lt;li&gt;&lt;em&gt;გაფართოებები&lt;/em&gt;: Chrome-ის ფუნქციური შესაძლებლობების გავრცობა შეგიძლიათ 100 000-ზე მეტი გაფართოების მეშვეობით <ph name="BEGIN_LINK" />Chrome Web Store<ph name="END_LINK" />-იდან.&lt;/li&gt;
+      &lt;/ul&gt;</translation>
 <translation id="827097179112817503">მთავარი გვერდის ღილაკის ჩვენება</translation>
 <translation id="8271268254812352141">მიიღეთ განმარტებები, თარგმნეთ ან გადაიყვანეთ საზომი ერთეულები ტექსტზე მარჯვენა დაწკაპუნების ან ხანგრძლივად შეხების მეშვეობით. სათარგმნი ენების მორგება <ph name="LINK_BEGIN" />ვებსაიტების ენების<ph name="LINK_END" /> სექციიდან შეგიძლიათ.</translation>
 <translation id="8271379370373330993">მშობლებო, მომდევნო რამდენიმე ნაბიჯი თქვენთვისაა. <ph name="DEVICE_TYPE" /> ბავშვს შეგიძლიათ დაუბრუნოთ ანგარიშის დაყენების შემდეგ.</translation>
@@ -10018,6 +10033,7 @@
 <translation id="8655972064210167941">შესვლა ვერ მოხერხდა, რადგან თქვენი პაროლის დადასტურება შეუძლებელია. გთხოვთ, დაუკავშირდეთ ადმინისტრატორს ან სცადოთ ხელახლა.</translation>
 <translation id="8656888282555543604">ბრაილის ჟურნალირების ჩართვა</translation>
 <translation id="8657393004602556571">გსურთ გამოხმაურების გაუქმება?</translation>
+<translation id="8657542881463614516">გამოიყენეთ გადაფურცვლის ჟესტი გვერდებს შორის ნავიგაციისთვის</translation>
 <translation id="8659608856364348875">კონტაქტები ფუნქციიდან „<ph name="FEATURE_NAME" />“</translation>
 <translation id="8661290697478713397">ბმულის გახსნა ინკო&amp;გნიტო ფანჯარაში</translation>
 <translation id="8662671328352114214">„<ph name="TYPE" />“ ქსელში გაწევრიანება</translation>
@@ -10393,6 +10409,7 @@
 <translation id="8931713990831679796">ეს პრინტერები დაკავშირებულია და გამოსაყენებლად მზად არის. მარტივი წვდომისთვის შეინახეთ თქვენს პროფილში.</translation>
 <translation id="8932654652795262306">მყისიერი ტეტერინგის დეტალები</translation>
 <translation id="893298445929867520">კალათები დამალულია. ისინი გამოჩნდება, როცა ცვლილებებს შეიტანთ.</translation>
+<translation id="8933314208895863334">ქუქი-ჩანაწერებია გაამდიდრებს თქვენს ონლაინ გამოცდილებას, ნებას დართავს რა ვებსაიტებს, შემოგთავაზონ სასარგებლო ფუნქციები</translation>
 <translation id="8933960630081805351">ჩ&amp;ვენება მაძიებელში</translation>
 <translation id="8934585454328207858">{NUM_EXTENSION,plural, =1{<ph name="EXTENSION1" />-ს წვდომა აქვს USB მოწყობილობებზე}=2{შემდეგ გაფართოებებს წვდომა აქვს მოწყობილობებზე: <ph name="EXTENSION1" />, <ph name="EXTENSION2" />}other{შემდეგ გაფართოებებს წვდომა აქვს მოწყობილობებზე: <ph name="EXTENSION1" />, <ph name="EXTENSION2" /> და {3} სხვა}}</translation>
 <translation id="8934732568177537184">გაგრძელება</translation>
diff --git a/chrome/app/resources/generated_resources_kk.xtb b/chrome/app/resources/generated_resources_kk.xtb
index 377b6d38..759284e2 100644
--- a/chrome/app/resources/generated_resources_kk.xtb
+++ b/chrome/app/resources/generated_resources_kk.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">Файлдарды өзгерту</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Файлды ашу мүмкін емес}other{Файлдарды ашу мүмкін емес}}</translation>
 <translation id="1282311502488501110">Кірмеу</translation>
-<translation id="1282465000333679776">Жүйе аудиосын бөлісу</translation>
 <translation id="1283126956823499975">Құрылғы параметрлерін реттеуге қатысты бірдеңе дұрыс болмады</translation>
 <translation id="1284277788676816155">Деректерді сақтауға рұқсат бермеу</translation>
 <translation id="1285320974508926690">Бұл сайтты ешқашан аудармау</translation>
@@ -1048,7 +1047,6 @@
 <translation id="1781502536226964113">Жаңа қойынды бетін ашу</translation>
 <translation id="1781553166608855614">Сөйлеу тілі</translation>
 <translation id="1781771911845953849">Аккаунттар және синхрондау</translation>
-<translation id="1781979858217752599">Терезе аудиосын бөлісу</translation>
 <translation id="1782101999402987960">Әкімші жаңартуларды бөгеген.</translation>
 <translation id="1782196717298160133">Телефоныңызды табу</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 ескертпе}other{# ескертпе}}</translation>
@@ -1612,7 +1610,6 @@
 <translation id="2187895286714876935">Сервер сертификатын импорттау қатесі</translation>
 <translation id="2187906491731510095">Кеңейтімдер жаңартылды</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> ашыңыз</translation>
-<translation id="2189787291884708275">Қойынды аудиосын бөлісу</translation>
 <translation id="2190069059097339078">WiFi Credentials Getter</translation>
 <translation id="219008588003277019">Native Client модулі: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(бос)</translation>
@@ -5282,6 +5279,7 @@
 <translation id="4998430619171209993">Қосулы</translation>
 <translation id="4999804342505941663">Мазаламау режимін қосу</translation>
 <translation id="5001526427543320409">Үшінші тарап cookie файлдары</translation>
+<translation id="5003993274120026347">Келесі сөйлем</translation>
 <translation id="5005498671520578047">Құпия сөзді көшіру</translation>
 <translation id="5006118752738286774">2 жыл бұрын</translation>
 <translation id="5006218871145547804">Crostini жүйесіндегі Android қолданбаларына арналған ADB құралы</translation>
@@ -9201,6 +9199,7 @@
 <translation id="8033958968890501070">Уақыт өтіп кетті</translation>
 <translation id="8035059678007243127">Алға-артқа өту кэшінде сақталған инкогнито беті: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Автотолтыруды жақсартуға көмектесіңіз</translation>
+<translation id="8036504271468642248">Алдыңғы сөйлем</translation>
 <translation id="8037117027592400564">Синтезделген сөйлеу арқылы айтылған барлық мәтінді оқу</translation>
 <translation id="8037357227543935929">Сұрау (әдепкі)</translation>
 <translation id="803771048473350947">Файл</translation>
diff --git a/chrome/app/resources/generated_resources_km.xtb b/chrome/app/resources/generated_resources_km.xtb
index 64bec49..c6881be 100644
--- a/chrome/app/resources/generated_resources_km.xtb
+++ b/chrome/app/resources/generated_resources_km.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">កែ​ឯកសារ</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{មិនអាចបើកឯកសារបានទេ}other{មិនអាចបើកឯកសារបានទេ}}</translation>
 <translation id="1282311502488501110">កុំ​ចូលគណនី</translation>
-<translation id="1282465000333679776">ចែករំលែក​សំឡេង​ប្រព័ន្ធ</translation>
 <translation id="1283126956823499975">មានអ្វីមួយ​ខុសប្រក្រតីពាក់ព័ន្ធនឹងការរៀបចំឧបករណ៍</translation>
 <translation id="1284277788676816155">កុំអនុញ្ញាត​ឱ្យរក្សាទុក​ទិន្នន័យ</translation>
 <translation id="1285320974508926690">មិនបកប្រែគេហទំព័រនេះទៀតឡើយ</translation>
@@ -1062,7 +1061,6 @@
 <translation id="1781502536226964113">បើកនៅក្នុងទំព័រផ្ទាំងថ្មី</translation>
 <translation id="1781553166608855614">ភាសានិយាយ</translation>
 <translation id="1781771911845953849">គណនី និង​ការធ្វើសមកាលកម្ម</translation>
-<translation id="1781979858217752599">ចែករំលែក​សំឡេង​វិនដូ</translation>
 <translation id="1782101999402987960">ការដំឡើងកំណែ​ត្រូវបាន​ទប់ស្កាត់​ដោយអ្នកគ្រប់គ្រង​របស់អ្នក</translation>
 <translation id="1782196717298160133">ការស្វែងរកទូរស័ព្ទរបស់អ្នក</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{កំណត់ចំណាំ 1}other{កំណត់ចំណាំ #}}</translation>
@@ -1627,7 +1625,6 @@
 <translation id="2187895286714876935">កំហុសឆ្គងការនាំចូលវិញ្ញាបនប័ត្រម៉ាស៊ីនមេ</translation>
 <translation id="2187906491731510095">បាន​ដំឡើង​ជំនាន់​កម្មវិធី​បន្ថែម​</translation>
 <translation id="2188881192257509750">បើក <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">ចែករំលែក​សំឡេង​របស់ផ្ទាំង</translation>
 <translation id="2190069059097339078">កម្មវិធីទទួលព័ត៌មានសម្គាល់អត្តសញ្ញាណ WiFi</translation>
 <translation id="219008588003277019">ម៉ូឌុលអតិថិជនដើម៖ <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(ទទេ)</translation>
@@ -5301,6 +5298,7 @@
 <translation id="4998430619171209993">បើក</translation>
 <translation id="4999804342505941663">បើកមុខងារកុំរំខាន</translation>
 <translation id="5001526427543320409">ខូគី​ភាគីទីបី</translation>
+<translation id="5003993274120026347">ប្រយោគ​បន្ទាប់</translation>
 <translation id="5005498671520578047">ថតចម្លងពាក្យសម្ងាត់</translation>
 <translation id="5006118752738286774">2 ឆ្នាំមុន</translation>
 <translation id="5006218871145547804">ADB សម្រាប់កម្មវិធី Android នៅក្នុង Crostini</translation>
@@ -9225,6 +9223,7 @@
 <translation id="8033958968890501070">អស់​ម៉ោង</translation>
 <translation id="8035059678007243127">ទំព័រឯកជនដែលបានរក្សាទុកក្នុង​ឃ្លាំងបម្រុងទុក​ទំព័រក្នុងសភាពដើម​ទាំងស្រុង៖ <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">ជួយកែលម្អការ​បំពេញស្វ័យប្រវត្តិ</translation>
+<translation id="8036504271468642248">ប្រយោគ​មុន</translation>
 <translation id="8037117027592400564">អានអត្ថបទនិយាយទាំងអស់ដោយការប្រើការនិយាយដែលបានសំយោគ</translation>
 <translation id="8037357227543935929">សួរ (លំនាំដើម)</translation>
 <translation id="803771048473350947">ឯកសារ</translation>
diff --git a/chrome/app/resources/generated_resources_kn.xtb b/chrome/app/resources/generated_resources_kn.xtb
index a6c14fd5..01ba9830 100644
--- a/chrome/app/resources/generated_resources_kn.xtb
+++ b/chrome/app/resources/generated_resources_kn.xtb
@@ -385,7 +385,6 @@
 <translation id="1280965841156951489">ಫೈಲ್‌ಗಳನ್ನು ಎಡಿಟ್ ಮಾಡಿ</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ಫೈಲ್ ತೆರೆಯಲು ಸಾಧ್ಯವಿಲ್ಲ}one{ಫೈಲ್‌ಗಳನ್ನು ತೆರೆಯಲು ಸಾಧ್ಯವಿಲ್ಲ}other{ಫೈಲ್‌ಗಳನ್ನು ತೆರೆಯಲು ಸಾಧ್ಯವಿಲ್ಲ}}</translation>
 <translation id="1282311502488501110">ಸೈನ್ ಇನ್ ಮಾಡಬೇಡಿ</translation>
-<translation id="1282465000333679776">ಸಿಸ್ಟಂ ಆಡಿಯೊವನ್ನು ಹಂಚಿಕೊಳ್ಳಿ</translation>
 <translation id="1283126956823499975">ಸಾಧನವನ್ನು ಸೆಟಪ್ ಮಾಡುವಾಗ ಏನೋ ತಪ್ಪಾಗಿದೆ</translation>
 <translation id="1284277788676816155">ಡೇಟಾವನ್ನು ಉಳಿಸಲು ಅನುಮತಿಸಬೇಡಿ</translation>
 <translation id="1285320974508926690">ಈ ಸೈಟ್ ಅನ್ನು ಎಂದಿಗೂ ಭಾಷಾಂತರಿಸದಿರಿ</translation>
@@ -1056,7 +1055,6 @@
 <translation id="1781502536226964113">ಹೊಸ ಟ್ಯಾಬ್ ಪುಟವನ್ನು ತೆರೆ</translation>
 <translation id="1781553166608855614">ಮಾತನಾಡುವ ಭಾಷೆ</translation>
 <translation id="1781771911845953849">ಖಾತೆಗಳು ಮತ್ತು ಸಿಂಕ್</translation>
-<translation id="1781979858217752599">ವಿಂಡೋ ಆಡಿಯೊವನ್ನು ಹಂಚಿಕೊಳ್ಳಿ</translation>
 <translation id="1782101999402987960">ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಅಪ್‌ಡೇಟ್‌ಗಳನ್ನು ನಿರ್ಬಂಧಿಸಿದ್ದಾರೆ</translation>
 <translation id="1782196717298160133">ನಿಮ್ಮ ಫೋನ್‌ ಹುಡುಕಲಾಗುತ್ತಿದೆ</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 ಟಿಪ್ಪಣಿ}one{# ಟಿಪ್ಪಣಿಗಳು}other{# ಟಿಪ್ಪಣಿಗಳು}}</translation>
@@ -1620,7 +1618,6 @@
 <translation id="2187895286714876935">ಸರ್ವರ್ ಪ್ರಮಾಣಪತ್ರದ ಆಮದು ದೋಷ</translation>
 <translation id="2187906491731510095">ವಿಸ್ತರಣೆಗಳನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಲಾಗಿದೆ</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> ತೆರೆಯಿರಿ</translation>
-<translation id="2189787291884708275">ಟ್ಯಾಬ್ ಆಡಿಯೋ ಹಂಚಿಕೊಳ್ಳಿ</translation>
 <translation id="2190069059097339078">ವೈಫೈ ರುಜುವಾತುಗಳ ಪಡೆಯುವಿಕೆ</translation>
 <translation id="219008588003277019">ಸ್ಥಳೀಯ ಕ್ಲೈಂಟ್ ಮಾಡ್ಯೂಲ್: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(ಖಾಲಿ)</translation>
@@ -5295,6 +5292,7 @@
 <translation id="4998430619171209993">ಆನ್‌</translation>
 <translation id="4999804342505941663">ಅಡಚಣೆ ಮಾಡಬೇಡ ಆನ್ ಮಾಡಿ</translation>
 <translation id="5001526427543320409">ಥರ್ಡ್-ಪಾರ್ಟಿ ಕುಕಿಗಳು</translation>
+<translation id="5003993274120026347">ಮುಂದಿನ ವಾಕ್ಯ</translation>
 <translation id="5005498671520578047">ಪಾಸ್‌ವರ್ಡ್ ನಕಲಿಸಿ</translation>
 <translation id="5006118752738286774">2 ವರ್ಷಗಳ ಹಿಂದೆ</translation>
 <translation id="5006218871145547804">Crostini Android ಆ್ಯಪ್ ADB</translation>
@@ -9219,6 +9217,7 @@
 <translation id="8033958968890501070">ಅವಧಿ ಮೀರಿದೆ</translation>
 <translation id="8035059678007243127">ಅಜ್ಞಾತ ಬ್ಯಾಕ್-ಫಾರ್ವರ್ಡ್ ಕ್ಯಾಷ್ ಮಾಡಿದ ಪುಟ: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">ಆಟೋಫಿಲ್ ಅನ್ನು ಸುಧಾರಿಸಲು ಸಹಾಯ ಮಾಡಿ</translation>
+<translation id="8036504271468642248">ಹಿಂದಿನ ವಾಕ್ಯ</translation>
 <translation id="8037117027592400564">ಸಂಯೋಜನೆ ಗೊಳಿಸಿದ ಧ್ವನಿಯನ್ನು ಬಳಸಿಕೊಂಡು ಮಾತನಾಡುವ ಎಲ್ಲಾ ಪಠ್ಯವನ್ನು ಓದಿ</translation>
 <translation id="8037357227543935929">ಕೇಳಿ (ಡಿಫಾಲ್ಟ್)</translation>
 <translation id="803771048473350947">ಫೈಲ್</translation>
diff --git a/chrome/app/resources/generated_resources_ko.xtb b/chrome/app/resources/generated_resources_ko.xtb
index c8f37eb..81feec89 100644
--- a/chrome/app/resources/generated_resources_ko.xtb
+++ b/chrome/app/resources/generated_resources_ko.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">파일 수정</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{파일을 열 수 없음}other{파일을 열 수 없음}}</translation>
 <translation id="1282311502488501110">로그인 안함</translation>
-<translation id="1282465000333679776">시스템 오디오 공유</translation>
 <translation id="1283126956823499975">기기를 설정하는 중에 문제가 발생했습니다</translation>
 <translation id="1284277788676816155">데이터 저장 허용 안 함</translation>
 <translation id="1285320974508926690">이 사이트 번역 안함</translation>
@@ -1062,7 +1061,6 @@
 <translation id="1781502536226964113">새 탭 페이지 열기</translation>
 <translation id="1781553166608855614">음성 언어</translation>
 <translation id="1781771911845953849">계정 및 동기화</translation>
-<translation id="1781979858217752599">창 오디오 공유</translation>
 <translation id="1782101999402987960">관리자가 업데이트를 차단했습니다.</translation>
 <translation id="1782196717298160133">휴대전화 찾는 중</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{메모 1개}other{매모 #개}}</translation>
@@ -1628,7 +1626,6 @@
 <translation id="2187895286714876935">서버 인증서 가져오기 오류</translation>
 <translation id="2187906491731510095">확장 프로그램 업데이트됨</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> 열기</translation>
-<translation id="2189787291884708275">탭 오디오 공유</translation>
 <translation id="2190069059097339078">WiFi 사용자 인증 정보 Getter</translation>
 <translation id="219008588003277019">네이티브 클라이언트 모듈: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(비어있음)</translation>
@@ -5301,6 +5298,7 @@
 <translation id="4998430619171209993">사용</translation>
 <translation id="4999804342505941663">방해 금지 모드 사용 설정</translation>
 <translation id="5001526427543320409">서드 파티 쿠키</translation>
+<translation id="5003993274120026347">다음 문장</translation>
 <translation id="5005498671520578047">비밀번호 복사</translation>
 <translation id="5006118752738286774">2년 전</translation>
 <translation id="5006218871145547804">Crostini Android 앱 ADB</translation>
@@ -9226,6 +9224,7 @@
 <translation id="8033958968890501070">시간 초과</translation>
 <translation id="8035059678007243127">시크릿 모드 뒤로-앞으로 캐시 페이지: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">자동 완성 개선에 참여하기</translation>
+<translation id="8036504271468642248">이전 문장</translation>
 <translation id="8037117027592400564">음성 출력 기능을 사용한 모든 음성 텍스트 조회</translation>
 <translation id="8037357227543935929">요청(기본값)</translation>
 <translation id="803771048473350947">파일</translation>
diff --git a/chrome/app/resources/generated_resources_ky.xtb b/chrome/app/resources/generated_resources_ky.xtb
index 3831a55e..0899019 100644
--- a/chrome/app/resources/generated_resources_ky.xtb
+++ b/chrome/app/resources/generated_resources_ky.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Файлдарды түзөтүү</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Файл ачылбай жатат}other{Файлдар ачылбай жатат}}</translation>
 <translation id="1282311502488501110">Кирбейм</translation>
-<translation id="1282465000333679776">Системанын аудиосун бөлүшүү</translation>
 <translation id="1283126956823499975">Түзмөктү тууралоодо ката кетти</translation>
 <translation id="1284277788676816155">Маалыматты сактоого тыюу салуу</translation>
 <translation id="1285320974508926690">Бул сайт эч качан которулбасын</translation>
@@ -1062,7 +1061,6 @@
 <translation id="1781502536226964113">Жаңы өтмөк бетин ачуу</translation>
 <translation id="1781553166608855614">Колдонулуучу тилдер</translation>
 <translation id="1781771911845953849">Аккаунттар жана шайкештирүү</translation>
-<translation id="1781979858217752599">Терезенин аудиосун бөлүшүү</translation>
 <translation id="1782101999402987960">Жаңыртуулар администраторуңуз тарабынан бөгөттөлгөн</translation>
 <translation id="1782196717298160133">Телефонуңуз изделүүдө</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 кыска жазуу}other{# кыска жазуу}}</translation>
@@ -1627,7 +1625,6 @@
 <translation id="2187895286714876935">Сервердин тастыктамасын импорттоо катасы.</translation>
 <translation id="2187906491731510095">Кеңейтүүлөр жаңырды</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> колдонмосун ачуу</translation>
-<translation id="2189787291884708275">Өтмөктүн аудиосун бөлүшүү</translation>
 <translation id="2190069059097339078">WiFi Credentials Getter</translation>
 <translation id="219008588003277019">Native Client модулу: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(бош)</translation>
@@ -5301,6 +5298,7 @@
 <translation id="4998430619171209993">Күйүк</translation>
 <translation id="4999804342505941663">"Тынчымды алба" режимин күйгүзүү</translation>
 <translation id="5001526427543320409">Үчүнчү тараптын cookie файлдары</translation>
+<translation id="5003993274120026347">Кийинки сүйлөм</translation>
 <translation id="5005498671520578047">Сырсөздү көчүрүү</translation>
 <translation id="5006118752738286774">2 жыл мурун</translation>
 <translation id="5006218871145547804">Crostini Android колдонмосунун ADB</translation>
@@ -9224,6 +9222,7 @@
 <translation id="8033958968890501070">Убакыт аяктады</translation>
 <translation id="8035059678007243127">Кештелген жашыруун барак: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Автотолтурууну жакшыртууга жардам бериңиз</translation>
+<translation id="8036504271468642248">Мурунку сүйлөм</translation>
 <translation id="8037117027592400564">Кеп синтезаторунун жардамы менен, бардык айтылган текстти окуңуз</translation>
 <translation id="8037357227543935929">Суроо (демейки)</translation>
 <translation id="803771048473350947">Файл</translation>
diff --git a/chrome/app/resources/generated_resources_lo.xtb b/chrome/app/resources/generated_resources_lo.xtb
index 03d3c12..07f0520 100644
--- a/chrome/app/resources/generated_resources_lo.xtb
+++ b/chrome/app/resources/generated_resources_lo.xtb
@@ -15,6 +15,7 @@
 <translation id="1006873397406093306">ສ່ວນຂະຫຍາຍນີ້ສາມາດອ່ານ ແລະ ປ່ຽນແປງຂໍ້ມູນໃນເວັບໄຊໄດ້. ທ່ານສາມາດຄວບຄຸມວ່າຈະໃຫ້ສ່ວນຂະຫຍາຍເຂົ້າເຖິງເວັບໄຊໃດແດ່ໄດ້.</translation>
 <translation id="1007057452468855774">ເປີດ Google Play Store</translation>
 <translation id="1008186147501209563">ສົ່ງບຸກມາກອອກ</translation>
+<translation id="1008209036711323236">ນັ້ນແມ່ນເຫດຜົນທີ່ວ່າ Chrome ກໍາລັງວາງແຜນທີ່ຈະຢຸດການໃຊ້ "ຄຸກກີ້ພາກສ່ວນທີສາມ" ເມື່ອພວກເຮົາແກ້ໄຂຄວາມກັງວົນດ້ານການແຂ່ງຂັນທີ່ຍັງເຫຼືອຂອງ <ph name="BEGIN_LINK" />ອົງການການແຂ່ງຂັນ ແລະ ການຕະຫຼາດຂອງ UK (CMA)<ph name="END_LINK" />.</translation>
 <translation id="1008261151167010035"><ph name="BRAND" /> ຈະຈື່ວິທີທີ່ທ່ານເຂົ້າສູ່ລະບົບ ແລະ ຈະເຂົ້າສູ່ລະບົບໃຫ້ທ່ານໂດຍອັດຕະໂນມັດເມື່ອເປັນໄປໄດ້. ເມື່ອປິດການຕັ້ງຄ່ານີ້, ລະບົບຈະຂໍໃຫ້ທ່ານຢືນຢັນທຸກໆເທື່ອ.</translation>
 <translation id="1008544602823861396">ຖືກບລັອກບໍ່ໃຫ້ໃຊ້ຂໍ້ມູນຂອງທ່ານຢູ່</translation>
 <translation id="1008557486741366299">ບໍ່ແມ່ນດຽວນີ້</translation>
@@ -384,7 +385,6 @@
 <translation id="1280965841156951489">ແກ້ໄຂໄຟລ໌</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ບໍ່ສາມາດເປີດໄຟລ໌ໄດ້}other{ບໍ່ສາມາດເປີດໄຟລ໌ໄດ້}}</translation>
 <translation id="1282311502488501110">ຢ່າເຂົ້າສູ່ລະບົບ</translation>
-<translation id="1282465000333679776">ແບ່ງປັນສຽງລະບົບ</translation>
 <translation id="1283126956823499975">ມີບາງຢ່າງຜິດພາດເກີດຂຶ້ນກັບການຕັ້ງຄ່າອຸປະກອນ</translation>
 <translation id="1284277788676816155">ບໍ່ອະນຸຍາດໃຫ້ບັນທຶກຂໍ້ມູນ</translation>
 <translation id="1285320974508926690">ຢ່າແປເວັບ​ໄຊ​ທ໌ນີ້</translation>
@@ -867,6 +867,7 @@
     <ph name="BEGIN_PARAGRAPH2" />ທ່ານສາມາດປິດບໍລິການນີ້ໄດ້ໃນການຕັ້ງຄ່າ.<ph name="END_PARAGRAPH2" /></translation>
 <translation id="1637224376458524414">ໃຊ້ບຸກມາກນີ້ໃນ iPhone ຂອງທ່ານ</translation>
 <translation id="1637765355341780467">ມີບາງຢ່າງຜິດພາດ ໃນເວລາເປີດໂປຣໄຟລ໌ຂອງທ່ານ. ບາງຄຸນສົມບັດອາດຈະບໍ່ສາມາດໃຊ້ໄດ້.</translation>
+<translation id="1637830036924985819">ບາງເທື່ອເວັບໄຊໃຊ້ຄຸກກີ້ໃນວິທີທີ່ພວກມັນບໍ່ໄດ້ຕັ້ງໃຈໃນເບື້ອງຕົ້ນ</translation>
 <translation id="1639239467298939599">ກໍາລັງໂຫຼດ</translation>
 <translation id="1640235262200048077"><ph name="IME_NAME" /> ໃຊ້ບໍ່ໄດ້ໃນແອັບ Linux ເທື່ອ</translation>
 <translation id="1640283014264083726">PKCS #1 MD4 ດ້ວຍການໃສ່ລະຫັດ RSA</translation>
@@ -1038,6 +1039,7 @@
 <translation id="1767508543310534319">ສຽງສະທ້ອນຂອງເຄື່ອງໝາຍວັກຕອນ</translation>
 <translation id="1768212860412467516">ສົ່ງຄຳຕິຊົມສຳລັບ <ph name="EXPERIMENT_NAME" /></translation>
 <translation id="1769104665586091481">ເປີດ​ລິ້ງຢູ່​ໃນໜ້າ​ຕ່າງ​ໃຫມ່</translation>
+<translation id="1769157454356586138">ສະແກນບໍ່ສຳເລັດ. ໄຟລ໌ນີ້ຖືກບລັອກໄວ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ</translation>
 <translation id="1770407692401984718">ລາກຮູບມາໃສ່ບ່ອນນີ້ ຫຼື</translation>
 <translation id="177053719077591686">ສຳຮອງຂໍ້ມູນແອັບ Android ໄປໃສ່ Google Drive.</translation>
 <translation id="1771075623623424448">ຊອກຫາໜ້າບັນທຶກອຸປະກອນຂອງໂປຣແກຣມທ່ອງເວັບບໍ? ເຂົ້າເບິ່ງ<ph name="BEGIN_LINK" /><ph name="CHROME_DEVICE_LOG_LINK" /><ph name="END_LINK" />.</translation>
@@ -1060,7 +1062,6 @@
 <translation id="1781502536226964113">ເປີດໜ້າແຖບໃໝ່</translation>
 <translation id="1781553166608855614">ພາສາເວົ້າ</translation>
 <translation id="1781771911845953849">ບັນຊີ ແລະ ການຊິ້ງຂໍ້ມູນ</translation>
-<translation id="1781979858217752599">ແບ່ງປັນສຽງໜ້າຈໍ</translation>
 <translation id="1782101999402987960">ອັບເດດຖືກບລັອກໄວ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ</translation>
 <translation id="1782196717298160133">ການຊອກ​ຫາ​ໂທລະ​ສັບ​ຂອງ​ທ່ານ</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 ບັນທຶກ}other{# ບັນທຶກ}}</translation>
@@ -1625,7 +1626,6 @@
 <translation id="2187895286714876935">ການນໍາໃບຢັ້ງຢືນເຊີບເວີເຂົ້າຜິດພາດ</translation>
 <translation id="2187906491731510095">ອັບເດດສ່ວນຂະຫຍາຍແລ້ວ</translation>
 <translation id="2188881192257509750">ເປີດ <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">ແບ່ງປັນສຽງແຖບ</translation>
 <translation id="2190069059097339078">ຕົວຮັບເອົາຂໍ້ມູນສະເພາະ WiFi</translation>
 <translation id="219008588003277019">ໂມດູນລູກຂ່າຍເດີມ: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(ເປົ່າ​ຫວ່າງ​)</translation>
@@ -2130,6 +2130,7 @@
 <translation id="2542050502251273923">ຕັ້ງຄ່າລະດັບການດີບັກຂອງຕົວຈັດການເຊື່ອມຕໍ່ເຄືອຂ່າຍ ແລະ ການບໍລິການອື່ນໂດຍໃຊ້ ff_debug.</translation>
 <translation id="2543780089903485983">{NUM_SUB_APP_INSTALLS,plural, =1{ການອະນຸຍາດທີ່ທ່ານມອບໃຫ້ກັບ "<ph name="APP_NAME" />" ຈະອະນຸຍາດແອັບນີ້ນຳ. <ph name="MANAGE_LINK" />}other{ການອະນຸຍາດທີ່ທ່ານມອບໃຫ້ກັບ "<ph name="APP_NAME" />" ຈະອະນຸຍາດແອັບເຫຼົ່ານີ້ນຳ. <ph name="MANAGE_LINK" />}}</translation>
 <translation id="2544352060595557290">ແຖບນີ້</translation>
+<translation id="2545743249923338554">ແຖບໃໝ່</translation>
 <translation id="2546302722632337735">ບໍ່ອະນຸຍາດໃຫ້ເວັບໄຊໃຊ້ຕົວລະບຸເພື່ອຫຼິ້ນເນື້ອຫາທີ່ມີການປົກປ້ອງ</translation>
 <translation id="2546991196809436099">ຊູມເຂົ້າເພື່ອເຮັດໃຫ້ລາຍການຕ່າງໆຢູ່ໜ້າຈໍໃຫຍ່ຂຶ້ນ. ໃຊ້ຊອກຫາ + Ctrl + M ເພື່ອເປີດ ແລະ ປິດແວ່ນຂະຫຍາຍ.</translation>
 <translation id="2548347166720081527">ອະນຸຍາດ <ph name="PERMISSION" /> ແລ້ວ</translation>
@@ -2684,6 +2685,7 @@
 <translation id="2967926928600500959">URL ທີ່ກົງກັບກົດລະບຽບເຫຼົ່ານີ້ຈະຖືກບັງຄັບໃຫ້ເປີດໃນໂປຣແກຣມທ່ອງເວັບສະເພາະ.</translation>
 <translation id="2969411787010981955">ສົ່ງຂໍ້ມູນອອກໄປໃສ່ສະຖານທີ່ທີ່ເລືອກໄວ້ແລ້ວ</translation>
 <translation id="2970766364519518369">ລາຍຊື່ຜູ້ຕິດຕໍ່ທີ່ເລືອກສາມາດແບ່ງປັນກັບທ່ານໄດ້ເມື່ອເຂົາເຈົ້າຢູ່ໃກ້ຄຽງ. ທ່ານຈະຖືກຖາມໃຫ້ອະນຸມັດຄຳຮ້ອງຂໍເຫຼົ່ານີ້. ທ່ານບໍ່ຈຳເປັນຕ້ອງອະນຸມັດການແບ່ງປັນລະຫວ່າງອຸປະກອນທີ່ເຂົ້າສູ່ລະບົບຫາ <ph name="USER_EMAIL" />.</translation>
+<translation id="2971514543824815520">ທ່ານອາດຈໍາເປັນຕ້ອງຣີສະຕາດແອັບຂອງທ່ານເພື່ອໃຫ້ການປ່ຽນແປງເຄີເຊີມີຜົນ</translation>
 <translation id="2972557485845626008">ເຟີມແວ</translation>
 <translation id="2972581237482394796">ເຮັດຄືນ</translation>
 <translation id="2973324205039581528">ປິດສຽງເວັບໄຊ</translation>
@@ -2800,6 +2802,7 @@
 <translation id="3046910703532196514">ໜ້າເວັບສໍາ​ເລັດ</translation>
 <translation id="304747341537320566">ໂປຣແກຣມສຽງເວົ້າ</translation>
 <translation id="3048336643003835855">ອຸປະກອນ HID ຈາກຜູ້ຂາຍ <ph name="VENDOR_ID" /></translation>
+<translation id="3048742847101793553">ອົງກອນຂອງທ່ານໄດ້ບລັອກໄຟລ໌ນີ້ເນື່ອງຈາກການສະແກນບໍ່ສຳເລັດ.</translation>
 <translation id="3048917188684939573">ບັນທຶກການສົ່ງສັນຍານ ແລະ ອຸປະກອນ</translation>
 <translation id="3051250416341590778">ຂະໜາດສະແດງຜົນ</translation>
 <translation id="3053013834507634016">ການໃຊ້ລະຫັດໃບຢັ້ງຢືນ</translation>
@@ -2880,6 +2883,7 @@
 <translation id="3117791853215125017">{COUNT,plural, =1{ສົ່ງ <ph name="ATTACHMENTS" /> ໄປຍັງ <ph name="DEVICE_NAME" /> ບໍ່ສຳເລັດ}other{ສົ່ງ <ph name="ATTACHMENTS" /> ໄປຍັງ <ph name="DEVICE_NAME" /> ບໍ່ສຳເລັດ}}</translation>
 <translation id="3118319026408854581">ຊ່ວຍ​ເຫຼືອ <ph name="PRODUCT_NAME" /></translation>
 <translation id="3118748462829336648">ເປີດແຜງຄວບຄຸມດ້ານຂ້າງ</translation>
+<translation id="3119743309973425629">ອັດຕາກະພິບຂອງເຄີເຊີຂໍ້ຄວາມ</translation>
 <translation id="3119948370277171654">ເນື້ອຫາ/URL ໃດທີ່ທ່ານກຳລັງສົ່ງສັນຍານ?</translation>
 <translation id="3122464029669770682">CPU</translation>
 <translation id="3122496702278727796">ສ້າງໄດເຣັກຕໍຣີຂໍ້ມູນບໍ່ສໍາເລັດ</translation>
@@ -3734,6 +3738,7 @@
 <translation id="3783889407390048282">ເພີ່ມພື້ນທີ່ຫວ່າງເພື່ອຫຼີກເວັ້ນການສູນເສຍສິດເຂົ້າເຖິງ Android.</translation>
 <translation id="3785308913036335955">ສະ​ແດງ​ທາງລັດແອັບ</translation>
 <translation id="3785727820640310185">ລະຫັດຜ່ານທີ່ບັນທຶກໄວ້ສຳລັບເວັບໄຊນີ້</translation>
+<translation id="3785748905555897481">ປ່ຽນລະຫັດ PIN ສຳເລັດແລ້ວ</translation>
 <translation id="3786224729726357296">ລຶບຂໍ້ມູນເວັບໄຊ ແລະ ການອະນຸຍາດສຳລັບ <ph name="SITE" /> ອອກ</translation>
 <translation id="3786834302860277193">ສະແດງຂີດກ້ອງສຳລັບຂໍ້ຄວາມປະກອບ</translation>
 <translation id="3787434344076711519">ກຳລັງລໍຖ້າການແປພາສາ</translation>
@@ -4395,6 +4400,7 @@
 <translation id="428963538941819373">ເວັບໄຊເຫຼົ່ານີ້ສາມາດໃຊ້ຂໍ້ມູນທີ່ພວກມັນບັນທຶກໄວ້ກ່ຽວກັບທ່ານໄດ້ໃນເວລາທ່ານເລືອກເບິ່ງ <ph name="HOST" /></translation>
 <translation id="4289732974614035569">ເລືອກ PIN</translation>
 <translation id="4290791284969893584">ຫຼັງຈາກການປິດໜ້າໃດໜຶ່ງ, ໜ້າວຽກທີ່ທ່ານເລີ່ມຕົ້ນໄວ້ອາດບໍ່ແລ້ວ</translation>
+<translation id="4290898381118933198">ປັດເພື່ອນຳທາງລະຫວ່າງໜ້າ</translation>
 <translation id="4291265871880246274">ກ່ອງໂຕ້​ຕອບການເຂົ້າສູ່ລະບົບ</translation>
 <translation id="429234155571566255">ສູດທີ່ເບິ່ງຫຼ້າສຸດເຫຼົ່ານີ້</translation>
 <translation id="429312253194641664">ເວັບໄຊກຳລັງຫຼິ້ນສື່ຢູ່</translation>
@@ -5300,6 +5306,7 @@
 <translation id="4998430619171209993">ເປີດ</translation>
 <translation id="4999804342505941663">ເປີດໂໝດຫ້າມລົບກວນ</translation>
 <translation id="5001526427543320409">ຄຸກກີ້ພາກສ່ວນທີສາມ</translation>
+<translation id="5003993274120026347">ປະໂຫຍດຕໍ່ໄປ</translation>
 <translation id="5005498671520578047">ອັດ​ສຳ​ເນົາ​ລະ​ຫັດ​ຜ່ານ</translation>
 <translation id="5006118752738286774">2 ປີກ່ອນ</translation>
 <translation id="5006218871145547804">ADB ຂອງແອັບ Android ໃນ Crostini</translation>
@@ -5374,6 +5381,7 @@
 <translation id="5063480226653192405">ການນໍາໃຊ້</translation>
 <translation id="5065775832226780415">Smart Lock</translation>
 <translation id="5066100345385738837">ຈັດການ DNS ທີ່ປອດໄພໃນການຕັ້ງຄ່າ ChromeOS</translation>
+<translation id="5066534201484101197">ເລື່ອນກາຍເພື່ອນຳທາງລະຫວ່າງໜ້າ</translation>
 <translation id="5067399438976153555">ເປີດ​ສະ​ເໝີ​ໄປ</translation>
 <translation id="5067867186035333991">ຖາມ​ເບິ່ງວ່າ <ph name="HOST" /> ຕ້ອງ​ການ​​ເຂົ້າຫາໄມໂຄຣໂຟນຂອງ​ທ່ານບໍ່</translation>
 <translation id="5068553687099139861">ສະແດງລະຫັດຜ່ານ</translation>
@@ -9220,6 +9228,7 @@
 <translation id="8033958968890501070">ໝົດເວລາ</translation>
 <translation id="8035059678007243127">ໜ້າແຄສຍ້ອນຫຼັງແບບບໍ່ເປີດເຜີຍຕົວຕົນ: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">ຊ່ວຍປັບປຸງການຕື່ມຂໍ້ມູນອັດຕະໂນມັດ</translation>
+<translation id="8036504271468642248">ປະໂຫຍກກ່ອນໜ້າ</translation>
 <translation id="8037117027592400564">ອ່ານຂໍ້ຄວາມທັງໝົດທີ່ໄດ້ເວົ້າໃນລະຫວ່າງການໃຊ້ຄໍາເວົ້າທີ່ຊິງໂຄຣໄນແລ້ວ</translation>
 <translation id="8037357227543935929">ຖາມ (ຄ່າເລີ່ມຕົ້ນ)</translation>
 <translation id="803771048473350947">ໄຟລ໌</translation>
@@ -9535,6 +9544,12 @@
 <translation id="826905130698769948">ໃບຮັບຮອງລູກຂ່າຍບໍ່ຖືກຕ້ອງ</translation>
 <translation id="8270320981823560179">Drive</translation>
 <translation id="82706708334564640">ປະຫວັດການດາວໂຫຼດຫຼ້າສຸດ</translation>
+<translation id="8270946420566049889">ທ່ານສາມາດປັບແຕ່ງ Chrome ຕາມທີ່ທ່ານຕ້ອງການໄດ້:
+      &lt;ul&gt;
+        &lt;li&gt;&lt;em&gt;ສິ່ງທີ່ດີທີ່ສຸດຂອງ Google&lt;/em&gt;, ສຳລັບຜູ້ທີ່ຕ້ອງການມັນ. ຕົວຢ່າງ: ທ່ານສາມາດເລືອກ Google ຊອກຫາໃຫ້ເປັນໂປຣແກຣມຊອກຫາເລີ່ມຕົ້ນຂອງ Chrome ແລະ ໃຊ້ຕົວຈັດການລະຫັດຜ່ານ Google ເພື່ອຮັບເອົາລະຫັດຜ່ານທັງໝົດຂອງທ່ານຢູ່ອຸປະກອນໃດກໍໄດ້. &lt;/li&gt;
+        &lt;li&gt;&lt;em&gt;ທາງເລືອກທີ່ມີຄວາມໝາຍ&lt;/em&gt;: Chrome ສະເໜີທາງເລືອກ ແລະ ການຄວບຄຸມໃຫ້ທ່ານດ້ວຍການຕັ້ງຄ່າ ແລະ ຂໍ້ມູນເພື່ອຊ່ວຍໃຫ້ທ່ານຕັດສິນໃຈແບບມີຄວາມໝາຍ.&lt;/li&gt;
+        &lt;li&gt;&lt;em&gt;ສ່ວນຂະຫຍາຍ&lt;/em&gt;: ທ່ານສາມາດຂະຫຍາຍການເຮັດວຽກຂອງ Chrome ດ້ວຍຫຼາຍກວ່າ 100,000 ສ່ວນຂະຫຍາຍໃນ <ph name="BEGIN_LINK" />Chrome Web Store<ph name="END_LINK" />.&lt;/li&gt;
+      &lt;/ul&gt;</translation>
 <translation id="827097179112817503">ສະແດງປຸ່ມໜ້າ​ຫຼັກ</translation>
 <translation id="8271268254812352141">ຮັບຄຳນິຍາມ, ການແປພາສາ ຫຼື ການປ່ຽນແປງຫົວໜ່ວຍເມື່ອທ່ານຄລິກຂວາ ຫຼື ແຕະໃສ່ຂໍ້ຄວາມຄ້າງໄວ້. ປັບແຕ່ງພາສາສຳລັບການແປໃນ <ph name="LINK_BEGIN" />ພາສາເວັບໄຊ<ph name="LINK_END" />.</translation>
 <translation id="8271379370373330993">ຮຽນພໍ່ແມ່, ຂັ້ນຕອນສອງສາມຢ່າງຕໍ່ໄປແມ່ນສຳລັບທ່ານ. ທ່ານສາມາດສົ່ງ <ph name="DEVICE_TYPE" /> ຄືນໃຫ້ເດັກໄດ້ຫຼັງຈາກຕັ້ງຄ່າບັນຊີແລ້ວ.</translation>
@@ -10031,6 +10046,7 @@
 <translation id="8655972064210167941">ລົງຊື່ເຂົ້າໃຊ້​ບໍ່​ສຳ​ເລັດ ເພາະ​ວ່າ​ລະ​ຫັດ​ຜ່ານ​ຂອງ​ທ່ານ​ບໍ່​ສາ​ມາດ​ຢືນ​ຢັນ​ໄດ້. ກະ​ລຸ​ນາ​ຕິດ​ຕໍ່​ຜູ້ຄວບຄຸມຂອງທ່ານ ຫຼື ລອງໃໝ່ອີກ.</translation>
 <translation id="8656888282555543604">ເປີດນຳໃຊ້ການບັນທຶກອັກສອນນູນ</translation>
 <translation id="8657393004602556571">ທ່ານຕ້ອງການຍົກເລີກຄຳຕິຊົມບໍ?</translation>
+<translation id="8657542881463614516">ໃຊ້ທ່າທາງປັດເພື່ອນຳທາງລະຫວ່າງໜ້າ</translation>
 <translation id="8659608856364348875">ລາຍຊື່ຜູ້ຕິດຕໍ່ <ph name="FEATURE_NAME" /></translation>
 <translation id="8661290697478713397">ເປີດລິ້ງຢູ່ໃນໜ້າ​ຕ່າງທີ່ບໍ່ເຜີຍຕົນຕົວ</translation>
 <translation id="8662671328352114214">ເຂົ້າຮ່ວມເຄືອຂ່າຍ <ph name="TYPE" /></translation>
@@ -10406,6 +10422,7 @@
 <translation id="8931713990831679796">ເຄື່ອງພິມເຫຼົ່ານີ້ເຊື່ອມຕໍ່ແລ້ວ ແລະ ພ້ອມນຳໃຊ້. ບັນທຶກໃສ່ໂປຣໄຟລ໌ຂອງທ່ານເພື່ອໃຫ້ເຂົ້າເຖິງໄດ້ງ່າຍຂຶ້ນ.</translation>
 <translation id="8932654652795262306">ລາຍລະອຽດການປ່ອຍສັນຍານທັນທີ</translation>
 <translation id="893298445929867520">ເຊື່ອງກະຕ່າໄວ້ແລ້ວ. ພວກມັນຈະປາກົດຂຶ້ນມາອີກເມື່ອທ່ານສ້າງການປ່ຽນແປງ.</translation>
+<translation id="8933314208895863334">ຄຸກກີ້ສາມາດຍົກລະດັບປະສົບການໃນການທ່ອງເວັບອອນລາຍຂອງທ່ານ, ຊ່ວຍໃຫ້ເວັບໄຊຕ່າງໆນຳສະເໜີຄຸນສົມບັດທີ່ເປັນປະໂຫຍດໃຫ້ກັບທ່ານໄດ້</translation>
 <translation id="8933960630081805351">ສະແດງຢູ່ໃນຕົວຊອກ​ຫາ</translation>
 <translation id="8934585454328207858">{NUM_EXTENSION,plural, =1{<ph name="EXTENSION1" /> ກຳລັງເຂົ້າເຖິງອຸປະກອນ USB}=2{ສ່ວນຂະຫຍາຍທີ່ເຂົ້າເຖິງອຸປະກອນ: <ph name="EXTENSION1" />, <ph name="EXTENSION2" />}other{ສ່ວນຂະຫຍາຍທີ່ເຂົ້າເຖິງອຸປະກອນ: <ph name="EXTENSION1" />, <ph name="EXTENSION2" /> ແລະ ອີກ {3} ລາຍການ}}</translation>
 <translation id="8934732568177537184">ສືບຕໍ່</translation>
diff --git a/chrome/app/resources/generated_resources_lt.xtb b/chrome/app/resources/generated_resources_lt.xtb
index 5e3f180..80ca2602 100644
--- a/chrome/app/resources/generated_resources_lt.xtb
+++ b/chrome/app/resources/generated_resources_lt.xtb
@@ -387,7 +387,6 @@
 <translation id="1280965841156951489">Redaguoti failus</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Nepavyksta atidaryti failo}one{Nepavyksta atidaryti failų}few{Nepavyksta atidaryti failų}many{Nepavyksta atidaryti failų}other{Nepavyksta atidaryti failų}}</translation>
 <translation id="1282311502488501110">Neprisijungti</translation>
-<translation id="1282465000333679776">Bendrinti sistemos garso įrašą</translation>
 <translation id="1283126956823499975">Nustatant įrenginį kilo problema</translation>
 <translation id="1284277788676816155">Neleisti išsaugoti duomenų</translation>
 <translation id="1285320974508926690">Niekada neversti šios svetainės</translation>
@@ -1065,7 +1064,6 @@
 <translation id="1781502536226964113">Atidaryti naujo skirtuko puslapį</translation>
 <translation id="1781553166608855614">Kalba, kuria kalbama</translation>
 <translation id="1781771911845953849">Paskyros ir sinchronizavimas</translation>
-<translation id="1781979858217752599">Bendrinti lango garso įrašą</translation>
 <translation id="1782101999402987960">Naujinius užblokavo administratorius</translation>
 <translation id="1782196717298160133">Telefono paieška</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{Vienas užrašas}one{# užrašas}few{# užrašai}many{# užrašo}other{# užrašų}}</translation>
@@ -1630,7 +1628,6 @@
 <translation id="2187895286714876935">Serverio sertifikato importavimo klaida</translation>
 <translation id="2187906491731510095">Plėtiniai atnaujinti</translation>
 <translation id="2188881192257509750">Atidaryti „<ph name="APPLICATION" />“</translation>
-<translation id="2189787291884708275">Bendrinti skirtuko garso įrašą</translation>
 <translation id="2190069059097339078">„Wi-Fi“ prisijungimo duomenų atsisiuntimo priemonė</translation>
 <translation id="219008588003277019">Vietinio kliento modulis: „<ph name="NEXE_NAME" />“</translation>
 <translation id="2190355936436201913">(tuščias)</translation>
@@ -5304,6 +5301,7 @@
 <translation id="4998430619171209993">Įjungta</translation>
 <translation id="4999804342505941663">Įjungti netrukdymo režimą</translation>
 <translation id="5001526427543320409">Trečiųjų šalių slapukai</translation>
+<translation id="5003993274120026347">Kitas sakinys</translation>
 <translation id="5005498671520578047">Kopijuoti slaptažodį</translation>
 <translation id="5006118752738286774">Prieš dvejus metus</translation>
 <translation id="5006218871145547804">„Android“ programų ADB „Crostini“</translation>
@@ -9236,6 +9234,7 @@
 <translation id="8033958968890501070">Skirtojo laiko pabaiga</translation>
 <translation id="8035059678007243127">Ilgalaikis viso inkognito puslapio saugojimas talpykloje: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Padėkite tobulinti Automatinio pildymo paslaugą</translation>
+<translation id="8036504271468642248">Ankstesnis sakinys</translation>
 <translation id="8037117027592400564">Skaityti visą tekstą sintezuota kalba</translation>
 <translation id="8037357227543935929">Klausti (numatytoji parinktis)</translation>
 <translation id="803771048473350947">Failas</translation>
diff --git a/chrome/app/resources/generated_resources_lv.xtb b/chrome/app/resources/generated_resources_lv.xtb
index 9692d73..9c2e1af1 100644
--- a/chrome/app/resources/generated_resources_lv.xtb
+++ b/chrome/app/resources/generated_resources_lv.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Rediģēt failus</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Nevar atvērt failu}zero{Nevar atvērt failus}one{Nevar atvērt failus}other{Nevar atvērt failus}}</translation>
 <translation id="1282311502488501110">Nepierakstīties</translation>
-<translation id="1282465000333679776">Kopīgot sistēmas audio</translation>
 <translation id="1283126956823499975">Iestatot šo ierīci, radās problēma</translation>
 <translation id="1284277788676816155">Neatļaut saglabāt datus</translation>
 <translation id="1285320974508926690">Nekad netulkot šo vietni</translation>
@@ -1053,7 +1052,6 @@
 <translation id="1781502536226964113">Atvērt Jaunas cilnes lapu</translation>
 <translation id="1781553166608855614">Runas valoda</translation>
 <translation id="1781771911845953849">Konti un sinhronizācija</translation>
-<translation id="1781979858217752599">Kopīgot loga audio</translation>
 <translation id="1782101999402987960">Jūsu administrators ir bloķējis atjauninājumus</translation>
 <translation id="1782196717298160133">Tālruņa atrašana</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 piezīme}zero{# piezīmju}one{# piezīme}other{# piezīmes}}</translation>
@@ -1617,7 +1615,6 @@
 <translation id="2187895286714876935">Servera sertifikāta importēšanas kļūda</translation>
 <translation id="2187906491731510095">Paplašinājumi ir atjaunināti</translation>
 <translation id="2188881192257509750">Atvērt lietojumprogrammu <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Kopīgot cilnes audio</translation>
 <translation id="2190069059097339078">Wi-Fi akreditācijas datu ieguvējs</translation>
 <translation id="219008588003277019">Native Client modulis: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(tukšs)</translation>
@@ -5287,6 +5284,7 @@
 <translation id="4998430619171209993">Ieslēgts</translation>
 <translation id="4999804342505941663">Ieslēgt režīmu “Netraucēt”</translation>
 <translation id="5001526427543320409">Trešo pušu sīkfaili</translation>
+<translation id="5003993274120026347">Nākamais teikums</translation>
 <translation id="5005498671520578047">Paroles kopēšana</translation>
 <translation id="5006118752738286774">Pirms 2 gadiem</translation>
 <translation id="5006218871145547804">Android–Chromebook ierīču savienojums Crostini Android lietotnēm</translation>
@@ -9212,6 +9210,7 @@
 <translation id="8033958968890501070">Noildze</translation>
 <translation id="8035059678007243127">Pilnīgas saglabāšanas kešatmiņā saglabātā inkognito lapa:<ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Palīdzēt uzlabot automātisko aizpildi</translation>
+<translation id="8036504271468642248">Iepriekšējais teikums</translation>
 <translation id="8037117027592400564">Lasīt visu tekstu, kas izrunāts, izmantojot sintezēto runu</translation>
 <translation id="8037357227543935929">Vaicāt (pēc noklusējuma)</translation>
 <translation id="803771048473350947">Fails</translation>
diff --git a/chrome/app/resources/generated_resources_mk.xtb b/chrome/app/resources/generated_resources_mk.xtb
index 39e6867..1dc2a89 100644
--- a/chrome/app/resources/generated_resources_mk.xtb
+++ b/chrome/app/resources/generated_resources_mk.xtb
@@ -385,7 +385,6 @@
 <translation id="1280965841156951489">Измени датотеки</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Датотеката не може да се отвори}one{Датотеките не може да се отворат}other{Датотеките не може да се отворат}}</translation>
 <translation id="1282311502488501110">Не се најавувај</translation>
-<translation id="1282465000333679776">Сподели аудио од системот</translation>
 <translation id="1283126956823499975">Нешто тргна наопаку со поставувањето на уредот</translation>
 <translation id="1284277788676816155">Не дозволувај да се зачувуваат податоци</translation>
 <translation id="1285320974508926690">Никогаш не преведувај ја оваа локација</translation>
@@ -1063,7 +1062,6 @@
 <translation id="1781502536226964113">Отвори ја страницата Нова картичка</translation>
 <translation id="1781553166608855614">Говорен јазик</translation>
 <translation id="1781771911845953849">Сметки и синхронизација</translation>
-<translation id="1781979858217752599">Сподели аудио од прозорецот</translation>
 <translation id="1782101999402987960">Администраторот ги блокирал ажурирањата</translation>
 <translation id="1782196717298160133">Се бара вашиот телефон</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 белешка}one{# белешка}other{# белешки}}</translation>
@@ -1628,7 +1626,6 @@
 <translation id="2187895286714876935">Грешка при увезување сертификат на сервер</translation>
 <translation id="2187906491731510095">Ажурирани екстензии</translation>
 <translation id="2188881192257509750">Отвори <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Сподели аудио од картичката</translation>
 <translation id="2190069059097339078">WiFi Credentials Getter</translation>
 <translation id="219008588003277019">Модул на матичен клиент: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(празно)</translation>
@@ -5302,6 +5299,7 @@
 <translation id="4998430619171209993">Вклучено</translation>
 <translation id="4999804342505941663">Вклучете „Не вознемирувај“</translation>
 <translation id="5001526427543320409">Колачиња од трети страни</translation>
+<translation id="5003993274120026347">Следна реченица</translation>
 <translation id="5005498671520578047">Копирање лозинка</translation>
 <translation id="5006118752738286774">Пред 2 години</translation>
 <translation id="5006218871145547804">ADB за апликации на Android за Crostini</translation>
@@ -9227,6 +9225,7 @@
 <translation id="8033958968890501070">Истекување</translation>
 <translation id="8035059678007243127">Инкогнито страница за кеш за движење наназад/нанапред: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Помогнете да се подобри автоматското пополнување</translation>
+<translation id="8036504271468642248">Претходна реченица</translation>
 <translation id="8037117027592400564">Прочитајте го текстот што се изговара со помош на синтетизиран говор.</translation>
 <translation id="8037357227543935929">Прашај (стандардно)</translation>
 <translation id="803771048473350947">Датотека</translation>
diff --git a/chrome/app/resources/generated_resources_ml.xtb b/chrome/app/resources/generated_resources_ml.xtb
index 66d5660..6603f91 100644
--- a/chrome/app/resources/generated_resources_ml.xtb
+++ b/chrome/app/resources/generated_resources_ml.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">ഫയലുകൾ എഡിറ്റ് ചെയ്യുക</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ഫയൽ തുറക്കാനാകുന്നില്ല}other{ഫയലുകൾ തുറക്കാനാകുന്നില്ല}}</translation>
 <translation id="1282311502488501110">സൈൻ ഇൻ ചെയ്യരുത്</translation>
-<translation id="1282465000333679776">സിസ്റ്റം ഓഡിയോ പങ്കിടുക</translation>
 <translation id="1283126956823499975">ഉപകരണം സജ്ജീകരിക്കുന്നതിൽ എന്തോ പിശകുണ്ടായി</translation>
 <translation id="1284277788676816155">ഡാറ്റ സംരക്ഷിക്കാൻ അനുവദിക്കരുത്</translation>
 <translation id="1285320974508926690">ഈ സൈറ്റ് ഒരിക്കലും വിവര്‍‌ത്തനം ചെയ്യരുത്</translation>
@@ -1050,7 +1049,6 @@
 <translation id="1781502536226964113">പുതിയ ടാബ് പേജ് തുറക്കുക</translation>
 <translation id="1781553166608855614">സംഭാഷണ ഭാഷ</translation>
 <translation id="1781771911845953849">അക്കൗണ്ടുകളും സമന്വയവും</translation>
-<translation id="1781979858217752599">വിൻഡോ ഓഡിയോ പങ്കിടുക</translation>
 <translation id="1782101999402987960">അപ്ഡേറ്റുകൾ നിങ്ങളുടെ അഡ്‌മിൻ ബ്ലോക്ക് ചെയ്തു</translation>
 <translation id="1782196717298160133">നിങ്ങളുടെ ഫോൺ കണ്ടെത്തുന്നു</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{ഒരു കുറിപ്പ്}other{# കുറിപ്പുകള്‍}}</translation>
@@ -1614,7 +1612,6 @@
 <translation id="2187895286714876935">സെര്‍വര്‍ സാക്ഷ്യപത്ര ഇറക്കുമതി പിശക്</translation>
 <translation id="2187906491731510095">വിപുലീകരണങ്ങൾ അപ്‌ഡേറ്റ് ചെയ്‌തു</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> തുറക്കുക</translation>
-<translation id="2189787291884708275">ടാബ് ഓഡിയോ പങ്കിടുക</translation>
 <translation id="2190069059097339078">WiFi ക്രെഡൻഷ്യലുകൾ ലഭ്യമാക്കൽ</translation>
 <translation id="219008588003277019">നേറ്റീവ് ക്ലയന്‍റ് മൊഡ്യൂള്‍‌: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(ശൂന്യം)</translation>
@@ -5283,6 +5280,7 @@
 <translation id="4998430619171209993">ഓണാണ്</translation>
 <translation id="4999804342505941663">'ശല്യപ്പെടുത്തരുത്' ഓണാക്കുക</translation>
 <translation id="5001526427543320409">മൂന്നാം-കക്ഷി കുക്കികൾ</translation>
+<translation id="5003993274120026347">അടുത്ത വാചകം</translation>
 <translation id="5005498671520578047">പാസ്‌വേഡ് പകർത്തുക</translation>
 <translation id="5006118752738286774">2 വർഷം മുമ്പ്</translation>
 <translation id="5006218871145547804">Crostini Android ആപ്പ് ADB</translation>
@@ -9208,6 +9206,7 @@
 <translation id="8033958968890501070">കാലഹരണപ്പെട്ടു</translation>
 <translation id="8035059678007243127">അദൃശ്യ ബാക്ക്-ഫോർവേഡ് കാഷെ പേജ്: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">സ്വയമേവ പൂരിപ്പിക്കൽ മെച്ചപ്പെടുത്താൻ സഹായിക്കുക</translation>
+<translation id="8036504271468642248">മുമ്പത്തെ വാചകം</translation>
 <translation id="8037117027592400564">സംശ്ലേഷിച്ച സംഭാഷണം ഉപയോഗിക്കുന്ന എല്ലാ ടെക്സ്റ്റ് സംഭാഷണവും റീഡുചെയ്യുക</translation>
 <translation id="8037357227543935929">ചോദിക്കുക (ഡിഫോൾട്ട്)</translation>
 <translation id="803771048473350947">ഫയല്‍</translation>
diff --git a/chrome/app/resources/generated_resources_mn.xtb b/chrome/app/resources/generated_resources_mn.xtb
index 4185eca1..ea4f2ca 100644
--- a/chrome/app/resources/generated_resources_mn.xtb
+++ b/chrome/app/resources/generated_resources_mn.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Файлуудыг засах</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Файлыг нээх боломжгүй}other{Файлуудыг нээх боломжгүй}}</translation>
 <translation id="1282311502488501110">Бүү нэвтэр</translation>
-<translation id="1282465000333679776">Системийн аудиог хуваалцах</translation>
 <translation id="1283126956823499975">Төхөөрөмжийг тохируулах үед ямар нэг алдаа гарлаа</translation>
 <translation id="1284277788676816155">Өгөгдөл хадгалахыг зөвшөөрөхгүй</translation>
 <translation id="1285320974508926690">Энэ сайтыг хэзээ ч бүү хөрвүүл</translation>
@@ -1058,7 +1057,6 @@
 <translation id="1781502536226964113">Шинэ цонхыг нээ</translation>
 <translation id="1781553166608855614">Текстээс яриа</translation>
 <translation id="1781771911845953849">Бүртгэл болон синк</translation>
-<translation id="1781979858217752599">Цонхны аудиог хуваалцах</translation>
 <translation id="1782101999402987960">Шинэчлэлтийг танай администратор блоклосон байна</translation>
 <translation id="1782196717298160133">Таны утсыг олж байна</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 тэмдэглэл}other{# тэмдэглэл}}</translation>
@@ -1623,7 +1621,6 @@
 <translation id="2187895286714876935">Серверийн Гэрчилгээг Импортлох үеийн алдаа</translation>
 <translation id="2187906491731510095">Өргөтгөлийг шинэчилсэн</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" />-г нээх</translation>
-<translation id="2189787291884708275">Табын аудио хуваалцах</translation>
 <translation id="2190069059097339078">WiFi үнэмлэх авагч</translation>
 <translation id="219008588003277019">Байнгын Үйлчлүүлэгчийн модуль: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(Хоосон)</translation>
@@ -5296,6 +5293,7 @@
 <translation id="4998430619171209993">Асаалттай</translation>
 <translation id="4999804342505941663">Бүү саад бол онцлогийг асаах</translation>
 <translation id="5001526427543320409">Гуравдагч талын күүки</translation>
+<translation id="5003993274120026347">Дараагийн өгүүлбэр</translation>
 <translation id="5005498671520578047">Нууц үг хуулах</translation>
 <translation id="5006118752738286774">2 жилийн өмнө</translation>
 <translation id="5006218871145547804">Crostini-н Андройд аппын ADB</translation>
@@ -9217,6 +9215,7 @@
 <translation id="8033958968890501070">Хугацаа хэтэрсэн</translation>
 <translation id="8035059678007243127">Нууцлалтай Back/Forward Cache хийсэн хуудас: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Автоматаар бөглөх хэсгийг сайжруулахад тусална уу</translation>
+<translation id="8036504271468642248">Өмнөх өгүүлбэр</translation>
 <translation id="8037117027592400564">Нэгтгэсэн яриаг ашиглан яригдсан бүх текстийг унш</translation>
 <translation id="8037357227543935929">Асуух (өгөгдмөл)</translation>
 <translation id="803771048473350947">Файл</translation>
diff --git a/chrome/app/resources/generated_resources_mr.xtb b/chrome/app/resources/generated_resources_mr.xtb
index f960be54..d7a4073 100644
--- a/chrome/app/resources/generated_resources_mr.xtb
+++ b/chrome/app/resources/generated_resources_mr.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">फाइल संपादित करा</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{फाइल उघडू शकत नाही}other{फाइल उघडू शकत नाही}}</translation>
 <translation id="1282311502488501110">साइन इन करू नका</translation>
-<translation id="1282465000333679776">सिस्टम ऑडिओ शेअर करा</translation>
 <translation id="1283126956823499975">डिव्हाइस सेट करताना काहीतरी चुकले</translation>
 <translation id="1284277788676816155">डेटा सेव्ह करण्याची अनुमती देऊ नका</translation>
 <translation id="1285320974508926690">या साइटचा कधीही भाषांतर करु नका</translation>
@@ -1061,7 +1060,6 @@
 <translation id="1781502536226964113">नवे टॅब पेज उघडा</translation>
 <translation id="1781553166608855614">बोली भाषा</translation>
 <translation id="1781771911845953849">खाती आणि सिंक</translation>
-<translation id="1781979858217752599">विंडो ऑडिओ शेअर करा</translation>
 <translation id="1782101999402987960">तुमच्या अ‍ॅडमिनिस्ट्रेटरने अपडेट ब्लॉक केले आहेत</translation>
 <translation id="1782196717298160133">तुमचा फोन शोधणे</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{एक टीप}other{# टिपा}}</translation>
@@ -1626,7 +1624,6 @@
 <translation id="2187895286714876935">सर्व्हर सर्टिफिकेट आयात एरर</translation>
 <translation id="2187906491731510095">विस्तार अपडेट केले</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> उघडा</translation>
-<translation id="2189787291884708275">टॅब ऑडिओ शेअर करा</translation>
 <translation id="2190069059097339078">WiFi क्रेडेंशियल मिळविणारा</translation>
 <translation id="219008588003277019">नेटिव्ह क्लायंट मॉड्युल: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(रिक्त)</translation>
@@ -5298,6 +5295,7 @@
 <translation id="4998430619171209993">सुरू</translation>
 <translation id="4999804342505941663">व्यत्यय आणू नका सुरू करा</translation>
 <translation id="5001526427543320409">तृतीय पक्ष कुकी</translation>
+<translation id="5003993274120026347">पुढील वाक्य</translation>
 <translation id="5005498671520578047">पासवर्ड कॉपी करा</translation>
 <translation id="5006118752738286774">दोन वर्षांपूर्वी</translation>
 <translation id="5006218871145547804">Crostini Android अ‍ॅप ADB</translation>
@@ -9222,6 +9220,7 @@
 <translation id="8033958968890501070">वेळ संपली</translation>
 <translation id="8035059678007243127">बॅक/फॉरवर्ड कॅशे केलेले गुप्त पेज: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">ऑटोफिल यामध्ये सुधारणा करण्यात मदत करा</translation>
+<translation id="8036504271468642248">मागील वाक्य</translation>
 <translation id="8037117027592400564">संकालित भाषण वापरून बोललेला सर्व मजकूर वाचा</translation>
 <translation id="8037357227543935929">विचारा (डीफॉल्ट)</translation>
 <translation id="803771048473350947">फाइल</translation>
diff --git a/chrome/app/resources/generated_resources_ms.xtb b/chrome/app/resources/generated_resources_ms.xtb
index 19956fc04..c1dc31c 100644
--- a/chrome/app/resources/generated_resources_ms.xtb
+++ b/chrome/app/resources/generated_resources_ms.xtb
@@ -18,6 +18,7 @@
 <translation id="1008261151167010035"><ph name="BRAND" /> mengingat cara anda log masuk dan secara automatik akan log masuk anda jika dibolehkan. Apabila tetapan dimatikan, anda akan diminta untuk memberikan pengesahan setiap kali sebelum log masuk.</translation>
 <translation id="1008544602823861396">disekat daripada menggunakan maklumat anda pada</translation>
 <translation id="1008557486741366299">Bukan Sekarang</translation>
+<translation id="100881991356161927">Nama laman</translation>
 <translation id="1009663062402466586">Kini kawalan permainan tersedia</translation>
 <translation id="1010833424573920260">{NUM_PAGES,plural, =1{Halaman Tidak Responsif}other{Halaman Tidak Responsif}}</translation>
 <translation id="1011003645819296594">Peranti disimpan</translation>
@@ -133,6 +134,7 @@
 <translation id="1093457606523402488">Rangkaian Kelihatan:</translation>
 <translation id="1093645050124056515">ctrl + alt + anak panah ke bawah</translation>
 <translation id="1094219634413363886">Anda akan menerima pemberitahuan jika rakaman dimulakan pada peranti terurus ini</translation>
+<translation id="1095557482034465422">Semak kebenaran laman pada <ph name="BEGIN_LINK_PERMISSIONS" /><ph name="PERMISSIONS" /><ph name="END_LINK_PERMISSIONS" /></translation>
 <translation id="1095761715416917775">Pastikan anda dapat mengakses data penyegerakan anda pada bila-bila masa</translation>
 <translation id="1095879482467973146">Google Password Manager pada web</translation>
 <translation id="109647177154844434">Tindakan menyahpasang Parallels Desktop akan memadamkan imej Windows anda. Ini termasuk aplikasi, tetapan dan data yang berkaitan. Anda pasti mahu meneruskan?</translation>
@@ -384,7 +386,6 @@
 <translation id="1280965841156951489">Edit fail</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Tidak dapat membuka fail}other{Tidak dapat membuka fail}}</translation>
 <translation id="1282311502488501110">Jangan Log Masuk</translation>
-<translation id="1282465000333679776">Kongsi audio sistem</translation>
 <translation id="1283126956823499975">Ada masalah ketika menyediakan peranti</translation>
 <translation id="1284277788676816155">Jangan benarkan penyimpanan data</translation>
 <translation id="1285320974508926690">Jangan sekali-kali menterjemahkan tapak ini</translation>
@@ -596,6 +597,7 @@
 <translation id="1454223536435069390">A&amp;mbil tangkapan skrin</translation>
 <translation id="145432137617179457">Bahasa semak ejaan</translation>
 <translation id="1455119378540982311">Saiz tetingkap pratetapan</translation>
+<translation id="1456849775870359518">Tab anda akan dibuka semula</translation>
 <translation id="1457907785077086338">Warna lencana apl</translation>
 <translation id="146000042969587795">Bingkai ini disekat kerana ia mengandungi beberapa kandungan selamat.</translation>
 <translation id="1461041542809785877">Prestasi</translation>
@@ -1062,7 +1064,6 @@
 <translation id="1781502536226964113">Buka halaman Tab Baharu</translation>
 <translation id="1781553166608855614">Bahasa pertuturan</translation>
 <translation id="1781771911845953849">Akaun dan penyegerakan</translation>
-<translation id="1781979858217752599">Kongsi audio tetingkap</translation>
 <translation id="1782101999402987960">Kemaskinian disekat oleh pentadbir anda</translation>
 <translation id="1782196717298160133">Mencari telefon anda</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 Nota}other{# Nota}}</translation>
@@ -1196,6 +1197,7 @@
 <translation id="187145082678092583">Kurang apl</translation>
 <translation id="1871534214638631766">Tunjukkan maklumat yang berkaitan apabila anda mengklik kanan atau menekan lama pada kandungan</translation>
 <translation id="1871615898038944731"><ph name="DEVICE_TYPE" /> anda sudah dikemas kini</translation>
+<translation id="1873513359268939357">Kalendar Outlook</translation>
 <translation id="1873920700418191231">Berikan kebenaran sekali lagi untuk <ph name="WEBSITE" /></translation>
 <translation id="1874248162548993294">Dibenarkan untuk memaparkan sebarang iklan</translation>
 <translation id="1874874185178737347">Susun Tab</translation>
@@ -1627,7 +1629,6 @@
 <translation id="2187895286714876935">Ralat Import Sijil Pelayan</translation>
 <translation id="2187906491731510095">Sambungan dikemas kini</translation>
 <translation id="2188881192257509750">Buka <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Kongsi audio tab</translation>
 <translation id="2190069059097339078">Pengutip Bukti Kelayakan WiFi</translation>
 <translation id="219008588003277019">Modul Klien Asli: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(kosong)</translation>
@@ -1653,6 +1654,7 @@
 <translation id="2210462644007531147">Tidak dapat menyelesaikan pemasangan</translation>
 <translation id="2211043920024403606">Maklumat profil</translation>
 <translation id="2211245494465528624">Urus pilihan penyegerakan</translation>
+<translation id="221297410904507041">Padamkan sejarah, kuki, cache dan pelbagai lagi</translation>
 <translation id="2214018885812055163">Folder kongsi</translation>
 <translation id="2214893006758804920">{LINE_COUNT,plural, =1{&lt;1 garisan tidak ditunjukkan&gt;}other{&lt;<ph name="NUMBER_OF_LINES" /> garisan tidak ditunjukkan&gt;}}</translation>
 <translation id="2215070081105889450">Kongsi tab atau skrin untuk berkongsi audio</translation>
@@ -1980,6 +1982,12 @@
 <translation id="2444874983932528148">Sambung semula pada tempat anda berhenti dengan mudah</translation>
 <translation id="2445081178310039857">Direktori akar sambungan adalah diperlukan.</translation>
 <translation id="2445484935443597917">Buat Profil Baharu</translation>
+<translation id="2445702184865563439">Maklumat ini mungkin berguna. Sebagai contoh, maklumat ini boleh membantu Chrome meningkatkan kualiti dengan memahami kepantasan halaman dimuatkan dalam keadaan yang berbeza. Berdasarkan tetapan anda, maklumat ini juga dapat:
+      &lt;ul&gt;
+        &lt;li&gt;Membantu anda menyemak imbas dengan lebih cepat. Sebagai contoh, carian Google anda pada masa lalu boleh membantu Chrome menggesa anda dengan ramalan untuk carian Google masa hadapan anda.&lt;/li&gt;
+        &lt;li&gt;Membolehkan laman mengoptimumkan pengalaman untuk peranti anda. Sebagai contoh, laman boleh menyelaraskan kandungan untuk telefon mudah alih anda dan mengingati keutamaan anda, seperti bahasa pilihan anda. &lt;/li&gt;
+        &lt;li&gt;Membantu pengiklan, termasuk Google, menyiarkan iklan yang lebih berkaitan.&lt;/li&gt;
+      &lt;/ul&gt;</translation>
 <translation id="2445726032315793326">Penggadang separa</translation>
 <translation id="244641233057214044">Berkaitan dengan carian anda</translation>
 <translation id="2447587550790814052">Kini anda boleh menggunakan Steam untuk Chromebook (Beta)</translation>
@@ -2511,6 +2519,7 @@
 <translation id="2835177225987815960">Persediaan pengimbasan semasa anda akan ditetapkan semula, termasuk sebarang suis yang ditetapkan dan keutamaan kelajuan autoimbas.</translation>
 <translation id="2835547721736623118">Perkhidmatan pengecaman pertuturan</translation>
 <translation id="2835761321523638096">Baca dan ubah masukan dalam senarai bacaan</translation>
+<translation id="2836112522909777958">Untuk memadamkan data, tutup semua tetingkap Inkognito</translation>
 <translation id="2836232638504556905">Untuk meneruskan, <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE" /> akan berkongsi nama, alamat e-mel dan gambar profil anda dengan laman ini. Lihat <ph name="BEGIN_LINK" />dasar privasi<ph name="END_LINK" /> laman ini.</translation>
 <translation id="2836269494620652131">Ranap</translation>
 <translation id="283669119850230892">Untuk menggunakan rangkaian <ph name="NETWORK_ID" />, mula-mula lengkapkan sambungan anda ke Internet di bawah.</translation>
@@ -2535,6 +2544,7 @@
 <translation id="2850541429955027218">Tambahkan tema</translation>
 <translation id="2850672011315104382">Gaya Tanda Baca</translation>
 <translation id="2853121255651601031">Kata Laluan Disimpan</translation>
+<translation id="2855243985454069333">Memadamkan sejarah daripada semua peranti yang disegerakkan</translation>
 <translation id="2855812646048059450">Log masuk dengan <ph name="CREDENTIAL_PROVIDER" /></translation>
 <translation id="2856776373509145513">Buat bekas baharu</translation>
 <translation id="2856907950922663165">Matikan penyulitan URL?</translation>
@@ -3044,6 +3054,7 @@
 <translation id="3264582393905923483">Konteks</translation>
 <translation id="3265459715026181080">Tutup Tetingkap</translation>
 <translation id="3266022278425892773">Persekitaran pembangunan Linux</translation>
+<translation id="3266030505377585301">Untuk memadamkan data semakan imbas daripada peranti ini dan menyimpan data semakan imbas tersebut dalam Google Account anda, <ph name="BEGIN_LINK" />log keluar<ph name="END_LINK" />.</translation>
 <translation id="3266274118485960573">Semakan keselamatan sedang dijalankan</translation>
 <translation id="3267726687589094446">Terus membenarkan muat turun automatik berbilang fail</translation>
 <translation id="3268451620468152448">Tab Terbuka</translation>
@@ -3238,6 +3249,7 @@
 <translation id="3424969259347320884">Terangkan Perkara Yang Sedang Anda Lakukan Semasa Ranap Tab Berlaku</translation>
 <translation id="3427092606871434483">Benarkan (lalai)</translation>
 <translation id="3429086384982427336">Apl yang disenaraikan di bawah tidak akan mengendalikan pautan protokol.</translation>
+<translation id="3429174588714165399">Buat pintasan kepada halaman ini</translation>
 <translation id="3429271624041785769">Bahasa kandungan web</translation>
 <translation id="3429275422858276529">Tandai halaman ini agar mudah dicari kemudian</translation>
 <translation id="3431715928297727378"><ph name="WINDOW_TITLE" /> - <ph name="MEMORY_VALUE" /> dikosongkan</translation>
@@ -3253,6 +3265,7 @@
 <translation id="3435738964857648380">Keselamatan</translation>
 <translation id="343578350365773421">Kehabisan kertas</translation>
 <translation id="3435896845095436175">Dayakan</translation>
+<translation id="3436545938885366107">Bayangkan anda mempunyai kafe kegemaran yang anda lawati untuk minum kopi pagi anda. Mungkin anda ialah pelanggan tetap sehingga pemilik kedai mengenali nama anda dan boleh membawakan pesanan anda, espresso berganda dengan satu gula, sebaik sahaja anda memasuki kafe tersebut.</translation>
 <translation id="3438633801274389918">Ninja</translation>
 <translation id="3439153939049640737">Sentiasa benarkan <ph name="HOST" /> mengakses mikrofon anda</translation>
 <translation id="3439970425423980614">Membuka PDF dalam Pratonton</translation>
@@ -3517,6 +3530,7 @@
 <translation id="3640214691812501263">Tambahkan "<ph name="EXTENSION_NAME" />" untuk <ph name="USER_NAME" />?</translation>
 <translation id="3640347231390550691">Lindungi kata laluan anda daripada pancingan data</translation>
 <translation id="3640613767643722554">Ajar Assistant supaya mengecam suara anda</translation>
+<translation id="364100968401221170">Untuk memadamkan data semakan imbas daripada semua peranti yang disegerakkan dan Google Account anda, <ph name="BEGIN_LINK" />log masuk<ph name="END_LINK" />.</translation>
 <translation id="3641456520301071208">Laman boleh meminta lokasi anda</translation>
 <translation id="3642070413432681490">Bulatkan kursor</translation>
 <translation id="3642699533549879077">Apabila orang lain melihat skrin anda, anda akan mendapat makluman dan kandungan pemberitahuan akan disembunyikan.</translation>
@@ -3693,6 +3707,7 @@
 <translation id="3757733214359997190">Tiada tapak ditemui</translation>
 <translation id="375841316537350618">Memuat turun skrip proksi...</translation>
 <translation id="3758887577462995665">Petua:</translation>
+<translation id="3759805539887442413">Untuk memadamkan data semakan imbas daripada semua peranti yang disegerakkan dan Google Account anda, <ph name="BEGIN_LINK" />masukkan ungkapan laluan anda<ph name="END_LINK" />.</translation>
 <translation id="3759933321830434300">Sekat sebahagian halaman web</translation>
 <translation id="3760460896538743390">Halaman Periksa &amp;Latar Belakang</translation>
 <translation id="37613671848467444">Buka dalam Tetingkap &amp;Inkognito</translation>
@@ -4591,6 +4606,7 @@
 <translation id="4432621511648257259">Kata laluan salah</translation>
 <translation id="4434611816075088065">Tiada perkara lain yang memerlukan perhatian anda sekarang</translation>
 <translation id="443475966875174318">Kemas kini atau alih keluar aplikasi yang tidak serasi</translation>
+<translation id="443503224864902151">Mengelog keluar anda dari kebanyakan laman. Anda akan kekal dilog masuk ke Google Account supaya data anda yang disegerakkan dapat dipadamkan.</translation>
 <translation id="4437947179446780764">Tambahkan penyedia perkhidmatan DNS tersuai</translation>
 <translation id="4438043733494739848">Lutsinar</translation>
 <translation id="4441124369922430666">Adakah anda ingin mulakan apl ini secara automatik apabila mesin ini dihidupkan?</translation>
@@ -4650,6 +4666,7 @@
 <translation id="4488257340342212116">Dibenarkan untuk menggunakan kamera anda</translation>
 <translation id="4490086832405043258">Gunakan tetapan proksi Chrome OS untuk profil ini.</translation>
 <translation id="4490798467014431984">Sambungan tidak dibenarkan pada laman ini</translation>
+<translation id="449102748655090594">Mengumpulkan tab anda…</translation>
 <translation id="449126573531210296">Sulitkan kata laluan yang disegerakkan menggunakan Google Account anda</translation>
 <translation id="4492265221907525667">Untuk menggunakan ciri percubaan baharu ini, sila log masuk.</translation>
 <translation id="449232563137139956">Tapak biasanya menunjukkan imej untuk memberikan ilustrasi, seperti foto untuk kedai dalam talian atau artikel berita</translation>
@@ -4683,6 +4700,7 @@
 <translation id="4510479820467554003">Senarai akaun ibu bapa</translation>
 <translation id="451102079304155829">troli</translation>
 <translation id="4511344327646819192">Untuk menghalang orang lain daripada menggunakan kata laluan anda, tukar kata laluan pada <ph name="WEBSITE" /></translation>
+<translation id="4513072860957814107">&amp;Padamkan Data Semakan Imbas...</translation>
 <translation id="4513872120116766993">Penulisan ramalan</translation>
 <translation id="4513946894732546136">Maklum balas</translation>
 <translation id="4515872537870654449">Hubungi Dell untuk penyelenggaraan. Dok akan dimatikan jika kipas tidak berfungsi.</translation>
@@ -4783,6 +4801,7 @@
 <translation id="4587589328781138893">Tapak</translation>
 <translation id="4588749726511456218">Pecutan penatalan <ph name="LINK_BEGIN" />Ketahui lebih lanjut<ph name="LINK_END" /></translation>
 <translation id="4589713469967853491">Log berjaya ditulis ke direktori Muat Turun.</translation>
+<translation id="4590785647529325123">Untuk memadamkan sejarah penyemakan imbas Inkognito daripada peranti anda, tutup semua tab Inkognito</translation>
 <translation id="459204634473266369">Tiada peranti disimpan pada <ph name="PRIMARY_EMAIL" /></translation>
 <translation id="4592891116925567110">Apl melukis stilus</translation>
 <translation id="4593021220803146968">&amp;Pergi ke <ph name="URL" /></translation>
@@ -4971,6 +4990,7 @@
 <translation id="4739639199548674512">Tiket</translation>
 <translation id="4740546261986864539">Dibuka baru-baru ini</translation>
 <translation id="4742334355511750246">Tidak dibenarkan untuk memaparkan imej</translation>
+<translation id="4742795653798179840">Data Chrome yang dipadamkan</translation>
 <translation id="4742970037960872810">Alih keluar serlahan</translation>
 <translation id="4743260470722568160"><ph name="BEGIN_LINK" />Ketahui cara mengemas kini aplikasi<ph name="END_LINK" /></translation>
 <translation id="4744268813103118742">Pergi ke Laman</translation>
@@ -5111,6 +5131,7 @@
 <translation id="4850669014075537160">Menatal</translation>
 <translation id="4850886885716139402">Lihat</translation>
 <translation id="485088796993065002">Tapak mungkin memainkan bunyi untuk memberikan audio untuk muzik, video dan media lain</translation>
+<translation id="4850919322897956733">Data dipadamkan.</translation>
 <translation id="4852383141291180386">Urus pemberitahuan apl</translation>
 <translation id="4852916668365817106">Warna tetikus</translation>
 <translation id="4853020600495124913">Buka dalam tetingkap &amp;baharu</translation>
@@ -5301,6 +5322,7 @@
 <translation id="4998430619171209993">Hidupkan</translation>
 <translation id="4999804342505941663">Hidupkan Jangan Ganggu</translation>
 <translation id="5001526427543320409">Kuki pihak ketiga</translation>
+<translation id="5003993274120026347">Ayat seterusnya</translation>
 <translation id="5005498671520578047">Salin kata laluan</translation>
 <translation id="5006118752738286774">2 tahun yang lalu</translation>
 <translation id="5006218871145547804">ADB apl Android Crostini</translation>
@@ -5466,6 +5488,7 @@
 <translation id="5130080518784460891">Eten</translation>
 <translation id="5130675701626084557">Profil tidak dapat dimuat turun. Sila cuba sebentar lagi atau hubungi pembawa untuk mendapatkan bantuan.</translation>
 <translation id="5131591206283983824">Penyeretan ketikan pad sentuh</translation>
+<translation id="5132130020119156609">Bergantung pada kebenaran laman, kuki ialah satu cara yang membolehkan laman menyimpan maklumat tentang aktiviti dalam talian anda.</translation>
 <translation id="5135533361271311778">Tidak dapat mencipta item penanda halaman.</translation>
 <translation id="513555878193063507">Tambahkan APN baharu</translation>
 <translation id="5136343472380336530">Pastikan kedua-dua peranti dibuka kunci, berada rapat di antara satu sama lain dan Bluetooth telah dihidupkan. <ph name="LINK_BEGIN" />Ketahui lebih lanjut<ph name="LINK_END" /></translation>
@@ -5506,10 +5529,17 @@
 <translation id="5160634252433617617">Papan kekunci fizikal</translation>
 <translation id="5160857336552977725">Log masuk ke <ph name="DEVICE_TYPE" /> anda</translation>
 <translation id="5161251470972801814">Peranti USB daripada <ph name="VENDOR_NAME" /></translation>
+<translation id="5161827038979306924">Apakah perbezaan antara sejarah penyemakan imbas anda dalam Chrome dengan sejarah carian anda?</translation>
 <translation id="5162905305237671850"><ph name="DEVICE_TYPE" /> telah disekat</translation>
 <translation id="5163910114647549394">Tab dialihkan ke bahagian hujung jalur tab</translation>
 <translation id="5164530241085602114">Pemberitahuan tidak dibenarkan untuk <ph name="SITE" /></translation>
 <translation id="516747639689914043">Protokol Pengangkutan Hiperteks (HTTP)</translation>
+<translation id="5170299781084543513">Selepas anda menemukan laman yang mahu diterokai, anda memutuskan (menggunakan kebenaran laman) jika laman boleh menggunakan ciri tertentu, sebagai contoh:
+      &lt;ul&gt;
+        &lt;li&gt;Gunakan Kamera peranti anda, Lokasi dan Mikrofon&lt;/li&gt;
+        &lt;li&gt;Simpan data pada peranti anda&lt;/li&gt;
+        &lt;li&gt;Sediakan ciri laman, seperti Pemberitahuan&lt;/li&gt;
+      &lt;/ul&gt;</translation>
 <translation id="5170568018924773124">Paparkan dalam folder</translation>
 <translation id="5171045022955879922">Buat carian atau taipkan URL</translation>
 <translation id="5171343362375269016">Memori Ditukar</translation>
@@ -5960,6 +5990,12 @@
 <translation id="5519900055135507385">Lindungi akaun ini dengan kata laluan kukuh. Kata laluan ini akan disimpan pada <ph name="GOOGLE_PASSWORD_MANAGER" /> untuk <ph name="EMAIL" />.</translation>
 <translation id="5521078259930077036">Adakah ini halaman utama yang anda jangkakan?</translation>
 <translation id="5522156646677899028">Sambungan ini mengandungi kelemahan keselamatan yang serius.</translation>
+<translation id="5522378895674097188">Anda boleh menyemak sejarah carian dan tetapan anda dalam <ph name="BEGIN_LINK" />Aktiviti Saya<ph name="END_LINK" />, jika:
+      &lt;ul&gt;
+        &lt;li&gt;Anda menggunakan Google Search&lt;/li&gt;
+        &lt;li&gt;Anda telah log masuk ke Google Account anda&lt;/li&gt;
+        &lt;li&gt;Anda telah menghidupkan Aktiviti Web &amp; Apl&lt;/li&gt;
+      &lt;/ul&gt;</translation>
 <translation id="5522403133543437426">Enjin carian yang digunakan dalam bar alamat.</translation>
 <translation id="5523149538118225875">{NUM_EXTENSIONS,plural, =1{Satu sambungan telah dipasang oleh pentadbir anda}other{# sambungan telah dipasang oleh pentadbir anda}}</translation>
 <translation id="5523532775593636291">Laman yang anda tambahkan akan sentiasa aktif dan memori tidak akan dikosongkan daripada laman tersebut</translation>
@@ -6256,6 +6292,7 @@
 <translation id="5758631781033351321">Anda dapat menemukan senarai bacaan anda di sini</translation>
 <translation id="5759397201362801675">Pilih perasaan</translation>
 <translation id="5759728514498647443">Dokumen yang anda hantar untuk dicetak melalui <ph name="APP_NAME" /> boleh dibaca oleh <ph name="APP_NAME" />.</translation>
+<translation id="5760318332127300368">Kosongkan data semakan imbas (<ph name="URL" />) juga, yang mungkin mengelog anda keluar dari Google.com. <ph name="LEARN_MORE" /></translation>
 <translation id="5762787084360227629">Masukkan maklumat Google Account anda</translation>
 <translation id="5763751966069581670">Tiada peranti USB ditemui</translation>
 <translation id="5764483294734785780">Si&amp;mpan audio sebagai...</translation>
@@ -6524,10 +6561,12 @@
 <translation id="5955809630138889698">Peranti ini mungkin layak untuk mod tunjuk cara dalam talian sahaja. Sila hubungi wakil sokongan anda untuk mendapatkan butiran lanjut.</translation>
 <translation id="5957987129450536192">Ketik ikon Pilih untuk Cakap berdekatan imej profil anda, kemudian pilih apa yang hendak anda dengar.</translation>
 <translation id="5959471481388474538">Rangkaian tak tersedia</translation>
+<translation id="5959982036207776176">Kanta Pembesar mengikut perkataan yang dibaca oleh pilih untuk bercakap</translation>
 <translation id="5963413905009737549">Bahagian</translation>
 <translation id="5963453369025043595"><ph name="NUM_HANDLES" /> (<ph name="NUM_KILOBYTES_LIVE" /> puncak)</translation>
 <translation id="5964113968897211042">{COUNT,plural, =0{Buka semua dalam tetingkap &amp;baharu}=1{Buka dalam tetingkap &amp;baharu}other{Buka semua ({COUNT}) dalam tetingkap &amp;baharu}}</translation>
 <translation id="5964247741333118902">Kandungan terbenam</translation>
+<translation id="5965607173855879702">Memadamkan data...</translation>
 <translation id="5966511985653515929">Data laman dipadamkan daripada peranti anda apabila anda menutup semua tetingkap</translation>
 <translation id="5968022600320704045">Tiada hasil carian</translation>
 <translation id="5969364029958154283">Ketahui lebih lanjut tentang menetapkan semula tetapan</translation>
@@ -6993,6 +7032,7 @@
 <translation id="6318125393809743217">Sertakan fail policies.json dengan konfigurasi dasar.</translation>
 <translation id="6318407754858604988">Muat turun dimulakan</translation>
 <translation id="6318944945640833942">Tidak dapat mengesan pencetak. Sila masukkan alamat pencetak sekali lagi.</translation>
+<translation id="6319278239690147683">Untuk memadamkan data semakan imbas daripada semua peranti yang disegerakkan dan Google Account anda, <ph name="BEGIN_LINK" />lawati tetapan penyegerakan<ph name="END_LINK" />.</translation>
 <translation id="6319476488490641553">Ruang pada peranti ini tidak mencukupi untuk memasang kemaskinian ini. Kosongkan <ph name="NECESSARY_SPACE" /> pada peranti anda dan cuba lagi.</translation>
 <translation id="6322370287306604163">Buka kunci dengan lebih cepat menggunakan cap jari</translation>
 <translation id="6322559670748154781">Fail ini tidak biasa dimuat turun dan telah disekat oleh Perlindungan Lanjutan</translation>
@@ -7020,6 +7060,7 @@
 <translation id="6344576354370880196">Pencetak yang disimpan</translation>
 <translation id="6344608411615208519"><ph name="BEGIN_LINK" />Penyemak imbas anda diurus<ph name="END_LINK" /> oleh ibu/bapa anda</translation>
 <translation id="6344622098450209924">Perlindungan Penjejakan</translation>
+<translation id="6344868544424352658">Sejarah penyemakan imbas Chrome anda mengandungi semua laman yang anda lawati dalam Chrome dalam suatu tempoh masa.</translation>
 <translation id="6345418402353744910">Nama pengguna dan kata laluan anda diperlukan untuk proksi <ph name="PROXY" /> agar pentadbir dapat mengkonfigurasikan rangkaian anda</translation>
 <translation id="6345566021391290381">Terdapat kata laluan yang dikongsi dengan anda pada <ph name="WEBSITE_NAME" />. Anda boleh menggunakan kata laluan tersebut dalam borang log masuk.</translation>
 <translation id="6345878117466430440">Tandai sebagai dibaca</translation>
@@ -7428,6 +7469,7 @@
 <translation id="6673898378497337661">meningkatkan kecerahan papan kekunci</translation>
 <translation id="6674571176963658787">Untuk memulakan penyegerakan, masukkan ungkapan laluan anda</translation>
 <translation id="6675665718701918026">Peranti penuding disambung</translation>
+<translation id="6676021247432396306">Apabila anda menyemak imbas web, anda menjana data - sebagai contoh, perkataan yang anda cari, laman yang anda lawati dan penyemak imbas serta peranti yang anda gunakan.</translation>
 <translation id="6676212663108450937">Sila pertimbangkan penggunaan set kepala semasa melatih suara anda</translation>
 <translation id="667752334740867460">Menerima maklumat Wi-Fi...</translation>
 <translation id="6678717876183468697">URL Pertanyaan</translation>
@@ -7929,6 +7971,7 @@
 <translation id="7049524156282610342">Data semakan imbas <ph name="DISPLAY_NAME" /></translation>
 <translation id="7050037487872780845">Konfigurasi tempat liputan tidak sah</translation>
 <translation id="7051222203795962489">{COUNT,plural, =1{Kata laluan disimpan dalam Google Account anda, <ph name="USER_EMAIL" />}other{Kata laluan disimpan dalam Google Account anda, <ph name="USER_EMAIL" />}}</translation>
+<translation id="7052762602787632571">&amp;Padamkan data semakan imbas...</translation>
 <translation id="7053983685419859001">Sekat</translation>
 <translation id="7055152154916055070">Ubah hala disekat:</translation>
 <translation id="7055451306017383754">Tidak dapat menyahkongsi kerana terdapat aplikasi yang menggunakan folder ini. Folder ini akan dinyahkongsi apabila Parallels Desktop ditutup selepas ini.</translation>
@@ -8061,6 +8104,7 @@
 <translation id="7169122689956315694">Hidupkan pemberitahuan apabila terdapat peranti berdekatan</translation>
 <translation id="7170236477717446850">Gambar profil</translation>
 <translation id="7171000599584840888">Tambah Profil...</translation>
+<translation id="7171245766710039393">Lawati <ph name="BEGIN_LINK_HISTORY" /><ph name="HISTORY" /><ph name="END_LINK_HISTORY" /> untuk menyemak dan mengurus sejarah penyemakan imbas anda. Ketahui lebih lanjut tentang <ph name="BEGIN_LINK_HELPCENTER" />data semakan imbas anda dalam Chrome dan cara mengurus data semakan imbas tersebut<ph name="END_LINK_HELPCENTER" />.</translation>
 <translation id="7171259390164035663">Jangan daftar</translation>
 <translation id="7172470549472604877">{NUM_TABS,plural, =1{Tambahkan tab pada kumpulan baharu}other{Tambahkan tab pada kumpulan baharu}}</translation>
 <translation id="7173114856073700355">Buka Tetapan</translation>
@@ -8492,6 +8536,7 @@
 <translation id="7497981768003291373">Anda tiada log teks WebRTC yang dirakam baru-baru ini.</translation>
 <translation id="7501957181231305652">atau</translation>
 <translation id="7502220299952823578">Tambahkan pada senarai "sentiasa pastikan laman ini aktif"</translation>
+<translation id="7502394262247226635">Apabila anda mencari sesuatu dalam bar alamat Chrome, enjin carian lalai anda menerima permintaan anda dan membalas dengan menunjukkan hasil carian yang berkaitan. Sejarah carian anda termasuk perkara yang anda cari dalam tempoh masa tertentu.</translation>
 <translation id="7502528909759062987">Jeda penghantaran tab pada <ph name="DEVICE_NAME" /></translation>
 <translation id="7502804472671406749">Tab kongsi boleh ditatal dan dizum</translation>
 <translation id="7503191893372251637">Jenis Sijil Netscape</translation>
@@ -8777,6 +8822,7 @@
 <translation id="7705524343798198388">VPN</translation>
 <translation id="7707108266051544351">Tapak ini telah disekat daripada menggunakan penderia gerakan.</translation>
 <translation id="7707922173985738739">Gunakan data mudah alih</translation>
+<translation id="7708143783728142771">Kuki membenarkan tahap penyesuaian keutamaan yang sama pada web. Apabila anda melawati laman, laman tersebut boleh menyimpan kuki dalam storan penyemak imbas peranti anda untuk mengingati pilihan laman anda, seperti bahasa yang anda tuturkan atau item yang mahu anda simpan dalam troli beli-belah. Kemudian, jika anda melawati laman itu sekali lagi menggunakan penyemak imbas yang sama, laman tersebut boleh membaca kuki yang ditetapkan dan anda boleh bermula dari tempat anda berhenti. Jenis kuki ini sering dirujuk sebagai kuki pihak pertama kerana kuki tersebut ditetapkan oleh laman yang anda lawati.</translation>
 <translation id="770831926727930011">Data setempat dilindungi oleh kata laluan lama anda. Masukkan kata laluan lama anda untuk memulihkan data setempat.</translation>
 <translation id="7709152031285164251">Gagal - <ph name="INTERRUPT_REASON" /></translation>
 <translation id="7710568461918838723">&amp;Cast...</translation>
@@ -9226,6 +9272,7 @@
 <translation id="8033958968890501070">Tamat masa</translation>
 <translation id="8035059678007243127">Halaman Dicache Kembali/Maju Inkognito: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Bantu Kami Tingkatkan Autolengkap</translation>
+<translation id="8036504271468642248">Ayat sebelumnya</translation>
 <translation id="8037117027592400564">Baca semua teks yang dituturkan menggunakan pertuturan disintesiskan</translation>
 <translation id="8037357227543935929">Tanya (lalai)</translation>
 <translation id="803771048473350947">Fail</translation>
@@ -9285,6 +9332,7 @@
 <translation id="8076835018653442223">Akses kepada fail setempat pada peranti anda dilumpuhkan oleh pentadbir anda</translation>
 <translation id="8077120325605624147">Mana-mana laman yang anda lawati boleh memaparkan sebarang iklan kepada anda</translation>
 <translation id="8077579734294125741">Profil Chrome Lain</translation>
+<translation id="8077749280021225629">Padamkan data semakan imbas (<ph name="URL" />) juga, yang akan mengelog anda keluar dari <ph name="DOMAIN" />. <ph name="LEARN_MORE" /></translation>
 <translation id="80790299200510644">Carian Imej</translation>
 <translation id="80798452873915119">Laman boleh meminta untuk mengurus tetingkap pada semua paparan anda</translation>
 <translation id="8080028325999236607">Tutup Semua Tab</translation>
@@ -9743,6 +9791,7 @@
 <translation id="8418445294933751433">&amp;Paparkan sebagai tab</translation>
 <translation id="8418675848396538775">Tambah <ph name="LANGUAGE_NAME" /></translation>
 <translation id="8419098111404128271">Hasil carian untuk '<ph name="SEARCH_TEXT" />'</translation>
+<translation id="8419144699778179708">Memadamkan sejarah, termasuk item dalam kotak carian</translation>
 <translation id="8420308167132684745">Edit entri kamus</translation>
 <translation id="8421361468937925547">Sari Kata Langsung (bahasa Inggeris sahaja)</translation>
 <translation id="8422748173858722634">IMEI</translation>
@@ -9842,6 +9891,7 @@
 <translation id="8494147475618188843">Tetapan Android</translation>
 <translation id="849488240089599592">Kembali ke Muat Turun Terbaharu</translation>
 <translation id="8496717697661868878">Jalankan Pemalam Ini</translation>
+<translation id="8497136774043290050">Apakah itu kuki pihak ketiga? Laman yang anda lawati boleh membenamkan kandungan daripada laman atau perkhidmatan lain, seperti imej, iklan, kandungan media sosial dan teks. Apabila mana-mana laman lain ini menggunakan kuki untuk menyimpan maklumat tentang anda, laman tersebut dikenali sebagai kuki pihak ketiga. Jika anda melawati beberapa laman yang membenamkan kandungan daripada sumber yang sama, seperti rangkaian iklan, kuki pihak ketiga boleh digunakan untuk tujuan pengiklanan dan menjejaki anda semasa anda menyemak imbas.</translation>
 <translation id="8497219075884839166">Windows Utilities</translation>
 <translation id="8498214519255567734">Memudahkan anda melihat skrin atau membaca dalam cahaya malap</translation>
 <translation id="8499083585497694743">Nyahredamkan mikrofon</translation>
@@ -10173,6 +10223,7 @@
 <translation id="8745034592125932220">Tidak dibenarkan menyimpan data pada peranti anda</translation>
 <translation id="8746654918629346731">Anda sudah meminta "<ph name="EXTENSION_NAME" />"</translation>
 <translation id="874689135111202667">{0,plural, =1{Muat naik satu fail ke tapak ini?}other{Muat naik # fail ke tapak ini?}}</translation>
+<translation id="8748916845823567967">Semua data dan kuki yang disimpan oleh <ph name="SITE" /> akan dipadamkan.</translation>
 <translation id="8749805710397399240">Tidak dapat menghantar skrin anda. Semak kebenaran Perakam Skrin dalam Pilihan Sistem.</translation>
 <translation id="8749826920799243530">Peranti tidak didaftarkan</translation>
 <translation id="8749863574775030885">Akses peranti USB daripada vendor yang tidak diketahui</translation>
@@ -10226,6 +10277,7 @@
 <translation id="8786824282808281903">Apabila anak anda melihat ikon ini, cap jari boleh digunakan untuk pengenalan atau meluluskan pembelian.</translation>
 <translation id="8787575090331305835">{NUM_TABS,plural, =1{Kumpulan Tidak Bernama – 1 Tab}other{Kumpulan Tidak Bernama – # Tab}}</translation>
 <translation id="8787752878731558379">Bantu kami meningkatkan Chrome dengan memberitahu kami sebab anda membenarkan kuki pihak ketiga</translation>
+<translation id="8789898473175677810">Chrome ialah sebahagian daripada <ph name="LINK_BEGIN" />usaha kerjasama<ph name="LINK_END" /> untuk mengurangkan penjejakan rentas laman dan menghentikan penggunaan kuki pihak ketiga. Walau bagaimanapun, kami sedang cuba melakukan tindakan ini dengan penuh tanggungjawab kerana banyak laman bergantung pada kuki pihak ketiga untuk berfungsi seperti yang direka bentuk. Sebagai contoh, banyak laman menggunakan kuki pihak ketiga untuk memudahkan log masuk, menyokong sistem sembang dan ulasan terbenam serta perkhidmatan pembayaran. Pengiklan sering menggunakan kuki pihak ketiga untuk meningkatkan iklan diperibadikan. Perkara ini penting kerana laman sering bergantung pada iklan untuk membantu mereka membayar perbelanjaan dan mengekalkan kandungan dalam talian mereka secara percuma.</translation>
 <translation id="8791157330927639737">Ketahui lebih lanjut tentang pengemaskinian</translation>
 <translation id="8791534160414513928">Hantar permintaan "Do Not Track" dengan trafik penyemakan imbas anda</translation>
 <translation id="8793390639824829328">Laman menggunakan ciri ini untuk menatal dan mengezum tab kongsi</translation>
@@ -10442,6 +10494,7 @@
 <translation id="8952831374766033534">Pilihan konfigurasi tidak disokong: <ph name="ERROR_LINE" /></translation>
 <translation id="8953476467359856141">Semasa mengecas</translation>
 <translation id="895347679606913382">Memulakan...</translation>
+<translation id="8954796993367253220">Untuk memadamkan sejarah mod Tetamu, tutup semua tetingkap Tetamu.</translation>
 <translation id="8955174612586215829">Cari tema</translation>
 <translation id="8957757410289731985">Sesuaikan profil</translation>
 <translation id="8959144235813727886">Laman dan apl</translation>
@@ -10853,6 +10906,7 @@
 <translation id="957960681186851048">Tapak ini cuba memuat turun berbilang fail secara automatik</translation>
 <translation id="958571289841636277">Navigasi ke belakang dan ke hadapan dengan gerak isyarat leret</translation>
 <translation id="960987915827980018">Tinggal kira-kira 1jam</translation>
+<translation id="961856697154696964">Padamkan data semakan imbas</translation>
 <translation id="962802172452141067">Pohon folder penanda halaman</translation>
 <translation id="963000966785016697">Cari Imej dengan <ph name="VISUAL_SEARCH_PROVIDER" /></translation>
 <translation id="964286338916298286">Pentadbir IT anda telah melumpuhkan Cenderahati Chrome untuk peranti anda.</translation>
diff --git a/chrome/app/resources/generated_resources_my.xtb b/chrome/app/resources/generated_resources_my.xtb
index 0374794f..d2b03ff6 100644
--- a/chrome/app/resources/generated_resources_my.xtb
+++ b/chrome/app/resources/generated_resources_my.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">ဖိုင်များတည်းဖြတ်ရန်</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ဖိုင်ကို ဖွင့်၍မရပါ}other{ဖိုင်များကို ဖွင့်၍မရပါ}}</translation>
 <translation id="1282311502488501110">လက်မှတ်ထိုး မဝင်ပါနှင့်</translation>
-<translation id="1282465000333679776">စနစ်အသံကို မျှဝေရန်</translation>
 <translation id="1283126956823499975">စက်ပစ္စည်း စနစ်ထည့်သွင်းမှုတွင် တစ်ခုခုမှားသွားသည်</translation>
 <translation id="1284277788676816155">ဒေတာသိမ်းခွင့်မပြုရန်</translation>
 <translation id="1285320974508926690">ဒီဆိုက်ကို ဘယ်တော့မှ ဘာသာမပြန်ပါနှင့်</translation>
@@ -1061,7 +1060,6 @@
 <translation id="1781502536226964113">တဲပ်စာမျက်နှာ အသစ်ဖွင့်ရန်</translation>
 <translation id="1781553166608855614">ပြောဆိုသည့် ဘာသာစကား</translation>
 <translation id="1781771911845953849">အကောင့်များနှင့် စင့်ခ်လုပ်ခြင်းများ</translation>
-<translation id="1781979858217752599">ဝင်းဒိုးအသံကို မျှဝေရန်</translation>
 <translation id="1782101999402987960">အပ်ဒိတ်များကို သင်၏စီမံခန့်ခွဲသူက ပိတ်ထားသည်</translation>
 <translation id="1782196717298160133">သင်၏ ဖုန်းကို ရှာကြည့်ခြင်း</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{မှတ်စု ၁ ခု}other{မှတ်စု # ခု}}</translation>
@@ -1625,7 +1623,6 @@
 <translation id="2187895286714876935">ဆာဗာ လက်မှတ် တင်သွင်းမှု အမှား</translation>
 <translation id="2187906491731510095">နောက်ဆက်တွဲများ အပ်ဒိတ်လုပ်ပြီးပါပြီ</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> ကို ဖွင့်ရန်</translation>
-<translation id="2189787291884708275">တဘ်အသံကို မျှဝေရန်</translation>
 <translation id="2190069059097339078">WiFi Credentials Getter</translation>
 <translation id="219008588003277019">ဇာတိဖောက်သည် သင်ရိုး: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(ဗလာ)</translation>
@@ -5299,6 +5296,7 @@
 <translation id="4998430619171209993">ဖွင့်</translation>
 <translation id="4999804342505941663">'မနှောင့်ယှက်ရ' ကို ဖွင့်ရန်</translation>
 <translation id="5001526427543320409">ပြင်ပကုမ္ပဏီ၏ကွတ်ကီး</translation>
+<translation id="5003993274120026347">နောက် ဝါကျ</translation>
 <translation id="5005498671520578047">စကားဝှက်ကို ကူးယူပါ</translation>
 <translation id="5006118752738286774">ပြီးခဲ့သော 2 နှစ်</translation>
 <translation id="5006218871145547804">Crostini Android အက်ပ် ADB</translation>
@@ -9220,6 +9218,7 @@
 <translation id="8033958968890501070">အချိန်ကုန်သွားသည်</translation>
 <translation id="8035059678007243127">ရှေ့/နောက် ကက်ရှ်သိမ်းထားသော ရုပ်ဖျက်စာမျက်နှာ- <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">‘အော်တိုဖြည့်’ ပိုကောင်းလာအောင် ကူညီရန်</translation>
+<translation id="8036504271468642248">ယခင် ဝါကျ</translation>
 <translation id="8037117027592400564">ဖန်တီး နှုတ်စကားကို အသုံးပြုပြီး ပြောကြားခဲ့သည့် စာသား အားလုံးကို ဖတ်ရန်</translation>
 <translation id="8037357227543935929">မေးရန် (မူရင်း)</translation>
 <translation id="803771048473350947">ဖိုင်</translation>
diff --git a/chrome/app/resources/generated_resources_ne.xtb b/chrome/app/resources/generated_resources_ne.xtb
index 7bd5530..637e136c 100644
--- a/chrome/app/resources/generated_resources_ne.xtb
+++ b/chrome/app/resources/generated_resources_ne.xtb
@@ -380,7 +380,6 @@
 <translation id="1280965841156951489">फाइलहरू सम्पादन गर्नुहोस्</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{फाइल खोल्न सकिएन}other{फाइलहरू खोल्न सकिएन}}</translation>
 <translation id="1282311502488501110">साइन इन नगर्नुहोस्</translation>
-<translation id="1282465000333679776">सिस्टममा बजिरहेको अडियो प्ले गर्नुहोस्</translation>
 <translation id="1283126956823499975">डिभाइस सेटअप गर्ने क्रममा कुनै समस्या आयो</translation>
 <translation id="1284277788676816155">डेटा सेभ गर्ने अनुमति नदिनुहोस्</translation>
 <translation id="1285320974508926690">यो साइट कहिले पनि अनुवाद नगर्नुहोस्</translation>
@@ -463,7 +462,7 @@
 <translation id="1348966090521113558">माउससम्बन्धी एस्सेसिबिलिटी सेटिङ</translation>
 <translation id="1350962700620017446">"<ph name="EXTENSION_NAME" />" डकुमेन्ट स्क्यानरहरू भेट्टाउन र प्रयोग गर्न चाहन्छ।</translation>
 <translation id="1352834119074414157">यो बन्डल काम नलाग्ने वा चोरी भएको हुन सक्छ। कृपया यो विन्डो बन्द गर्नुहोस् र यसलाई फेरि डाउनलोड गर्नुहोस्</translation>
-<translation id="1353275871123211385">एप अनुमोदन गर्ने तथा यन्त्र चलाएर बिताउने समय सीमा तोक्ने जस्ता अभिभावकीय नियन्त्रण सुविधाहरू प्रयोग गर्न बच्चासँग अनिवार्य रूपमा कुनै अभिभावकले सुपरिवेक्षण गर्ने Google खाता हुनु पर्छ। तपाईं पछि Google Classroom जस्ता संयन्त्र प्रयोग गर्नका निम्ति विद्यालयको खाता थप्न सक्नुहुन्छ।</translation>
+<translation id="1353275871123211385">एप अनुमोदन गर्ने तथा यन्त्र चलाएर बिताउने समय सीमा तोक्ने जस्ता अभिभावकीय कन्ट्रोल प्रयोग गर्न बच्चासँग अनिवार्य रूपमा कुनै अभिभावकले सुपरिवेक्षण गर्ने Google खाता हुनु पर्छ। तपाईं पछि Google Classroom जस्ता संयन्त्र प्रयोग गर्नका निम्ति विद्यालयको खाता थप्न सक्नुहुन्छ।</translation>
 <translation id="135389172849514421">अफलाइन हुँदा पनि प्रयोग गर्न मिल्छ</translation>
 <translation id="1353980523955420967">PPD फेला पार्न सकिएन। आफ्नो Chromebook अनलाइन भएको सुनिश्चित गरी फेरि प्रयास गर्नुहोस्।</translation>
 <translation id="1354045473509304750"><ph name="HOST" /> लाई तपाईंको डिभाइसको क्यामेरा प्रयोग गर्ने तथा क्यामेरा यताउता घुमाउने अनुमति दिइराख्नुहोस्</translation>
@@ -957,7 +956,7 @@
 <translation id="1708563369218024896">कुनै पनि डेटा कलेक्टर चयन गरिएको छैन। कृपया कम्तीमा एउटा डेटा कलेक्टर चयन गर्नुहोस्।</translation>
 <translation id="1708713382908678956"><ph name="NAME_PH" /> (ID: <ph name="ID_PH" />)</translation>
 <translation id="1708839673480942471">एपबाट सूचना प्राप्त गर्ने सुविधा, Do Not Disturb र एपमा ब्याज देखाउने सुविधा व्यवस्थापन गर्नुहोस्</translation>
-<translation id="1708979186656821319">डाउनलोड पूरा हुँदा बबल नदेखाइयोस्</translation>
+<translation id="1708979186656821319">डाउनलोड पूरा हुँदा बबल नदेखाउनुहोस्</translation>
 <translation id="1709106626015023981"><ph name="WIDTH" /> गुणा <ph name="HEIGHT" /> (मूल)</translation>
 <translation id="1709217939274742847">प्रमाणीकरणका लागि प्रयोग गर्न कुनै टिकट छान्नुहोस्। <ph name="LINK_BEGIN" />थप जान्नुहोस्<ph name="LINK_END" /></translation>
 <translation id="1709762881904163296">नेटवर्कसम्बन्धी सेटिङहरू</translation>
@@ -1048,7 +1047,6 @@
 <translation id="1781502536226964113">नयाँ ट्याब पेज खोल्नुहोस्</translation>
 <translation id="1781553166608855614">पढेर सुनाइने भाषा</translation>
 <translation id="1781771911845953849">खाता र सिंक सुविधा</translation>
-<translation id="1781979858217752599">विन्डोमा बजिरहेको अडियो सेयर गर्नुहोस्</translation>
 <translation id="1782101999402987960">तपाईंका एड्मिनले अपडेट गर्न नमिल्ने बनाएका छन्</translation>
 <translation id="1782196717298160133">तपाईंको फोन पत्ता लगाउँदैछ</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{एउटा नोट}other{# वटा नोट}}</translation>
@@ -1061,7 +1059,7 @@
 <translation id="1790976235243700817">पहुँच हटाउनुहोस्</translation>
 <translation id="1791662854739702043">स्थापना गरियो</translation>
 <translation id="1792619191750875668">विस्तारित प्रदर्शन</translation>
-<translation id="1794051631868188691"><ph name="MERCHANT" /> कहिल्यै नदेखाइयोस्</translation>
+<translation id="1794051631868188691"><ph name="MERCHANT" /> कहिल्यै नदेखाउनुहोस्</translation>
 <translation id="1794212650797661990"><ph name="DOMAIN" /> को पासवर्ड लुकाउनुहोस्</translation>
 <translation id="1794791083288629568">हामीलाई यस समस्याको समाधान गर्नमा मद्दत गर्न प्रतिक्रिया पठाउनुहोस्।</translation>
 <translation id="1795214765651529549">क्लासिक प्रयोग गर्नुहोस्</translation>
@@ -1612,7 +1610,6 @@
 <translation id="2187895286714876935">सर्भर सर्टिफिकेट आयात त्रुटि</translation>
 <translation id="2187906491731510095">विस्तारहरू अद्यावधिक गरिए</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> खोल्नुहोस्</translation>
-<translation id="2189787291884708275">ट्याबमा बजिरहेको अडियो सेयर गर्नुहोस्</translation>
 <translation id="2190069059097339078">Wi-Fi प्रमाणपत्रहरू प्राप्तकर्ता</translation>
 <translation id="219008588003277019">स्वदेशी ग्राहक मोड्युल: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(खालि)</translation>
@@ -2162,7 +2159,7 @@
 <translation id="2586672484245266891">कृपया कुनै अझ छोटो URL प्रविष्टि गर्नुहोस्</translation>
 <translation id="2587922766792651800">समय सकियो</translation>
 <translation id="2588636910004461974"><ph name="VENDOR_NAME" /> का यन्त्रहरू</translation>
-<translation id="2589658397149952302">Drive का फाइलहरू कहिल्यै पनि नदेखाइयोस्</translation>
+<translation id="2589658397149952302">Drive का फाइलहरू कहिल्यै पनि नदेखाउनुहोस्</translation>
 <translation id="2593499352046705383">सुरु गर्नुअघि आफ्नो डेटा ब्याकअप गर्न नभुल्नुहोस्। तपाईंले <ph name="DEVICE_OS" /> इन्स्टल गर्नुभयो भने तपाईंको हार्ड ड्राइभमा भएका सबै डेटा ओभरराइट हुने छन्। g.co/flex/InstallGuide मा गई थप जान्नुहोस्।</translation>
 <translation id="2594832159966169099">V8 को सुरक्षा व्यवस्थापन गर्नुहोस्</translation>
 <translation id="2594999711683503743">Google मा खोज्नुहोस् वा URL टाइप गर्नुहोस्</translation>
@@ -2713,7 +2710,7 @@
 <translation id="3003623123441819449">CSS क्यास</translation>
 <translation id="3003967365858406397">तपाईंको <ph name="PHONE_NAME" /> ले कुनै निजी Wi-Fi जडान सिर्जना गर्दछ।</translation>
 <translation id="3004385386820284928">किबोर्डका की कस्टमाइज गर्नुहोस्</translation>
-<translation id="3005574332301273731">नदेखाइयोस्</translation>
+<translation id="3005574332301273731">नदेखाउनुहोस्</translation>
 <translation id="3006881078666935414">उपयोगसम्बन्धी कुनै डेटा छैन</translation>
 <translation id="3007410324195400631">यो पेजका बारेमा नोटहरू लेख्नुहोस्</translation>
 <translation id="3007771295016901659">प्रतिलिपि गरिएको ट्याब</translation>
@@ -5282,6 +5279,7 @@
 <translation id="4998430619171209993">सक्रिय छ</translation>
 <translation id="4999804342505941663">'बाधा नपुऱ्याउनुहोस्' मोड अन गर्नुहोस्</translation>
 <translation id="5001526427543320409">तेस्रो पक्षीय कुकीहरू</translation>
+<translation id="5003993274120026347">अर्को वाक्य</translation>
 <translation id="5005498671520578047">पासवर्ड प्रतिलिपि गर्नुहोस्</translation>
 <translation id="5006118752738286774">२ वर्षअघि</translation>
 <translation id="5006218871145547804">Crostini मा Android एपको ADB</translation>
@@ -5410,7 +5408,7 @@
 <translation id="5106350808162641062">हटाउनुहोस्</translation>
 <translation id="5106608587025903971">साइन इन गर्दा आफ्नो Google खाताको पासवर्ड हाल्नुको साटो तपाईं यो डिभाइसको <ph name="DEVICE_TYPE" /> पासवर्ड राख्न सक्नुहुन्छ</translation>
 <translation id="510695978163689362"><ph name="USER_EMAIL" /> Family Link मार्फत सुपरिवेक्षण गरिएको छ। अभिभावकको निगरानीमा विद्यालयका स्रोत साधन प्रयोग गर्न तिमी विद्यालयका खाता थप्न सक्छौ।</translation>
-<translation id="5107093668001980925"><ph name="MODULE_NAME" /> कहिल्यै पनि नदेखाइयोस्</translation>
+<translation id="5107093668001980925"><ph name="MODULE_NAME" /> कहिल्यै पनि नदेखाउनुहोस्</translation>
 <translation id="5107443654503185812">एउटा एक्स्टेन्सनले सुरक्षित ब्राउजिङ सेवा निष्क्रिय पारेको छ</translation>
 <translation id="5108967062857032718">सेटिङहरू - Android एपहरूलाई हटाउनुहोस्</translation>
 <translation id="5109044022078737958">मिया</translation>
@@ -7453,7 +7451,7 @@
 <translation id="6712943853047024245">तपाईंले <ph name="WEBSITE" /> मा यो युजरनेमको पासवर्ड सेभ गरिसक्नुभएको छ</translation>
 <translation id="6713233729292711163">कार्य प्रोफाइल हाल्नुहोस्</translation>
 <translation id="6713441551032149301">लन्चर की थिचिराख्दा फङ्सन की र माथिल्लो लहरका सिस्टम कीका बिचमा अदलबदल हुने पारियोस्</translation>
-<translation id="6713668088933662563">यी भाषाहरूमा अनुवाद गर्ने विकल्प कहिल्यै नदेखाइयोस्</translation>
+<translation id="6713668088933662563">यी भाषाहरूमा अनुवाद गर्ने विकल्प कहिल्यै नदेखाउनुहोस्</translation>
 <translation id="6715803357256707211">तपाईंको Linux एप स्थापना गर्ने क्रममा कुनै त्रुटि भयो। विस्तृत विवरणका लागि सूचनामा क्लिक गर्नुहोस्।</translation>
 <translation id="6716049856796700977">केही कुराले पनि तपाईंको लोकेसन प्रयोग गर्न सक्दैन। तर तपाईंको लोकेसन तपाईंको IP एड्रेसमार्फत अझै पनि एप तथा वेबसाइटहरूमा देखिन सक्छ। <ph name="LINK_BEGIN" />थप जान्नुहोस्<ph name="LINK_END" /></translation>
 <translation id="6716798148881908873">इन्टरनेट चलिरहेको छैन। आफ्नो इन्टरनेट कनेक्सन जाँच्नुहोस् वा कुनै अर्को Wi-Fi नेटवर्कमा कनेक्ट गरी हेर्नुहोस्।</translation>
@@ -7727,7 +7725,7 @@
 <translation id="6912007319859991306">सेलुलर SIM PIN</translation>
 <translation id="6912380255120084882">कुनै अर्को डिभाइसमा दर्ता गरी हेर्नुहोस्</translation>
 <translation id="691289340230098384">क्याप्सनसम्बन्धी प्राथमिकताहरू</translation>
-<translation id="6914812290245989348">असुरक्षित साइटहरूमा जानुअघि कुनै पनि चेतावनी नदेखाइयोस्</translation>
+<translation id="6914812290245989348">असुरक्षित साइटहरूमा जानुअघि कुनै पनि चेतावनी नदेखाउनुहोस्</translation>
 <translation id="6916590542764765824">विस्तार व्यवस्थापन गर्नुहोस्</translation>
 <translation id="6918677045355889289">ChromeOS अपडेट गर्नु पर्ने हुन्छ</translation>
 <translation id="6918733588290914545">Android फोनमार्फत द्रुत रूपमा सेटअप गर्नुहोस्</translation>
@@ -9204,6 +9202,7 @@
 <translation id="8033958968890501070">समयावधि सकियो</translation>
 <translation id="8035059678007243127">इन्कोग्निटो मोडमा ब्याक/फर्वार्ड क्यास गरिएको पेज: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">अटोफिल सुविधाको गुणस्तर सुधार गर्न मद्दत गर्नुहोस्</translation>
+<translation id="8036504271468642248">अघिल्लो वाक्य</translation>
 <translation id="8037117027592400564">बोलिएका सबै पाठहरूलाई संश्लेषण गरिएको बोली प्रयोग गरेर पढ्नुहोस्</translation>
 <translation id="8037357227543935929">सोध्नुहोस् (डिफल्ट मान)</translation>
 <translation id="803771048473350947">फाइल</translation>
diff --git a/chrome/app/resources/generated_resources_nl.xtb b/chrome/app/resources/generated_resources_nl.xtb
index f673cd7..8caf2c1 100644
--- a/chrome/app/resources/generated_resources_nl.xtb
+++ b/chrome/app/resources/generated_resources_nl.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">Bestanden bewerken</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Kan bestand niet openen}other{Kan bestanden niet openen}}</translation>
 <translation id="1282311502488501110">Niet inloggen</translation>
-<translation id="1282465000333679776">Systeemaudio delen</translation>
 <translation id="1283126956823499975">Er is iets misgegaan bij het instellen van het apparaat</translation>
 <translation id="1284277788676816155">Niet toestaan dat gegevens worden opgeslagen</translation>
 <translation id="1285320974508926690">Deze site nooit vertalen</translation>
@@ -1051,7 +1050,6 @@
 <translation id="1781502536226964113">De pagina 'Nieuw tabblad' openen</translation>
 <translation id="1781553166608855614">Gesproken taal</translation>
 <translation id="1781771911845953849">Accounts en synchronisatie</translation>
-<translation id="1781979858217752599">Audio van venster delen</translation>
 <translation id="1782101999402987960">Je beheerder heeft updates geblokkeerd</translation>
 <translation id="1782196717298160133">Je telefoon zoeken</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 notitie}other{# notities}}</translation>
@@ -1615,7 +1613,6 @@
 <translation id="2187895286714876935">Fout bij importeren van servercertificaat</translation>
 <translation id="2187906491731510095">Extensies geüpdatet</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> openen</translation>
-<translation id="2189787291884708275">Audio van tabblad delen</translation>
 <translation id="2190069059097339078">WiFi Credentials Getter</translation>
 <translation id="219008588003277019">Native Client-module: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(leeg)</translation>
@@ -5283,6 +5280,7 @@
 <translation id="4998430619171209993">Aan</translation>
 <translation id="4999804342505941663">Niet storen aanzetten</translation>
 <translation id="5001526427543320409">Cookies van derden</translation>
+<translation id="5003993274120026347">Volgende zin</translation>
 <translation id="5005498671520578047">Wachtwoord kopiëren</translation>
 <translation id="5006118752738286774">2 jaar geleden</translation>
 <translation id="5006218871145547804">Android-app-ADB voor Crostini</translation>
@@ -9200,6 +9198,7 @@
 <translation id="8033958968890501070">Time-out</translation>
 <translation id="8035059678007243127">Incognitopagina in Back-Forward Cache: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Help Automatisch invullen te verbeteren</translation>
+<translation id="8036504271468642248">Vorige zin</translation>
 <translation id="8037117027592400564">Alle tekst lezen die wordt gesproken met gesynthetiseerde spraak</translation>
 <translation id="8037357227543935929">Vragen (standaard)</translation>
 <translation id="803771048473350947">Archief</translation>
diff --git a/chrome/app/resources/generated_resources_no.xtb b/chrome/app/resources/generated_resources_no.xtb
index 45f01d6..1feaa95b 100644
--- a/chrome/app/resources/generated_resources_no.xtb
+++ b/chrome/app/resources/generated_resources_no.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Rediger filer</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Kan ikke åpne filen}other{Kan ikke åpne filene}}</translation>
 <translation id="1282311502488501110">Ikke logg på</translation>
-<translation id="1282465000333679776">Del systemlyd</translation>
 <translation id="1283126956823499975">Noe gikk galt under konfigureringen av enheten</translation>
 <translation id="1284277788676816155">Ikke tillat lagring av data</translation>
 <translation id="1285320974508926690">Oversett aldri dette nettstedet</translation>
@@ -1057,7 +1056,6 @@
 <translation id="1781502536226964113">Åpne siden Ny fane</translation>
 <translation id="1781553166608855614">Talespråk</translation>
 <translation id="1781771911845953849">Kontoer og synkronisering</translation>
-<translation id="1781979858217752599">Del vinduslyd</translation>
 <translation id="1782101999402987960">Administratoren din blokkerer oppdateringer</translation>
 <translation id="1782196717298160133">Finner telefonen din</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 merknad}other{# merknader}}</translation>
@@ -1622,7 +1620,6 @@
 <translation id="2187895286714876935">Feil ved import av tjenersertifikat</translation>
 <translation id="2187906491731510095">Utvidelser er oppdatert</translation>
 <translation id="2188881192257509750">Åpne <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Del fanelyd</translation>
 <translation id="2190069059097339078">WiFi Credentials Getter</translation>
 <translation id="219008588003277019">Native Client-modul: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(tom)</translation>
@@ -5293,6 +5290,7 @@
 <translation id="4998430619171209993">På</translation>
 <translation id="4999804342505941663">Slå på Ikke forstyrr</translation>
 <translation id="5001526427543320409">Tredjeparts informasjonskapsler</translation>
+<translation id="5003993274120026347">Neste setning</translation>
 <translation id="5005498671520578047">Kopiér passordet</translation>
 <translation id="5006118752738286774">For 2 år siden</translation>
 <translation id="5006218871145547804">Android-app-ADB for Crostini</translation>
@@ -9217,6 +9215,7 @@
 <translation id="8033958968890501070">Tidsavbrudd</translation>
 <translation id="8035059678007243127">Inkognitoside i frem-og-tilbake-bufferen: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Bidra til å gjøre autofyll bedre</translation>
+<translation id="8036504271468642248">Forrige setning</translation>
 <translation id="8037117027592400564">lese hele teksten med syntetisert tale</translation>
 <translation id="8037357227543935929">Spør (standard)</translation>
 <translation id="803771048473350947">Fil</translation>
diff --git a/chrome/app/resources/generated_resources_or.xtb b/chrome/app/resources/generated_resources_or.xtb
index 98e09ca..fbcc9db5 100644
--- a/chrome/app/resources/generated_resources_or.xtb
+++ b/chrome/app/resources/generated_resources_or.xtb
@@ -383,7 +383,6 @@
 <translation id="1280965841156951489">ଫାଇଲଗୁଡ଼ିକୁ ଏଡିଟ୍ କରନ୍ତୁ</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ଫାଇଲକୁ ଖୋଲାଯାଇପାରିବ ନାହିଁ}other{ଫାଇଲଗୁଡ଼ିକୁ ଖୋଲାଯାଇପାରିବ ନାହିଁ}}</translation>
 <translation id="1282311502488501110">ସାଇନ୍ ଇନ୍ କରନ୍ତୁ ନାହିଁ</translation>
-<translation id="1282465000333679776">ସିଷ୍ଟମ୍ ଅଡିଓକୁ ସେୟାର୍ କରନ୍ତୁ</translation>
 <translation id="1283126956823499975">ଡିଭାଇସ ସେଟ ଅପ କରିବାରେ କିଛି ତ୍ରୁଟି ହୋଇଛି</translation>
 <translation id="1284277788676816155">ଡାଟା ସେଭ କରିବାକୁ ଅନୁମତି ଦିଅନ୍ତୁ ନାହିଁ</translation>
 <translation id="1285320974508926690">ଏହି ସାଇଟ୍‍କୁ କଦାପି ଅନୁବାଦ କରନ୍ତୁ ନାହିଁ</translation>
@@ -1050,7 +1049,6 @@
 <translation id="1781502536226964113">ନୂତନ ଟାବ୍ ପୃଷ୍ଠା ଖୋଲନ୍ତୁ</translation>
 <translation id="1781553166608855614">କଥିତ ଭାଷା</translation>
 <translation id="1781771911845953849">ଆକାଉଣ୍ଟ ଏବଂ ସିଙ୍କ୍</translation>
-<translation id="1781979858217752599">ୱିଣ୍ଡୋ ଅଡିଓ ସେୟାର୍ କରନ୍ତୁ</translation>
 <translation id="1782101999402987960">ଆପଣଙ୍କ ଆଡମିନିଷ୍ଟ୍ରେଟରଙ୍କ ଦ୍ୱାରା ଅପଡେଟଗୁଡ଼ିକୁ ବ୍ଲକ୍ କରାଯାଇଛି</translation>
 <translation id="1782196717298160133">ଆପଣଙ୍କ ଫୋନ୍ ଖୋଜାଯାଉଛି</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1ଟି ନୋଟ}other{#ଟି ନୋଟ}}</translation>
@@ -1612,7 +1610,6 @@
 <translation id="2187895286714876935">ସର୍ଭର୍ ସାର୍ଟିଫିକେଟ୍ ଇମ୍ପୋର୍ଟ କରିବାରେ ତ୍ରୁଟି</translation>
 <translation id="2187906491731510095">ଏକ୍ସଟେନ୍‌ସନ୍‌ଗୁଡ଼ିକ ଅପ୍‌ଡେଟ୍ କରାଯାଇଛି</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> ଖୋଲନ୍ତୁ</translation>
-<translation id="2189787291884708275">ଟାବର ଅଡିଓ ସେୟାର୍ କରନ୍ତୁ</translation>
 <translation id="2190069059097339078">ୱାଇଫାଇ କ୍ରେଡେନ୍ସିଆଲ୍ ପ୍ରାପ୍ତକର୍ତ୍ତା</translation>
 <translation id="219008588003277019">ସ୍ଥାନୀୟ କ୍ଲାଏଣ୍ଟ ମଡ୍ୟୁଲ୍: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(ଖାଲି)</translation>
@@ -5283,6 +5280,7 @@
 <translation id="4998430619171209993">ଚାଲୁ ଅଛି</translation>
 <translation id="4999804342505941663">"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ" ଫିଚରକୁ ଚାଲୁ କରନ୍ତୁ</translation>
 <translation id="5001526427543320409">ତୃତୀୟ-ପକ୍ଷ କୁକୀଗୁଡ଼ିକ</translation>
+<translation id="5003993274120026347">ପରବର୍ତ୍ତୀ ବାକ୍ୟ</translation>
 <translation id="5005498671520578047">ପାସ୍‍ୱର୍ଡ କପି କରନ୍ତୁ</translation>
 <translation id="5006118752738286774">2 ବର୍ଷ ପୂର୍ବେ</translation>
 <translation id="5006218871145547804">Crostini Android ଆପ୍ ADB</translation>
@@ -9204,6 +9202,7 @@
 <translation id="8033958968890501070">ସମୟ ସମାପ୍ତି</translation>
 <translation id="8035059678007243127">ଇନକଗ୍ନିଟୋ ବ୍ୟାକ୍/ଫରୱାର୍ଡ୍ କ୍ୟାଶ୍ ପୃଷ୍ଠା: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">ଅଟୋଫିଲକୁ ଉନ୍ନତ କରିବାରେ ସାହାଯ୍ୟ କରନ୍ତୁ</translation>
+<translation id="8036504271468642248">ପୂର୍ବବର୍ତ୍ତୀ ବାକ୍ୟ</translation>
 <translation id="8037117027592400564">ସ୍ପୀଚ୍‍ର ସମ୍ମିଶ୍ରଣ ବ୍ୟବହାର କରି ସମସ୍ତ କୁହାଯାଇଥିବା ଟେକ୍ସଟ୍‍ ପଢ଼ନ୍ତୁ</translation>
 <translation id="8037357227543935929">ପଚାରନ୍ତୁ (ଡିଫଲ୍ଟ)</translation>
 <translation id="803771048473350947">ଫାଇଲ୍</translation>
diff --git a/chrome/app/resources/generated_resources_pa.xtb b/chrome/app/resources/generated_resources_pa.xtb
index 7c38890..3d1f3fe6 100644
--- a/chrome/app/resources/generated_resources_pa.xtb
+++ b/chrome/app/resources/generated_resources_pa.xtb
@@ -385,7 +385,6 @@
 <translation id="1280965841156951489">ਫ਼ਾਈਲਾਂ ਦਾ ਸੰਪਾਦਨ ਕਰੋ</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ਫ਼ਾਈਲ ਨੂੰ ਨਹੀਂ ਖੋਲ੍ਹਿਆ ਜਾ ਸਕਦਾ}one{ਫ਼ਾਈਲ ਨੂੰ ਨਹੀਂ ਖੋਲ੍ਹਿਆ ਜਾ ਸਕਦਾ}other{ਫ਼ਾਈਲਾਂ ਨੂੰ ਨਹੀਂ ਖੋਲ੍ਹਿਆ ਜਾ ਸਕਦਾ}}</translation>
 <translation id="1282311502488501110">ਸਾਈਨ-ਇਨ ਨਾ ਕਰੋ</translation>
-<translation id="1282465000333679776">ਸਿਸਟਮ ਆਡੀਓ ਸਾਂਝਾ ਕਰੋ</translation>
 <translation id="1283126956823499975">ਇਸ ਡੀਵਾਈਸ ਦਾ ਸੈੱਟਅੱਪ ਕਰਨ ਵੇਲੇ ਕੋਈ ਗੜਬੜ ਹੋ ਗਈ</translation>
 <translation id="1284277788676816155">ਡਾਟਾ ਰੱਖਿਅਤ ਕਰਨ ਦੀ ਆਗਿਆ ਨਾ ਦਿਓ</translation>
 <translation id="1285320974508926690">ਕਦੇ ਵੀ ਇਸ ਸਾਈਟ ਦਾ ਅਨੁਵਾਦ ਨਾ ਕਰੋ</translation>
@@ -1063,7 +1062,6 @@
 <translation id="1781502536226964113">ਨਵੀਂ ਟੈਬ ਪੰਨਾ ਖੋਲ੍ਹੋ</translation>
 <translation id="1781553166608855614">ਬੋਲਚਾਲ ਦੀ ਭਾਸ਼ਾ</translation>
 <translation id="1781771911845953849">ਖਾਤੇ ਅਤੇ ਸਿੰਕ</translation>
-<translation id="1781979858217752599">ਵਿੰਡੋ ਆਡੀਓ ਸਾਂਝਾ ਕਰੋ</translation>
 <translation id="1782101999402987960">ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਅੱਪਡੇਟਾਂ ਨੂੰ ਬਲਾਕ ਕਰ ਦਿੱਤਾ ਗਿਆ ਹੈ</translation>
 <translation id="1782196717298160133">ਤੁਹਾਡਾ ਫ਼ੋਨ ਲੱਭ ਰਿਹਾ ਹੈ</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 ਨੋਟ-ਕਥਨ}one{# ਨੋਟ-ਕਥਨ}other{# ਨੋਟ-ਕਥਨ}}</translation>
@@ -1628,7 +1626,6 @@
 <translation id="2187895286714876935">ਸਰਵਰ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਆਯਾਤ ਗੜਬੜ</translation>
 <translation id="2187906491731510095">ਐਕਸਟੈਂਸ਼ਨਾਂ ਅੱਪਡੇਟ ਕੀਤੀਆਂ ਗਈਆਂ</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> ਖੋਲ੍ਹੋ</translation>
-<translation id="2189787291884708275">ਟੈਬ ਆਡੀਓ ਸਾਂਝਾ ਕਰੋ</translation>
 <translation id="2190069059097339078">WiFi ਕ੍ਰੈਡੈਂਸ਼ੀਅਲ ਗੈਟਰ</translation>
 <translation id="219008588003277019">ਨੇਟਿਵ ਕਲਾਇੰਟ ਮਾਡਿਊਲ: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(ਖਾਲੀ)</translation>
@@ -5303,6 +5300,7 @@
 <translation id="4998430619171209993">ਚਾਲੂ</translation>
 <translation id="4999804342505941663">'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ' ਨੂੰ ਚਾਲੂ ਕਰੋ</translation>
 <translation id="5001526427543320409">ਤੀਜੀ-ਧਿਰ ਦੀਆਂ ਕੁਕੀਜ਼</translation>
+<translation id="5003993274120026347">ਅਗਲਾ ਵਾਕ</translation>
 <translation id="5005498671520578047">ਪਾਸਵਰਡ ਕਾਪੀ ਕਰੋ</translation>
 <translation id="5006118752738286774">2 ਸਾਲ ਪਹਿਲਾਂ</translation>
 <translation id="5006218871145547804">Crostini Android ਐਪ ADB</translation>
@@ -9228,6 +9226,7 @@
 <translation id="8033958968890501070">ਸਮਾਂ-ਸਮਾਪਤੀ</translation>
 <translation id="8035059678007243127">ਪੂਰੇ ਪੰਨੇ ਦੇ ਕੈਸ਼ੇ ਵਿੱਚ ਸਟੋਰ ਕੀਤਾ ਇਨਕੋਗਨਿਟੋ ਪੰਨਾ: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">ਆਟੋਫਿਲ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਵਿੱਚ ਮਦਦ ਕਰੋ</translation>
+<translation id="8036504271468642248">ਪਿਛਲਾ ਵਾਕ</translation>
 <translation id="8037117027592400564">ਸਿੰਥੇਸਾਈਜ਼ਡ ਸਪੀਚ ਵਰਤਦੇ ਹੋਏ ਬੋਲਿਆ ਗਿਆ ਸਾਰਾ ਟੈਕਸਟ ਪੜ੍ਹੋ</translation>
 <translation id="8037357227543935929">ਪੁੱਛੋ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)</translation>
 <translation id="803771048473350947">ਫਾਈਲ</translation>
diff --git a/chrome/app/resources/generated_resources_pl.xtb b/chrome/app/resources/generated_resources_pl.xtb
index da70cfa..df3a283 100644
--- a/chrome/app/resources/generated_resources_pl.xtb
+++ b/chrome/app/resources/generated_resources_pl.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Edytuj pliki</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Nie można otworzyć pliku}few{Nie można otworzyć plików}many{Nie można otworzyć plików}other{Nie można otworzyć plików}}</translation>
 <translation id="1282311502488501110">Nie loguj się</translation>
-<translation id="1282465000333679776">Udostępnij dźwięk z komputera</translation>
 <translation id="1283126956823499975">Podczas konfigurowania urządzenia coś poszło nie tak</translation>
 <translation id="1284277788676816155">Nie zezwalaj na zapisywanie danych</translation>
 <translation id="1285320974508926690">Nigdy nie tłumacz tej witryny</translation>
@@ -1053,7 +1052,6 @@
 <translation id="1781502536226964113">Otwórz stronę nowej karty</translation>
 <translation id="1781553166608855614">Język wypowiedzi</translation>
 <translation id="1781771911845953849">Konta i synchronizacja</translation>
-<translation id="1781979858217752599">Udostępnij dźwięk z okna</translation>
 <translation id="1782101999402987960">Administrator zablokował aktualizacje</translation>
 <translation id="1782196717298160133">Znajdowanie Twojego telefonu</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 uwaga}few{# uwagi}many{# uwag}other{# uwagi}}</translation>
@@ -1612,7 +1610,6 @@
 <translation id="2187895286714876935">Błąd importowania certyfikatu serwera</translation>
 <translation id="2187906491731510095">Rozszerzenia zaktualizowane</translation>
 <translation id="2188881192257509750">Otwórz <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Udostępnij dźwięk z karty</translation>
 <translation id="2190069059097339078">Program do pobierania danych logowania do Wi-Fi</translation>
 <translation id="219008588003277019">Moduł klienta natywnego: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(puste)</translation>
@@ -5267,6 +5264,7 @@
 <translation id="4998430619171209993">Włączono</translation>
 <translation id="4999804342505941663">Włącz tryb Nie przeszkadzać</translation>
 <translation id="5001526427543320409">Pliki cookie innych firm</translation>
+<translation id="5003993274120026347">Następne zdanie</translation>
 <translation id="5005498671520578047">Skopiuj hasło</translation>
 <translation id="5006118752738286774">2 lata temu</translation>
 <translation id="5006218871145547804">ADB aplikacji Crostini na Androida</translation>
@@ -9191,6 +9189,7 @@
 <translation id="8033958968890501070">Przekroczono limit czasu</translation>
 <translation id="8035059678007243127">Strona w trybie incognito w pamięci podręcznej stanu strony internetowej: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Pomóż nam ulepszać autouzupełnianie</translation>
+<translation id="8036504271468642248">Poprzednie zdanie</translation>
 <translation id="8037117027592400564">Odczyt całego tekstu mówionego przez syntezator mowy</translation>
 <translation id="8037357227543935929">Pytaj (domyślnie)</translation>
 <translation id="803771048473350947">Plik</translation>
diff --git a/chrome/app/resources/generated_resources_pt-BR.xtb b/chrome/app/resources/generated_resources_pt-BR.xtb
index 9a30107..b696d914 100644
--- a/chrome/app/resources/generated_resources_pt-BR.xtb
+++ b/chrome/app/resources/generated_resources_pt-BR.xtb
@@ -385,7 +385,6 @@
 <translation id="1280965841156951489">Editar arquivos</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Não é possível abrir o arquivo}one{Não é possível abrir o arquivo}other{Não é possível abrir os arquivos}}</translation>
 <translation id="1282311502488501110">Não fazer login</translation>
-<translation id="1282465000333679776">Compartilhar áudio do sistema</translation>
 <translation id="1283126956823499975">Algo deu errado ao configurar o dispositivo</translation>
 <translation id="1284277788676816155">Não permitir que dados sejam salvos</translation>
 <translation id="1285320974508926690">Nunca traduzir este site</translation>
@@ -1063,7 +1062,6 @@
 <translation id="1781502536226964113">Abrir Nova guia</translation>
 <translation id="1781553166608855614">Idioma falado</translation>
 <translation id="1781771911845953849">Contas e sincronização</translation>
-<translation id="1781979858217752599">Compartilhar áudio da janela</translation>
 <translation id="1782101999402987960">As atualizações estão bloqueadas pelo administrador</translation>
 <translation id="1782196717298160133">Como encontrar seu smartphone</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 anotação}one{# anotação}other{# anotações}}</translation>
@@ -1628,7 +1626,6 @@
 <translation id="2187895286714876935">Erro de importação do certificado de servidor</translation>
 <translation id="2187906491731510095">Extensões atualizadas</translation>
 <translation id="2188881192257509750">Abrir <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Compartilhar áudio da guia</translation>
 <translation id="2190069059097339078">Getter de credenciais de Wi-Fi</translation>
 <translation id="219008588003277019">Módulo do cliente nativo: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(vazio)</translation>
@@ -5302,6 +5299,7 @@
 <translation id="4998430619171209993">Ativado</translation>
 <translation id="4999804342505941663">Ativar o Não perturbe</translation>
 <translation id="5001526427543320409">Cookies de terceiros</translation>
+<translation id="5003993274120026347">Próxima frase</translation>
 <translation id="5005498671520578047">Copiar senha</translation>
 <translation id="5006118752738286774">2 anos atrás</translation>
 <translation id="5006218871145547804">ADB de apps Android no Crostini</translation>
@@ -9230,6 +9228,7 @@
 <translation id="8033958968890501070">Expirada</translation>
 <translation id="8035059678007243127">Página de navegação anônima salva em cache de avanço e retorno: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Ajude a melhorar o preenchimento automático</translation>
+<translation id="8036504271468642248">Frase anterior</translation>
 <translation id="8037117027592400564">Ler todo texto falado usando voz sintetizada</translation>
 <translation id="8037357227543935929">Perguntar (padrão)</translation>
 <translation id="803771048473350947">Arquivo</translation>
diff --git a/chrome/app/resources/generated_resources_pt-PT.xtb b/chrome/app/resources/generated_resources_pt-PT.xtb
index c191b7aa..afdcfba 100644
--- a/chrome/app/resources/generated_resources_pt-PT.xtb
+++ b/chrome/app/resources/generated_resources_pt-PT.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">Editar ficheiros</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Não é possível abrir o ficheiro}other{Não é possível abrir os ficheiros}}</translation>
 <translation id="1282311502488501110">Não iniciar sessão</translation>
-<translation id="1282465000333679776">Partilhar áudio do sistema</translation>
 <translation id="1283126956823499975">Algo correu mal com a configuração do dispositivo</translation>
 <translation id="1284277788676816155">Não permitir guardar dados</translation>
 <translation id="1285320974508926690">Nunca traduzir este site</translation>
@@ -1051,7 +1050,6 @@
 <translation id="1781502536226964113">Abrir a página Novo separador</translation>
 <translation id="1781553166608855614">Idioma falado</translation>
 <translation id="1781771911845953849">Contas e sincronização</translation>
-<translation id="1781979858217752599">Partilhar áudio da janela</translation>
 <translation id="1782101999402987960">As atualizações estão bloqueadas pelo seu administrador</translation>
 <translation id="1782196717298160133">A localizar o seu telemóvel</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 nota}other{# notas}}</translation>
@@ -1615,7 +1613,6 @@
 <translation id="2187895286714876935">Erro na importação do certificado do servidor</translation>
 <translation id="2187906491731510095">Extensões atualizadas.</translation>
 <translation id="2188881192257509750">Abrir <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Partilhar áudio do separador</translation>
 <translation id="2190069059097339078">Obtenção de credenciais de Wi-Fi</translation>
 <translation id="219008588003277019">Módulo Native Client: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(vazio)</translation>
@@ -5286,6 +5283,7 @@
 <translation id="4998430619171209993">Ativado</translation>
 <translation id="4999804342505941663">Ativar o modo Não incomodar</translation>
 <translation id="5001526427543320409">Cookies de terceiros</translation>
+<translation id="5003993274120026347">Frase seguinte</translation>
 <translation id="5005498671520578047">Copiar palavra-passe</translation>
 <translation id="5006118752738286774">Há 2 anos</translation>
 <translation id="5006218871145547804">ADB de apps Android do Crostini</translation>
@@ -9212,6 +9210,7 @@
 <translation id="8033958968890501070">Limite de tempo</translation>
 <translation id="8035059678007243127">Página de Navegação anónima na cache para a frente/para trás: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Ajudar a melhorar o preenchimento automático</translation>
+<translation id="8036504271468642248">Frase anterior</translation>
 <translation id="8037117027592400564">Ler todo o texto falado através da voz sintetizada</translation>
 <translation id="8037357227543935929">Pedir (predefinição)</translation>
 <translation id="803771048473350947">Ficheiro</translation>
diff --git a/chrome/app/resources/generated_resources_ro.xtb b/chrome/app/resources/generated_resources_ro.xtb
index f26a717..f7b1a06 100644
--- a/chrome/app/resources/generated_resources_ro.xtb
+++ b/chrome/app/resources/generated_resources_ro.xtb
@@ -383,7 +383,6 @@
 <translation id="1280965841156951489">Editează fișierele</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Fișierul nu se poate deschide}few{Fișierele nu se pot deschide}other{Fișierele nu se pot deschide}}</translation>
 <translation id="1282311502488501110">Nu mă conectez</translation>
-<translation id="1282465000333679776">Trimite conținutul audio de pe sistem</translation>
 <translation id="1283126956823499975">A apărut o eroare la configurarea dispozitivului</translation>
 <translation id="1284277788676816155">Nu permite salvarea datelor</translation>
 <translation id="1285320974508926690">Nu traduce niciodată acest site</translation>
@@ -1052,7 +1051,6 @@
 <translation id="1781502536226964113">Deschideți pagina Filă nouă</translation>
 <translation id="1781553166608855614">Limba vorbită</translation>
 <translation id="1781771911845953849">Conturi și sincronizare</translation>
-<translation id="1781979858217752599">Trimite conținutul audio din fereastră</translation>
 <translation id="1782101999402987960">Actualizările au fost blocate de administrator</translation>
 <translation id="1782196717298160133">Se găsește telefonul</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{O notă}few{# note}other{# de note}}</translation>
@@ -1616,7 +1614,6 @@
 <translation id="2187895286714876935">Eroare de import a certificatului serverului</translation>
 <translation id="2187906491731510095">Extensiile au fost actualizate</translation>
 <translation id="2188881192257509750">Deschide <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Trimite conținutul audio din filă</translation>
 <translation id="2190069059097339078">Instrument de obținere a datelor de conectare WiFi</translation>
 <translation id="219008588003277019">Modul Client nativ: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(gol)</translation>
@@ -5286,6 +5283,7 @@
 <translation id="4998430619171209993">Activat</translation>
 <translation id="4999804342505941663">Activează funcția Nu deranja</translation>
 <translation id="5001526427543320409">Cookie-uri terță parte</translation>
+<translation id="5003993274120026347">Propoziția următoare</translation>
 <translation id="5005498671520578047">Copiază parola</translation>
 <translation id="5006118752738286774">Acum 2 ani</translation>
 <translation id="5006218871145547804">ADB în aplicațiile pentru Android în Crostini</translation>
@@ -9213,6 +9211,7 @@
 <translation id="8033958968890501070">Expirare</translation>
 <translation id="8035059678007243127">Pagină incognito din memoria cache înainte-înapoi: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Ajută la îmbunătățirea completării automate</translation>
+<translation id="8036504271468642248">Propoziția anterioară</translation>
 <translation id="8037117027592400564">Citește tot textul rostit folosind vorbirea sintetizată</translation>
 <translation id="8037357227543935929">Solicită (în mod prestabilit)</translation>
 <translation id="803771048473350947">Fișier</translation>
diff --git a/chrome/app/resources/generated_resources_ru.xtb b/chrome/app/resources/generated_resources_ru.xtb
index f133af4..bba6e3e5 100644
--- a/chrome/app/resources/generated_resources_ru.xtb
+++ b/chrome/app/resources/generated_resources_ru.xtb
@@ -385,7 +385,6 @@
 <translation id="1280965841156951489">Разрешить</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Не удалось открыть файл.}one{Не удалось открыть файлы.}few{Не удалось открыть файлы.}many{Не удалось открыть файлы.}other{Не удалось открыть файлы.}}</translation>
 <translation id="1282311502488501110">Отмена</translation>
-<translation id="1282465000333679776">Предоставить доступ к аудио в системе</translation>
 <translation id="1283126956823499975">При настройке устройства что-то пошло не так</translation>
 <translation id="1284277788676816155">Запретить сохранять данные</translation>
 <translation id="1285320974508926690">Никогда не переводить этот сайт</translation>
@@ -1052,7 +1051,6 @@
 <translation id="1781502536226964113">Новая вкладка</translation>
 <translation id="1781553166608855614">Язык озвучивания</translation>
 <translation id="1781771911845953849">Аккаунты и синхронизация</translation>
-<translation id="1781979858217752599">Предоставить доступ к аудио в окне</translation>
 <translation id="1782101999402987960">Администратор заблокировал обновления.</translation>
 <translation id="1782196717298160133">Поиск телефона</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 заметка}one{# заметка}few{# заметки}many{# заметок}other{# заметки}}</translation>
@@ -1614,7 +1612,6 @@
 <translation id="2187895286714876935">Ошибка при импорте сертификата сервера</translation>
 <translation id="2187906491731510095">Расширения обновлены</translation>
 <translation id="2188881192257509750">Открыть приложение "<ph name="APPLICATION" />"</translation>
-<translation id="2189787291884708275">Предоставить доступ к аудио на вкладке</translation>
 <translation id="2190069059097339078">Получение параметров доступа по Wi-Fi</translation>
 <translation id="219008588003277019">Модуль Native Client: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(пусто)</translation>
@@ -5078,7 +5075,7 @@
 <translation id="4842976633412754305">Страница пытается загрузить скрипты из непроверенных источников.</translation>
 <translation id="4844333629810439236">Другие раскладки</translation>
 <translation id="4844347226195896707">Просматривайте пароли, даже если не используете Chrome или Android. Для этого войдите в систему на сайте &lt;a target='_blank' href='<ph name="LINK" />'&gt;passwords.google.com&lt;/a&gt;.</translation>
-<translation id="484462545196658690">Выбрать автоматически</translation>
+<translation id="484462545196658690">Авто</translation>
 <translation id="4846628405149428620">Укажите, где этот сайт может сохранять изменения</translation>
 <translation id="4846680374085650406">Параметр настроен в соответствии с рекомендациями администратора.</translation>
 <translation id="4847242508757499006">Выберите "Повторить". Если вам достаточно ограниченных возможностей просмотра и редактирования, нажмите "Открыть в базовом редакторе".</translation>
@@ -5279,6 +5276,7 @@
 <translation id="4998430619171209993">Включено</translation>
 <translation id="4999804342505941663">Включить режим "Не беспокоить"</translation>
 <translation id="5001526427543320409">Сторонние файлы cookie</translation>
+<translation id="5003993274120026347">К следующему предложению</translation>
 <translation id="5005498671520578047">Копировать пароль</translation>
 <translation id="5006118752738286774">2 года назад</translation>
 <translation id="5006218871145547804">Инструмент adb для Android-приложений в Crostini</translation>
@@ -9200,6 +9198,7 @@
 <translation id="8033958968890501070">Время истекло</translation>
 <translation id="8035059678007243127">Страница возвратного кеша в режиме инкогнито: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Помочь в улучшении автозаполнения</translation>
+<translation id="8036504271468642248">К предыдущему предложению</translation>
 <translation id="8037117027592400564">Доступ к тексту, произнесенному синтезатором речи</translation>
 <translation id="8037357227543935929">Спрашивать (по умолчанию)</translation>
 <translation id="803771048473350947">Файл</translation>
diff --git a/chrome/app/resources/generated_resources_si.xtb b/chrome/app/resources/generated_resources_si.xtb
index 24f80dd..cea5df8 100644
--- a/chrome/app/resources/generated_resources_si.xtb
+++ b/chrome/app/resources/generated_resources_si.xtb
@@ -387,7 +387,6 @@
 <translation id="1280965841156951489">ගොනු සංස්කරණ කරන්න</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ගොනුව විවෘත කළ නොහැක}one{ගොනු විවෘත කළ නොහැක}other{ගොනු විවෘත කළ නොහැක}}</translation>
 <translation id="1282311502488501110">පුරන්න එපා</translation>
-<translation id="1282465000333679776">පද්ධති ශ්‍රව්‍යය බෙදා ගන්න</translation>
 <translation id="1283126956823499975">උපාංගය පිහිටුවීම සමග යමක් වැරදී ඇත</translation>
 <translation id="1284277788676816155">දත්ත සුරැකීමට ඉඩ නොදෙන්න</translation>
 <translation id="1285320974508926690">මෙම අඩවිය කිසිවිට පරිවර්තනය නොකරන්න</translation>
@@ -1054,7 +1053,6 @@
 <translation id="1781502536226964113">නව ටැබ පිටුව විවෘත කරන්න</translation>
 <translation id="1781553166608855614">කථන භාෂාව</translation>
 <translation id="1781771911845953849">ගිණුම් සහ සමමුහූර්තය</translation>
-<translation id="1781979858217752599">කවුළු ශ්‍රව්‍යය බෙදා ගන්න</translation>
 <translation id="1782101999402987960">ඔබගේ පරිපාලක විසින් යාවත්කාලීන කිරීම් අවහිර කර ඇත.</translation>
 <translation id="1782196717298160133">ඔබගේ දුරකථනය සොයමින්</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 සටහනක්}one{සටහන් #ක්}other{සටහන් #ක්}}</translation>
@@ -1620,7 +1618,6 @@
 <translation id="2187895286714876935">සේවාදායක සහතික ආනයන දෝශය</translation>
 <translation id="2187906491731510095">දිගු යාවත්කාලීනයි</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> විවෘත කරන්න</translation>
-<translation id="2189787291884708275">ශ්‍රව්‍ය ටැබය බෙදා ගන්න</translation>
 <translation id="2190069059097339078">WiFi අක්තපත්‍ර ලබාගන්නා</translation>
 <translation id="219008588003277019">සහජ සේවා ග්‍රාහක ඒකකය: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(හිස්)</translation>
@@ -5314,6 +5311,7 @@
 <translation id="4998430619171209993">ක්‍රියාත්මකයි</translation>
 <translation id="4999804342505941663">බාධා නොකිරීම ක්‍රියාත්මක කරන්න</translation>
 <translation id="5001526427543320409">තෙවන පාර්ශ්ව කුකීස්</translation>
+<translation id="5003993274120026347">ඊළඟ වාක්‍යය</translation>
 <translation id="5005498671520578047">මුරපදය පිටපත් කරන්න</translation>
 <translation id="5006118752738286774">වසර 2කට පෙර</translation>
 <translation id="5006218871145547804">Crostini Android යෙදුම් ADB</translation>
@@ -9261,6 +9259,7 @@
 <translation id="8033958968890501070">කාල නිමාව</translation>
 <translation id="8035059678007243127">අප්‍රසිද්ධ පසුපසට/ඉදිරියට හැඹිලිගත කළ පිටුව: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">ස්වයං පිරවුම වැඩි දියුණු කිරීමට උදවු වන්න</translation>
+<translation id="8036504271468642248">පෙර වාක්‍යය</translation>
 <translation id="8037117027592400564">සංශ්ලේෂණය කළ කථනය භාවිතා කරමින් කථා කළ සියලු පෙළ කියවන්න</translation>
 <translation id="8037357227543935929">විමසන්න (පෙරනිමි)</translation>
 <translation id="803771048473350947">ගොනුව</translation>
diff --git a/chrome/app/resources/generated_resources_sk.xtb b/chrome/app/resources/generated_resources_sk.xtb
index d7ff308..ca550fe 100644
--- a/chrome/app/resources/generated_resources_sk.xtb
+++ b/chrome/app/resources/generated_resources_sk.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Upraviť súbory</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Súbor sa nedá otvoriť}few{Súbory sa nedajú otvoriť}many{Can't open files}other{Súbory sa nedajú otvoriť}}</translation>
 <translation id="1282311502488501110">Neprihlasovať sa</translation>
-<translation id="1282465000333679776">Zdieľať zvuk systému</translation>
 <translation id="1283126956823499975">Pri nastavovaní zariadenia sa niečo pokazilo</translation>
 <translation id="1284277788676816155">Nepovoliť ukladať údaje</translation>
 <translation id="1285320974508926690">Nikdy neprekladať tieto webové stránky</translation>
@@ -1053,7 +1052,6 @@
 <translation id="1781502536226964113">Otvoriť stránku Nová karta</translation>
 <translation id="1781553166608855614">Hovorený jazyk</translation>
 <translation id="1781771911845953849">Účty a synchronizácia</translation>
-<translation id="1781979858217752599">Zdieľať zvuk okna</translation>
 <translation id="1782101999402987960">Aktualizácie zablokoval váš správca</translation>
 <translation id="1782196717298160133">Nájsť telefón</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 poznámka}few{# poznámky}many{# Notes}other{# poznámok}}</translation>
@@ -1617,7 +1615,6 @@
 <translation id="2187895286714876935">Chyba importovania certifikátu servera</translation>
 <translation id="2187906491731510095">Rozšírenia boli aktualizované</translation>
 <translation id="2188881192257509750">Otvoriť <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Zdieľať zvuk karty</translation>
 <translation id="2190069059097339078">WiFi Credentials Getter</translation>
 <translation id="219008588003277019">Modul miestneho klienta: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(prázdne)</translation>
@@ -5287,6 +5284,7 @@
 <translation id="4998430619171209993">Zapnuté</translation>
 <translation id="4999804342505941663">Zapnúť režim bez vyrušení</translation>
 <translation id="5001526427543320409">Súbory cookie tretích strán</translation>
+<translation id="5003993274120026347">Ďalšia veta</translation>
 <translation id="5005498671520578047">Kopírovanie hesla</translation>
 <translation id="5006118752738286774">Pred 2 rokmi</translation>
 <translation id="5006218871145547804">ADB aplikácií pre Android v systéme Crostini</translation>
@@ -9215,6 +9213,7 @@
 <translation id="8033958968890501070">Časový limit vypršal</translation>
 <translation id="8035059678007243127">Stránka v režime inkognito v spätnej vyrovnávacej pamäti: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Pomôcť zlepšiť automatické dopĺňanie</translation>
+<translation id="8036504271468642248">Predchádzajúca veta</translation>
 <translation id="8037117027592400564">Čítať akýkoľvek hovorený text prenesený pomocou hlasového syntetizátora</translation>
 <translation id="8037357227543935929">Opýtať sa (predvolené)</translation>
 <translation id="803771048473350947">Súbor</translation>
diff --git a/chrome/app/resources/generated_resources_sl.xtb b/chrome/app/resources/generated_resources_sl.xtb
index 628bb46..5aba295 100644
--- a/chrome/app/resources/generated_resources_sl.xtb
+++ b/chrome/app/resources/generated_resources_sl.xtb
@@ -387,7 +387,6 @@
 <translation id="1280965841156951489">Uredi datoteke</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Datoteke ni mogoče odpreti}one{Datotek ni mogoče odpreti}two{Datotek ni mogoče odpreti}few{Datotek ni mogoče odpreti}other{Datotek ni mogoče odpreti}}</translation>
 <translation id="1282311502488501110">Brez prijave</translation>
-<translation id="1282465000333679776">Deli zvok sistema</translation>
 <translation id="1283126956823499975">Pri nastavljanju naprave je prišlo do napake</translation>
 <translation id="1284277788676816155">Ne dovoli shranjevanja podatkov</translation>
 <translation id="1285320974508926690">Nikoli ne prevedi tega spletnega mesta</translation>
@@ -1065,7 +1064,6 @@
 <translation id="1781502536226964113">Odpri nov zavihek s povezavami</translation>
 <translation id="1781553166608855614">Govorjeni jezik</translation>
 <translation id="1781771911845953849">Računi in sinhronizacija</translation>
-<translation id="1781979858217752599">Deli zvok okna</translation>
 <translation id="1782101999402987960">Posodobitve je blokiral skrbnik.</translation>
 <translation id="1782196717298160133">Iskanje telefona</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 opomba}one{# opomba}two{# opombi}few{# opombe}other{# opomb}}</translation>
@@ -1630,7 +1628,6 @@
 <translation id="2187895286714876935">Napaka pri uvozu strežniškega potrdila</translation>
 <translation id="2187906491731510095">Razširitve posodobljene</translation>
 <translation id="2188881192257509750">Odpri aplikacijo <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Deli zvok zavihka</translation>
 <translation id="2190069059097339078">Pripomoček za pridobivanje poverilnic za WiFi</translation>
 <translation id="219008588003277019">Modul »Native Client«: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(prazno)</translation>
@@ -5304,6 +5301,7 @@
 <translation id="4998430619171209993">Vklopljeno</translation>
 <translation id="4999804342505941663">Vklop načina Ne moti</translation>
 <translation id="5001526427543320409">Piškotki tretjih oseb</translation>
+<translation id="5003993274120026347">Naslednji stavek</translation>
 <translation id="5005498671520578047">Kopiranje gesla</translation>
 <translation id="5006118752738286774">Pred 2 letoma</translation>
 <translation id="5006218871145547804">ADB za aplikacije za Android v Crostiniju</translation>
@@ -9237,6 +9235,7 @@
 <translation id="8033958968890501070">Potek časovne omejitve</translation>
 <translation id="8035059678007243127">Anonimna stran v predpomnilniku za hitro obnovitev strani: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Pomagajte izboljšati samodejno izpolnjevanje</translation>
+<translation id="8036504271468642248">Prejšnji stavek</translation>
 <translation id="8037117027592400564">Branje in izgovarjava vsega besedila z uporabo sintetiziranega govora</translation>
 <translation id="8037357227543935929">Zahteva (privzeto)</translation>
 <translation id="803771048473350947">Datoteka</translation>
diff --git a/chrome/app/resources/generated_resources_sq.xtb b/chrome/app/resources/generated_resources_sq.xtb
index da3727f..2d0ae9ec 100644
--- a/chrome/app/resources/generated_resources_sq.xtb
+++ b/chrome/app/resources/generated_resources_sq.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">Modifiko skedarët</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Skedari nuk mund të hapet}other{Skedarët nuk mund të hapen}}</translation>
 <translation id="1282311502488501110">Mos u identifiko</translation>
-<translation id="1282465000333679776">Ndaj audion e sistemit</translation>
 <translation id="1283126956823499975">Ndodhi një gabim gjatë konfigurimit të pajisjes</translation>
 <translation id="1284277788676816155">Mos lejo ruajtjen e të dhënave</translation>
 <translation id="1285320974508926690">Asnjëherë mos e përkthe këtë sajt</translation>
@@ -1048,7 +1047,6 @@
 <translation id="1781502536226964113">Hap faqen "Skedë e re"</translation>
 <translation id="1781553166608855614">Gjuha e folur</translation>
 <translation id="1781771911845953849">Llogaritë dhe sinkronizimi</translation>
-<translation id="1781979858217752599">Ndaj audion e dritares</translation>
 <translation id="1782101999402987960">Përditësimet janë bllokuar nga administratori yt</translation>
 <translation id="1782196717298160133">Gjetja e telefonit</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 shënim}other{# shënime}}</translation>
@@ -1612,7 +1610,6 @@
 <translation id="2187895286714876935">Gabim në importimin e certifikatës së serverit</translation>
 <translation id="2187906491731510095">Shtesat u përditësuan</translation>
 <translation id="2188881192257509750">Hap <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Ndaj audion e skedës</translation>
 <translation id="2190069059097339078">Marrësi i kredencialeve Wi-Fi</translation>
 <translation id="219008588003277019">Moduli i klientit origjinal: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(bosh)</translation>
@@ -5283,6 +5280,7 @@
 <translation id="4998430619171209993">Aktiv</translation>
 <translation id="4999804342505941663">Aktivizo "Mos shqetëso"</translation>
 <translation id="5001526427543320409">Kukit e palëve të treta</translation>
+<translation id="5003993274120026347">Fjalia tjetër</translation>
 <translation id="5005498671520578047">Kopjo fjalëkalimin</translation>
 <translation id="5006118752738286774">2 vite më parë</translation>
 <translation id="5006218871145547804">ADB-ja e aplikacionit Android për Crostini</translation>
@@ -9205,6 +9203,7 @@
 <translation id="8033958968890501070">Skadimi</translation>
 <translation id="8035059678007243127">Faqja e memories specifike të faqes së plotë "të fshehtë": <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Ndihmo në përmirësimin e "Plotësimit automatik"</translation>
+<translation id="8036504271468642248">Fjalia e mëparshme</translation>
 <translation id="8037117027592400564">Lexo të gjithë tekstin e folur duke përdorur ligjërimin e sintetizuar</translation>
 <translation id="8037357227543935929">Pyet (parazgjedhja)</translation>
 <translation id="803771048473350947">Skedar</translation>
diff --git a/chrome/app/resources/generated_resources_sr-Latn.xtb b/chrome/app/resources/generated_resources_sr-Latn.xtb
index 65d9c80..16c16b0 100644
--- a/chrome/app/resources/generated_resources_sr-Latn.xtb
+++ b/chrome/app/resources/generated_resources_sr-Latn.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Izmeni datoteke</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Otvaranje fajla nije uspelo}one{Otvaranje fajlova nije uspelo}few{Otvaranje fajlova nije uspelo}other{Otvaranje fajlova nije uspelo}}</translation>
 <translation id="1282311502488501110">Ne prijavljuj me</translation>
-<translation id="1282465000333679776">Deli zvuk sistema</translation>
 <translation id="1283126956823499975">Došlo je do greške pri podešavanju uređaja</translation>
 <translation id="1284277788676816155">Ne dozvoli čuvanje podataka</translation>
 <translation id="1285320974508926690">Nikad ne prevodi ovaj sajt</translation>
@@ -1050,7 +1049,6 @@
 <translation id="1781502536226964113">Otvori novu karticu</translation>
 <translation id="1781553166608855614">Govorni jezik</translation>
 <translation id="1781771911845953849">Nalozi i sinhronizacija</translation>
-<translation id="1781979858217752599">Deli zvuk prozora</translation>
 <translation id="1782101999402987960">Administrator je blokirao ažuriranja</translation>
 <translation id="1782196717298160133">Tražimo telefon</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 beleška}one{# beleška}few{# beleške}other{# beleški}}</translation>
@@ -1613,7 +1611,6 @@
 <translation id="2187895286714876935">Greška pri uvozu serverskog sertifikata</translation>
 <translation id="2187906491731510095">Dodaci su ažurirani</translation>
 <translation id="2188881192257509750">Otvori <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Deli zvuk kartice</translation>
 <translation id="2190069059097339078">Dobijanje akreditiva za WiFi</translation>
 <translation id="219008588003277019">Modul originalnog klijenta: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(prazno)</translation>
@@ -5283,6 +5280,7 @@
 <translation id="4998430619171209993">Uključeno</translation>
 <translation id="4999804342505941663">Uključite režim Ne uznemiravaj</translation>
 <translation id="5001526427543320409">Kolačići treće strane</translation>
+<translation id="5003993274120026347">Sledeća rečenica</translation>
 <translation id="5005498671520578047">Kopiranje lozinke</translation>
 <translation id="5006118752738286774">pre 2 godine</translation>
 <translation id="5006218871145547804">ADB za Android aplikacije za Crostini</translation>
@@ -9212,6 +9210,7 @@
 <translation id="8033958968890501070">Vreme je isteklo</translation>
 <translation id="8035059678007243127">Cela keširana stranice bez arhiviranja: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Pomozite nam da poboljšamo automatsko popunjavanje</translation>
+<translation id="8036504271468642248">Prethodna rečenica</translation>
 <translation id="8037117027592400564">Čitanje svog teksta izgovorenog pomoću sintetizovanog govora</translation>
 <translation id="8037357227543935929">Pitaj (podrazumevano)</translation>
 <translation id="803771048473350947">Datoteka</translation>
diff --git a/chrome/app/resources/generated_resources_sr.xtb b/chrome/app/resources/generated_resources_sr.xtb
index 766bf17..0628fc6 100644
--- a/chrome/app/resources/generated_resources_sr.xtb
+++ b/chrome/app/resources/generated_resources_sr.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Измени датотеке</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Отварање фајла није успело}one{Отварање фајлова није успело}few{Отварање фајлова није успело}other{Отварање фајлова није успело}}</translation>
 <translation id="1282311502488501110">Не пријављуј ме</translation>
-<translation id="1282465000333679776">Дели звук система</translation>
 <translation id="1283126956823499975">Дошло је до грешке при подешавању уређаја</translation>
 <translation id="1284277788676816155">Не дозволи чување података</translation>
 <translation id="1285320974508926690">Никад не преводи овај сајт</translation>
@@ -1050,7 +1049,6 @@
 <translation id="1781502536226964113">Отвори нову картицу</translation>
 <translation id="1781553166608855614">Говорни језик</translation>
 <translation id="1781771911845953849">Налози и синхронизација</translation>
-<translation id="1781979858217752599">Дели звук прозора</translation>
 <translation id="1782101999402987960">Администратор је блокирао ажурирања</translation>
 <translation id="1782196717298160133">Тражимо телефон</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 белешка}one{# белешка}few{# белешке}other{# белешки}}</translation>
@@ -1613,7 +1611,6 @@
 <translation id="2187895286714876935">Грешка при увозу серверског сертификата</translation>
 <translation id="2187906491731510095">Додаци су ажурирани</translation>
 <translation id="2188881192257509750">Отвори <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Дели звук картице</translation>
 <translation id="2190069059097339078">Добијање акредитива за WiFi</translation>
 <translation id="219008588003277019">Модул оригиналног клијента: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(празно)</translation>
@@ -5283,6 +5280,7 @@
 <translation id="4998430619171209993">Укључено</translation>
 <translation id="4999804342505941663">Укључите режим Не узнемиравај</translation>
 <translation id="5001526427543320409">Колачићи треће стране</translation>
+<translation id="5003993274120026347">Следећа реченица</translation>
 <translation id="5005498671520578047">Копирање лозинке</translation>
 <translation id="5006118752738286774">пре 2 године</translation>
 <translation id="5006218871145547804">ADB за Android апликације за Crostini</translation>
@@ -9212,6 +9210,7 @@
 <translation id="8033958968890501070">Време је истекло</translation>
 <translation id="8035059678007243127">Цела кеширана странице без архивирања: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Помозите нам да побољшамо аутоматско попуњавање</translation>
+<translation id="8036504271468642248">Претходна реченица</translation>
 <translation id="8037117027592400564">Читање свог текста изговореног помоћу синтетизованог говора</translation>
 <translation id="8037357227543935929">Питај (подразумевано)</translation>
 <translation id="803771048473350947">Датотека</translation>
diff --git a/chrome/app/resources/generated_resources_sv.xtb b/chrome/app/resources/generated_resources_sv.xtb
index a7ae5d4c..3812f81 100644
--- a/chrome/app/resources/generated_resources_sv.xtb
+++ b/chrome/app/resources/generated_resources_sv.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Redigera filer</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Det går inte att öppna filen}other{Det går inte att öppna filerna}}</translation>
 <translation id="1282311502488501110">Logga inte in</translation>
-<translation id="1282465000333679776">Dela ljud från systemet</translation>
 <translation id="1283126956823499975">Något gick fel med konfigureringen av enheten</translation>
 <translation id="1284277788676816155">Tillåt inte att data sparas</translation>
 <translation id="1285320974508926690">Översätt aldrig den här webbplatsen</translation>
@@ -1062,7 +1061,6 @@
 <translation id="1781502536226964113">Öppna sidan Ny flik</translation>
 <translation id="1781553166608855614">Talat språk</translation>
 <translation id="1781771911845953849">Konton och synkronisering</translation>
-<translation id="1781979858217752599">Dela ljud från fönster</translation>
 <translation id="1782101999402987960">Uppdateringar blockeras av administratören</translation>
 <translation id="1782196717298160133">Sök efter din mobil</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 anteckning}other{# anteckningar}}</translation>
@@ -1627,7 +1625,6 @@
 <translation id="2187895286714876935">Fel vid import av servercertifikat</translation>
 <translation id="2187906491731510095">Tillägg har uppdaterats</translation>
 <translation id="2188881192257509750">Öppna <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Dela ljud från flik</translation>
 <translation id="2190069059097339078">Hämtningsfunktion för wifi-användaruppgifter</translation>
 <translation id="219008588003277019">Native Client-modul: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(tom)</translation>
@@ -5301,6 +5298,7 @@
 <translation id="4998430619171209993">På</translation>
 <translation id="4999804342505941663">Aktivera Stör ej</translation>
 <translation id="5001526427543320409">Tredjepartscookies</translation>
+<translation id="5003993274120026347">Nästa mening</translation>
 <translation id="5005498671520578047">Kopiera lösenord</translation>
 <translation id="5006118752738286774">För 2 år sedan</translation>
 <translation id="5006218871145547804">ADB för Android-appar i Crostini</translation>
@@ -9226,6 +9224,7 @@
 <translation id="8033958968890501070">Tidsgränsen överskreds</translation>
 <translation id="8035059678007243127">Inkognitosida i vilocacheminne: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Hjälp till att förbättra autofyll</translation>
+<translation id="8036504271468642248">Föregående mening</translation>
 <translation id="8037117027592400564">Läsa all text som läses upp med syntetiskt tal</translation>
 <translation id="8037357227543935929">Fråga (standard)</translation>
 <translation id="803771048473350947">Arkiv</translation>
diff --git a/chrome/app/resources/generated_resources_sw.xtb b/chrome/app/resources/generated_resources_sw.xtb
index 27ca666..ceb3715 100644
--- a/chrome/app/resources/generated_resources_sw.xtb
+++ b/chrome/app/resources/generated_resources_sw.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Badilisha faili</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Haiwezi kufungua faili}other{Haiwezi kufungua faili}}</translation>
 <translation id="1282311502488501110">Usiingie Katika Akaunti</translation>
-<translation id="1282465000333679776">Shiriki sauti iliyo kwenye mfumo huu</translation>
 <translation id="1283126956823499975">Hitilafu fulani imetokea wakati wa kuweka mipangilio ya kifaa</translation>
 <translation id="1284277788676816155">Hairuhusu kuhifadhi data</translation>
 <translation id="1285320974508926690">Kamwe usitafsiri tovuti hii</translation>
@@ -1059,7 +1058,6 @@
 <translation id="1781502536226964113">Fungua ukurasa Mpya wa Kichupo</translation>
 <translation id="1781553166608855614">Kwa ujumbe wa sauti</translation>
 <translation id="1781771911845953849">Akaunti na usawazishaji</translation>
-<translation id="1781979858217752599">Shiriki sauti iliyo kwenye dirisha hili</translation>
 <translation id="1782101999402987960">Masasisho yamezuiwa na msimamizi wako</translation>
 <translation id="1782196717298160133">Inatafuta simu yako</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{Dokezo 1}other{Madokezo #}}</translation>
@@ -1623,7 +1621,6 @@
 <translation id="2187895286714876935">Hitilafu ya Kuleta Cheti cha Seva</translation>
 <translation id="2187906491731510095">Imesasisha viendelezi</translation>
 <translation id="2188881192257509750">Fungua <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Shiriki sauti iliyo kwenye kichupo hiki</translation>
 <translation id="2190069059097339078">Kipataji cha Kitambulisho cha WiFi</translation>
 <translation id="219008588003277019">Sehemu Asili ya Seva-teja: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(tupu)</translation>
@@ -5296,6 +5293,7 @@
 <translation id="4998430619171209993">Imewashwa</translation>
 <translation id="4999804342505941663">Washa kipengele cha Usinisumbue</translation>
 <translation id="5001526427543320409">Vidakuzi vya washirika wengine</translation>
+<translation id="5003993274120026347">Sentensi inayofuata</translation>
 <translation id="5005498671520578047">Nakili nenosiri</translation>
 <translation id="5006118752738286774">Miaka miwili iliyopita</translation>
 <translation id="5006218871145547804">ADB ya programu ya Android kwenye Crostini</translation>
@@ -9222,6 +9220,7 @@
 <translation id="8033958968890501070">Muda umekwisha</translation>
 <translation id="8035059678007243127">Ukurasa fiche Uliohifadhiwa kwenye Kipengele cha Kuakibisha Ukurasa Kamili: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Saidia Kuboresha kipengele cha Kujaza kiotomatiki</translation>
+<translation id="8036504271468642248">Sentensi iliyotangulia</translation>
 <translation id="8037117027592400564">Soma maandishi yote yaliyotamkwa ukitumia matamshi yaliyounganishwa</translation>
 <translation id="8037357227543935929">Uliza (chaguomsingi)</translation>
 <translation id="803771048473350947">Faili</translation>
diff --git a/chrome/app/resources/generated_resources_ta.xtb b/chrome/app/resources/generated_resources_ta.xtb
index ceb0bf6..d7b98f9f 100644
--- a/chrome/app/resources/generated_resources_ta.xtb
+++ b/chrome/app/resources/generated_resources_ta.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">ஃபைல்களைத் திருத்து</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ஃபைலைத் திறக்க முடியவில்லை}other{ஃபைல்களைத் திறக்க முடியவில்லை}}</translation>
 <translation id="1282311502488501110">உள்நுழைய வேண்டாம்</translation>
-<translation id="1282465000333679776">சிஸ்டத்தின் ஆடியோவைப் பகிர்</translation>
 <translation id="1283126956823499975">சாதனத்தை அமைக்கும்போது ஏதோ தவறாகிவிட்டது</translation>
 <translation id="1284277788676816155">டேட்டாச் சேமிக்க அனுமதிக்காதே</translation>
 <translation id="1285320974508926690">இந்த தளத்தை எப்போதும் மொழிபெயர்க்க வேண்டாம்</translation>
@@ -1062,7 +1061,6 @@
 <translation id="1781502536226964113">புதிய தாவல் பக்கத்தைத் திற</translation>
 <translation id="1781553166608855614">பேசும் மொழி</translation>
 <translation id="1781771911845953849">கணக்குகளும் ஒத்திசைவும்</translation>
-<translation id="1781979858217752599">சாளரத்தின் ஆடியோவைப் பகிர்</translation>
 <translation id="1782101999402987960">புதுப்பிப்புகளை உங்கள் நிர்வாகி தடுத்துள்ளார்</translation>
 <translation id="1782196717298160133">ஃபோனைக் கண்டறிகிறது</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 குறிப்பு}other{# குறிப்புகள்}}</translation>
@@ -1627,7 +1625,6 @@
 <translation id="2187895286714876935">சேவையக சான்றிதழ் இறக்குமதி பிழை</translation>
 <translation id="2187906491731510095">நீட்டிப்புகள் புதுப்பிக்கப்பட்டன</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" />ஐத் திற</translation>
-<translation id="2189787291884708275">உலாவிப் பக்கத்தின் ஆடியோவைப் பகிர்</translation>
 <translation id="2190069059097339078">வைஃபை கிரெடென்ஷியல் கெட்டர்</translation>
 <translation id="219008588003277019">நேட்டிவ் கிளையன்ட் மாடியூல்: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(காலி)</translation>
@@ -5301,6 +5298,7 @@
 <translation id="4998430619171209993">ஆன் செய்யப்பட்டுள்ளது</translation>
 <translation id="4999804342505941663">‘தொந்தரவு செய்ய வேண்டாம்’ அம்சத்தை இயக்குதல்</translation>
 <translation id="5001526427543320409">மூன்றாம் தரப்புக் குக்கீகள்</translation>
+<translation id="5003993274120026347">அடுத்த வாக்கியம்</translation>
 <translation id="5005498671520578047">கடவுச்சொல்லை நகலெடு</translation>
 <translation id="5006118752738286774">2 ஆண்டுகளுக்கு முன்பு</translation>
 <translation id="5006218871145547804">Crostini Android ஆப்ஸ் ADB</translation>
@@ -9227,6 +9225,7 @@
 <translation id="8033958968890501070">நேரம் முடிந்தது</translation>
 <translation id="8035059678007243127">‘முன் பின் பக்கங்களைத் தற்காலிகமாகச் சேமித்தல்’ அம்சத்தில் சேமிக்கப்பட்ட மறைநிலைப் பக்கம்: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">தன்னிரப்பியை மேம்படுத்த உதவுங்கள்</translation>
+<translation id="8036504271468642248">முந்தைய வாக்கியம்</translation>
 <translation id="8037117027592400564">தொகுக்கப்பட்ட பேச்சைப் பயன்படுத்திப் பேசப்படும் எல்லா உரையையும் படிக்கலாம்</translation>
 <translation id="8037357227543935929">கேள் (இயல்பு)</translation>
 <translation id="803771048473350947">ஃபைல்</translation>
diff --git a/chrome/app/resources/generated_resources_te.xtb b/chrome/app/resources/generated_resources_te.xtb
index d12da34..cea390a 100644
--- a/chrome/app/resources/generated_resources_te.xtb
+++ b/chrome/app/resources/generated_resources_te.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">ఎడిటింగ్‌ను అనుమతించండి</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{ఫైల్‌ను తెరవడం సాధ్యపడదు}other{ఫైల్స్‌ను తెరవడం సాధ్యపడదు}}</translation>
 <translation id="1282311502488501110">సైన్ ఇన్ చేయవద్దు</translation>
-<translation id="1282465000333679776">సిస్టమ్ ఆడియోను షేర్ చేయండి</translation>
 <translation id="1283126956823499975">పరికరాన్ని సెటప్ చేయడంలో ఏదో పొరపాటు జరిగింది</translation>
 <translation id="1284277788676816155">డేటాను సేవ్ చేయడానికి సైట్‌ను అనుమతించవద్దు</translation>
 <translation id="1285320974508926690">ఈ సైట్‌ను ఎప్పటికీ అనువదించవద్దు</translation>
@@ -1060,7 +1059,6 @@
 <translation id="1781502536226964113">కొత్త‌ ట్యాబ్ పేజీని తెరవండి</translation>
 <translation id="1781553166608855614">మాట్లాడే భాష</translation>
 <translation id="1781771911845953849">ఖాతాలు మరియు సింక్‌</translation>
-<translation id="1781979858217752599">విండో ఆడియోను షేర్ చేయండి</translation>
 <translation id="1782101999402987960">మీ అడ్మినిస్ట్రేటర్ ద్వారా అప్‌డేట్‌లు బ్లాక్ చేయబడ్డాయి</translation>
 <translation id="1782196717298160133">మీ ఫోన్‌ను కనుగొంటోంది</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 గమనిక}other{# గమనికలు}}</translation>
@@ -1625,7 +1623,6 @@
 <translation id="2187895286714876935">సర్వర్ ప్రమాణపత్రం దిగుమతి ఎర్రర్</translation>
 <translation id="2187906491731510095">ఎక్స్‌టెన్షన్‌లు అప్‌డేట్ చేయబడ్డాయి</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" />ని తెరువు</translation>
-<translation id="2189787291884708275">ట్యాబ్ ఆడియోను షేర్ చేయండి</translation>
 <translation id="2190069059097339078">WiFi క్రెడెన్షియల్స్ గెట్టర్</translation>
 <translation id="219008588003277019">స్థానిక క్లయింట్ మాడ్యూల్: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(ఖాళీ)</translation>
@@ -5299,6 +5296,7 @@
 <translation id="4998430619171209993">ఆన్‌లో ఉంది</translation>
 <translation id="4999804342505941663">'అంతరాయం కలిగించవద్దు'ను ఆన్ చేయండి</translation>
 <translation id="5001526427543320409">థర్డ్-పార్టీ కుక్కీలు</translation>
+<translation id="5003993274120026347">తర్వాతి వాక్యం</translation>
 <translation id="5005498671520578047">పాస్‌వర్డ్ కాపీచేయడం</translation>
 <translation id="5006118752738286774">2 సంవత్సరాల క్రితం</translation>
 <translation id="5006218871145547804">Crostini Android యాప్ ADB</translation>
@@ -9220,6 +9218,7 @@
 <translation id="8033958968890501070">సమయం ముగిసింది</translation>
 <translation id="8035059678007243127">అజ్ఞాత వెనుకకు-ముందుకు కాష్ పేజీ: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">ఆటోఫిల్‌ను మెరుగుపరచడంలో సహాయపడండి</translation>
+<translation id="8036504271468642248">మునుపటి వాక్యం</translation>
 <translation id="8037117027592400564">సంశ్లేషణ ప్రసంగాన్ని ఉపయోగించి మాట్లాడిన మొత్తం వచనాన్ని చదవడం</translation>
 <translation id="8037357227543935929">అడగాలి (డిఫాల్ట్)</translation>
 <translation id="803771048473350947">ఫైల్</translation>
diff --git a/chrome/app/resources/generated_resources_th.xtb b/chrome/app/resources/generated_resources_th.xtb
index 4690b0c..c089545 100644
--- a/chrome/app/resources/generated_resources_th.xtb
+++ b/chrome/app/resources/generated_resources_th.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">แก้ไขไฟล์</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{เปิดไฟล์ไม่ได้}other{เปิดไฟล์ไม่ได้}}</translation>
 <translation id="1282311502488501110">ไม่ต้องลงชื่อเข้าใช้</translation>
-<translation id="1282465000333679776">แชร์เสียงของระบบ</translation>
 <translation id="1283126956823499975">เกิดข้อผิดพลาดในการตั้งค่าอุปกรณ์</translation>
 <translation id="1284277788676816155">ไม่อนุญาตให้บันทึกข้อมูล</translation>
 <translation id="1285320974508926690">ไม่ต้องแปลเว็บไซต์นี้</translation>
@@ -1051,7 +1050,6 @@
 <translation id="1781502536226964113">เปิดหน้าแท็บใหม่</translation>
 <translation id="1781553166608855614">ภาษาที่พูด</translation>
 <translation id="1781771911845953849">บัญชีและการซิงค์</translation>
-<translation id="1781979858217752599">แชร์เสียงของหน้าต่าง</translation>
 <translation id="1782101999402987960">ผู้ดูแลระบบได้บล็อกการอัปเดต</translation>
 <translation id="1782196717298160133">กำลังค้นหาโทรศัพท์ของคุณ</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{โน้ต 1 รายการ}other{โน้ต # รายการ}}</translation>
@@ -1615,7 +1613,6 @@
 <translation id="2187895286714876935">ข้อผิดพลาดในการนำเข้าใบรับรองเซิร์ฟเวอร์</translation>
 <translation id="2187906491731510095">อัปเดตส่วนขยายแล้ว</translation>
 <translation id="2188881192257509750">เปิด <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">แชร์เสียงของแท็บ</translation>
 <translation id="2190069059097339078">ตัวรับข้อมูลรับรอง Wi-Fi</translation>
 <translation id="219008588003277019">โมดูล Native Client: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(ว่างเปล่า)</translation>
@@ -5285,6 +5282,7 @@
 <translation id="4998430619171209993">เปิด</translation>
 <translation id="4999804342505941663">เปิดโหมดห้ามรบกวน</translation>
 <translation id="5001526427543320409">คุกกี้ของบุคคลที่สาม</translation>
+<translation id="5003993274120026347">ประโยคถัดไป</translation>
 <translation id="5005498671520578047">คัดลอกรหัสผ่าน</translation>
 <translation id="5006118752738286774">2 ปีที่ผ่านมา</translation>
 <translation id="5006218871145547804">ADB ของแอป Android ใน Crostini</translation>
@@ -9206,6 +9204,7 @@
 <translation id="8033958968890501070">หมดเวลา</translation>
 <translation id="8035059678007243127">หน้าแคชย้อนหลังในโหมดไม่ระบุตัวตน: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">ช่วยปรับปรุงการป้อนข้อความอัตโนมัติ</translation>
+<translation id="8036504271468642248">ประโยคก่อนหน้า</translation>
 <translation id="8037117027592400564">อ่านข้อความทั้งหมดที่พูดโดยใช้เสียงสังเคราะห์</translation>
 <translation id="8037357227543935929">ขอ (ค่าเริ่มต้น)</translation>
 <translation id="803771048473350947">ไฟล์</translation>
diff --git a/chrome/app/resources/generated_resources_tr.xtb b/chrome/app/resources/generated_resources_tr.xtb
index 6ffb376..189cacb 100644
--- a/chrome/app/resources/generated_resources_tr.xtb
+++ b/chrome/app/resources/generated_resources_tr.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">Dosyaları düzenle</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Dosya açılamıyor}other{Dosyalar açılamıyor}}</translation>
 <translation id="1282311502488501110">Oturum Açma</translation>
-<translation id="1282465000333679776">Sistem sesini paylaş</translation>
 <translation id="1283126956823499975">Cihaz kurulurken bir hata oluştu</translation>
 <translation id="1284277788676816155">Veri kaydetmeye izin verme</translation>
 <translation id="1285320974508926690">Bu siteyi asla çevirme</translation>
@@ -1051,7 +1050,6 @@
 <translation id="1781502536226964113">Yeni Sekme sayfasını aç</translation>
 <translation id="1781553166608855614">Konuşma dili</translation>
 <translation id="1781771911845953849">Hesaplar ve senkronizasyon</translation>
-<translation id="1781979858217752599">Pencere sesini paylaş</translation>
 <translation id="1782101999402987960">Güncellemeler yöneticiniz tarafından engellendi</translation>
 <translation id="1782196717298160133">Telefonunuz bulunuyor</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 Not:}other{# Not}}</translation>
@@ -1614,7 +1612,6 @@
 <translation id="2187895286714876935">Sunucu Sertifikası İçe Aktarma Hatası</translation>
 <translation id="2187906491731510095">Uzantılar güncellendi</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> adlı uygulamayı aç</translation>
-<translation id="2189787291884708275">Sekme sesini paylaş</translation>
 <translation id="2190069059097339078">WiFi Credentials Getter</translation>
 <translation id="219008588003277019">Özgün İstemci modülü: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(boş)</translation>
@@ -5283,6 +5280,7 @@
 <translation id="4998430619171209993">Açık</translation>
 <translation id="4999804342505941663">Rahatsız Etmeyin özelliğini aç</translation>
 <translation id="5001526427543320409">Üçüncü taraf çerezleri</translation>
+<translation id="5003993274120026347">Sonraki cümle</translation>
 <translation id="5005498671520578047">Şifreyi kopyalayın</translation>
 <translation id="5006118752738286774">2 yıl önce</translation>
 <translation id="5006218871145547804">Crostini Android uygulaması ADB'si</translation>
@@ -9208,6 +9206,7 @@
 <translation id="8033958968890501070">Zaman aşımı</translation>
 <translation id="8035059678007243127">Gizli Geri/İleri Önbelleğe Alınmış Sayfa: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Otomatik doldurma özelliğinin iyileştirilmesine yardım edin</translation>
+<translation id="8036504271468642248">Önceki cümle</translation>
 <translation id="8037117027592400564">Sentezlenmiş konuşma özelliği kullanılarak söylenen tüm metni okuma</translation>
 <translation id="8037357227543935929">Sor (varsayılan)</translation>
 <translation id="803771048473350947">Dosya</translation>
diff --git a/chrome/app/resources/generated_resources_uk.xtb b/chrome/app/resources/generated_resources_uk.xtb
index 5b63f78..024801d 100644
--- a/chrome/app/resources/generated_resources_uk.xtb
+++ b/chrome/app/resources/generated_resources_uk.xtb
@@ -387,7 +387,6 @@
 <translation id="1280965841156951489">Змінити файли</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Не вдалося відкрити файл}one{Не вдалося відкрити файли}few{Не вдалося відкрити файли}many{Не вдалося відкрити файли}other{Не вдалося відкрити файли}}</translation>
 <translation id="1282311502488501110">Не входити</translation>
-<translation id="1282465000333679776">Надати доступ до системного аудіо</translation>
 <translation id="1283126956823499975">Не вдалося налаштувати пристрій</translation>
 <translation id="1284277788676816155">Не дозволяти зберігати дані</translation>
 <translation id="1285320974508926690">Ніколи не перекладати цей сайт</translation>
@@ -1065,7 +1064,6 @@
 <translation id="1781502536226964113">Відкрити сторінку нової вкладки</translation>
 <translation id="1781553166608855614">Синтез мовлення</translation>
 <translation id="1781771911845953849">Облікові записи та синхронізація</translation>
-<translation id="1781979858217752599">Надати доступ до аудіо у вікні</translation>
 <translation id="1782101999402987960">Адміністратор заблокував оновлення</translation>
 <translation id="1782196717298160133">Пошук вашого телефона</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 нотатка}one{# нотатка}few{# нотатки}many{# нотаток}other{# нотатки}}</translation>
@@ -1630,7 +1628,6 @@
 <translation id="2187895286714876935">Помилка імпортування сертифіката сервера</translation>
 <translation id="2187906491731510095">Розширення оновлено</translation>
 <translation id="2188881192257509750">Відкрити <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Надати доступ до аудіо на вкладці</translation>
 <translation id="2190069059097339078">Засіб отримання облікових даних Wi-Fi</translation>
 <translation id="219008588003277019">Модуль Native Client: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(пусто)</translation>
@@ -5304,6 +5301,7 @@
 <translation id="4998430619171209993">Увімкнено</translation>
 <translation id="4999804342505941663">Увімкнути режим "Не турбувати"</translation>
 <translation id="5001526427543320409">Сторонні файли cookie</translation>
+<translation id="5003993274120026347">Наступне речення</translation>
 <translation id="5005498671520578047">Копіювати пароль</translation>
 <translation id="5006118752738286774">2 роки тому</translation>
 <translation id="5006218871145547804">ADB в додатках для Android у Crostini</translation>
@@ -9231,6 +9229,7 @@
 <translation id="8033958968890501070">Час очікування минув</translation>
 <translation id="8035059678007243127">Сторінка зворотного кешу в анонімному режимі: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Допоможіть покращити функцію автозаповнення</translation>
+<translation id="8036504271468642248">Попереднє речення</translation>
 <translation id="8037117027592400564">Читати весь текст, відтворений за допомогою синтезованого мовлення</translation>
 <translation id="8037357227543935929">Запитувати (за умовчанням)</translation>
 <translation id="803771048473350947">Файл</translation>
diff --git a/chrome/app/resources/generated_resources_ur.xtb b/chrome/app/resources/generated_resources_ur.xtb
index 657d1529..bc19619 100644
--- a/chrome/app/resources/generated_resources_ur.xtb
+++ b/chrome/app/resources/generated_resources_ur.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">فائلز میں ترمیم کریں</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{فائل نہیں کھل سکتی ہے}other{فائلز نہیں کھل سکتی ہیں}}</translation>
 <translation id="1282311502488501110">سائن ان نہ کریں</translation>
-<translation id="1282465000333679776">سسٹم آڈیو کا اشتراک کریں</translation>
 <translation id="1283126956823499975">آلے کو سیٹ اپ کرنے کے ساتھ کچھ غلط ہو گیا</translation>
 <translation id="1284277788676816155">ڈیٹا محفوظ کرنے کی اجازت نہ دیں</translation>
 <translation id="1285320974508926690">اس سائٹ کا ترجمہ کبھی نہ کریں</translation>
@@ -1051,7 +1050,6 @@
 <translation id="1781502536226964113">نیا ٹیب صفحہ کھولیں</translation>
 <translation id="1781553166608855614">بول چال کی زبان</translation>
 <translation id="1781771911845953849">اکاؤنٹس اور مطابقت پذیری</translation>
-<translation id="1781979858217752599">ونڈو آڈیو کا اشتراک کریں</translation>
 <translation id="1782101999402987960">آپ کے منتظم کی جانب سے اپ ڈیٹس کو مسدود کر دیا گیا</translation>
 <translation id="1782196717298160133">آپ کا فون تلاش کرنا</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 نوٹ}other{# نوٹس}}</translation>
@@ -1616,7 +1614,6 @@
 <translation id="2187895286714876935">سرور سرٹیفکیٹ کی درآمد میں خرابی</translation>
 <translation id="2187906491731510095">ایکسٹینشنز اپ ڈیٹ ہو گئیں</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> کھولیں</translation>
-<translation id="2189787291884708275">ٹیب آڈیو کا اشتراک کریں</translation>
 <translation id="2190069059097339078">‏WiFi اسناد حاصل کنندہ</translation>
 <translation id="219008588003277019">‏Native Client ماڈیول: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(خالی)</translation>
@@ -5287,6 +5284,7 @@
 <translation id="4998430619171209993">آن</translation>
 <translation id="4999804342505941663">'ڈسٹرب نہ کریں' کو آن کریں</translation>
 <translation id="5001526427543320409">فریق ثالث کوکیز</translation>
+<translation id="5003993274120026347">اگلا جملہ</translation>
 <translation id="5005498671520578047">پاس ورڈ کاپی کریں</translation>
 <translation id="5006118752738286774">2 سال پہلے</translation>
 <translation id="5006218871145547804">‏Crostini Android ایپ ADB</translation>
@@ -9209,6 +9207,7 @@
 <translation id="8033958968890501070">وقت ختم ہو گیا</translation>
 <translation id="8035059678007243127">بیک/فارورڈکیش کردہ پوشیدگی صفحہ: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">آٹو فل کو بہتر بنانے میں مدد کریں</translation>
+<translation id="8036504271468642248">پچھلا جملہ</translation>
 <translation id="8037117027592400564">سنتھیسائز کردہ اسپیچ کا استعمال کر کے بولے گئے سبھی متن کو پڑھیں</translation>
 <translation id="8037357227543935929">پوچھیں (ڈیفالٹ)</translation>
 <translation id="803771048473350947">فائل</translation>
diff --git a/chrome/app/resources/generated_resources_uz.xtb b/chrome/app/resources/generated_resources_uz.xtb
index 814c081..3dd7c4d 100644
--- a/chrome/app/resources/generated_resources_uz.xtb
+++ b/chrome/app/resources/generated_resources_uz.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">Fayllarni tahrirlash</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Fayl ochilmadi}other{Fayllar ochilmadi}}</translation>
 <translation id="1282311502488501110">Kirilmasin</translation>
-<translation id="1282465000333679776">Tizim audiosini ulashish</translation>
 <translation id="1283126956823499975">Qurilmani sozlashda nimadir xato ketdi</translation>
 <translation id="1284277788676816155">Maʼlumotlarni saqlashni taqiqlash</translation>
 <translation id="1285320974508926690">Bu sayt hech qachon tarjima qilinmasin</translation>
@@ -1049,7 +1048,6 @@
 <translation id="1781502536226964113">Yangi varaq sahifasini ochish</translation>
 <translation id="1781553166608855614">Nutq tili</translation>
 <translation id="1781771911845953849">Hisoblar va sinxronizatsiya</translation>
-<translation id="1781979858217752599">Oyna audiosini ulashish</translation>
 <translation id="1782101999402987960">Yangilanishlar administrator tomonidan bloklangan</translation>
 <translation id="1782196717298160133">Telefon qidiruvi</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 ta qayd}other{# ta qayd}}</translation>
@@ -1614,7 +1612,6 @@
 <translation id="2187895286714876935">Server sertifikatini import qilishda xatolik yuz berdi</translation>
 <translation id="2187906491731510095">Kengaytmalar yangilandi</translation>
 <translation id="2188881192257509750"><ph name="APPLICATION" /> ilovasini ochish</translation>
-<translation id="2189787291884708275">Varaq audiosini ulashish</translation>
 <translation id="2190069059097339078">Wi-Fi ruxsat parametrlarini qabul qilish</translation>
 <translation id="219008588003277019">Native Client moduli: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(bo‘sh)</translation>
@@ -5288,6 +5285,7 @@
 <translation id="4998430619171209993">Yoniq</translation>
 <translation id="4999804342505941663">Bezovta qilinmasin rejimini yoqing</translation>
 <translation id="5001526427543320409">Tashqi cookie fayllar</translation>
+<translation id="5003993274120026347">Keyingi gap</translation>
 <translation id="5005498671520578047">Parolni nusxalash</translation>
 <translation id="5006118752738286774">2 yil oldin</translation>
 <translation id="5006218871145547804">Crostini tizimida Android ilovalar uchun ADB vositasi</translation>
@@ -9210,6 +9208,7 @@
 <translation id="8033958968890501070">Vaqt tugadi</translation>
 <translation id="8035059678007243127">Inkognito rejimida orqaga qaytarilgan kesh sahifasi: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Avtomatik kiritishni yaxshilashga yordam bering</translation>
+<translation id="8036504271468642248">Avvalgi gap</translation>
 <translation id="8037117027592400564">Nutq sintezatori orqali barcha matnni ovozli o‘qish</translation>
 <translation id="8037357227543935929">So‘ralsin (standart sozlama)</translation>
 <translation id="803771048473350947">Fayl</translation>
diff --git a/chrome/app/resources/generated_resources_vi.xtb b/chrome/app/resources/generated_resources_vi.xtb
index 8451a98..b3e2593 100644
--- a/chrome/app/resources/generated_resources_vi.xtb
+++ b/chrome/app/resources/generated_resources_vi.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">Chỉnh sửa tệp</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Không thể mở tệp}other{Không thể mở các tệp}}</translation>
 <translation id="1282311502488501110">Không đăng nhập</translation>
-<translation id="1282465000333679776">Chia sẻ âm thanh của hệ thống</translation>
 <translation id="1283126956823499975">Đã xảy ra lỗi khi thiết lập thiết bị</translation>
 <translation id="1284277788676816155">Không cho phép lưu dữ liệu</translation>
 <translation id="1285320974508926690">Không bao giờ dịch trang web này</translation>
@@ -1062,7 +1061,6 @@
 <translation id="1781502536226964113">Mở trang thẻ mới</translation>
 <translation id="1781553166608855614">Ngôn ngữ nói</translation>
 <translation id="1781771911845953849">Tài khoản và đồng bộ hóa</translation>
-<translation id="1781979858217752599">Chia sẻ âm thanh trên cửa sổ</translation>
 <translation id="1782101999402987960">Quản trị viên của bạn đã chặn các bản cập nhật</translation>
 <translation id="1782196717298160133">Tìm điện thoại của bạn</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 ghi chú}other{# ghi chú}}</translation>
@@ -1627,7 +1625,6 @@
 <translation id="2187895286714876935">Lỗi nhập chứng chỉ máy chủ</translation>
 <translation id="2187906491731510095">Đã cập nhật tiện ích</translation>
 <translation id="2188881192257509750">Mở <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Chia sẻ âm thanh của thẻ</translation>
 <translation id="2190069059097339078">Trình nhận thông tin đăng nhập WiFi</translation>
 <translation id="219008588003277019">Mô-đun Ứng dụng khách Gốc: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(trống)</translation>
@@ -5301,6 +5298,7 @@
 <translation id="4998430619171209993">Đang bật</translation>
 <translation id="4999804342505941663">Bật chế độ Không làm phiền</translation>
 <translation id="5001526427543320409">Cookie của bên thứ ba</translation>
+<translation id="5003993274120026347">Câu tiếp theo</translation>
 <translation id="5005498671520578047">Sao chép mật khẩu</translation>
 <translation id="5006118752738286774">2 năm trước</translation>
 <translation id="5006218871145547804">Cầu gỡ lỗi Android (ADB) cho ứng dụng Android trong Crostini</translation>
@@ -9228,6 +9226,7 @@
 <translation id="8033958968890501070">Hết giờ</translation>
 <translation id="8035059678007243127">Trang ẩn danh lưu trong bộ nhớ đệm cho thao tác tiến/lùi: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Góp phần cải thiện tính năng Tự động điền</translation>
+<translation id="8036504271468642248">Câu trước</translation>
 <translation id="8037117027592400564">Đọc tất cả văn bản được nói bằng giọng nói tổng hợp</translation>
 <translation id="8037357227543935929">Yêu cầu (mặc định)</translation>
 <translation id="803771048473350947">Tệp</translation>
diff --git a/chrome/app/resources/generated_resources_zh-CN.xtb b/chrome/app/resources/generated_resources_zh-CN.xtb
index 3bdcef3..df80218 100644
--- a/chrome/app/resources/generated_resources_zh-CN.xtb
+++ b/chrome/app/resources/generated_resources_zh-CN.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">修改文件</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{无法打开文件}other{无法打开文件}}</translation>
 <translation id="1282311502488501110">不登录</translation>
-<translation id="1282465000333679776">分享系统中的音频</translation>
 <translation id="1283126956823499975">设置设备时出了点问题</translation>
 <translation id="1284277788676816155">不允许保存数据</translation>
 <translation id="1285320974508926690">一律不翻译此网站</translation>
@@ -1046,7 +1045,6 @@
 <translation id="1781502536226964113">打开新标签页</translation>
 <translation id="1781553166608855614">语音采用的语言</translation>
 <translation id="1781771911845953849">账号和同步</translation>
-<translation id="1781979858217752599">分享窗口中的音频</translation>
 <translation id="1782101999402987960">您的管理员已禁止进行更新</translation>
 <translation id="1782196717298160133">正在查找您的手机</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 条记事}other{# 条记事}}</translation>
@@ -1608,7 +1606,6 @@
 <translation id="2187895286714876935">服务器证书导入错误</translation>
 <translation id="2187906491731510095">扩展程序已更新</translation>
 <translation id="2188881192257509750">打开<ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">分享标签页中的音频</translation>
 <translation id="2190069059097339078">WiFi 凭据获取工具</translation>
 <translation id="219008588003277019">Native Client 模块:<ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(空)</translation>
@@ -5276,6 +5273,7 @@
 <translation id="4998430619171209993">已开启</translation>
 <translation id="4999804342505941663">开启“勿扰”模式</translation>
 <translation id="5001526427543320409">第三方 Cookie</translation>
+<translation id="5003993274120026347">下一句</translation>
 <translation id="5005498671520578047">复制密码</translation>
 <translation id="5006118752738286774">2 年前</translation>
 <translation id="5006218871145547804">Crostini Android 应用 ADB</translation>
@@ -9198,6 +9196,7 @@
 <translation id="8033958968890501070">已超时</translation>
 <translation id="8035059678007243127">无痕式往返缓存版页面:<ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">帮助改进自动填充功能</translation>
+<translation id="8036504271468642248">上一句</translation>
 <translation id="8037117027592400564">读取使用合成语音说出的所有文字</translation>
 <translation id="8037357227543935929">询问(默认)</translation>
 <translation id="803771048473350947">文件</translation>
diff --git a/chrome/app/resources/generated_resources_zh-HK.xtb b/chrome/app/resources/generated_resources_zh-HK.xtb
index a888dba0..3dae7de 100644
--- a/chrome/app/resources/generated_resources_zh-HK.xtb
+++ b/chrome/app/resources/generated_resources_zh-HK.xtb
@@ -384,7 +384,6 @@
 <translation id="1280965841156951489">編輯檔案</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{無法開啟檔案}other{無法開啟檔案}}</translation>
 <translation id="1282311502488501110">不登入</translation>
-<translation id="1282465000333679776">分享系統音訊</translation>
 <translation id="1283126956823499975">設定裝置時發生問題</translation>
 <translation id="1284277788676816155">不允許儲存資料</translation>
 <translation id="1285320974508926690">永不翻譯此網站</translation>
@@ -1061,7 +1060,6 @@
 <translation id="1781502536226964113">開啟新分頁</translation>
 <translation id="1781553166608855614">使用的語言</translation>
 <translation id="1781771911845953849">帳戶同埋同步處理</translation>
-<translation id="1781979858217752599">分享視窗音訊</translation>
 <translation id="1782101999402987960">您的管理員已封鎖更新</translation>
 <translation id="1782196717298160133">正在搜尋您的手機</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 份筆記}other{# 份筆記}}</translation>
@@ -1627,7 +1625,6 @@
 <translation id="2187895286714876935">伺服器憑證匯入錯誤</translation>
 <translation id="2187906491731510095">擴充程式更新咗</translation>
 <translation id="2188881192257509750">開啟 <ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">分享分頁音訊</translation>
 <translation id="2190069059097339078">WiFi 憑證取得工具</translation>
 <translation id="219008588003277019">Native Client 模組:<ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(空白)</translation>
@@ -5297,6 +5294,7 @@
 <translation id="4998430619171209993">開啟</translation>
 <translation id="4999804342505941663">開啟「請勿騷擾」</translation>
 <translation id="5001526427543320409">第三方 Cookie</translation>
+<translation id="5003993274120026347">下一句</translation>
 <translation id="5005498671520578047">複製密碼</translation>
 <translation id="5006118752738286774">2 年前</translation>
 <translation id="5006218871145547804">Crostini 的 Android 應用程式 ADB</translation>
@@ -9219,6 +9217,7 @@
 <translation id="8033958968890501070">逾時</translation>
 <translation id="8035059678007243127">向前/返回快取中的無痕頁面:<ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">協助改善「自動填入」功能</translation>
+<translation id="8036504271468642248">上一句</translation>
 <translation id="8037117027592400564">讀取使用合成語音朗讀的所有文字</translation>
 <translation id="8037357227543935929">要求 (預設)</translation>
 <translation id="803771048473350947">檔案</translation>
diff --git a/chrome/app/resources/generated_resources_zh-TW.xtb b/chrome/app/resources/generated_resources_zh-TW.xtb
index 12debe7f..b82ea4b 100644
--- a/chrome/app/resources/generated_resources_zh-TW.xtb
+++ b/chrome/app/resources/generated_resources_zh-TW.xtb
@@ -382,7 +382,6 @@
 <translation id="1280965841156951489">編輯檔案</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{無法開啟檔案}other{無法開啟檔案}}</translation>
 <translation id="1282311502488501110">不登入</translation>
-<translation id="1282465000333679776">分享系統音訊</translation>
 <translation id="1283126956823499975">設定裝置時發生錯誤</translation>
 <translation id="1284277788676816155">不允許儲存資料</translation>
 <translation id="1285320974508926690">一律不翻譯此網站</translation>
@@ -1051,7 +1050,6 @@
 <translation id="1781502536226964113">開啟新分頁</translation>
 <translation id="1781553166608855614">使用的語言</translation>
 <translation id="1781771911845953849">帳戶與同步處理</translation>
-<translation id="1781979858217752599">分享視窗音訊</translation>
 <translation id="1782101999402987960">管理員已禁止更新作業</translation>
 <translation id="1782196717298160133">搜尋你的手機</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{1 則記事}other{# 則記事}}</translation>
@@ -1615,7 +1613,6 @@
 <translation id="2187895286714876935">伺服器憑證匯入錯誤</translation>
 <translation id="2187906491731510095">擴充功能已更新</translation>
 <translation id="2188881192257509750">開啟「<ph name="APPLICATION" />」</translation>
-<translation id="2189787291884708275">分享分頁音訊</translation>
 <translation id="2190069059097339078">WiFi 憑證擷取工具</translation>
 <translation id="219008588003277019">Native Client 模組:<ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(空白)</translation>
@@ -5284,6 +5281,7 @@
 <translation id="4998430619171209993">開啟</translation>
 <translation id="4999804342505941663">開啟「零打擾」模式</translation>
 <translation id="5001526427543320409">第三方 Cookie</translation>
+<translation id="5003993274120026347">下一句</translation>
 <translation id="5005498671520578047">複製密碼</translation>
 <translation id="5006118752738286774">2 年前</translation>
 <translation id="5006218871145547804">Crostini Android 應用程式 ADB</translation>
@@ -9205,6 +9203,7 @@
 <translation id="8033958968890501070">逾時</translation>
 <translation id="8035059678007243127">無痕模式往返快取頁面:<ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">協助改善自動填入功能</translation>
+<translation id="8036504271468642248">上一句</translation>
 <translation id="8037117027592400564">讀取使用合成語音朗讀的所有文字</translation>
 <translation id="8037357227543935929">詢問 (預設)</translation>
 <translation id="803771048473350947">檔案</translation>
diff --git a/chrome/app/resources/generated_resources_zu.xtb b/chrome/app/resources/generated_resources_zu.xtb
index 4a89568..fd4a78e 100644
--- a/chrome/app/resources/generated_resources_zu.xtb
+++ b/chrome/app/resources/generated_resources_zu.xtb
@@ -385,7 +385,6 @@
 <translation id="1280965841156951489">Hlela amafayela</translation>
 <translation id="1281746473742296584">{NUM_OF_FILES,plural, =1{Ayikwazi ukuvula ifayela}one{Ayikwazi ukuvula amafayela}other{Ayikwazi ukuvula amafayela}}</translation>
 <translation id="1282311502488501110">Ungangeni ngemvume</translation>
-<translation id="1282465000333679776">Yabelana ngomsindo wesistimu</translation>
 <translation id="1283126956823499975">Kukhona okungahambanga kahle ngokusetha idivayisi</translation>
 <translation id="1284277788676816155">Ungavumeli ukulondoloza idatha</translation>
 <translation id="1285320974508926690">Ungalokothi uhumushe leli sayithi</translation>
@@ -1061,7 +1060,6 @@
 <translation id="1781502536226964113">Vula ikhasi lethebhu entsha</translation>
 <translation id="1781553166608855614">Ulimi olukhulunywayo</translation>
 <translation id="1781771911845953849">Ama-akhawunti nokuvumelanisa</translation>
-<translation id="1781979858217752599">Yabelana ngomsindo wewindi</translation>
 <translation id="1782101999402987960">Izibuyekezo zivinjelwe umlawuli wakho</translation>
 <translation id="1782196717298160133">Thola ifoni yakho</translation>
 <translation id="1782541958479207225">{NUM_NOTES,plural, =1{Inothi eli-1}one{Amanothi angu-#}other{Amanothi angu-#}}</translation>
@@ -1627,7 +1625,6 @@
 <translation id="2187895286714876935">Iphutha lokungenisa isitifiketi seseva</translation>
 <translation id="2187906491731510095">Izandiso zubuyekeziwe</translation>
 <translation id="2188881192257509750">Vula i-<ph name="APPLICATION" /></translation>
-<translation id="2189787291884708275">Yabelana ngomsindo wethebhu</translation>
 <translation id="2190069059097339078">Isitholi sokuqinisekisa i-Wi-Fi</translation>
 <translation id="219008588003277019">Imojuli yeklayenti lomdabu: <ph name="NEXE_NAME" /></translation>
 <translation id="2190355936436201913">(lutho)</translation>
@@ -5301,6 +5298,7 @@
 <translation id="4998430619171209993">Vuliwe</translation>
 <translation id="4999804342505941663">Vula ukungaphazamisi</translation>
 <translation id="5001526427543320409">Amakhukhi wongahlangene ngqo</translation>
+<translation id="5003993274120026347">Umusho olandelayo</translation>
 <translation id="5005498671520578047">Kopisha iphasiwedi</translation>
 <translation id="5006118752738286774">Iminyaka emi-2 edlule</translation>
 <translation id="5006218871145547804">I-ADB yohlelo lokusebenza le-Crostini Android</translation>
@@ -9226,6 +9224,7 @@
 <translation id="8033958968890501070">Ukuphela kwesikhathi</translation>
 <translation id="8035059678007243127">Ikhasi Lenqolobane Yasemuva-Phambili le-Incognito: <ph name="BACK_FORWARD_CACHE_INCOGNITO_PAGE_URL" /></translation>
 <translation id="8036193484521570992">Siza ukuthuthukisa Ukugcwalisa okuzenzakalelayo</translation>
+<translation id="8036504271468642248">Umusho wangaphambilini</translation>
 <translation id="8037117027592400564">Funda wonke umbhalo okhulunywayo usebenzisa inkulumo ekhulisiwe</translation>
 <translation id="8037357227543935929">Buza (okuzenzakalelayo)</translation>
 <translation id="803771048473350947">Ifayela</translation>
diff --git a/chrome/app/resources/google_chrome_strings_id.xtb b/chrome/app/resources/google_chrome_strings_id.xtb
index ad7f0f77..7aebfa5c 100644
--- a/chrome/app/resources/google_chrome_strings_id.xtb
+++ b/chrome/app/resources/google_chrome_strings_id.xtb
@@ -246,6 +246,7 @@
 <translation id="4793679854893018356">Pelajari cara Chrome menjaga keamanan Anda</translation>
 <translation id="4828579605166583682">Google Chrome mencoba mengganti sandi yang ada. Ketik sandi Windows Anda untuk mengizinkannya.</translation>
 <translation id="4842397268809523050">ChromeOS Flex tidak dapat menyinkronkan data Anda karena Sinkronisasi tidak tersedia untuk domain Anda.</translation>
+<translation id="4862446263930606916">Organisasi Anda dapat melihat dan mengelola data penjelajahan di profil kerja Anda, seperti bookmark, histori, dan sandi. Organisasi Anda tidak dapat melihat data penjelajahan di profil Chrome pribadi.</translation>
 <translation id="4873692836499071887">Untuk mendapatkan update Google Chrome berikutnya, Anda memerlukan macOS 11 atau yang lebih baru. Komputer ini menggunakan macOS 10.15.</translation>
 <translation id="4873783916118289636">Meninjau kontrol privasi dan keamanan utama di Chrome</translation>
 <translation id="4891791193823137474">Jalankan Google Chrome di latar belakang</translation>
@@ -490,6 +491,7 @@
 <translation id="8989968390305463310">Histori penjelajahan Anda memengaruhi iklan yang Anda lihat dan minat yang diperkirakan di bawah. Untuk melindungi privasi Anda, Chrome otomatis menghapus minat Anda secara berkala setiap bulan. Minat dapat diperbarui kecuali jika Anda menghapusnya.</translation>
 <translation id="8999117580775242387">Jika HTTPS tidak tersedia, Chrome akan menggunakan koneksi yang tidak aman tanpa memperingatkan Anda</translation>
 <translation id="8999208279178790196">{0,plural, =0{Update Chrome tersedia}=1{Update Chrome tersedia}other{Update Chrome telah tersedia selama # hari}}</translation>
+<translation id="9024318700713112071">Setel Chrome sebagai browser default</translation>
 <translation id="9053892488859122171">Sistem ChromeOS Flex</translation>
 <translation id="9090566250983691233">Pelajari alasan Chrome memblokir beberapa file</translation>
 <translation id="911206726377975832">Hapus juga data browsing Anda?</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ms.xtb b/chrome/app/resources/google_chrome_strings_ms.xtb
index 18141d29..01c8ae6d 100644
--- a/chrome/app/resources/google_chrome_strings_ms.xtb
+++ b/chrome/app/resources/google_chrome_strings_ms.xtb
@@ -4,6 +4,7 @@
 <translation id="1001534784610492198">Arkib pemasang rosak atau tidak sah. Sila muat turun Google Chrome semula.</translation>
 <translation id="1026101648481255140">Sambung Semula Pemasangan</translation>
 <translation id="102763973188675173">Sesuaikan dan kawal Google Chrome. Kemas kini tersedia.</translation>
+<translation id="1028061813283459617">Untuk memadamkan data semakan imbas daripada peranti ini dan menyimpan data semakan imbas tersebut dalam Google Account anda, <ph name="BEGIN_LINK" />log keluar dari Chrome<ph name="END_LINK" />.</translation>
 <translation id="1065672644894730302">Pilihan anda tidak dapat dibaca. Beberapa ciri mungkin tidak tersedia dan perubahan terhadap pilihan tidak akan disimpan.</translation>
 <translation id="1088300314857992706"><ph name="USER_EMAIL_ADDRESS" /> menggunakan Chrome sebelum ini</translation>
 <translation id="110877069173485804">Ini Chrome anda</translation>
diff --git a/chrome/browser/android/history/browsing_history_bridge.cc b/chrome/browser/android/history/browsing_history_bridge.cc
index 13267134..e471721b 100644
--- a/chrome/browser/android/history/browsing_history_bridge.cc
+++ b/chrome/browser/android/history/browsing_history_bridge.cc
@@ -94,8 +94,8 @@
         env, j_app_ids_result_obj_,
         base::android::ConvertUTF8ToJavaString(env, id));
   }
-  Java_BrowsingHistoryBridge_onQueryAppIdComplete(env, j_history_service_obj_,
-                                                  j_app_ids_result_obj_);
+  Java_BrowsingHistoryBridge_onQueryAppsComplete(env, j_history_service_obj_,
+                                                 j_app_ids_result_obj_);
 }
 
 void BrowsingHistoryBridge::GetLastVisitToHostBeforeRecentNavigations(
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index e142218..a6ed5f1 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -5263,6 +5263,7 @@
     "app_list/search/common/keyword_util_unittest.cc",
     "app_list/search/common/string_util_unittest.cc",
     "app_list/search/desks_admin_template_provider_unittest.cc",
+    "app_list/search/essential_search/essential_search_manager_unittest.cc",
     "app_list/search/essential_search/socs_cookie_fetcher_unittest.cc",
     "app_list/search/federated_metrics_manager_unittest.cc",
     "app_list/search/files/diacritics_checker_unittest.cc",
diff --git a/chrome/browser/ash/accessibility/accessibility_manager.cc b/chrome/browser/ash/accessibility/accessibility_manager.cc
index 62795aa..f27e873b 100644
--- a/chrome/browser/ash/accessibility/accessibility_manager.cc
+++ b/chrome/browser/ash/accessibility/accessibility_manager.cc
@@ -1809,6 +1809,13 @@
                                 reduced_animations_enabled);
     }
 
+    if (::features::IsAccessibilityCaretBlinkIntervalSettingEnabled()) {
+      int caret_blink_interval_ms =
+          prefs->GetInteger(prefs::kAccessibilityCaretBlinkInterval);
+      base::UmaHistogramSparse("Accessibility.CrosCaretBlinkInterval",
+                               caret_blink_interval_ms);
+    }
+
     base::UmaHistogramBoolean(
         "Accessibility.CrosCursorColor",
         prefs->GetBoolean(prefs::kAccessibilityCursorColorEnabled));
diff --git a/chrome/browser/ash/app_list/search/essential_search/essential_search_manager.cc b/chrome/browser/ash/app_list/search/essential_search/essential_search_manager.cc
index 4a50960..7de1193 100644
--- a/chrome/browser/ash/app_list/search/essential_search/essential_search_manager.cc
+++ b/chrome/browser/ash/app_list/search/essential_search/essential_search_manager.cc
@@ -223,6 +223,12 @@
 
 void EssentialSearchManager::OnCookieAddedToUserProfile(
     net::CookieAccessResult result) {
+  // Notify the test that OnCookieAddedToUserProfile has been triggered.
+  if (cookie_insertion_closure_for_test_) {
+    CHECK_IS_TEST();
+    std::move(cookie_insertion_closure_for_test_).Run();
+  }
+
   if (!result.status.IsInclude()) {
     // Handle SOCS cookie insertion failure.
     LOG(WARNING) << "Failed to add SOCS cookie to user profile. Retrying.";
diff --git a/chrome/browser/ash/app_list/search/essential_search/essential_search_manager.h b/chrome/browser/ash/app_list/search/essential_search/essential_search_manager.h
index 40e7f32..0cfaebf 100644
--- a/chrome/browser/ash/app_list/search/essential_search/essential_search_manager.h
+++ b/chrome/browser/ash/app_list/search/essential_search/essential_search_manager.h
@@ -58,6 +58,12 @@
   // EssentialSearchEnabled policy set.
   bool ShouldDisableSearchSuggest() const;
 
+  void set_cookie_insertion_closure_for_test(
+      base::OnceClosure cookie_insertion_closure_for_test) {
+    cookie_insertion_closure_for_test_ =
+        std::move(cookie_insertion_closure_for_test);
+  }
+
  private:
   void MaybeFetchSocsCookie();
 
@@ -89,6 +95,9 @@
   // Observer for EssentialSearch-related prefs.
   std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
 
+  // Used to notify the test that the cookie was inserted in the user's profile.
+  base::OnceClosure cookie_insertion_closure_for_test_;
+
   const raw_ptr<Profile> primary_profile_;
 
   std::unique_ptr<SocsCookieFetcher> socs_cookie_fetcher_;
diff --git a/chrome/browser/ash/app_list/search/essential_search/essential_search_manager_unittest.cc b/chrome/browser/ash/app_list/search/essential_search/essential_search_manager_unittest.cc
new file mode 100644
index 0000000..543b9c73
--- /dev/null
+++ b/chrome/browser/ash/app_list/search/essential_search/essential_search_manager_unittest.cc
@@ -0,0 +1,128 @@
+// Copyright 2024 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/ash/app_list/search/essential_search/essential_search_manager.h"
+
+#include "base/test/bind.h"
+#include "base/test/task_environment.h"
+#include "base/test/test_future.h"
+#include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/testing_profile_manager.h"
+#include "components/prefs/testing_pref_service.h"
+#include "components/signin/public/identity_manager/identity_test_environment.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/test/browser_task_environment.h"
+#include "net/cookies/canonical_cookie.h"
+#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
+#include "services/network/public/mojom/cookie_manager.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ash::test {
+namespace {
+constexpr char kEmail[] = "test-user@example.com";
+constexpr char16_t kEmail16[] = u"test-user@example.com";
+constexpr char kValidCookieHeader[] =
+    "%s=%s; Domain=.google.com; Expires=Thu, 01-Jan-2026 00:00:00 GMT; Path=/; "
+    "Secure; SameSite=lax";
+constexpr char kCookieName[] = "SOCS";
+constexpr char kCookieValue[] = "SOCS_VALUE";
+}  // namespace
+
+class EssentialSearchManagerTest : public testing::Test {
+ protected:
+  EssentialSearchManagerTest();
+  ~EssentialSearchManagerTest() override;
+
+  // testing::Test:
+  void SetUp() override;
+
+  void CreateEssentialSearchManager();
+  void DestroyEssentialSearchManager();
+
+  void ExpectSocsCookieInUserProfile(const std::string& cookie_name,
+                                     const std::string& cookie_value);
+
+  content::BrowserTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+
+  std::unique_ptr<IdentityTestEnvironmentProfileAdaptor>
+      identity_test_env_adaptor_;
+  raw_ptr<signin::IdentityTestEnvironment> identity_test_env_;
+
+  std::unique_ptr<TestingProfileManager> profile_manager_;
+  raw_ptr<TestingProfile> profile_;
+
+  std::unique_ptr<app_list::EssentialSearchManager> essential_search_manager_;
+};
+
+EssentialSearchManagerTest::EssentialSearchManagerTest()
+    : essential_search_manager_(nullptr) {}
+
+EssentialSearchManagerTest::~EssentialSearchManagerTest() = default;
+
+void EssentialSearchManagerTest::SetUp() {
+  profile_manager_ = std::make_unique<TestingProfileManager>(
+      TestingBrowserProcess::GetGlobal());
+  ASSERT_TRUE(profile_manager_->SetUp());
+  TestingProfile::TestingFactories factories =
+      IdentityTestEnvironmentProfileAdaptor::
+          GetIdentityTestEnvironmentFactories();
+  profile_ =
+      profile_manager_->CreateTestingProfile(kEmail, /*prefs=*/{}, kEmail16,
+                                             /*avatar_id=*/0, factories);
+  identity_test_env_adaptor_ =
+      std::make_unique<IdentityTestEnvironmentProfileAdaptor>(profile_.get());
+  identity_test_env_ = identity_test_env_adaptor_->identity_test_env();
+}
+
+void EssentialSearchManagerTest::CreateEssentialSearchManager() {
+  essential_search_manager_ =
+      std::make_unique<app_list::EssentialSearchManager>(profile_);
+}
+
+void EssentialSearchManagerTest::ExpectSocsCookieInUserProfile(
+    const std::string& cookie_name,
+    const std::string& cookie_value) {
+  base::test::TestFuture<const net::CookieList&> future;
+
+  profile_->GetDefaultStoragePartition()
+      ->GetCookieManagerForBrowserProcess()
+      ->GetAllCookies(future.GetCallback());
+
+  net::CookieList cookie_list = future.Take();
+  EXPECT_GT(cookie_list.size(), 0u);
+
+  const auto socs_cookie_iterator = base::ranges::find(
+      cookie_list, cookie_name,
+      [](const net::CanonicalCookie& cookie) { return cookie.Name(); });
+  ASSERT_NE(socs_cookie_iterator, cookie_list.end());
+  EXPECT_EQ(cookie_value, socs_cookie_iterator->Value());
+}
+
+TEST_F(EssentialSearchManagerTest, OnCookieFetchedSucceed) {
+  identity_test_env_->MakePrimaryAccountAvailable(kEmail,
+                                                  signin::ConsentLevel::kSync);
+  // Enable EssentialSearchEnabled policy
+  profile_->GetTestingPrefService()->SetManagedPref(
+      prefs::kEssentialSearchEnabled, base::Value(true));
+
+  CreateEssentialSearchManager();
+
+  base::RunLoop run_loop;
+  essential_search_manager_->set_cookie_insertion_closure_for_test(
+      run_loop.QuitClosure());
+
+  // Add SOCS cookie to the user profile
+  std::string cookie_header =
+      base::StringPrintf(kValidCookieHeader, kCookieName, kCookieValue);
+  essential_search_manager_->OnCookieFetched(cookie_header);
+  run_loop.Run();
+
+  ExpectSocsCookieInUserProfile(kCookieName, kCookieValue);
+}
+
+}  // namespace ash::test
diff --git a/chrome/browser/ash/audio/audio_survey_handler.cc b/chrome/browser/ash/audio/audio_survey_handler.cc
index 7346d709..5f4ec33 100644
--- a/chrome/browser/ash/audio/audio_survey_handler.cc
+++ b/chrome/browser/ash/audio/audio_survey_handler.cc
@@ -18,6 +18,8 @@
       return kHatsAudioSurvey;
     case CrasAudioHandler::SurveyType::kBluetooth:
       return kHatsBluetoothAudioSurvey;
+    case CrasAudioHandler::SurveyType::kOutputProc:
+      return kHatsAudioOutputProcSurvey;
   }
 }
 
@@ -68,6 +70,7 @@
 AudioSurveyHandler::AudioSurveyHandler(std::unique_ptr<Delegate> delegate)
     : delegate_(std::move(delegate)) {
   if (!base::FeatureList::IsEnabled(kHatsAudioSurvey.feature) &&
+      !base::FeatureList::IsEnabled(kHatsAudioOutputProcSurvey.feature) &&
       !base::FeatureList::IsEnabled(kHatsBluetoothAudioSurvey.feature)) {
     VLOG(1) << "Audio survey feature is not enabled";
     return;
diff --git a/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager.cc b/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager.cc
index 7581710..430fc54 100644
--- a/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager.cc
+++ b/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager.cc
@@ -9,6 +9,7 @@
 #include "ash/public/cpp/reauth_reason.h"
 #include "base/check.h"
 #include "base/functional/callback_helpers.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/time/default_clock.h"
 #include "base/trace_event/trace_event.h"
 #include "chrome/browser/ash/login/auth/chrome_safe_mode_delegate.h"
@@ -33,6 +34,10 @@
 #include "content/public/browser/storage_partition.h"
 
 namespace ash {
+namespace {
+constexpr char kLockScreenReauthHistogram[] =
+    "ChromeOS.LockScreenReauth.LockScreenReauthReason";
+}  // namespace
 
 LockScreenReauthManager::LockScreenReauthManager(Profile* primary_profile)
     : primary_profile_(primary_profile),
@@ -205,6 +210,7 @@
   }
 
   ResetOnlineReauth();
+  SendLockscreenReauthReason();
   if (is_reauth_required_by_saml_token_mismatch_) {
     in_session_password_sync_manager_.FetchTokenAsync();
   }
@@ -220,6 +226,27 @@
   LockScreenStartReauthDialog::Dismiss();
 }
 
+void LockScreenReauthManager::SendLockscreenReauthReason() {
+  if (is_reauth_required_by_gaia_time_limit_policy_) {
+    base::UmaHistogramEnumeration(kLockScreenReauthHistogram,
+                                  ReauthReason::kGaiaLockScreenReauthPolicy,
+                                  ReauthReason::kNumReauthFlowReasons);
+  }
+
+  if (is_reauth_required_by_saml_time_limit_policy_) {
+    base::UmaHistogramEnumeration(kLockScreenReauthHistogram,
+                                  ReauthReason::kSamlLockScreenReauthPolicy,
+                                  ReauthReason::kNumReauthFlowReasons);
+  }
+
+  if (is_reauth_required_by_saml_token_mismatch_) {
+    base::UmaHistogramEnumeration(
+        kLockScreenReauthHistogram,
+        ReauthReason::kSamlPasswordSyncTokenValidationFailed,
+        ReauthReason::kNumReauthFlowReasons);
+  }
+}
+
 void LockScreenReauthManager::OnPasswordUpdateSuccess(
     std::unique_ptr<UserContext> user_context) {
   DCHECK(user_context);
diff --git a/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager.h b/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager.h
index c74a859..a5f6615 100644
--- a/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager.h
+++ b/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager.h
@@ -103,6 +103,10 @@
   void OnPasswordUpdateFailure(std::unique_ptr<UserContext> user_context,
                                AuthenticationError error);
 
+  // Send the reason(s) why a user is required to reauthenticate online in the
+  // lock screen to UMA.
+  void SendLockscreenReauthReason();
+
   const raw_ptr<Profile> primary_profile_;
   const raw_ptr<const user_manager::User, DanglingUntriaged> primary_user_;
   UserContext user_context_;
diff --git a/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager_unittest.cc b/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager_unittest.cc
index fd3faf7..4436e504 100644
--- a/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager_unittest.cc
+++ b/chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager_unittest.cc
@@ -3,9 +3,12 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/ash/login/lock/online_reauth/lock_screen_reauth_manager.h"
+
 #include <memory>
 
+#include "ash/public/cpp/reauth_reason.h"
 #include "base/memory/raw_ptr.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/login/login_pref_names.h"
@@ -32,6 +35,9 @@
 const char kSAMLUserEmail2[] = "bob@corp.example.com";
 
 constexpr base::TimeDelta kSamlOnlineShortDelay = base::Seconds(10);
+
+constexpr char kLockScreenReauthHistogram[] =
+    "ChromeOS.LockScreenReauth.LockScreenReauthReason";
 }  // namespace
 
 class LockScreenReauthManagerTest : public testing::Test {
@@ -46,6 +52,7 @@
   void CreateLockScreenReauthManager();
   void DestroyLockScreenReauthManager();
 
+  void SetReauthRequiredBySamlTokenMismatch();
   bool IsReauthRequiredBySamlTokenMismatch();
   bool IsReauthRequiredBySamlTimeLimitPolicy();
 
@@ -70,6 +77,7 @@
   std::unique_ptr<LockScreenReauthManager> manager_;
   base::test::ScopedFeatureList feature_list_;
   std::unique_ptr<user_manager::KnownUser> known_user_;
+  const base::HistogramTester histogram_tester_;
 };
 
 LockScreenReauthManagerTest::LockScreenReauthManagerTest() : manager_(nullptr) {
@@ -124,6 +132,10 @@
   proximity_auth::ScreenlockBridge::Get()->SetLockHandler(lock_handler_.get());
 }
 
+void LockScreenReauthManagerTest::SetReauthRequiredBySamlTokenMismatch() {
+  manager_->is_reauth_required_by_saml_token_mismatch_ = true;
+}
+
 bool LockScreenReauthManagerTest::IsReauthRequiredBySamlTokenMismatch() {
   return manager_->is_reauth_required_by_saml_token_mismatch_;
 }
@@ -189,6 +201,13 @@
 
   EXPECT_TRUE(IsReauthRequiredBySamlTimeLimitPolicy());
   EXPECT_TRUE(proximity_auth::ScreenlockBridge::Get()->IsLocked());
+  histogram_tester_.ExpectBucketCount(
+      kLockScreenReauthHistogram, ReauthReason::kGaiaLockScreenReauthPolicy, 0);
+  histogram_tester_.ExpectBucketCount(
+      kLockScreenReauthHistogram, ReauthReason::kSamlLockScreenReauthPolicy, 0);
+  histogram_tester_.ExpectBucketCount(
+      kLockScreenReauthHistogram,
+      ReauthReason::kSamlPasswordSyncTokenValidationFailed, 0);
 }
 
 TEST_F(LockScreenReauthManagerTest, AuthenticateWithCorrectUser) {
@@ -217,6 +236,49 @@
   EXPECT_FALSE(IsReauthRequiredBySamlTimeLimitPolicy());
   now = known_user_->GetLastOnlineSignin(saml_login_account_id1_);
   EXPECT_EQ(now, expected_signin_time);
+  histogram_tester_.ExpectBucketCount(
+      kLockScreenReauthHistogram, ReauthReason::kGaiaLockScreenReauthPolicy, 0);
+  histogram_tester_.ExpectBucketCount(
+      kLockScreenReauthHistogram, ReauthReason::kSamlLockScreenReauthPolicy, 1);
+  histogram_tester_.ExpectBucketCount(
+      kLockScreenReauthHistogram,
+      ReauthReason::kSamlPasswordSyncTokenValidationFailed, 0);
+}
+
+TEST_F(LockScreenReauthManagerTest, FlowTriggeredByPolicyAndInvalidToken) {
+  base::Time now = test_environment_.GetMockClock()->Now();
+  known_user_->SetLastOnlineSignin(saml_login_account_id1_, now);
+  known_user_->SetOfflineSigninLimit(saml_login_account_id1_,
+                                     kSamlOnlineShortDelay);
+  base::Time expected_signin_time = now + kSamlOnlineShortDelay;
+
+  CreateLockScreenReauthManager();
+  LockScreen();
+  EXPECT_CALL(*lock_handler_,
+              SetAuthType(saml_login_account_id1_,
+                          proximity_auth::mojom::AuthType::ONLINE_SIGN_IN,
+                          std::u16string()))
+      .Times(1);
+  EXPECT_CALL(*lock_handler_, Unlock(saml_login_account_id1_)).Times(1);
+  fake_user_manager_->SaveForceOnlineSignin(saml_login_account_id1_, true);
+  SetReauthRequiredBySamlTokenMismatch();
+  test_environment_.FastForwardBy(kSamlOnlineShortDelay);
+  manager_->MaybeForceReauthOnLockScreen(
+      ReauthReason::kSamlLockScreenReauthPolicy);
+  EXPECT_TRUE(IsReauthRequiredBySamlTimeLimitPolicy());
+  UserContext user_context(user_manager::UserType::kRegular,
+                           saml_login_account_id1_);
+  manager_->OnAuthSuccess(user_context);
+  EXPECT_FALSE(IsReauthRequiredBySamlTimeLimitPolicy());
+  now = known_user_->GetLastOnlineSignin(saml_login_account_id1_);
+  EXPECT_EQ(now, expected_signin_time);
+  histogram_tester_.ExpectBucketCount(
+      kLockScreenReauthHistogram, ReauthReason::kGaiaLockScreenReauthPolicy, 0);
+  histogram_tester_.ExpectBucketCount(
+      kLockScreenReauthHistogram, ReauthReason::kSamlLockScreenReauthPolicy, 1);
+  histogram_tester_.ExpectBucketCount(
+      kLockScreenReauthHistogram,
+      ReauthReason::kSamlPasswordSyncTokenValidationFailed, 1);
 }
 
 TEST_F(LockScreenReauthManagerTest, PolicySetToFalse) {
diff --git a/chrome/browser/ash/login/ui/login_display_host_mojo.cc b/chrome/browser/ash/login/ui/login_display_host_mojo.cc
index 7e6c886..c9342cbe 100644
--- a/chrome/browser/ash/login/ui/login_display_host_mojo.cc
+++ b/chrome/browser/ash/login/ui/login_display_host_mojo.cc
@@ -61,6 +61,7 @@
 #include "chromeos/ash/components/browser_context_helper/browser_context_helper.h"
 #include "chromeos/ash/components/login/auth/public/auth_types.h"
 #include "chromeos/ash/components/login/auth/public/user_context.h"
+#include "chromeos/ash/components/osauth/public/auth_hub.h"
 #include "chromeos/ash/components/settings/cros_settings.h"
 #include "components/account_id/account_id.h"
 #include "components/startup_metric_utils/common/startup_metric_utils.h"
@@ -489,6 +490,8 @@
 
   CreateExistingUserController();
 
+  AuthHub::Get()->InitializeForMode(AuthHubMode::kLoginScreen);
+
   // Load the UI.
   existing_user_controller_->Init(user_manager::UserManager::Get()->GetUsers());
 
diff --git a/chrome/browser/ash/login/users/chrome_user_manager_impl.cc b/chrome/browser/ash/login/users/chrome_user_manager_impl.cc
index 3731946..b9cc402 100644
--- a/chrome/browser/ash/login/users/chrome_user_manager_impl.cc
+++ b/chrome/browser/ash/login/users/chrome_user_manager_impl.cc
@@ -395,35 +395,6 @@
   return &multi_user_sign_in_policy_controller_;
 }
 
-user_manager::UserList ChromeUserManagerImpl::GetUsersAllowedForMultiProfile()
-    const {
-  // Supervised users are not allowed to use multi-profiles.
-  if (GetLoggedInUsers().size() == 1 &&
-      GetPrimaryUser()->GetType() != user_manager::UserType::kRegular) {
-    return user_manager::UserList();
-  }
-
-  // No user is allowed if the primary user policy forbids it.
-  if (user_manager::GetMultiUserSignInPolicy(GetPrimaryUser()) ==
-      MultiUserSignInPolicy::kNotAllowed) {
-    return {};
-  }
-
-  user_manager::UserList result;
-  for (user_manager::User* user : GetUsers()) {
-    if (user->GetType() == user_manager::UserType::kRegular &&
-        !user->is_logged_in()) {
-      // Users with a policy that prevents them being added to a session will be
-      // shown in login UI but will be grayed out.
-      // Same applies to owner account (see http://crbug.com/385034).
-      result.push_back(user);
-    }
-  }
-
-  // Extract out users that are allowed on login screen.
-  return FindLoginAllowedUsersFrom(result);
-}
-
 user_manager::UserList ChromeUserManagerImpl::GetUnlockUsers() const {
   const user_manager::UserList& logged_in_users = GetLoggedInUsers();
   if (logged_in_users.empty()) {
diff --git a/chrome/browser/ash/login/users/chrome_user_manager_impl.h b/chrome/browser/ash/login/users/chrome_user_manager_impl.h
index 519c231..817ffb5e 100644
--- a/chrome/browser/ash/login/users/chrome_user_manager_impl.h
+++ b/chrome/browser/ash/login/users/chrome_user_manager_impl.h
@@ -66,7 +66,6 @@
 
   // UserManager implementation:
   void Shutdown() override;
-  user_manager::UserList GetUsersAllowedForMultiProfile() const override;
   user_manager::UserList GetUnlockUsers() const override;
   void SaveUserOAuthStatus(
       const AccountId& account_id,
diff --git a/chrome/browser/autofill/autofill_across_iframes_browsertest.cc b/chrome/browser/autofill/autofill_across_iframes_browsertest.cc
index 2b3d548..c89e97d3 100644
--- a/chrome/browser/autofill/autofill_across_iframes_browsertest.cc
+++ b/chrome/browser/autofill/autofill_across_iframes_browsertest.cc
@@ -173,7 +173,7 @@
 
   std::vector<std::string> values;
   for (const FormFieldData& field : form.fields) {
-    LocalFrameToken frame = field.host_frame;
+    LocalFrameToken frame = field.host_frame();
     if (frame_to_iters[frame] == frame_to_values[frame].end())
       return {};
     values.push_back(*frame_to_iters[frame]++);
@@ -323,7 +323,7 @@
             },
             num_fields));
     for (const auto& field : *form)
-      const_cast<AutofillField&>(*field).is_focusable = true;
+      const_cast<AutofillField&>(*field).set_is_focusable(true);
     return form;
   }
 
@@ -676,8 +676,8 @@
     auto unspecified = HtmlFieldType::kUnspecified;
     auto m = [](std::string_view host, HtmlFieldType type) {
       return Pointee(AllOf(Property(&AutofillField::html_type, Eq(type)),
-                           Field(&AutofillField::origin,
-                                 Property(&url::Origin::host, Eq(host)))));
+                           Property(&AutofillField::origin,
+                                    Property(&url::Origin::host, Eq(host)))));
     };
     // The indentation reflects the nesting of frames.
     // clang-format off
@@ -739,8 +739,8 @@
     // clang-format on
   }
   const FormData& form_data = form->ToFormData();
-  ASSERT_EQ("e.com", form_data.fields[4].origin.host());
-  ASSERT_EQ("cc-name", form_data.fields[4].autocomplete_attribute);
+  ASSERT_EQ("e.com", form_data.fields[4].origin().host());
+  ASSERT_EQ("cc-name", form_data.fields[4].autocomplete_attribute());
   FillCard(main_frame(), form_data, form_data.fields[4]);
   EXPECT_TRUE(main_autofill_manager().WaitForAutofill(5));
   {
@@ -789,9 +789,10 @@
     auto exp = HtmlFieldType::kCreditCardExpDate4DigitYear;
     auto cvc = HtmlFieldType::kCreditCardVerificationCode;
     auto m = [](HtmlFieldType type) {
-      return Pointee(AllOf(Property(&AutofillField::html_type, Eq(type)),
-                           Field(&AutofillField::origin,
-                                 Property(&url::Origin::host, Eq("a.com")))));
+      return Pointee(
+          AllOf(Property(&AutofillField::html_type, Eq(type)),
+                Property(&AutofillField::origin,
+                         Property(&url::Origin::host, Eq("a.com")))));
     };
     EXPECT_THAT(form->fields(), ElementsAre(m(name), m(num), m(exp), m(cvc),  //
                                             m(name), m(num), m(exp), m(cvc),  //
diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc
index f83b02b..2df9052d 100644
--- a/chrome/browser/autofill/autofill_browsertest.cc
+++ b/chrome/browser/autofill/autofill_browsertest.cc
@@ -36,6 +36,7 @@
 #include "components/autofill/content/browser/content_autofill_driver.h"
 #include "components/autofill/content/browser/content_autofill_driver_factory.h"
 #include "components/autofill/content/browser/test_autofill_manager_injector.h"
+#include "components/autofill/core/browser/address_data_manager_test_api.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/browser_autofill_manager.h"
 #include "components/autofill/core/browser/data_model/autofill_profile.h"
@@ -184,7 +185,8 @@
     ASSERT_TRUE(
         autofill_manager_injector_[web_contents()]->WaitForFormsSeen(1));
     // Shortcut explicit save prompts and automatically accept.
-    personal_data_manager()->set_auto_accept_address_imports_for_testing(true);
+    test_api(personal_data_manager()->address_data_manager())
+        .set_auto_accept_address_imports(true);
     TestAutofillManagerWaiter waiter(*autofill_manager(),
                                      {AutofillManagerEvent::kFormSubmitted});
     ASSERT_TRUE(
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc
index b948489..b38f84f 100644
--- a/chrome/browser/autofill/autofill_interactive_uitest.cc
+++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -3777,7 +3777,7 @@
     return AllOf(
         Property("name", &FormFieldData::name, nvu.name),
         Property("value", &FormFieldData::value, nvu.value),
-        Field("user_input", &FormFieldData::user_input, nvu.user_input));
+        Property("user_input", &FormFieldData::user_input, nvu.user_input));
   }
 
   void ExecuteScript(const std::string& script) {
diff --git a/chrome/browser/autofill/autofill_uitest.cc b/chrome/browser/autofill/autofill_uitest.cc
index 0cd01f3..8c27e2c 100644
--- a/chrome/browser/autofill/autofill_uitest.cc
+++ b/chrome/browser/autofill/autofill_uitest.cc
@@ -90,7 +90,6 @@
 }
 
 void BrowserAutofillManagerTestDelegateImpl::FireEvent(ObservedUiEvents event) {
-  DCHECK(event_waiter_);
   if (event_waiter_ && (!ignore_back_to_back_event_types_.contains(event) ||
                         last_event_ != event)) {
     event_waiter_->OnEvent(event);
diff --git a/chrome/browser/autofill/autofill_uitest_util.cc b/chrome/browser/autofill/autofill_uitest_util.cc
index 58ab3c0..e62a3ae 100644
--- a/chrome/browser/autofill/autofill_uitest_util.cc
+++ b/chrome/browser/autofill/autofill_uitest_util.cc
@@ -78,8 +78,8 @@
   form.url = GURL("https://foo.com/bar");
   form.fields = {test::CreateTestFormField(
       "Full name", "name", "", FormControlType::kInputText, "name")};
-  form.fields.front().is_focusable = true;
-  form.fields.front().should_autocomplete = true;
+  form.fields.front().set_is_focusable(true);
+  form.fields.front().set_should_autocomplete(true);
 
   // Not adding a profile would result in `AskForValuesToFill()` not finding any
   // suggestions and hiding the Autofill Popup.
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index eb1da16..d41e913 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -203,7 +203,8 @@
 
       <if expr="enable_hangout_services_extension">
         <!-- Hangout Services extension, included in Google Chrome builds only. -->
-        <include name="IDR_HANGOUT_SERVICES_MANIFEST" file="resources\hangout_services\manifest.json" type="BINDATA" />
+        <include name="IDR_HANGOUT_SERVICES_MANIFEST_V2" file="resources\hangout_services\manifest_v2.json" type="BINDATA" />
+        <include name="IDR_HANGOUT_SERVICES_MANIFEST_V3" file="resources\hangout_services\manifest_v3.json" type="BINDATA" />
       </if>
 
       <!-- Desk API extension, enabled on managed ChromeOS devices -->
diff --git a/chrome/browser/compose/chrome_compose_client.cc b/chrome/browser/compose/chrome_compose_client.cc
index 1a517b4b..ea12b2a 100644
--- a/chrome/browser/compose/chrome_compose_client.cc
+++ b/chrome/browser/compose/chrome_compose_client.cc
@@ -154,7 +154,7 @@
   if (!skip_show_dialog_for_test_) {
     // The bounds given by autofill are relative to the top level frame. Here we
     // offset by the WebContents container to make up for that.
-    gfx::RectF bounds_in_screen = trigger_field.bounds;
+    gfx::RectF bounds_in_screen = trigger_field.bounds();
     bounds_in_screen.Offset(
         GetWebContents().GetContainerBounds().OffsetFromOrigin());
 
@@ -293,7 +293,7 @@
   // dialog if it splits a surrogate pair character. Ensure that any invalid
   // characters are removed.
   std::string selected_text =
-      base::UTF16ToUTF8(RemoveLastCharIfInvalid(trigger_field.selected_text));
+      base::UTF16ToUTF8(RemoveLastCharIfInvalid(trigger_field.selected_text()));
 
   ComposeSession* current_session;
 
@@ -502,9 +502,9 @@
   GURL url = GetWebContents().GetPrimaryMainFrame()->GetLastCommittedURL();
 
   return compose_enabling_->ShouldTriggerPopup(
-      form_field_data.autocomplete_attribute, profile_, translate_manager,
+      form_field_data.autocomplete_attribute(), profile_, translate_manager,
       HasSession(form_field_data.global_id()),
-      top_level_frame->GetLastCommittedOrigin(), form_field_data.origin, url,
+      top_level_frame->GetLastCommittedOrigin(), form_field_data.origin(), url,
       trigger_source);
 }
 
diff --git a/chrome/browser/compose/chrome_compose_client_unittest.cc b/chrome/browser/compose/chrome_compose_client_unittest.cc
index ca9856f5..97d13f19 100644
--- a/chrome/browser/compose/chrome_compose_client_unittest.cc
+++ b/chrome/browser/compose/chrome_compose_client_unittest.cc
@@ -310,13 +310,13 @@
   GURL GetPageUrl() { return GURL("http://foo/1"); }
 
   void SetSelection(const std::u16string& selection) {
-    field_data().selected_text = selection;
+    field_data().set_selected_text(selection);
   }
 
   // Emulate selected text truncation performed by Autofill.
   void SetSelectionWithTruncation(const std::u16string& selection,
                                   size_t max_length) {
-    field_data().selected_text = selection.substr(0, max_length);
+    field_data().set_selected_text(selection.substr(0, max_length));
   }
 
  protected:
diff --git a/chrome/browser/compose/compose_dialog_browsertest.cc b/chrome/browser/compose/compose_dialog_browsertest.cc
index 1e42ff6..eff7fe9 100644
--- a/chrome/browser/compose/compose_dialog_browsertest.cc
+++ b/chrome/browser/compose/compose_dialog_browsertest.cc
@@ -63,7 +63,7 @@
   gfx::PointF textarea_center =
       content::GetCenterCoordinatesOfElementWithId(web_contents, "elem1");
   autofill::FormFieldData field_data;
-  field_data.bounds = gfx::RectF((textarea_center), gfx::SizeF(1, 1));
+  field_data.set_bounds(gfx::RectF((textarea_center), gfx::SizeF(1, 1)));
 
   auto* client = ChromeComposeClient::FromWebContents(web_contents);
   client->ShowComposeDialog(
@@ -101,7 +101,7 @@
   gfx::PointF textarea_center =
       content::GetCenterCoordinatesOfElementWithId(web_contents, "elem1");
   autofill::FormFieldData field_data;
-  field_data.bounds = gfx::RectF((textarea_center), gfx::SizeF(1, 1));
+  field_data.set_bounds(gfx::RectF((textarea_center), gfx::SizeF(1, 1)));
 
   auto* client = ChromeComposeClient::FromWebContents(web_contents);
   client->ShowComposeDialog(
@@ -127,7 +127,7 @@
   gfx::PointF textarea_center =
       content::GetCenterCoordinatesOfElementWithId(web_contents, "elem1");
   autofill::FormFieldData field_data;
-  field_data.bounds = gfx::RectF((textarea_center), gfx::SizeF(1, 1));
+  field_data.set_bounds(gfx::RectF((textarea_center), gfx::SizeF(1, 1)));
 
   client->ShowComposeDialog(
       autofill::AutofillComposeDelegate::UiEntryPoint::kAutofillPopup,
@@ -155,7 +155,7 @@
   gfx::PointF textarea_center =
       content::GetCenterCoordinatesOfElementWithId(web_contents, "elem1");
   autofill::FormFieldData field_data;
-  field_data.bounds = gfx::RectF((textarea_center), gfx::SizeF(1, 1));
+  field_data.set_bounds(gfx::RectF((textarea_center), gfx::SizeF(1, 1)));
 
   auto* client = ChromeComposeClient::FromWebContents(web_contents);
   client->ShowComposeDialog(
diff --git a/chrome/browser/devtools/protocol/devtools_autofill_browsertest.cc b/chrome/browser/devtools/protocol/devtools_autofill_browsertest.cc
index e4e552e..dc073b1 100644
--- a/chrome/browser/devtools/protocol/devtools_autofill_browsertest.cc
+++ b/chrome/browser/devtools/protocol/devtools_autofill_browsertest.cc
@@ -481,11 +481,11 @@
   form.fields.push_back(test::CreateTestFormField(
       /*label=*/"", "name_1", "value_1", FormControlType::kInputText));
   form.fields.back().set_id_attribute(u"id_1");
-  form.fields.back().host_frame = form.host_frame;
+  form.fields.back().set_host_frame(form.host_frame);
   form.fields.push_back(test::CreateTestFormField(
       /*label=*/"", "name_2", "value_2", FormControlType::kInputText));
   form.fields.back().set_id_attribute(u"id_2");
-  form.fields.back().host_frame = form.host_frame;
+  form.fields.back().set_host_frame(form.host_frame);
 
   // The parsed form is queried by
   // AutofillHandler::OnFillOrPreviewDataModelForm() to obtain the type
@@ -618,7 +618,7 @@
   web_contents()->ForEachRenderFrameHost([&](content::RenderFrameHost* rfh) {
     // Call the driver of the field host iframe.
     if (rfh->GetFrameToken().ToString() ==
-        form.fields[0].host_frame->ToString()) {
+        form.fields[0].host_frame()->ToString()) {
       ASSERT_NE(rfh->GetFrameToken(), main_frame()->GetFrameToken());
       auto* driver = static_cast<mojom::AutofillDriver*>(
           autofill::ContentAutofillDriver::GetForRenderFrameHost(rfh));
diff --git a/chrome/browser/extensions/component_extensions_allowlist/allowlist.cc b/chrome/browser/extensions/component_extensions_allowlist/allowlist.cc
index 164344c8e..a24f8ad 100644
--- a/chrome/browser/extensions/component_extensions_allowlist/allowlist.cc
+++ b/chrome/browser/extensions/component_extensions_allowlist/allowlist.cc
@@ -89,7 +89,8 @@
   switch (manifest_resource_id) {
     // Please keep the list in alphabetical order.
 #if BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION)
-    case IDR_HANGOUT_SERVICES_MANIFEST:
+    case IDR_HANGOUT_SERVICES_MANIFEST_V2:
+    case IDR_HANGOUT_SERVICES_MANIFEST_V3:
 #endif
     case IDR_NETWORK_SPEECH_SYNTHESIS_MANIFEST:
     case IDR_WEBSTORE_MANIFEST:
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc
index ed60d53..ba9775d88a 100644
--- a/chrome/browser/extensions/component_loader.cc
+++ b/chrome/browser/extensions/component_loader.cc
@@ -92,6 +92,12 @@
 
 namespace {
 
+#if BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION)
+BASE_FEATURE(kHangoutsExtensionV3,
+             "HangoutsExtensionV3",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+#endif  // BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION)
+
 bool g_enable_background_extensions_during_testing = false;
 
 #if BUILDFLAG(IS_CHROMEOS_ASH) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
@@ -356,8 +362,14 @@
 
 #if BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION)
 void ComponentLoader::AddHangoutServicesExtension() {
-  Add(IDR_HANGOUT_SERVICES_MANIFEST,
-      base::FilePath(FILE_PATH_LITERAL("hangout_services")));
+  // Finch controlled migration to a v3 Manifest - see crbug.com/326877912.
+  if (base::FeatureList::IsEnabled(kHangoutsExtensionV3)) {
+    Add(IDR_HANGOUT_SERVICES_MANIFEST_V3,
+        base::FilePath(FILE_PATH_LITERAL("hangout_services")));
+  } else {
+    Add(IDR_HANGOUT_SERVICES_MANIFEST_V2,
+        base::FilePath(FILE_PATH_LITERAL("hangout_services")));
+  }
 }
 #endif  // BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION)
 
diff --git a/chrome/browser/fast_checkout/fast_checkout_trigger_validator_impl.cc b/chrome/browser/fast_checkout/fast_checkout_trigger_validator_impl.cc
index 5f13172..34680c0 100644
--- a/chrome/browser/fast_checkout/fast_checkout_trigger_validator_impl.cc
+++ b/chrome/browser/fast_checkout/fast_checkout_trigger_validator_impl.cc
@@ -66,7 +66,7 @@
   }
 
   // Trigger only on focusable fields.
-  if (!field.is_focusable) {
+  if (!field.is_focusable()) {
     LogAutofillInternals("not triggered because field was not focusable.");
     return FastCheckoutTriggerOutcome::kFailureFieldNotFocusable;
   }
@@ -103,16 +103,17 @@
   // Check browser form's signature and renderer form's signature.
   autofill::FormSignature form_signature =
       autofill::CalculateFormSignature(form);
-  bool is_trigger_form = capabilities_fetcher_->IsTriggerFormSupported(
-                             form.main_frame_origin, form_signature) ||
-                         capabilities_fetcher_->IsTriggerFormSupported(
-                             form.main_frame_origin, field.host_form_signature);
+  bool is_trigger_form =
+      capabilities_fetcher_->IsTriggerFormSupported(form.main_frame_origin,
+                                                    form_signature) ||
+      capabilities_fetcher_->IsTriggerFormSupported(
+          form.main_frame_origin, field.host_form_signature());
   if (!is_trigger_form) {
     LogAutofillInternals(
         "not triggered because there is no Fast Checkout support for form "
         "signatures {" +
         base::NumberToString(form_signature.value()) + ", " +
-        base::NumberToString(field.host_form_signature.value()) +
+        base::NumberToString(field.host_form_signature().value()) +
         "} on origin " + form.main_frame_origin.Serialize() + ".");
   }
   return is_trigger_form;
diff --git a/chrome/browser/fast_checkout/fast_checkout_trigger_validator_impl_unittest.cc b/chrome/browser/fast_checkout/fast_checkout_trigger_validator_impl_unittest.cc
index 1286a07e..d58badd 100644
--- a/chrome/browser/fast_checkout/fast_checkout_trigger_validator_impl_unittest.cc
+++ b/chrome/browser/fast_checkout/fast_checkout_trigger_validator_impl_unittest.cc
@@ -185,7 +185,7 @@
 
 TEST_F(FastCheckoutTriggerValidatorTest,
        ShouldRun_FieldNotFocusable_ReturnsFalse) {
-  field_.is_focusable = false;
+  field_.set_is_focusable(false);
   EXPECT_EQ(ShouldRun(), FastCheckoutTriggerOutcome::kFailureFieldNotFocusable);
 }
 
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 8ae70f9..579452b9 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1479,7 +1479,7 @@
   {
     "name": "content-suggestions-magic-stack",
     "owners": [ "thegreenfrog@google.com", "bling-flags@google.com" ],
-    "expiry_milestone": 125
+    "expiry_milestone": 132
   },
   {
     "name": "contextual-nudges",
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index e38a351..c5769fe 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -363,7 +363,6 @@
     &syncer::kReplaceSyncPromosWithSignInPromos,
     &syncer::kSyncAndroidLimitNTPPromoImpressions,
     &syncer::kSyncEnableContactInfoDataTypeInTransportMode,
-    &syncer::kSyncShowIdentityErrorsForSignedInUsers,
     &syncer::kWebApkBackupAndRestoreBackend,
     &tab_groups::kTabGroupSyncAndroid,
     &webapps::features::kPwaUniversalInstallUi,
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index be1fc7a..832910d2 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -449,8 +449,6 @@
             "SyncAndroidLimitNTPPromoImpressions";
     public static final String SYNC_ENABLE_CONTACT_INFO_DATA_TYPE_IN_TRANSPORT_MODE =
             "SyncEnableContactInfoDataTypeInTransportMode";
-    public static final String SYNC_SHOW_IDENTITY_ERRORS_FOR_SIGNED_IN_USERS =
-            "SyncShowIdentityErrorsForSignedInUsers";
     public static final String TAB_DRAG_DROP_ANDROID = "TabDragDropAndroid";
     public static final String TAB_GROUP_PANE_ANDROID = "TabGroupPaneAndroid";
     public static final String TAB_GROUP_PARITY_ANDROID = "TabGroupParityAndroid";
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
index ead3f4a..2e7ad06e 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -182,7 +182,7 @@
   form.renderer_id = autofill::test::MakeFormRendererId();
   form.fields = std::move(fields);
   for (FormFieldData& field : form.fields) {
-    field.host_frame = form.host_frame;
+    field.set_host_frame(form.host_frame);
   }
   return form;
 }
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.cc
index d27d503..b70c74b 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl.cc
@@ -286,7 +286,7 @@
     // notice feature is enabled.
     pref_service_->SetBoolean(prefs::kPrivacySandboxM1TopicsEnabled, false);
     pref_service_->SetBoolean(prefs::kPrivacySandboxM1FledgeEnabled, false);
-    if (!privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.Get()) {
+    if (!privacy_sandbox::IsRestrictedNoticeRequired()) {
       pref_service_->SetBoolean(prefs::kPrivacySandboxM1AdMeasurementEnabled,
                                 false);
     }
@@ -302,7 +302,7 @@
 
   // kRestricted prompt suppression reason must be cleared at startup when
   // restricted notice feature is enabled.
-  if (privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.Get() &&
+  if (privacy_sandbox::IsRestrictedNoticeRequired() &&
       static_cast<PromptSuppressedReason>(
           pref_service->GetInteger(prefs::kPrivacySandboxM1PromptSuppressed)) ==
           PromptSuppressedReason::kRestricted) {
@@ -375,7 +375,7 @@
         privacy_sandbox::TopicsConsentUpdateSource::kConfirmation, false);
   } else if (PromptAction::kRestrictedNoticeAcknowledge == action ||
              PromptAction::kRestrictedNoticeOpenSettings == action) {
-    CHECK(privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.Get());
+    CHECK(privacy_sandbox::IsRestrictedNoticeRequired());
     pref_service_->SetBoolean(
         prefs::kPrivacySandboxM1RestrictedNoticeAcknowledged, true);
     pref_service_->SetBoolean(prefs::kPrivacySandboxM1AdMeasurementEnabled,
@@ -1051,14 +1051,14 @@
   // If the Privacy Sandbox is restricted, set the suppression reason as such,
   // and do not show a prompt.
   if (privacy_sandbox_settings->IsPrivacySandboxRestricted() &&
-      !privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.Get()) {
+      !privacy_sandbox::IsRestrictedNoticeRequired()) {
     pref_service->SetInteger(
         prefs::kPrivacySandboxM1PromptSuppressed,
         static_cast<int>(PromptSuppressedReason::kRestricted));
     return PromptType::kNone;
   }
 
-  if (privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.Get()) {
+  if (privacy_sandbox::IsRestrictedNoticeRequired()) {
     CHECK(privacy_sandbox::IsConsentRequired() ||
           privacy_sandbox::IsNoticeRequired());
     if (!pref_service->GetBoolean(
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl_unittest.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl_unittest.cc
index 37f82fe..ae419fa 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl_unittest.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service_impl_unittest.cc
@@ -579,7 +579,8 @@
 
   feature_list()->Reset();
   feature_list()->InitAndEnableFeatureWithParameters(
-      privacy_sandbox::kPrivacySandboxSettings4, {{"notice-required", "true"}});
+      privacy_sandbox::kPrivacySandboxSettings4,
+      {{privacy_sandbox::kPrivacySandboxSettings4NoticeRequiredName, "true"}});
   privacy_sandbox_service()->PromptActionOccurred(PromptAction::kNoticeShown);
   EXPECT_EQ(1, user_action_tester.GetActionCount(
                    "Settings.PrivacySandbox.Notice.Shown"));
@@ -631,7 +632,7 @@
   feature_list()->Reset();
   feature_list()->InitAndEnableFeatureWithParameters(
       privacy_sandbox::kPrivacySandboxSettings4,
-      {{"consent-required", "true"}});
+      {{privacy_sandbox::kPrivacySandboxSettings4ConsentRequiredName, "true"}});
 
   privacy_sandbox_service()->PromptActionOccurred(PromptAction::kConsentShown);
   EXPECT_EQ(1, user_action_tester.GetActionCount(
@@ -665,7 +666,9 @@
   feature_list()->Reset();
   feature_list()->InitAndEnableFeatureWithParameters(
       privacy_sandbox::kPrivacySandboxSettings4,
-      {{"consent-required", "true"}, {"restricted-notice", "true"}});
+      {{privacy_sandbox::kPrivacySandboxSettings4ConsentRequiredName, "true"},
+       {privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
+        "true"}});
 
   privacy_sandbox_service()->PromptActionOccurred(
       PromptAction::kRestrictedNoticeOpenSettings);
@@ -1819,7 +1822,9 @@
   void InitializeFeaturesBeforeStart() override {
     feature_list()->InitAndEnableFeatureWithParameters(
         privacy_sandbox::kPrivacySandboxSettings4,
-        {{"notice-required", "true"}, {"restricted-notice", "true"}});
+        {{privacy_sandbox::kPrivacySandboxSettings4NoticeRequiredName, "true"},
+         {privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
+          "true"}});
   }
 };
 
@@ -1888,7 +1893,8 @@
        PromptSuppressReasonClearedWhenRestrictedNoticeEnabled) {
   feature_list()->InitAndEnableFeatureWithParameters(
       privacy_sandbox::kPrivacySandboxSettings4,
-      {{"restricted-notice", "true"}});
+      {{privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
+        "true"}});
 
   prefs()->SetInteger(prefs::kPrivacySandboxM1PromptSuppressed,
                       static_cast<int>(PromptSuppressedReason::kRestricted));
@@ -1903,7 +1909,8 @@
        PromptSuppressReasonNotClearedWhenRestrictedNoticeDisabled) {
   feature_list()->InitAndEnableFeatureWithParameters(
       privacy_sandbox::kPrivacySandboxSettings4,
-      {{"restricted-notice", "false"}});
+      {{privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
+        "false"}});
 
   prefs()->SetInteger(prefs::kPrivacySandboxM1PromptSuppressed,
                       static_cast<int>(PromptSuppressedReason::kRestricted));
@@ -1964,7 +1971,8 @@
        RestrictedEnabledDoesntClearAdMeasurementPref) {
   feature_list()->InitAndEnableFeatureWithParameters(
       privacy_sandbox::kPrivacySandboxSettings4,
-      {{"restricted-notice", "true"}});
+      {{privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
+        "true"}});
 
   prefs()->SetBoolean(prefs::kPrivacySandboxM1TopicsEnabled, true);
   prefs()->SetBoolean(prefs::kPrivacySandboxM1FledgeEnabled, true);
@@ -1983,7 +1991,9 @@
   void InitializeFeaturesBeforeStart() override {
     feature_list()->InitAndEnableFeatureWithParameters(
         privacy_sandbox::kPrivacySandboxSettings4,
-        {{"consent-required", "true"}, {"notice-required", "false"}});
+        {{privacy_sandbox::kPrivacySandboxSettings4ConsentRequiredName, "true"},
+         {privacy_sandbox::kPrivacySandboxSettings4NoticeRequiredName,
+          "false"}});
   }
 };
 
@@ -2088,9 +2098,10 @@
   feature_list()->Reset();
   feature_list()->InitAndEnableFeatureWithParameters(
       privacy_sandbox::kPrivacySandboxSettings4,
-      {{"consent-required", "true"},
-       {"notice-required", "true"},
-       {"restricted-notice", "true"}});
+      {{privacy_sandbox::kPrivacySandboxSettings4ConsentRequiredName, "true"},
+       {privacy_sandbox::kPrivacySandboxSettings4NoticeRequiredName, "true"},
+       {privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
+        "true"}});
 
   std::map<PromptAction, TrustSafetySentimentService::FeatureArea>
       expected_feature_areas;
@@ -2306,7 +2317,10 @@
   void InitializeFeaturesBeforeStart() override {
     feature_list()->InitAndEnableFeatureWithParameters(
         privacy_sandbox::kPrivacySandboxSettings4,
-        {{"consent-required", "false"}, {"notice-required", "true"}});
+        {{privacy_sandbox::kPrivacySandboxSettings4ConsentRequiredName,
+          "false"},
+         {privacy_sandbox::kPrivacySandboxSettings4NoticeRequiredName,
+          "true"}});
   }
 };
 
@@ -2493,9 +2507,10 @@
   void InitializeFeaturesBeforeStart() override {
     feature_list()->InitAndEnableFeatureWithParameters(
         privacy_sandbox::kPrivacySandboxSettings4,
-        {{"consent-required", "false"},
-         {"notice-required", "true"},
-         {privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.name,
+        {{privacy_sandbox::kPrivacySandboxSettings4ConsentRequiredName,
+          "false"},
+         {privacy_sandbox::kPrivacySandboxSettings4NoticeRequiredName, "true"},
+         {privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
           "true"}});
   }
 };
@@ -2641,9 +2656,10 @@
   void InitializeFeaturesBeforeStart() override {
     feature_list()->InitAndEnableFeatureWithParameters(
         privacy_sandbox::kPrivacySandboxSettings4,
-        {{"consent-required", "false"},
-         {"notice-required", "true"},
-         {privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.name,
+        {{privacy_sandbox::kPrivacySandboxSettings4ConsentRequiredName,
+          "false"},
+         {privacy_sandbox::kPrivacySandboxSettings4NoticeRequiredName, "true"},
+         {privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
           "true"}});
   }
 };
@@ -2734,9 +2750,10 @@
   void InitializeFeaturesBeforeStart() override {
     feature_list()->InitAndEnableFeatureWithParameters(
         privacy_sandbox::kPrivacySandboxSettings4,
-        {{"consent-required", "false"},
-         {"notice-required", "true"},
-         {privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.name,
+        {{privacy_sandbox::kPrivacySandboxSettings4ConsentRequiredName,
+          "false"},
+         {privacy_sandbox::kPrivacySandboxSettings4NoticeRequiredName, "true"},
+         {privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
           "true"}});
   }
 };
@@ -2812,9 +2829,10 @@
   void InitializeFeaturesBeforeStart() override {
     feature_list()->InitAndEnableFeatureWithParameters(
         privacy_sandbox::kPrivacySandboxSettings4,
-        {{"consent-required", "false"},
-         {"notice-required", "true"},
-         {privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.name,
+        {{privacy_sandbox::kPrivacySandboxSettings4ConsentRequiredName,
+          "false"},
+         {privacy_sandbox::kPrivacySandboxSettings4NoticeRequiredName, "true"},
+         {privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
           "true"}});
   }
 };
@@ -2869,9 +2887,10 @@
   void InitializeFeaturesBeforeStart() override {
     feature_list()->InitAndEnableFeatureWithParameters(
         privacy_sandbox::kPrivacySandboxSettings4,
-        {{"consent-required", "false"},
-         {"notice-required", "true"},
-         {privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.name,
+        {{privacy_sandbox::kPrivacySandboxSettings4ConsentRequiredName,
+          "false"},
+         {privacy_sandbox::kPrivacySandboxSettings4NoticeRequiredName, "true"},
+         {privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
           "true"}});
   }
 };
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.cc
index fa6a8481..63e8ce53 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.cc
@@ -75,6 +75,10 @@
 
 PrivacySandboxSettingsDelegate::~PrivacySandboxSettingsDelegate() = default;
 
+bool PrivacySandboxSettingsDelegate::IsRestrictedNoticeEnabled() const {
+  return privacy_sandbox::IsRestrictedNoticeRequired();
+}
+
 bool PrivacySandboxSettingsDelegate::IsPrivacySandboxRestricted() const {
   if (privacy_sandbox::kPrivacySandboxSettings4ForceRestrictedUserForTesting
           .Get()) {
@@ -133,7 +137,7 @@
 
 bool PrivacySandboxSettingsDelegate::IsSubjectToM1NoticeRestricted() const {
   // If the feature is deactivated, the notice shouldn't be shown.
-  if (!privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.Get()) {
+  if (!privacy_sandbox::IsRestrictedNoticeRequired()) {
     return false;
   }
   return PrivacySandboxRestrictedNoticeRequired();
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.h b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.h
index 1bdae83..0b3fe5fe 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.h
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate.h
@@ -33,6 +33,7 @@
   ~PrivacySandboxSettingsDelegate() override;
 
   // PrivacySandboxSettings::Delegate:
+  bool IsRestrictedNoticeEnabled() const override;
   bool IsPrivacySandboxRestricted() const override;
   bool IsPrivacySandboxCurrentlyUnrestricted() const override;
   bool IsIncognitoProfile() const override;
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate_unittest.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate_unittest.cc
index 7527764..4137b0b7 100644
--- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate_unittest.cc
+++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings_delegate_unittest.cc
@@ -148,7 +148,7 @@
        RestrictedNoticeRequiredForSignedInUser) {
   feature_list()->InitAndEnableFeatureWithParameters(
       privacy_sandbox::kPrivacySandboxSettings4,
-      {{privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.name,
+      {{privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
         "true"}});
   // Sign the user in.
   identity_test_env()->MakePrimaryAccountAvailable(
@@ -173,7 +173,7 @@
        RestrictedNoticeRequiredWithoutAccountToken) {
   feature_list()->InitAndEnableFeatureWithParameters(
       privacy_sandbox::kPrivacySandboxSettings4,
-      {{privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.name,
+      {{privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
         "true"}});
   // Sign the user in.
   identity_test_env()->MakePrimaryAccountAvailable(
@@ -197,7 +197,7 @@
        RestrictedNoticeRequiredForSignedOutUser) {
   feature_list()->InitAndEnableFeatureWithParameters(
       privacy_sandbox::kPrivacySandboxSettings4,
-      {{privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.name,
+      {{privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
         "true"}});
   // If the user is not signed in to Chrome then we don't use any age signal and
   // don't restrict the feature.
@@ -208,7 +208,7 @@
        RestrictedNoticeRequiredFeatureDisabled) {
   feature_list()->InitAndEnableFeatureWithParameters(
       privacy_sandbox::kPrivacySandboxSettings4,
-      {{privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.name,
+      {{privacy_sandbox::kPrivacySandboxSettings4RestrictedNoticeName,
         "false"}});
   identity_test_env()->MakePrimaryAccountAvailable(
       kTestEmail, signin::ConsentLevel::kSignin);
diff --git a/chrome/browser/resources/ash/settings/metrics_utils.ts b/chrome/browser/resources/ash/settings/metrics_utils.ts
index 55cd3670..f8c3a13 100644
--- a/chrome/browser/resources/ash/settings/metrics_utils.ts
+++ b/chrome/browser/resources/ash/settings/metrics_utils.ts
@@ -154,6 +154,10 @@
     type: PrefType.NUMBER,
   },
   // os_a11y_page/keyboard_and_text_input_page.ts
+  'settings.a11y.caret.blink_interval': {
+    setting: Setting.kCaretBlinkInterval,
+    type: PrefType.NUMBER,
+  },
   'settings.a11y.caret_highlight': {
     setting: Setting.kHighlightTextCaret,
     type: PrefType.BOOLEAN,
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_my.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_my.xtb
index 38b61d57..9be9322 100644
--- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_my.xtb
+++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_my.xtb
@@ -1139,7 +1139,7 @@
 <translation id="9014206344398081366">ChromeVox ရှင်းလင်းပို့ချချက်</translation>
 <translation id="9040132695316389094">ခေါင်းစီး ၁</translation>
 <translation id="9061884144798498064">အစက် ၈ စက်ပါ မျက်မမြင်စာ ဇယားကို ရွေးပါ−</translation>
-<translation id="9063946545000394379">ယခင်စာလုံးသို့ ရွှေ့ရန်</translation>
+<translation id="9063946545000394379">ယခင် အက္ခရာသို့ ရွှေ့ရန်</translation>
 <translation id="9065283790526219006">+ပေါ့ပ်အာ့ပ်</translation>
 <translation id="9065912140022662363">နောက်ထပ် ရေဒီယိုခလုတ် မရှိပါ</translation>
 <translation id="9067522039955793016">စာမျက်နှာခြားခြင်း</translation>
diff --git a/chrome/browser/resources/chromeos/login/screens/common/oobe_reset.html b/chrome/browser/resources/chromeos/login/screens/common/oobe_reset.html
index 2c8f901..17872b0 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/oobe_reset.html
+++ b/chrome/browser/resources/chromeos/login/screens/common/oobe_reset.html
@@ -38,7 +38,7 @@
     for-step="restart-required,revert-promise,powerwash-proposal"
     footer-shrinkable>
   <iron-icon slot="icon" icon="oobe-32:alert"></iron-icon>
-  <h1 slot="title">
+  <h1 slot="title" aria-live="polite">
     [[i18nDynamic(locale, 'resetWarningTitle')]]
   </h1>
   <div slot="subtitle" class="powerwash-warning">
diff --git a/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.ts b/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.ts
index eda9d17..adc9ba99 100644
--- a/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.ts
+++ b/chrome/browser/resources/chromeos/login/screens/common/signin_fatal_error.ts
@@ -14,7 +14,6 @@
 import '../../components/dialogs/oobe_adaptive_dialog.js';
 import '../../components/buttons/oobe_text_button.js';
 
-import {assert} from '//resources/js/assert.js';
 import {PolymerElementProperties} from '//resources/polymer/v3_0/polymer/interfaces.js';
 import {mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
@@ -161,11 +160,10 @@
         return this.i18nDynamic(locale, 'fatalErrorMessageNoAccountDetails');
       case OobeTypes.FatalErrorCode.INSECURE_CONTENT_BLOCKED:
         const url = params.url;
-        assert(url);
-        return this.i18nDynamic(locale, 'fatalErrorMessageInsecureURL', url);
+        return this.i18nDynamic(
+            locale, 'fatalErrorMessageInsecureURL', url || '');
       case OobeTypes.FatalErrorCode.CUSTOM:
-        assert(params.errorText);
-        return params.errorText;
+        return params.errorText || '';
       default:
         return '';
     }
diff --git a/chrome/browser/resources/hangout_services/manifest.json b/chrome/browser/resources/hangout_services/manifest_v2.json
similarity index 100%
rename from chrome/browser/resources/hangout_services/manifest.json
rename to chrome/browser/resources/hangout_services/manifest_v2.json
diff --git a/chrome/browser/resources/hangout_services/manifest_v3.json b/chrome/browser/resources/hangout_services/manifest_v3.json
new file mode 100644
index 0000000..bbbbc39
--- /dev/null
+++ b/chrome/browser/resources/hangout_services/manifest_v3.json
@@ -0,0 +1,32 @@
+{
+  // Manifest V3 version of the extension, otherwise equivalent to manifest_v2.json.
+  // Only one of manifest_v2.json or manifest_v3.json will be loaded, chosen at
+  // runtime based on the kHangoutsExtensionV3 base feature.
+
+  // Extension ID: nkeimhogjdpnpccoofpliimaahmaaome
+  "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAQt2ZDdPfoSe/JI6ID5bgLHRCnCu9T36aYczmhw/tnv6QZB2I6WnOCMZXJZlRdqWc7w9jo4BWhYS50Vb4weMfh/I0On7VcRwJUgfAxW2cHB+EkmtI1v4v/OU24OqIa1Nmv9uRVeX0GjhQukdLNhAE6ACWooaf5kqKlCeK+1GOkQIDAQAB",
+
+  "name": "Google Hangouts",
+  // Note: Always update the version number when this file is updated. Chrome
+  // triggers extension preferences update on the version increase.
+  "version": "1.4.0",
+  "manifest_version": 3,
+  "externally_connectable": {
+    "matches": [
+      "https://*.google.com/*"
+    ]
+  },
+  "background": {
+    "service_worker": "thunk.js"
+  },
+  "incognito": "split",
+  "permissions": [
+    "desktopCapture",
+    "enterprise.hardwarePlatform",
+    "processes",
+    "system.cpu",
+    "webrtcAudioPrivate",
+    "webrtcDesktopCapturePrivate",
+    "webrtcLoggingPrivate"
+  ]
+}
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.html b/chrome/browser/resources/settings/people_page/sync_account_control.html
index 3bcf696..52d7a1c 100644
--- a/chrome/browser/resources/settings/people_page/sync_account_control.html
+++ b/chrome/browser/resources/settings/people_page/sync_account_control.html
@@ -164,23 +164,25 @@
                 '$i18nPolymer{signedInTo}', '$i18nPolymer{syncingTo}',
                 shownAccount_.email, syncStatus.hasError, syncStatus.signedIn,
                 syncStatus.disabled, syncStatus.firstSetupInProgress,
-                shownAccount_.isPrimaryAccount)]]
+                shownAccount_.isPrimaryAccount, syncStatus.signinPaused)]]
           </div>
         </div>
 <!-- Chrome OS does not allow switching users for sync. -->
 <if expr="not chromeos_ash">
         <cr-icon-button class="icon-arrow-dropdown cr-button-gap"
             hidden="[[!shouldAllowAccountSwitch_(syncStatus.signedIn,
-                syncStatus.domain)]]"
+                syncStatus.domain, syncStatus.signinPaused)]]"
             on-click="onMenuButtonClick_" id="dropdown-arrow"
             aria-label="$i18n{useAnotherAccount}">
         </cr-icon-button>
         <div class="separator"
             hidden="[[!shouldAllowAccountSwitch_(syncStatus.signedIn,
-                syncStatus.domain)]]"></div>
+                syncStatus.domain, syncStatus.signinPaused)]]">
+        </div>
 </if>
         <cr-button id="sync-button" class="action-button cr-button-gap"
-            hidden="[[shouldHideSyncButton_(syncStatus.signedIn)]]"
+            hidden="[[shouldHideSyncButton_(syncStatus.signedIn,
+                syncStatus.signinPaused)]]"
             on-click="onSyncButtonClick_"
             disabled="[[shouldDisableSyncButton_(showSetupButtons_,
                     syncStatus.firstSetupInProgress,
@@ -210,12 +212,23 @@
             $i18n{confirm}
           </cr-button>
         </div>
+        <div id="signin-paused-buttons"
+            hidden="[[!shouldShowSigninPausedButtons_(
+                syncStatus.signinPaused)]]">
+          <cr-button class="cr-button-gap" on-click="onSigninClick_">
+            $i18n{signinPaused}
+          </cr-button>
+          <cr-button class="cr-button-gap" on-click="onSignoutClick_">
+            $i18n{peopleSignOut}
+          </cr-button>
+        </div>
+
       </div>
 <!-- Chrome OS does not allow switching users for sync. -->
 <if expr="not chromeos_ash">
       <template is="dom-if"
           if="[[shouldAllowAccountSwitch_(syncStatus.signedIn,
-              syncStatus.domain)]]" restamp>
+              syncStatus.domain, syncStatus.signinPaused)]]" restamp>
         <cr-action-menu id="menu" auto-reposition
             role-description="$i18n{menu}">
           <template is="dom-repeat" items="[[storedAccounts_]]">
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.ts b/chrome/browser/resources/settings/people_page/sync_account_control.ts
index 1e80ecc36..1d4ad67 100644
--- a/chrome/browser/resources/settings/people_page/sync_account_control.ts
+++ b/chrome/browser/resources/settings/people_page/sync_account_control.ts
@@ -227,19 +227,24 @@
   }
 
   private getAccountLabel_(
-      signedInLabel: string, syncingLabel: string, account: string): string {
+      signedInLabel: string, syncingLabel: string, email: string): string {
+    // When in sign in paused, only show the email address.
+    if (this.syncStatus.signinPaused) {
+      return email;
+    }
+
     if (this.syncStatus.firstSetupInProgress) {
-      return this.syncStatus.statusText || account;
+      return this.syncStatus.statusText || email;
     }
 
     if (this.syncStatus.signedIn && !this.syncStatus.hasError &&
         !this.syncStatus.disabled) {
-      return loadTimeData.substituteString(syncingLabel, account);
+      return loadTimeData.substituteString(syncingLabel, email);
     }
 
-    return (this.shownAccount_ && this.shownAccount_!.isPrimaryAccount) ?
-        loadTimeData.substituteString(signedInLabel, account) :
-        account;
+    return (this.shownAccount_! && this.shownAccount_!!.isPrimaryAccount) ?
+        loadTimeData.substituteString(signedInLabel, email) :
+        email;
   }
 
   private getAccountImageSrc_(image: string|null): string {
@@ -326,12 +331,13 @@
 
   /**
    * Determines whether the sync button should be hidden, in the case where the
-   * user has sync enabled or if the property to hide the banner was explicitly
-   * set.
+   * user has sync enabled, is in sign in paused, or if the property to hide
+   * the banner was explicitly set.
    */
   private shouldHideSyncButton_(): boolean {
     return this.hideButtons ||
-        (!!this.syncStatus && !!this.syncStatus.signedIn);
+        (!!this.syncStatus &&
+         (!!this.syncStatus.signedIn || !!this.syncStatus.signinPaused));
   }
 
   private shouldShowTurnOffButton_(): boolean {
@@ -368,6 +374,7 @@
     }
     // </if>
     return !this.syncStatus.signedIn && !this.hideButtons &&
+        !this.syncStatus.signinPaused &&
         (!loadTimeData.getBoolean('turnOffSyncAllowedForManagedProfiles') ||
          !this.syncStatus.domain);
   }
@@ -515,6 +522,10 @@
     this.dispatchEvent(new CustomEvent(
         'sync-setup-done', {bubbles: true, composed: true, detail: true}));
   }
+
+  private shouldShowSigninPausedButtons_() {
+    return !!this.syncStatus && !!this.syncStatus.signinPaused;
+  }
 }
 
 declare global {
diff --git a/chrome/browser/resources/settings_shared/people_page/sync_browser_proxy.ts b/chrome/browser/resources/settings_shared/people_page/sync_browser_proxy.ts
index d89c0df..70d1389 100644
--- a/chrome/browser/resources/settings_shared/people_page/sync_browser_proxy.ts
+++ b/chrome/browser/resources/settings_shared/people_page/sync_browser_proxy.ts
@@ -39,6 +39,7 @@
   statusText?: string;
   supervisedUser?: boolean;
   syncSystemEnabled?: boolean;
+  signinPaused?: boolean;
 }
 
 /**
diff --git a/chrome/browser/resources/side_panel/read_anything/app.html b/chrome/browser/resources/side_panel/read_anything/app.html
index fc71daa..3aa2cbf4 100644
--- a/chrome/browser/resources/side_panel/read_anything/app.html
+++ b/chrome/browser/resources/side_panel/read_anything/app.html
@@ -1,11 +1,11 @@
 <style include="cr-hidden-style sp-shared-style">
-  html[chrome-refresh-2023] #empty-state-container {
+  :host-context([chrome-refresh-2023]) #empty-state-container {
     border-radius: 12px;
   }
   .sp-scroller {
     display: block;
   }
-  html[chrome-refresh-2023] #empty-state-container {
+  :host-context([chrome-refresh-2023]) #empty-state-container {
     margin: 0 8px;
     padding: 20px 0;
   }
@@ -14,19 +14,19 @@
     width: 100%;
   }
 
-  #appFlexParent {
+  #flexParent {
     height: 100%;
     width: 100%;
     display: flex;
     flex-direction: column;
   }
 
-  #appFlexParent #container-parent {
+  #container-parent {
+    background: var(--background-color);
     height: 100%;
-    overflow: auto;
   }
 
-  html[chrome-refresh-2023] .sp-scroller::-webkit-scrollbar-track {
+  :host-context([chrome-refresh-2023]) .sp-scroller::-webkit-scrollbar-track {
     margin-top: 6px;
     margin-bottom: 6px;
   }
@@ -41,7 +41,7 @@
     user-select: auto;
   }
 
-  #appFlexParent #container {
+  #container {
     background: var(--background-color);
     color: var(--foreground-color);
     font-family: var(--font-family);
@@ -53,40 +53,40 @@
     max-width: 60ch;
     margin: 0 auto;
   }
-  #appFlexParent a:link {
+  a:link {
     color: var(--link-color);
   }
-  #appFlexParent a:visited {
+  a:visited {
     color: var(--visited-link-color);
   }
-  #appFlexParent #empty-state-container {
+  #empty-state-container {
     background: var(--background-color);
     height: 100%;
     padding: 20px;
   }
-  #appFlexParent sp-empty-state {
+  sp-empty-state {
     display: flex;
     margin: 0 auto 16px auto;
     width: fit-content;
   }
-  #appFlexParent ::selection {
+  ::selection {
     background: var(--selection-color);
     color: var(--selection-text-color);
   }
-  #appFlexParent .current-read-highlight {
+  .current-read-highlight {
     background-color: var(--current-highlight-bg-color);
   }
-  #appFlexParent .previous-read-highlight {
+  .previous-read-highlight {
     color: var(--previous-highlight-color);
     background-color: transparent;
   }
 
-  #appFlexParent img {
+  img {
     max-width: 100%;
   }
 
 </style>
-<div id="appFlexParent" on-keydown="onKeyDown_">
+<div id="flexParent" on-keydown="onKeyDown_">
   <div id="toolbar-container" hidden="[[!isWebUIToolbarVisible_]]">
     <read-anything-toolbar
       paused="[[speechPlayingState.paused]]"
diff --git a/chrome/browser/resources/side_panel/read_anything/app.ts b/chrome/browser/resources/side_panel/read_anything/app.ts
index d6396d5..6cc665e 100644
--- a/chrome/browser/resources/side_panel/read_anything/app.ts
+++ b/chrome/browser/resources/side_panel/read_anything/app.ts
@@ -205,7 +205,7 @@
 export interface ReadAnythingElement {
   $: {
     toolbar: ReadAnythingToolbarElement,
-    appFlexParent: HTMLElement,
+    flexParent: HTMLElement,
     container: HTMLElement,
   };
 }
@@ -228,14 +228,6 @@
   private startTime = Date.now();
   private constructorTime: number;
 
-  // eslint-disable-next-line @typescript-eslint/naming-convention
-  override _attachDom(dom: Node|null): ShadowRoot|null {
-    if (dom) {
-      this.appendChild(dom);
-    }
-    return null;
-  }
-
   // Maps a DOM node to the AXNodeID that was used to create it. DOM nodes and
   // AXNodeIDs are unique, so this is a two way map where either DOM node or
   // AXNodeID can be used to access the other.
@@ -343,7 +335,7 @@
     // panel. This follows Side Panel best practices and prevents loading
     // artifacts from showing if the side panel is shown before content is
     // ready.
-    listenOnce(this.$.appFlexParent, 'dom-change', () => {
+    listenOnce(this.$.flexParent, 'dom-change', () => {
       setTimeout(() => chrome.readingMode.shouldShowUi(), 0);
     });
 
@@ -362,7 +354,9 @@
       if (!this.hasContent_ || !this.speechPlayingState.paused) {
         return;
       }
-      const selection = this.getSelection();
+      const shadowRoot = this.shadowRoot;
+      assert(shadowRoot, 'no shadow root');
+      const selection = shadowRoot.getSelection();
       assert(selection, 'no selection');
       const {anchorNode, anchorOffset, focusNode, focusOffset} = selection;
       if (!anchorNode || !focusNode) {
@@ -449,11 +443,6 @@
       htmlTag = 'div';
     }
 
-    // Only one body tag is allowed per document.
-    if (htmlTag === 'body') {
-      htmlTag = 'div';
-    }
-
     const url = chrome.readingMode.getUrl(nodeId);
 
     if (!this.shouldShowLinks() && htmlTag === 'a') {
@@ -665,7 +654,9 @@
   }
 
   getSelection(): any {
-    const selection = document.getSelection();
+    const shadowRoot = this.shadowRoot;
+    assert(shadowRoot, 'no shadow root');
+    const selection = shadowRoot.getSelection();
     return selection;
   }
 
@@ -739,8 +730,12 @@
   }
 
   updateLinks() {
+    if (!this.shadowRoot) {
+      return;
+    }
+
     const selector = this.shouldShowLinks() ? 'span[data-link]' : 'a';
-    const elements = this.querySelectorAll(selector);
+    const elements = this.shadowRoot.querySelectorAll(selector);
 
     for (const elem of elements) {
       assert(elem instanceof HTMLElement, 'link is not an HTMLElement');
diff --git a/chrome/browser/safety_hub/android/java/src/org/chromium/chrome/browser/safety_hub/SafetyHubFetchService.java b/chrome/browser/safety_hub/android/java/src/org/chromium/chrome/browser/safety_hub/SafetyHubFetchService.java
index f3173a3..344245b 100644
--- a/chrome/browser/safety_hub/android/java/src/org/chromium/chrome/browser/safety_hub/SafetyHubFetchService.java
+++ b/chrome/browser/safety_hub/android/java/src/org/chromium/chrome/browser/safety_hub/SafetyHubFetchService.java
@@ -14,8 +14,8 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.profiles.ProfileManager;
 import org.chromium.chrome.browser.sync.SyncServiceFactory;
-import org.chromium.components.background_task_scheduler.BackgroundTask;
 import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory;
+import org.chromium.components.background_task_scheduler.NativeBackgroundTask;
 import org.chromium.components.background_task_scheduler.TaskIds;
 import org.chromium.components.background_task_scheduler.TaskInfo;
 import org.chromium.components.background_task_scheduler.TaskParameters;
@@ -27,7 +27,7 @@
 import java.util.concurrent.TimeUnit;
 
 /** Manages the scheduling of Safety Hub fetch jobs. */
-public class SafetyHubFetchService implements BackgroundTask {
+public class SafetyHubFetchService extends NativeBackgroundTask {
     private static final int SAFETY_HUB_JOB_INTERVAL_IN_DAYS = 1;
 
     /** See {@link ChromeActivitySessionTracker#onForegroundSessionStart()}. */
@@ -62,14 +62,26 @@
     }
 
     @Override
-    public boolean onStartTask(
-            Context context, TaskParameters parameters, final TaskFinishedCallback callback) {
-        fetchBreachedCredentialsCount(callback);
-        return false;
+    protected int onStartTaskBeforeNativeLoaded(
+            Context context, TaskParameters taskParameters, TaskFinishedCallback callback) {
+        return StartBeforeNativeResult.LOAD_NATIVE;
     }
 
     @Override
-    public boolean onStopTask(Context context, TaskParameters taskParameters) {
+    protected void onStartTaskWithNative(
+            Context context, TaskParameters taskParameters, TaskFinishedCallback callback) {
+        fetchBreachedCredentialsCount(callback);
+    }
+
+    @Override
+    protected boolean onStopTaskBeforeNativeLoaded(Context context, TaskParameters taskParameters) {
+        // Reschedule task if native didn't complete loading, the call to GMSCore wouldn't have been
+        // made at this point.
+        return true;
+    }
+
+    @Override
+    protected boolean onStopTaskWithNative(Context context, TaskParameters taskParameters) {
         // GMSCore has no mechanism to abort dispatched tasks.
         return false;
     }
diff --git a/chrome/browser/safety_hub/android/junit/src/org/chromium/chrome/browser/safety_hub/SafetyHubFetchServiceTest.java b/chrome/browser/safety_hub/android/junit/src/org/chromium/chrome/browser/safety_hub/SafetyHubFetchServiceTest.java
index 9f06de3..5bc9093 100644
--- a/chrome/browser/safety_hub/android/junit/src/org/chromium/chrome/browser/safety_hub/SafetyHubFetchServiceTest.java
+++ b/chrome/browser/safety_hub/android/junit/src/org/chromium/chrome/browser/safety_hub/SafetyHubFetchServiceTest.java
@@ -8,6 +8,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
@@ -49,6 +50,7 @@
 import org.chromium.components.background_task_scheduler.BackgroundTask;
 import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler;
 import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory;
+import org.chromium.components.background_task_scheduler.NativeBackgroundTask;
 import org.chromium.components.background_task_scheduler.TaskIds;
 import org.chromium.components.background_task_scheduler.TaskInfo;
 import org.chromium.components.background_task_scheduler.TaskParameters;
@@ -142,7 +144,7 @@
         setPasswordSync(false);
         TaskParameters params = TaskParameters.create(TaskIds.SAFETY_HUB_JOB_ID).build();
 
-        new SafetyHubFetchService().onStartTask(mContext, params, mTaskFinishedCallback);
+        new SafetyHubFetchService().onStartTaskWithNative(mContext, params, mTaskFinishedCallback);
 
         verify(mPrefService, never()).setInteger(eq(Pref.BREACHED_CREDENTIALS_COUNT), anyInt());
         verify(mTaskFinishedCallback, times(1)).taskFinished(eq(/* needsReschedule= */ true));
@@ -153,7 +155,7 @@
         setUPMStatus(false);
         TaskParameters params = TaskParameters.create(TaskIds.SAFETY_HUB_JOB_ID).build();
 
-        new SafetyHubFetchService().onStartTask(mContext, params, mTaskFinishedCallback);
+        new SafetyHubFetchService().onStartTaskWithNative(mContext, params, mTaskFinishedCallback);
 
         verify(mPrefService, never()).setInteger(eq(Pref.BREACHED_CREDENTIALS_COUNT), anyInt());
         verify(mTaskFinishedCallback, times(1)).taskFinished(eq(/* needsReschedule= */ true));
@@ -164,7 +166,7 @@
         TaskParameters params = TaskParameters.create(TaskIds.SAFETY_HUB_JOB_ID).build();
         mPasswordCheckupClientHelper.setError(new Exception());
 
-        new SafetyHubFetchService().onStartTask(mContext, params, mTaskFinishedCallback);
+        new SafetyHubFetchService().onStartTaskWithNative(mContext, params, mTaskFinishedCallback);
 
         verify(mPrefService, never()).setInteger(eq(Pref.BREACHED_CREDENTIALS_COUNT), anyInt());
         verify(mTaskFinishedCallback, times(1)).taskFinished(eq(/* needsReschedule= */ true));
@@ -176,7 +178,7 @@
         TaskParameters params = TaskParameters.create(TaskIds.SAFETY_HUB_JOB_ID).build();
         mPasswordCheckupClientHelper.setBreachedCredentialsCount(breachedCredentialsCount);
 
-        new SafetyHubFetchService().onStartTask(mContext, params, mTaskFinishedCallback);
+        new SafetyHubFetchService().onStartTaskWithNative(mContext, params, mTaskFinishedCallback);
 
         verify(mPrefService, times(1))
                 .setInteger(Pref.BREACHED_CREDENTIALS_COUNT, breachedCredentialsCount);
@@ -184,6 +186,19 @@
     }
 
     @Test
+    public void testStartTask_BeforeNativeLoaded() {
+        TaskParameters params = TaskParameters.create(TaskIds.SAFETY_HUB_JOB_ID).build();
+
+        int result =
+                new SafetyHubFetchService()
+                        .onStartTaskBeforeNativeLoaded(mContext, params, mTaskFinishedCallback);
+
+        assertEquals(NativeBackgroundTask.StartBeforeNativeResult.LOAD_NATIVE, result);
+        // Task finished can only gets called from the native part, when async processing starts.
+        verify(mTaskFinishedCallback, times(0)).taskFinished(anyBoolean());
+    }
+
+    @Test
     @Features.EnableFeatures(ChromeFeatureList.SAFETY_HUB)
     public void onSessionStart_WithSafetyHubEnabled_SchedulesTask() {
         SafetyHubFetchService.onForegroundSessionStart();
diff --git a/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc b/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc
index 3627767..fb622afb 100644
--- a/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc
+++ b/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc
@@ -1386,8 +1386,8 @@
   ASSERT_FALSE(switches::IsExplicitBrowserSigninUIOnDesktopEnabled(
       switches::ExplicitBrowserSigninPhase::kExperimental));
 
-  // Disabling `switches::kUnoDesktop` should not reset the pref.
-  EXPECT_TRUE(browser()->profile()->GetPrefs()->GetBoolean(
+  // Disabling `switches::kUnoDesktop` should reset the pref.
+  EXPECT_FALSE(browser()->profile()->GetPrefs()->GetBoolean(
       prefs::kExplicitBrowserSignin));
   // Disabling `switches::kUnoDesktop` feature should revert back to the
   // previous default state, since there were no interactions, defaults to
diff --git a/chrome/browser/sync/test/integration/bookmarks_helper.cc b/chrome/browser/sync/test/integration/bookmarks_helper.cc
index 7e3cf4a..4f6e477c 100644
--- a/chrome/browser/sync/test/integration/bookmarks_helper.cc
+++ b/chrome/browser/sync/test/integration/bookmarks_helper.cc
@@ -911,6 +911,11 @@
   cb_.Run();
 }
 
+void AnyBookmarkChangeObserver::BookmarkNodeFaviconChanged(
+    const bookmarks::BookmarkNode* node) {
+  cb_.Run();
+}
+
 BookmarkModelStatusChangeChecker::BookmarkModelStatusChangeChecker() = default;
 
 BookmarkModelStatusChangeChecker::~BookmarkModelStatusChangeChecker() {
diff --git a/chrome/browser/sync/test/integration/bookmarks_helper.h b/chrome/browser/sync/test/integration/bookmarks_helper.h
index 1ea5363..aa1a231 100644
--- a/chrome/browser/sync/test/integration/bookmarks_helper.h
+++ b/chrome/browser/sync/test/integration/bookmarks_helper.h
@@ -308,6 +308,7 @@
 
   // BaseBookmarkModelObserver overrides.
   void BookmarkModelChanged() override;
+  void BookmarkNodeFaviconChanged(const bookmarks::BookmarkNode* node) override;
 
  private:
   const base::RepeatingClosure cb_;
diff --git a/chrome/browser/sync/test/integration/single_client_plus_address_sync_test.cc b/chrome/browser/sync/test/integration/single_client_plus_address_sync_test.cc
index b1896ed..12587ea 100644
--- a/chrome/browser/sync/test/integration/single_client_plus_address_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_plus_address_sync_test.cc
@@ -56,7 +56,11 @@
   }
 
   // PlusAddressService::Observer:
-  void OnPlusAddressesChanged() override { CheckExitCondition(); }
+  void OnPlusAddressesChanged(
+      const std::vector<plus_addresses::PlusAddressDataChange>& changes)
+      override {
+    CheckExitCondition();
+  }
 
  private:
   const raw_ptr<PlusAddressService> service_;
diff --git a/chrome/browser/sync/test/integration/single_client_webauthn_credentials_sync_test.cc b/chrome/browser/sync/test/integration/single_client_webauthn_credentials_sync_test.cc
index 3d08215..5c0af5d3 100644
--- a/chrome/browser/sync/test/integration/single_client_webauthn_credentials_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_webauthn_credentials_sync_test.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/containers/span.h"
+#include "base/location.h"
 #include "base/rand_util.h"
 #include "base/ranges/algorithm.h"
 #include "base/test/scoped_feature_list.h"
@@ -24,6 +25,7 @@
 #include "components/sync/model/in_memory_metadata_change_list.h"
 #include "components/sync/protocol/entity_specifics.pb.h"
 #include "components/sync/protocol/webauthn_credential_specifics.pb.h"
+#include "components/version_info/version_info.h"
 #include "components/webauthn/core/browser/passkey_model.h"
 #include "components/webauthn/core/browser/passkey_model_change.h"
 #include "components/webauthn/core/browser/passkey_model_utils.h"
@@ -34,6 +36,7 @@
 
 namespace {
 
+using testing::ElementsAre;
 using testing::IsEmpty;
 using testing::Optional;
 using testing::UnorderedElementsAre;
@@ -73,6 +76,27 @@
 
 constexpr int32_t kTrustedVaultKeyVersion = 23;
 
+MATCHER_P2(MatchesDeletionOrigin, expected_version, expected_location, "") {
+  const sync_pb::DeletionOrigin& actual_origin = arg;
+  if (actual_origin.chromium_version() != expected_version) {
+    *result_listener << "Expected version " << expected_version << " but got "
+                     << actual_origin.chromium_version();
+    return false;
+  }
+  if (actual_origin.file_name_hash() !=
+      base::PersistentHash(expected_location.file_name())) {
+    *result_listener << "Unexpected file name hash: "
+                     << actual_origin.file_name_hash();
+    return false;
+  }
+  if (actual_origin.file_line_number() != expected_location.line_number()) {
+    *result_listener << "Unexpected line number: "
+                     << actual_origin.file_line_number();
+    return false;
+  }
+  return true;
+}
+
 bool PublicKeyForPasskeyEquals(
     const sync_pb::WebauthnCredentialSpecifics& passkey,
     base::span<const uint8_t> trusted_vault_key,
@@ -388,6 +412,8 @@
 // Deleting a local passkey should remove from the server.
 IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                        UploadLocalPasskeyDeletion) {
+  const base::Location kLocation = FROM_HERE;
+
   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
 
   sync_pb::WebauthnCredentialSpecifics passkey = NewPasskey();
@@ -399,9 +425,14 @@
   PasskeyChangeObservationChecker change_checker(
       kSingleProfile,
       {{webauthn::PasskeyModelChange::ChangeType::REMOVE, sync_id}});
-  GetModel().DeletePasskey(passkey.credential_id());
+  GetModel().DeletePasskey(passkey.credential_id(), kLocation);
   EXPECT_TRUE(ServerPasskeysMatchChecker(IsEmpty()).Wait());
   EXPECT_TRUE(change_checker.Wait());
+
+  EXPECT_THAT(GetFakeServer()->GetCommittedDeletionOrigins(
+                  syncer::ModelType::WEBAUTHN_CREDENTIAL),
+              ElementsAre(MatchesDeletionOrigin(
+                  version_info::GetVersionNumber(), kLocation)));
 }
 
 // Downloading a deletion for a passkey that does not exist locally should not
@@ -448,7 +479,7 @@
 
   MockPasskeyModelObserver observer(&GetModel());
   EXPECT_CALL(observer, OnPasskeysChanged).Times(0);
-  EXPECT_FALSE(GetModel().DeletePasskey("non existing id"));
+  EXPECT_FALSE(GetModel().DeletePasskey("non existing id", FROM_HERE));
   EXPECT_TRUE(
       ServerPasskeysMatchChecker(UnorderedElementsAre(EntityHasSyncId(sync_id)))
           .Wait());
@@ -487,7 +518,7 @@
       ServerPasskeysMatchChecker(testing::BeginEndDistanceIs(6)).Wait());
 
   // Delete passkey 4. This should result in only passkey 4 being deleted.
-  ASSERT_TRUE(GetModel().DeletePasskey(passkey4.credential_id()));
+  ASSERT_TRUE(GetModel().DeletePasskey(passkey4.credential_id(), FROM_HERE));
   EXPECT_TRUE(ServerPasskeysMatchChecker(
                   UnorderedElementsAre(EntityHasSyncId(passkey1.sync_id()),
                                        EntityHasSyncId(passkey2.sync_id()),
@@ -497,7 +528,7 @@
                   .Wait());
 
   // Delete passkey 5. This should also result in only passkey 5 being deleted.
-  ASSERT_TRUE(GetModel().DeletePasskey(passkey5.credential_id()));
+  ASSERT_TRUE(GetModel().DeletePasskey(passkey5.credential_id(), FROM_HERE));
   EXPECT_TRUE(ServerPasskeysMatchChecker(
                   UnorderedElementsAre(EntityHasSyncId(passkey1.sync_id()),
                                        EntityHasSyncId(passkey2.sync_id()),
@@ -506,7 +537,7 @@
                   .Wait());
 
   // Delete passkey 6. All credentials should be deleted.
-  ASSERT_TRUE(GetModel().DeletePasskey(passkey6.credential_id()));
+  ASSERT_TRUE(GetModel().DeletePasskey(passkey6.credential_id(), FROM_HERE));
   EXPECT_TRUE(ServerPasskeysMatchChecker(IsEmpty()).Wait());
 }
 
@@ -536,7 +567,7 @@
                       EntityHasSyncId(different_user_id_passkey.sync_id())))
                   .Wait());
 
-  ASSERT_TRUE(GetModel().DeletePasskey(passkey.credential_id()));
+  ASSERT_TRUE(GetModel().DeletePasskey(passkey.credential_id(), FROM_HERE));
   EXPECT_TRUE(ServerPasskeysMatchChecker(
                   UnorderedElementsAre(
                       EntityHasSyncId(different_rp_id_passkey.sync_id()),
@@ -563,8 +594,8 @@
                   .Wait());
 
   // Deleting should fail because neither passkey is head of a shadow chain.
-  ASSERT_FALSE(GetModel().DeletePasskey(passkey1.credential_id()));
-  ASSERT_FALSE(GetModel().DeletePasskey(passkey2.credential_id()));
+  ASSERT_FALSE(GetModel().DeletePasskey(passkey1.credential_id(), FROM_HERE));
+  ASSERT_FALSE(GetModel().DeletePasskey(passkey2.credential_id(), FROM_HERE));
   EXPECT_TRUE(ServerPasskeysMatchChecker(
                   UnorderedElementsAre(EntityHasSyncId(passkey1.sync_id()),
                                        EntityHasSyncId(passkey2.sync_id())))
@@ -583,7 +614,7 @@
                   .Wait());
   EXPECT_THAT(GetModel().GetAllPasskeys(),
               UnorderedElementsAre(PasskeyHasSyncId(passkey.sync_id())));
-  GetModel().DeletePasskey(passkey.credential_id());
+  GetModel().DeletePasskey(passkey.credential_id(), FROM_HERE);
   EXPECT_TRUE(GetModel().GetAllPasskeys().empty());
 }
 
diff --git a/chrome/browser/sync/test/integration/two_client_webauthn_credentials_sync_test.cc b/chrome/browser/sync/test/integration/two_client_webauthn_credentials_sync_test.cc
index 0eccaef..1cb5418 100644
--- a/chrome/browser/sync/test/integration/two_client_webauthn_credentials_sync_test.cc
+++ b/chrome/browser/sync/test/integration/two_client_webauthn_credentials_sync_test.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 "base/location.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/sync/test/integration/multi_client_status_change_checker.h"
 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
@@ -51,7 +52,7 @@
   ASSERT_TRUE(AwaitAllModelsMatch());
   EXPECT_EQ(model1.GetAllSyncIds().size(), 2u);
 
-  ASSERT_TRUE(model1.DeletePasskey(passkey0.credential_id()));
+  ASSERT_TRUE(model1.DeletePasskey(passkey0.credential_id(), FROM_HERE));
   ASSERT_TRUE(AwaitAllModelsMatch());
   EXPECT_EQ(model1.GetAllSyncIds().size(), 1u);
 }
diff --git a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl_unittest.cc b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl_unittest.cc
index 2edbeefa..4bafb2c 100644
--- a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl_unittest.cc
+++ b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl_unittest.cc
@@ -159,7 +159,7 @@
   void ConfigureForCreditCards(const CreditCard& card) {
     form_ = test::CreateTestCreditCardFormData(/*is_https=*/true,
                                                /*use_month_type=*/false);
-    form_.fields[0].is_focusable = true;
+    form_.fields[0].set_is_focusable(true);
     autofill_client_.GetPersonalDataManager()->AddCreditCard(card);
   }
 
@@ -169,7 +169,7 @@
     iban.set_value(std::u16string(test::kIbanValue16));
     autofill_client_.GetPersonalDataManager()->AddAsLocalIban(std::move(iban));
     form_ = test::CreateTestIbanFormData(/*value=*/"");
-    form_.fields[0].is_focusable = true;
+    form_.fields[0].set_is_focusable(true);
   }
 
   void OnFormsSeen() {
@@ -271,7 +271,7 @@
 
 TEST_P(TouchToFillDelegateAndroidImplPaymentMethodUnitTest,
        TryToShowTouchToFillFailsForPaymentMethodIfFieldIsNotFocusable) {
-  form_.fields[0].is_focusable = false;
+  form_.fields[0].set_is_focusable(false);
   ASSERT_FALSE(touch_to_fill_delegate_->IsShowingTouchToFill());
 
   TryToShowTouchToFill(/*expected_success=*/false);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index f98ff0dc..c2c6483 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1409,6 +1409,8 @@
       "sad_tab_helper.cc",
       "sad_tab_helper.h",
       "sad_tab_types.h",
+      "safety_hub/abusive_notification_permissions_manager.cc",
+      "safety_hub/abusive_notification_permissions_manager.h",
       "safety_hub/extensions_result.cc",
       "safety_hub/extensions_result.h",
       "safety_hub/menu_notification.cc",
@@ -3119,6 +3121,8 @@
       "webui/ash/cloud_upload/cloud_upload_util.h",
       "webui/ash/cloud_upload/drive_upload_handler.cc",
       "webui/ash/cloud_upload/drive_upload_handler.h",
+      "webui/ash/cloud_upload/drive_upload_observer.cc",
+      "webui/ash/cloud_upload/drive_upload_observer.h",
       "webui/ash/cloud_upload/one_drive_upload_handler.cc",
       "webui/ash/cloud_upload/one_drive_upload_handler.h",
       "webui/ash/connectivity_diagnostics_dialog.cc",
@@ -5181,6 +5185,8 @@
       "views/autofill/popup/popup_row_view.h",
       "views/autofill/popup/popup_row_with_button_view.cc",
       "views/autofill/popup/popup_row_with_button_view.h",
+      "views/autofill/popup/popup_search_bar_view.cc",
+      "views/autofill/popup/popup_search_bar_view.h",
       "views/autofill/popup/popup_separator_view.cc",
       "views/autofill/popup/popup_separator_view.h",
       "views/autofill/popup/popup_title_view.cc",
diff --git a/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view_impl.cc b/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view_impl.cc
index 9191154..1ded785 100644
--- a/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view_impl.cc
+++ b/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view_impl.cc
@@ -10,6 +10,7 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
 #include "base/functional/callback.h"
 #include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
@@ -77,12 +78,11 @@
   if (!controller_) {
     return;
   }
-  const int line_count = controller_->GetLineCount();
-  JNIEnv* env = base::android::AttachCurrentThread();
-  ScopedJavaLocalRef<jobjectArray> data_array =
-      Java_AutofillKeyboardAccessoryViewBridge_createAutofillSuggestionArray(
-          env, line_count);
 
+  JNIEnv* env = base::android::AttachCurrentThread();
+  const int line_count = controller_->GetLineCount();
+  std::vector<ScopedJavaLocalRef<jobject>> java_suggestions;
+  java_suggestions.reserve(line_count);
   for (int i = 0; i < line_count; ++i) {
     const Suggestion& suggestion = controller_->GetSuggestionAt(i);
     int android_icon_id = 0;
@@ -111,14 +111,16 @@
       }
     }
 
-    Java_AutofillKeyboardAccessoryViewBridge_addToAutofillSuggestionArray(
-        env, data_array, i, label, sublabel, android_icon_id,
-        base::to_underlying(suggestion.popup_item_id),
-        controller_->GetRemovalConfirmationText(i, nullptr, nullptr),
-        suggestion.feature_for_iph ? suggestion.feature_for_iph->name : "",
-        url::GURLAndroid::FromNativeGURL(env, suggestion.custom_icon_url));
+    java_suggestions.push_back(
+        Java_AutofillKeyboardAccessoryViewBridge_createAutofillSuggestion(
+            env, label, sublabel, android_icon_id,
+            base::to_underlying(suggestion.popup_item_id),
+            controller_->GetRemovalConfirmationText(i, nullptr, nullptr),
+            suggestion.feature_for_iph ? suggestion.feature_for_iph->name : "",
+            url::GURLAndroid::FromNativeGURL(env, suggestion.custom_icon_url)));
   }
-  Java_AutofillKeyboardAccessoryViewBridge_show(env, java_object_, data_array);
+  Java_AutofillKeyboardAccessoryViewBridge_show(env, java_object_,
+                                                std::move(java_suggestions));
 }
 
 void AutofillKeyboardAccessoryViewImpl::AxAnnounce(const std::u16string& text) {
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/MinorModeHelper.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/MinorModeHelper.java
index ea07a4e..4ca3b5e 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/MinorModeHelper.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/MinorModeHelper.java
@@ -76,7 +76,7 @@
         int NUM_ENTRIES = 4;
     };
 
-    @interface SyncButtonClicked {
+    public @interface SyncButtonClicked {
         // These values are persisted to logs. Entries should not be renumbered and
         // numeric values should never be reused.
         int SYNC_OPT_IN_EQUAL_WEIGHTED = 0;
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninView.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninView.java
index 5df8b9ae..d74cb234 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninView.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninView.java
@@ -168,7 +168,7 @@
         this.mAcceptOnClickListener.onClick(view);
     }
 
-    private void refuseOnClickListener(View view) {
+    void refuseButtonClicked() {
         if (this.mAcceptButtonType == ButtonType.PRIMARY_FILLED) {
             MinorModeHelper.recordButtonClicked(
                     MinorModeHelper.SyncButtonClicked.SYNC_CANCEL_NOT_EQUAL_WEIGHTED);
@@ -212,10 +212,7 @@
     private void createButtons() {
         mRefuseButton =
                 DualControlLayout.createButtonForLayout(
-                        getContext(),
-                        DualControlLayout.ButtonType.SECONDARY,
-                        "",
-                        this::refuseOnClickListener);
+                        getContext(), DualControlLayout.ButtonType.SECONDARY, "", null);
         mRefuseButton.setLayoutParams(
                 new ViewGroup.LayoutParams(
                         ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncConsentFragmentBase.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncConsentFragmentBase.java
index 50be3f1d..94829e0 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncConsentFragmentBase.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncConsentFragmentBase.java
@@ -667,6 +667,7 @@
     }
 
     private void onRefuseButtonClicked(View button) {
+        mSigninView.refuseButtonClicked();
         refuseSignIn();
     }
 
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
index bfef3ea..5e42621b 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -1309,8 +1309,8 @@
       <message name="IDS_CLEAR_BROWSING_DATA_IMPORTANT_DIALOG_BUTTON" desc="The text of the button to perform the clear action in the dialog presenting the user with 'important' sites that they can exclude from clearing.">
         Delete
       </message>
-      <message name="IDS_OPEN_CLEAR_BROWSING_DATA_DIALOG_BUTTON" desc="Title of the button that will open the clear browsing data dialog.">
-        Clear browsing data…
+      <message name="IDS_OPEN_CLEAR_BROWSING_DATA_DIALOG_BUTTON" desc="Title of the button that will open the delete browsing data dialog.">
+        Delete browsing data…
       </message>
       <message name="IDS_OPEN_FULL_CHROME_HISTORY" desc="Title of the button that will open the full history in Chrome browser from CCT history page.">
               Open full Chrome history
@@ -2142,7 +2142,7 @@
         Turn off sync?
       </message>
       <message name="IDS_SIGNOUT_MANAGED_ACCOUNT_TITLE" desc="Title for sign out of Chrome dialog for enterprise account [CHAR_LIMIT=40]">
-        Clear your Chrome data from this device?
+        Delete your Chrome data from this device?
       </message>
       <message name="IDS_SIGNOUT_MESSAGE" desc="The text is displayed as the message of a dialog to confirm whether the user wants to sign out of Chrome. The dialog is titled ‘Sign out of Chrome?’. The user can cancel and stay signed in, or confirm and sign out.">
         Some Chrome features won\u2019t be available anymore
@@ -2154,7 +2154,7 @@
         Your bookmarks, history, and other Chrome data will no longer be synced to your Google Account
       </message>
       <message name="IDS_REMOVE_LOCAL_DATA" desc="Checkbox to delete all existing data in local device storage">
-        Also clear your Chrome data from this device
+        Also delete your Chrome data from this device
       </message>
       <message name="IDS_SIGNOUT_MANAGED_ACCOUNT_MESSAGE" desc="Message to display for sign out of Chrome dialog when the account has enterprise management, and all user data will be erased">
         Because you're signing out of an account managed by <ph name="DOMAIN_NAME">%1$s<ex>google.com</ex></ph>, your Chrome data will be deleted from this device. It will remain in your Google Account.
@@ -2294,7 +2294,7 @@
       </message>
       <message name="IDS_SYNC_ENCRYPTION_CREATE_PASSPHRASE" desc="Prompt user to create a custom sync password.">
         Payment methods and addresses from Google Pay won’t be encrypted. Browsing history from Chrome won’t sync.
-Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>clear the Chrome data in your account<ph name="END_LINK">END_LINK</ph>.
+Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>delete the Chrome data in your account<ph name="END_LINK">END_LINK</ph>.
       </message>
       <message name="IDS_SYNC_ENTER_CUSTOM_PASSPHRASE_HINT" desc="Hint for the passphrase field when user is to type in a passphrase. [CHAR_LIMIT=30]">
         Passphrase
@@ -2312,7 +2312,7 @@
         This field cannot be blank
       </message>
       <message name="IDS_SYNC_PASSPHRASE_RECOVER" desc="Inform the user how they can reset their passphrase if they have forgotten it." meaning="Android">
-        If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>clear the Chrome data in your account<ph name="END_LINK">END_LINK</ph>.
+        If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>delete the Chrome data in your account<ph name="END_LINK">END_LINK</ph>.
       </message>
       <message name="IDS_SYNC_PASSPHRASES_DO_NOT_MATCH" desc="Inform user that their sync password does not match.">
         Passphrases do not match
@@ -2320,7 +2320,7 @@
       <message name="IDS_SYNC_PASSPHRASE_ENCRYPTION_RESET_INSTRUCTIONS" desc="Inform user how to change their encryption setting.">
         Passphrase encryption doesn’t include payment methods and addresses from Google Pay.
 
-To change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>clear the Chrome data in your account<ph name="END_LINK">END_LINK</ph>.
+To change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>delete the Chrome data in your account<ph name="END_LINK">END_LINK</ph>.
       </message>
       <message name="IDS_SYNC_PASSPHRASE_INCORRECT" desc="Inform the user that the passphrase they entered for sync is incorrect. [CHAR_LIMIT=40]">
         Incorrect passphrase
@@ -2425,7 +2425,7 @@
         The service is not available; try again later.
       </message>
       <message name="IDS_WIPING_PROFILE_DATA_TITLE" desc="Title for the progress dialog shown while profile data is being wiped after signing out of an enterprise account">
-        Clearing account data
+        Deleting account data
       </message>
       <message name="IDS_WIPING_PROFILE_DATA_MESSAGE" desc="Message for the progress dialog shown while profile data is being wiped after signing out of an enterprise account">
         Please wait…
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_OPEN_CLEAR_BROWSING_DATA_DIALOG_BUTTON.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_OPEN_CLEAR_BROWSING_DATA_DIALOG_BUTTON.png.sha1
new file mode 100644
index 0000000..d975b9b
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_OPEN_CLEAR_BROWSING_DATA_DIALOG_BUTTON.png.sha1
@@ -0,0 +1 @@
+f0125cbe76dc3701101c828cfcfbc133c7805a65
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_REMOVE_LOCAL_DATA.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_REMOVE_LOCAL_DATA.png.sha1
index e925d54..77398825 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_REMOVE_LOCAL_DATA.png.sha1
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_REMOVE_LOCAL_DATA.png.sha1
@@ -1 +1 @@
-52ec60c38256bd198a2fca7310ad7245379811b0
\ No newline at end of file
+882a3cb9407089145f7270ea223489f6b1579191
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SIGNOUT_MANAGED_ACCOUNT_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SIGNOUT_MANAGED_ACCOUNT_TITLE.png.sha1
index aed418d4..5233bf1c 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SIGNOUT_MANAGED_ACCOUNT_TITLE.png.sha1
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SIGNOUT_MANAGED_ACCOUNT_TITLE.png.sha1
@@ -1 +1 @@
-85809a4d887b019fde1aa008fed1db222faccc11
\ No newline at end of file
+f32352d1ff33f4434377ee4d7007419c88627d29
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_ENCRYPTION_CREATE_PASSPHRASE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_ENCRYPTION_CREATE_PASSPHRASE.png.sha1
index 7831c855..bfc1cf6 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_ENCRYPTION_CREATE_PASSPHRASE.png.sha1
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_ENCRYPTION_CREATE_PASSPHRASE.png.sha1
@@ -1 +1 @@
-6478154806f459c144c88d5bdd9dc42a3de52a66
\ No newline at end of file
+5e7a19b45f3d3eede491fcb0116322c95e1cd85a
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_PASSPHRASE_ENCRYPTION_RESET_INSTRUCTIONS.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_PASSPHRASE_ENCRYPTION_RESET_INSTRUCTIONS.png.sha1
index 3c7aedb6..48780a7 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_PASSPHRASE_ENCRYPTION_RESET_INSTRUCTIONS.png.sha1
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_PASSPHRASE_ENCRYPTION_RESET_INSTRUCTIONS.png.sha1
@@ -1 +1 @@
-f56fb12015b969926f4c7abdb5c707c796d58000
\ No newline at end of file
+be3a3ddcf817f29b0510cd6ff5bad31af5cf025d
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_PASSPHRASE_RECOVER.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_PASSPHRASE_RECOVER.png.sha1
index 4185390..bfc1cf6 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_PASSPHRASE_RECOVER.png.sha1
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_SYNC_PASSPHRASE_RECOVER.png.sha1
@@ -1 +1 @@
-00cb13797ee0d76815ced6a250dd0b0b45e4dd1f
\ No newline at end of file
+5e7a19b45f3d3eede491fcb0116322c95e1cd85a
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_WIPING_PROFILE_DATA_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_WIPING_PROFILE_DATA_TITLE.png.sha1
new file mode 100644
index 0000000..f07f334
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_WIPING_PROFILE_DATA_TITLE.png.sha1
@@ -0,0 +1 @@
+7dd602f27fa3c39fdefa26263ee751f12b82627a
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb
index 066c96b..2995a03 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb
@@ -1074,7 +1074,7 @@
 <translation id="6573096386450695060">همیشه مجاز</translation>
 <translation id="6573431926118603307">‏برگه‌هایی که در دستگاه‌های دیگر در Chrome باز کرده‌اید، در اینجا نمایان می‌شوند.</translation>
 <translation id="6583199322650523874">نشانک‌گذاری صفحه کنونی</translation>
-<translation id="6588043302623806746">‏استفاده از DNS ایمن</translation>
+<translation id="6588043302623806746">استفاده از ساناد امن</translation>
 <translation id="6590471736817333463">تا ۶۰٪ در مصرف داده صرفه‌جویی کنید</translation>
 <translation id="6590680911007613645">مطمئن شوید گذرواژه‌ای که ذخیره می‌کنید با گذرواژه <ph name="SITE" /> مطابقت داشته باشد</translation>
 <translation id="6593061639179217415">سایت مخصوص رایانه</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb
index 22153181..fdb0439 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb
@@ -1054,6 +1054,7 @@
 <translation id="6477928892249167417">Situs ini sepertinya penting untuk Anda:</translation>
 <translation id="6481963882741794338">Tautkan Chrome dan layanan Google lainnya untuk personalisasi dan tujuan lainnya</translation>
 <translation id="6482749332252372425">Download <ph name="FILE_NAME" /> gagal karena ruang penyimpanan tidak cukup.</translation>
+<translation id="6495590690749880440">Buka Grup Tab?</translation>
 <translation id="650224091954855786">{FILE_COUNT,plural, =1{File didownload}other{# download selesai}}</translation>
 <translation id="6508722015517270189">Buka Ulang Chrome</translation>
 <translation id="6518133107902771759">Verifikasi</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb
index 74d0ca2a0..56b9355 100644
--- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb
+++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb
@@ -174,10 +174,12 @@
 <translation id="1933845786846280168">Tab yang Dipilih</translation>
 <translation id="1943432128510653496">Simpan kata laluan</translation>
 <translation id="1944535645109964458">Tiada kunci laluan tersedia</translation>
+<translation id="1957557050935255529">Memuatkan PDF…</translation>
 <translation id="1959679933317802873">Menunggu kandungan</translation>
 <translation id="1960290143419248813">Kemas kini Chrome tidak disokong untuk versi Android ini lagi</translation>
 <translation id="1963976881984600709">Perlindungan standard</translation>
 <translation id="1966710179511230534">Sila kemas kini butiran log masuk anda.</translation>
+<translation id="1969037871259811890">Tindakan memadamkan data semakan imbas anda tidak membuat anda log keluar dari Google Account anda. Untuk berbuat demikian, <ph name="BEGIN_LINK1" />log keluar dari Chrome<ph name="END_LINK1" />.</translation>
 <translation id="197288927597451399">Simpan</translation>
 <translation id="1973912524893600642">Kekalkan Data</translation>
 <translation id="1974060860693918893">Lanjutan</translation>
@@ -338,6 +340,7 @@
 <translation id="2841216154655874070">{NUM_DAYS,plural, =1{Disemak 1 hari yang lalu}other{Disemak # hari yang lalu}}</translation>
 <translation id="2842985007712546952">Folder induk</translation>
 <translation id="2853415089995957805">Chrome mempramuat halaman yang mungkin anda lawati supaya halaman tersebut dimuatkan dengan lebih pantas apabila dilawati</translation>
+<translation id="2855243985454069333">Memadamkan sejarah daripada semua peranti yang disegerakkan</translation>
 <translation id="2856503607207334158">Log masuk gagal</translation>
 <translation id="2860954141821109167">Pastikan apl telefon didayakan pada peranti ini</translation>
 <translation id="2861923151411510142">Sesetengah ciri Chrome tidak akan tersedia lagi</translation>
@@ -706,6 +709,7 @@
 <translation id="4738836084190194332">Kali terakhir disegerakkan: <ph name="WHEN" /></translation>
 <translation id="474121291218385686">Tapis mengikut apl</translation>
 <translation id="4741753828624614066">Anda akan mendapat cadangan yang dipertingkatkan dalam bar alamat</translation>
+<translation id="4742795653798179840">Data Chrome yang dipadamkan</translation>
 <translation id="4742970037960872810">Alih keluar serlahan</translation>
 <translation id="4749960740855309258">Buka tab baharu</translation>
 <translation id="4750356170202299988">Kandungan untuk minda muda</translation>
@@ -921,6 +925,7 @@
 <translation id="5810288467834065221">Hak Cipta <ph name="YEAR" /> Google LLC. Hak cipta terpelihara.</translation>
 <translation id="5814749351757353073">Ikuti perkembangan laman kegemaran anda</translation>
 <translation id="5822875253699806474">Untuk segera kembali kepada laman yang telah anda lawati, segerakkan tab dan sejarah anda</translation>
+<translation id="5828921839638612740">Anda boleh memadamkan data dalam Tetapan Chrome</translation>
 <translation id="5829586821381540080">Disimpan dalam <ph name="FOLDER_NAME" /></translation>
 <translation id="583281660410589416">Tidak diketahui</translation>
 <translation id="5833984609253377421">Kongsi pautan</translation>
@@ -1112,6 +1117,7 @@
 <translation id="6715020873764921614">Adakah anda mahu memuat turun <ph name="FILE_NAME" /> (<ph name="FILE_SIZE" />) juga?</translation>
 <translation id="6719634564325948108">Sambung menggunakan Kod QR?</translation>
 <translation id="6723740634201835758">Dalam Google Account anda</translation>
+<translation id="6734310707649923383">Anda boleh melihat halaman yang telah dilawati atau memadamkan halaman tersebut daripada sejarah anda</translation>
 <translation id="6738867403308150051">Memuat turun…</translation>
 <translation id="67404633032079629">Sesetengah sejarah web anda mungkin tidak dipaparkan di sini. Untuk melihat sejarah web lengkap, ketik Buka sejarah Chrome lengkap.</translation>
 <translation id="674388916582496364">Menjadi kebiasaan bagi laman yang anda lawati mengingati perkara yang anda minati, untuk memeribadikan pengalaman anda. Laman boleh menyimpan maklumat tentang minat anda menggunakan Chrome.</translation>
@@ -1247,6 +1253,7 @@
 <translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Kongsi 1 item yang dipilih}other{Kongsi # item yang dipilih}}</translation>
 <translation id="7359002509206457351">Akses kaedah pembayaran</translation>
 <translation id="7363349185727752629">Panduan pilihan privasi anda</translation>
+<translation id="7364103838544876661">Lagi pilihan untuk memadamkan data semakan imbas</translation>
 <translation id="7375125077091615385">Jenis:</translation>
 <translation id="7376560087009844242">Dengan menyertakan lebih banyak teks halaman, anda mungkin melihat hasil yang lebih baik apabila menggunakan Sentuh untuk Cari. Anda boleh melawati <ph name="BEGIN_LINK" />tetapan<ph name="END_LINK" /> pada bila-bila masa untuk menukar tetapan ini.</translation>
 <translation id="7379900596734708416">Tema gelap untuk laman tersedia</translation>
@@ -1436,6 +1443,7 @@
 <translation id="8215740705341534369">Helaian sisi</translation>
 <translation id="8218622182176210845">Urus akaun anda</translation>
 <translation id="8221401890884589479">Anda boleh menyekat laman yang anda tidak mahu. Chrome juga memadamkan laman yang disimpan melebihi 30 hari daripada senarai secara automatik. <ph name="BEGIN_LINK" />Ketahui lebih lanjut<ph name="END_LINK" /></translation>
+<translation id="8221985041778490865">Memadamkan data semakan imbas</translation>
 <translation id="8223642481677794647">Menu kad suapan</translation>
 <translation id="8236097722223016103">Tambahkan pada penanda halaman</translation>
 <translation id="8237871086242677046">Helaian bawah cerapan halaman</translation>
@@ -1467,6 +1475,7 @@
 <translation id="8413126021676339697">Paparkan sejarah penuh</translation>
 <translation id="8413795581997394485">Melindungi daripada laman, muat turun dan sambungan yang diketahui berbahaya. Apabila anda melawat laman, Chrome menghantar bahagian pengeliruan URL kepada Google melalui pelayan privasi yang menyembunyikan alamat IP anda. Jika laman melakukan sesuatu yang mencurigakan, URL penuh dan sedikit kandungan halaman turut dihantar.</translation>
 <translation id="8414396119627470038">Log masuk ke <ph name="SITE_ETLD_PLUS_ONE" /> menggunakan <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE" /></translation>
+<translation id="8419144699778179708">Memadamkan sejarah, termasuk item dalam kotak carian</translation>
 <translation id="8419244640277402268">Sertakan</translation>
 <translation id="8422250855136581222">Tiada tab pada peranti ini</translation>
 <translation id="8424781820952413435">Halaman dihantar. Untuk melihat halaman itu, buka Chrome pada <ph name="DEVICE_TYPE" /> anda</translation>
@@ -1630,16 +1639,19 @@
 <translation id="926205370408745186">Alih keluar aktiviti Chrome anda daripada Kesejahteraan Digital</translation>
 <translation id="927968626442779827">Gunakan mod Ringkas pada Google Chrome</translation>
 <translation id="928550791203542716">Mengikuti <ph name="SITE_NAME" /></translation>
+<translation id="930124987204876019">Padamkan sejarah, kuki, data laman, cache…</translation>
 <translation id="93533588269984624">Semua kata laluan akan dimuat turun pada peranti anda dan dialih keluar daripada <ph name="CHROME_CHANNEL" /></translation>
 <translation id="938850635132480979">Ralat: <ph name="ERROR_CODE" /></translation>
 <translation id="939598580284253335">Masukkan frasa laluan</translation>
 <translation id="952301137339791907">Helaian bawah cerapan halaman dibuka</translation>
 <translation id="95817756606698420">Chrome boleh menggunakan <ph name="BEGIN_BOLD" />Sogou<ph name="END_BOLD" /> untuk melakukan carian di China. Anda boleh menukarnya dalam <ph name="BEGIN_LINK" />Tetapan<ph name="END_LINK" />.</translation>
+<translation id="961856697154696964">Padamkan data semakan imbas</translation>
 <translation id="96681097142096641">Lihat paparan mudah?</translation>
 <translation id="970715775301869095"><ph name="MINUTES" /> minit lagi</translation>
 <translation id="981121421437150478">Luar talian</translation>
 <translation id="983192555821071799">Tutup semua tab</translation>
 <translation id="987264212798334818">Umum</translation>
+<translation id="988091779042748639">Untuk memadamkan sejarah penyemakan imbas Inkognito daripada peranti anda, tutup semua tab Inkognito.</translation>
 <translation id="992745192656291733"><ph name="TAB_COUNT" /> tab</translation>
 <translation id="993520549480398880">Kosongkan juga penanda halaman, sejarah dan pelbagai lagi daripada kereta ini</translation>
 <translation id="996149300115483134">Menu kad suapan ditutup</translation>
diff --git a/chrome/browser/ui/autofill/autofill_context_menu_manager_browsertest.cc b/chrome/browser/ui/autofill/autofill_context_menu_manager_browsertest.cc
index 2b14fed..bb632b0 100644
--- a/chrome/browser/ui/autofill/autofill_context_menu_manager_browsertest.cc
+++ b/chrome/browser/ui/autofill/autofill_context_menu_manager_browsertest.cc
@@ -245,7 +245,7 @@
         LocalFrameToken(main_rfh()->GetFrameToken().value());
     form.host_frame = frame_token;
     for (FormFieldData& field : form.fields) {
-      field.host_frame = frame_token;
+      field.set_host_frame(frame_token);
     }
   }
 
diff --git a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.cc b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.cc
index c0a3e0d..1e65cbe 100644
--- a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.cc
+++ b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.cc
@@ -81,6 +81,11 @@
   NOTREACHED_NORETURN();
 }
 
+bool AutofillKeyboardAccessoryAdapter::HasFocus() const {
+  // Having focus on view is relevant for the desktop implementation only.
+  NOTREACHED_NORETURN();
+}
+
 // AutofillSuggestionController implementation.
 
 void AutofillKeyboardAccessoryAdapter::AcceptSuggestion(int index) {
diff --git a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.h b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.h
index bc6bdc3..58798d9 100644
--- a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.h
+++ b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.h
@@ -67,6 +67,7 @@
   std::optional<int32_t> GetAxUniqueId() override;
   base::WeakPtr<AutofillPopupView> CreateSubPopupView(
       base::WeakPtr<AutofillSuggestionController> controller) override;
+  bool HasFocus() const override;
 
   // AutofillSuggestionController:
   // Hidden: void OnSuggestionsChanged() override;
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
index 9ebb458..e5817d1 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
@@ -272,6 +272,12 @@
                           reason == PopupHidingReason::kEndEditing)) {
     return;  // Don't close the popup while waiting for an update.
   }
+
+  if (reason == PopupHidingReason::kFocusChanged && view_ &&
+      view_->HasFocus()) {
+    return;
+  }
+
   // For tests, keep open when hiding is due to external stimuli.
   if (keep_popup_open_for_testing_ &&
       (reason == PopupHidingReason::kWidgetChanged ||
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl_unittest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_impl_unittest.cc
index 7823903..94dcd532 100644
--- a/chrome/browser/ui/autofill/autofill_popup_controller_impl_unittest.cc
+++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl_unittest.cc
@@ -175,6 +175,28 @@
 }
 
 TEST_F(AutofillPopupControllerImplTest,
+       PopupHidesOnWebContentsFocusLossIfViewIsNotFocused) {
+  ShowSuggestions(manager(), {PopupItemId::kAddressEntry});
+
+  EXPECT_CALL(client().popup_view(), HasFocus).WillOnce(Return(false));
+  EXPECT_CALL(client().popup_view(), Hide);
+  client().popup_controller(manager()).Hide(PopupHidingReason::kFocusChanged);
+
+  Mock::VerifyAndClearExpectations(&client().popup_view());
+}
+
+TEST_F(AutofillPopupControllerImplTest,
+       PopupDoesntHideOnWebContentsFocusLossIfViewIsFocused) {
+  ShowSuggestions(manager(), {PopupItemId::kAddressEntry});
+
+  EXPECT_CALL(client().popup_view(), HasFocus).WillOnce(Return(true));
+  EXPECT_CALL(client().popup_view(), Hide).Times(0);
+  client().popup_controller(manager()).Hide(PopupHidingReason::kFocusChanged);
+
+  Mock::VerifyAndClearExpectations(&client().popup_view());
+}
+
+TEST_F(AutofillPopupControllerImplTest,
        RemoveAutocompleteSuggestion_IgnoresClickOutsideCheck) {
   ShowSuggestions(manager(), {PopupItemId::kAutocompleteEntry,
                               PopupItemId::kAutocompleteEntry});
diff --git a/chrome/browser/ui/autofill/autofill_popup_view.h b/chrome/browser/ui/autofill/autofill_popup_view.h
index 8fc9b6f..33b1d74 100644
--- a/chrome/browser/ui/autofill/autofill_popup_view.h
+++ b/chrome/browser/ui/autofill/autofill_popup_view.h
@@ -64,6 +64,9 @@
   virtual std::optional<AutofillClient::PopupScreenLocation>
   GetPopupScreenLocation() const = 0;
 
+  // Indicates whether any of the view elements currently has focus.
+  virtual bool HasFocus() const = 0;
+
   // Returns a weak pointer to itself.
   virtual base::WeakPtr<AutofillPopupView> GetWeakPtr() = 0;
 
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc
index 96c65a0b..ba15d41 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.cc
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -1177,7 +1177,7 @@
             feature_engagement::kIPHAutofillManualFallbackFeature,
             kAutofillManualFallbackElementId);
   }
-  autofill_field_promo_controller_manual_fallback_->Show(field.bounds);
+  autofill_field_promo_controller_manual_fallback_->Show(field.bounds());
 #endif  // !BUILDFLAG(IS_ANDROID)
 }
 
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client_interactive_uitest.cc b/chrome/browser/ui/autofill/chrome_autofill_client_interactive_uitest.cc
index 00dee8a..8a3a303 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client_interactive_uitest.cc
+++ b/chrome/browser/ui/autofill/chrome_autofill_client_interactive_uitest.cc
@@ -96,7 +96,7 @@
 IN_PROC_BROWSER_TEST_F(ChromeAutofillClientBrowserTest,
                        AutofillPopupIsShownIfOverlappingWithIph) {
   FormData form = test::CreateTestAddressFormData();
-  form.fields[0].bounds = gfx::RectF(10, 10);
+  form.fields[0].set_bounds(gfx::RectF(10, 10));
   client()->ShowAutofillFieldIphForManualFallbackFeature(form.fields[0]);
 
   auto delegate = std::make_unique<MockAutofillExternalDelegate>(
diff --git a/chrome/browser/ui/autofill/mock_autofill_popup_view.h b/chrome/browser/ui/autofill/mock_autofill_popup_view.h
index f9160ed..c3a81fb9 100644
--- a/chrome/browser/ui/autofill/mock_autofill_popup_view.h
+++ b/chrome/browser/ui/autofill/mock_autofill_popup_view.h
@@ -41,6 +41,7 @@
               GetPopupScreenLocation,
               (),
               (const override));
+  MOCK_METHOD(bool, HasFocus, (), (const override));
 
   base::WeakPtr<AutofillPopupView> GetWeakPtr() override {
     return weak_ptr_factory_.GetWeakPtr();
diff --git a/chrome/browser/ui/prefs/pref_watcher.cc b/chrome/browser/ui/prefs/pref_watcher.cc
index 3a3a90d..9ac76e4c 100644
--- a/chrome/browser/ui/prefs/pref_watcher.cc
+++ b/chrome/browser/ui/prefs/pref_watcher.cc
@@ -17,6 +17,7 @@
 #include "components/live_caption/pref_names.h"
 #include "components/privacy_sandbox/tracking_protection_settings.h"
 #include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"
+#include "ui/native_theme/native_theme.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/constants/ash_pref_names.h"
@@ -84,6 +85,7 @@
   CHECK(tracking_protection_settings_);
   tracking_protection_settings_observation_.Observe(
       tracking_protection_settings_);
+  native_theme_observation_.Observe(ui::NativeTheme::GetInstanceForWeb());
 
   profile_pref_change_registrar_.Init(profile_->GetPrefs());
 
@@ -149,6 +151,11 @@
   local_state_pref_change_registrar_.RemoveAll();
 }
 
+void PrefWatcher::OnNativeThemeUpdated(
+    ui::NativeTheme* observed_theme) {
+  UpdateRendererPreferences();
+}
+
 void PrefWatcher::OnDoNotTrackEnabledChanged() {
   UpdateRendererPreferences();
 }
diff --git a/chrome/browser/ui/prefs/pref_watcher.h b/chrome/browser/ui/prefs/pref_watcher.h
index c442c6f..79ce1590d 100644
--- a/chrome/browser/ui/prefs/pref_watcher.h
+++ b/chrome/browser/ui/prefs/pref_watcher.h
@@ -7,6 +7,7 @@
 
 #include "base/memory/raw_ptr.h"
 #include "base/memory/singleton.h"
+#include "base/scoped_observation.h"
 #include "chrome/browser/profiles/profile_keyed_service_factory.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/prefs/pref_change_registrar.h"
@@ -14,6 +15,7 @@
 #include "components/privacy_sandbox/tracking_protection_settings_observer.h"
 #include "mojo/public/cpp/bindings/remote_set.h"
 #include "third_party/blink/public/mojom/renderer_preference_watcher.mojom.h"
+#include "ui/native_theme/native_theme_observer.h"
 
 class Profile;
 class PrefsTabHelper;
@@ -21,7 +23,8 @@
 // Watches updates in WebKitPreferences and blink::RendererPreferences, and
 // notifies tab helpers and registered watchers of those updates.
 class PrefWatcher : public KeyedService,
-                    public privacy_sandbox::TrackingProtectionSettingsObserver {
+                    public privacy_sandbox::TrackingProtectionSettingsObserver,
+                    public ui::NativeThemeObserver {
  public:
   explicit PrefWatcher(Profile* profile);
   ~PrefWatcher() override;
@@ -37,6 +40,9 @@
   // KeyedService overrides:
   void Shutdown() override;
 
+  // ui::NativeThemeObserver:
+  void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override;
+
   void OnDoNotTrackEnabledChanged() override;
 
   void UpdateRendererPreferences();
@@ -62,6 +68,9 @@
   // preference changes, use |tab_helpers_|.
   mojo::RemoteSet<blink::mojom::RendererPreferenceWatcher>
       renderer_preference_watchers_;
+
+    base::ScopedObservation<ui::NativeTheme, ui::NativeThemeObserver>
+      native_theme_observation_{this};
 };
 
 class PrefWatcherFactory : public ProfileKeyedServiceFactory {
diff --git a/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.cc b/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.cc
new file mode 100644
index 0000000..3d6d80c
--- /dev/null
+++ b/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.cc
@@ -0,0 +1,177 @@
+// Copyright 2024 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/safety_hub/abusive_notification_permissions_manager.h"
+
+#include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h"
+#include "content/public/browser/browser_thread.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+AbusiveNotificationPermissionsManager::AbusiveNotificationPermissionsManager(
+    scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager,
+    scoped_refptr<HostContentSettingsMap> hcsm)
+    : database_manager_(database_manager),
+      hcsm_(hcsm),
+      safe_browsing_check_delay_(kCheckUrlTimeoutMs) {}
+
+AbusiveNotificationPermissionsManager::
+    ~AbusiveNotificationPermissionsManager() = default;
+
+ContentSettingsForOneType
+AbusiveNotificationPermissionsManager::GetRevokedPermissions() const {
+  return hcsm_->GetSettingsForOneType(
+      ContentSettingsType::REVOKED_ABUSIVE_NOTIFICATION_PERMISSIONS);
+}
+
+void AbusiveNotificationPermissionsManager::
+    CheckNotificationPermissionOrigins() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  if (!database_manager_) {
+    return;
+  }
+  ResetSafeBrowsingCheckHelpers();
+  auto notification_permission_settings =
+      hcsm_->GetSettingsForOneType(ContentSettingsType::NOTIFICATIONS);
+  for (const auto& setting : notification_permission_settings) {
+    // Ignore origins where the permission is not CONTENT_SETTING_ALLOW or the
+    // user previously bypassed a warning or re-allowed the permission in Safety
+    // Hub.
+    if (ShouldCheckOrigin(setting)) {
+      // Since we are dealing with permissions for specific origins, and there
+      // are no wildcard values in the pattern, it is safe to convert between
+      // ContentSettingsPattern, string, and URL types.
+      GURL setting_url = GURL(setting.primary_pattern.ToString());
+      PerformSafeBrowsingChecks(setting_url);
+    }
+  }
+}
+
+AbusiveNotificationPermissionsManager::SafeBrowsingCheckClient::
+    SafeBrowsingCheckClient(
+        safe_browsing::SafeBrowsingDatabaseManager* database_manager,
+        std::set<std::string>* abusive_origins,
+        raw_ptr<std::map<SafeBrowsingCheckClient*,
+                         std::unique_ptr<SafeBrowsingCheckClient>>>
+            safe_browsing_request_clients,
+        GURL url,
+        int safe_browsing_check_delay)
+    : database_manager_(database_manager),
+      abusive_origins_(abusive_origins),
+      safe_browsing_request_clients_(safe_browsing_request_clients),
+      url_(url),
+      safe_browsing_check_delay_(safe_browsing_check_delay) {}
+
+AbusiveNotificationPermissionsManager::SafeBrowsingCheckClient::
+    ~SafeBrowsingCheckClient() {
+  if (timer_.IsRunning()) {
+    database_manager_->CancelCheck(this);
+    timer_.Stop();
+  }
+}
+
+void AbusiveNotificationPermissionsManager::SafeBrowsingCheckClient::
+    CheckSocialEngineeringBlocklist() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  // Set a timer to fail open, i.e. call it "allowlisted", if the full
+  // check takes too long.
+  auto timeout_callback =
+      base::BindOnce(&AbusiveNotificationPermissionsManager::
+                         SafeBrowsingCheckClient::OnCheckBlocklistTimeout,
+                     weak_factory_.GetWeakPtr());
+
+  // Start a timer to abort the check if it takes too long.
+  timer_.Start(FROM_HERE, base::Milliseconds(safe_browsing_check_delay_),
+               std::move(timeout_callback));
+
+  // Check the phishing blocklist, since this is where we'll find blocklisted
+  // abusive notification sites.
+  bool is_safe_synchronously = database_manager_->CheckBrowseUrl(
+      url_,
+      safe_browsing::CreateSBThreatTypeSet(
+          {safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING}),
+      this, safe_browsing::CheckBrowseUrlType::kHashDatabase);
+  // If we can synchronously determine that the URL is safe, stop the timer to
+  // avoid `OnCheckBlocklistTimeout` from being called, since
+  // `OnCheckBrowseUrlResult` won't be called.
+  if (is_safe_synchronously) {
+    timer_.Stop();
+    safe_browsing_request_clients_->erase(this);
+    // The previous line results in deleting this object.
+    // No further access to the object's attributes is permitted here.
+  }
+}
+
+void AbusiveNotificationPermissionsManager::SafeBrowsingCheckClient::
+    OnCheckBrowseUrlResult(const GURL& url,
+                           safe_browsing::SBThreatType threat_type,
+                           const safe_browsing::ThreatMetadata& metadata) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  // Stop the timer to avoid `OnCheckBlocklistTimeout` from being called, since
+  // we got a blocklist check result in time.
+  timer_.Stop();
+  if (threat_type == safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING) {
+    abusive_origins_->insert(url.spec());
+  }
+  safe_browsing_request_clients_->erase(this);
+  // The previous line results in deleting this object.
+  // No further access to the object's attributes is permitted here.
+}
+
+void AbusiveNotificationPermissionsManager::SafeBrowsingCheckClient::
+    OnCheckBlocklistTimeout() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  database_manager_->CancelCheck(this);
+  safe_browsing_request_clients_->erase(this);
+  // The previous line results in deleting this object.
+  // No further access to the object's attributes is permitted here.
+}
+
+void AbusiveNotificationPermissionsManager::PerformSafeBrowsingChecks(
+    GURL url) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  auto new_sb_check = std::make_unique<SafeBrowsingCheckClient>(
+      database_manager_.get(), &abusive_notification_permission_origins_,
+      &safe_browsing_request_clients_, url, safe_browsing_check_delay_);
+  auto new_sb_check_ptr = new_sb_check.get();
+  safe_browsing_request_clients_[new_sb_check_ptr] = std::move(new_sb_check);
+  new_sb_check_ptr->CheckSocialEngineeringBlocklist();
+}
+
+bool AbusiveNotificationPermissionsManager::ShouldCheckOrigin(
+    const ContentSettingPatternSource& setting) const {
+  DCHECK(hcsm_);
+  if (setting.setting_value == CONTENT_SETTING_ALLOW &&
+      setting.secondary_pattern == ContentSettingsPattern::Wildcard()) {
+    content_settings::SettingInfo info;
+    // Since we are dealing with permissions for specific origins, and there
+    // are no wildcard values in the pattern, it is safe to convert between
+    // ContentSettingsPattern, string, and URL types.
+    GURL setting_url(setting.primary_pattern.ToString());
+    base::Value stored_value(hcsm_->GetWebsiteSetting(
+        setting_url, setting_url,
+        ContentSettingsType::REVOKED_ABUSIVE_NOTIFICATION_PERMISSIONS, &info));
+
+    if (!stored_value.is_dict()) {
+      return false;
+    }
+
+    if (stored_value.GetDict()
+            .Find(safety_hub::kRevokedStatusDictKeyStr)
+            ->GetString() == safety_hub::kRevokeStr) {
+      return true;
+    }
+    DCHECK(stored_value.GetDict()
+               .Find(safety_hub::kRevokedStatusDictKeyStr)
+               ->GetString() == safety_hub::kIgnoreStr);
+  }
+  return false;
+}
+
+void AbusiveNotificationPermissionsManager::ResetSafeBrowsingCheckHelpers() {
+  abusive_notification_permission_origins_ = {};
+  if (!safe_browsing_request_clients_.empty()) {
+    safe_browsing_request_clients_.clear();
+  }
+}
diff --git a/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.h b/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.h
new file mode 100644
index 0000000..8bb376f
--- /dev/null
+++ b/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager.h
@@ -0,0 +1,168 @@
+// Copyright 2024 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_SAFETY_HUB_ABUSIVE_NOTIFICATION_PERMISSIONS_MANAGER_H_
+#define CHROME_BROWSER_UI_SAFETY_HUB_ABUSIVE_NOTIFICATION_PERMISSIONS_MANAGER_H_
+
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/browser/ui/safety_hub/safety_hub_constants.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/content_settings/core/common/content_settings.h"
+#include "components/safe_browsing/core/browser/db/database_manager.h"
+
+class GURL;
+
+namespace {
+// Maximum time in milliseconds to wait for the Safe Browsing service reputation
+// check. After this amount of time the outstanding check will be aborted, and
+// the resource will be treated as if it were safe.
+const int kCheckUrlTimeoutMs = 5000;
+}  // namespace
+
+namespace safe_browsing {
+struct ThreatMetadata;
+}  // namespace safe_browsing
+
+// This class keeps track of abusive notification permissions by checking URLs
+// against the Safe Browsing social engineering blocklist. This also handles
+// automatic revocation and responding to user decisions in Safety Hub.
+class AbusiveNotificationPermissionsManager {
+ public:
+  explicit AbusiveNotificationPermissionsManager(
+      scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager>
+          database_manager,
+      scoped_refptr<HostContentSettingsMap> hcsm);
+
+  AbusiveNotificationPermissionsManager(
+      const AbusiveNotificationPermissionsManager&) = delete;
+  AbusiveNotificationPermissionsManager& operator=(
+      const AbusiveNotificationPermissionsManager&) = delete;
+
+  ~AbusiveNotificationPermissionsManager();
+
+  // Returns the list of all permissions that have been revoked.
+  ContentSettingsForOneType GetRevokedPermissions() const;
+
+  // Calls `PerformSafeBrowsingChecks` on URLs which have notifications
+  // enabled and haven't been marked as a URL to be ignored.
+  void CheckNotificationPermissionOrigins();
+
+ private:
+  friend class AbusiveNotificationPermissionsManagerTest;
+  FRIEND_TEST_ALL_PREFIXES(
+      AbusiveNotificationPermissionsManagerTest,
+      AddAllowedAbusiveNotificationSitesToRevokedOriginSet);
+  FRIEND_TEST_ALL_PREFIXES(
+      AbusiveNotificationPermissionsManagerTest,
+      DoesNotAddSafeAbusiveNotificationSitesToRevokedOriginSet);
+  FRIEND_TEST_ALL_PREFIXES(AbusiveNotificationPermissionsManagerTest,
+                           DoesNotAddBlockedSettingToRevokedList);
+  FRIEND_TEST_ALL_PREFIXES(AbusiveNotificationPermissionsManagerTest,
+                           DoesNotAddIgnoredSettingToRevokedList);
+  FRIEND_TEST_ALL_PREFIXES(AbusiveNotificationPermissionsManagerTest,
+                           DoesNotAddAbusiveNotificationSitesOnTimeout);
+
+  // On object creation, checks the Safe Browsing blocklist for `url_`
+  // and adds to `abusive_notification_permission_origins_` if blocklisted.
+  // This subclass is necessary to avoid concurrency issues - each
+  // request needs its own Client and the AbusiveNotificationPermissionsManager
+  // makes multiple Safe Browsing requests.
+  class SafeBrowsingCheckClient
+      : safe_browsing::SafeBrowsingDatabaseManager::Client {
+   public:
+    SafeBrowsingCheckClient(
+        safe_browsing::SafeBrowsingDatabaseManager* database_manager,
+        std::set<std::string>* abusive_origins_ptr,
+        raw_ptr<std::map<SafeBrowsingCheckClient*,
+                         std::unique_ptr<SafeBrowsingCheckClient>>>
+            safe_browsing_request_clients,
+        GURL url,
+        int safe_browsing_check_delay);
+
+    ~SafeBrowsingCheckClient() override;
+
+    // Trigger the call to check the Safe Browsing social engineering blocklist.
+    void CheckSocialEngineeringBlocklist();
+
+   private:
+    // safe_browsing::SafeBrowsingDatabaseManager::Client:
+    void OnCheckBrowseUrlResult(
+        const GURL& url,
+        safe_browsing::SBThreatType threat_type,
+        const safe_browsing::ThreatMetadata& metadata) override;
+
+    // Callback to be run if we make a Safe Browsing blocklist request and have
+    // not received a response within `kCheckUrlTimeoutMs` time.
+    void OnCheckBlocklistTimeout();
+
+    // A pointer to the `database_manager_` of the
+    // `AbusiveNotificationPermissionsManager`.
+    raw_ptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_;
+
+    // A pointer to the `abusive_notification_permission_origins_`
+    // of the `AbusiveNotificationPermissionsManager`.
+    raw_ptr<std::set<std::string>> abusive_origins_;
+
+    // A pointer to the `safe_browsing_request_clients_`
+    // of the `AbusiveNotificationPermissionsManager`.
+    raw_ptr<std::map<SafeBrowsingCheckClient*,
+                     std::unique_ptr<SafeBrowsingCheckClient>>>
+        safe_browsing_request_clients_;
+
+    // The URL that is being checked against the Safe Browsing blocklist.
+    GURL url_;
+
+    // Delay amount allowed for blocklist checks.
+    int safe_browsing_check_delay_;
+
+    // Timer for running Safe Browsing blocklist checks. If `kCheckUrlTimeoutMs`
+    // time has passed, run `OnCheckBlocklistTimeout`.
+    base::OneShotTimer timer_;
+
+    base::WeakPtrFactory<
+        AbusiveNotificationPermissionsManager::SafeBrowsingCheckClient>
+        weak_factory_{this};
+  };
+
+  // Primarily used for tests.
+  const std::set<std::string>& GetLastAbusiveOrigins() {
+    return abusive_notification_permission_origins_;
+  }
+  void SetNullSBCheckDelayForTesting() { safe_browsing_check_delay_ = 0; }
+
+  // Create a `SafeBrowsingCheckClient` object, triggering a blocklist check,
+  // and add it to `safe_browsing_request_clients_`.
+  void PerformSafeBrowsingChecks(GURL url);
+
+  // Returns true if the notification permission is allowed and the setting
+  // does not indicate "ignore".
+  bool ShouldCheckOrigin(const ContentSettingPatternSource& setting) const;
+
+  // Clears any helper members that stored state from the previous safety check.
+  // Called each time we check a set of URLs with Safe Browsing.
+  void ResetSafeBrowsingCheckHelpers();
+
+  // Used for interactions with the local database, when checking the blocklist.
+  scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> database_manager_;
+
+  // Object that allows us to manage site permissions.
+  scoped_refptr<HostContentSettingsMap> hcsm_;
+
+  // Set of origins with notification permissions granted that were found to be
+  // on the Safe Browsing blocklist and should be automatically revoked.
+  std::set<std::string> abusive_notification_permission_origins_;
+
+  // Safe Browsing blocklist check clients. Each object is responsible for a
+  // single Safe Browsing check, given a URL. Stored this way so that the object
+  // can delete itself from this map within the SafeBrowsingCheckClient.
+  std::map<SafeBrowsingCheckClient*, std::unique_ptr<SafeBrowsingCheckClient>>
+      safe_browsing_request_clients_;
+
+  // Length of time allowed for Safe Browsing check before timeout. This allows
+  // us to test timeout behavior.
+  int safe_browsing_check_delay_;
+};
+
+#endif  // CHROME_BROWSER_UI_SAFETY_HUB_ABUSIVE_NOTIFICATION_PERMISSIONS_MANAGER_H_
diff --git a/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager_unittest.cc b/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager_unittest.cc
new file mode 100644
index 0000000..08c762523
--- /dev/null
+++ b/chrome/browser/ui/safety_hub/abusive_notification_permissions_manager_unittest.cc
@@ -0,0 +1,238 @@
+// Copyright 2024 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/safety_hub/abusive_notification_permissions_manager.h"
+
+#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/permissions/constants.h"
+#include "components/safe_browsing/core/browser/db/database_manager.h"
+#include "components/safe_browsing/core/browser/db/test_database_manager.h"
+#include "components/safe_browsing/core/browser/db/util.h"
+#include "components/safe_browsing/core/browser/db/v4_local_database_manager.h"
+#include "content/public/browser/browser_context.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+const ContentSettingsType notifications_type =
+    ContentSettingsType::NOTIFICATIONS;
+const ContentSettingsType revoked_notifications_type =
+    ContentSettingsType::REVOKED_ABUSIVE_NOTIFICATION_PERMISSIONS;
+
+class MockSafeBrowsingDatabaseManager
+    : public safe_browsing::TestSafeBrowsingDatabaseManager {
+ public:
+  MockSafeBrowsingDatabaseManager()
+      : safe_browsing::TestSafeBrowsingDatabaseManager(
+            base::SequencedTaskRunner::GetCurrentDefault(),
+            base::SequencedTaskRunner::GetCurrentDefault()) {}
+  MockSafeBrowsingDatabaseManager(const MockSafeBrowsingDatabaseManager&) =
+      delete;
+  MockSafeBrowsingDatabaseManager& operator=(
+      const MockSafeBrowsingDatabaseManager&) = delete;
+
+  bool CheckBrowseUrl(const GURL& gurl,
+                      const safe_browsing::SBThreatTypeSet& threat_types,
+                      Client* client,
+                      safe_browsing::CheckBrowseUrlType check_type) override {
+    CHECK(client);
+    base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
+        FROM_HERE,
+        base::BindOnce(&MockSafeBrowsingDatabaseManager::OnCheckBrowseURLDone,
+                       this, gurl, client->GetWeakPtr()));
+    return false;
+  }
+
+  void CancelCheck(Client* client) override { called_cancel_check_ = true; }
+
+  bool HasCalledCancelCheck() { return called_cancel_check_; }
+
+  void SetThreatTypeForUrl(GURL gurl, safe_browsing::SBThreatType threat_type) {
+    urls_threat_type_[gurl.spec()] = threat_type;
+  }
+
+ protected:
+  ~MockSafeBrowsingDatabaseManager() override = default;
+
+ private:
+  void OnCheckBrowseURLDone(const GURL& gurl, base::WeakPtr<Client> client) {
+    if (called_cancel_check_) {
+      return;
+    }
+    CHECK(client);
+    client->OnCheckBrowseUrlResult(gurl, urls_threat_type_[gurl.spec()],
+                                   safe_browsing::ThreatMetadata());
+  }
+
+  base::flat_map<std::string, safe_browsing::SBThreatType> urls_threat_type_;
+  bool called_cancel_check_ = false;
+};
+
+}  // namespace
+
+class AbusiveNotificationPermissionsManagerTest : public ::testing::Test {
+ public:
+  void SetUp() override {
+    mock_database_manager_ = new MockSafeBrowsingDatabaseManager();
+  }
+
+  void TearDown() override { mock_database_manager_.reset(); }
+
+  HostContentSettingsMap* hcsm() {
+    return HostContentSettingsMapFactory::GetForProfile(&profile_);
+  }
+
+  MockSafeBrowsingDatabaseManager* mock_database_manager() {
+    return mock_database_manager_.get();
+  }
+
+  void AddAbusiveNotification(std::string url,
+                              ContentSetting cs,
+                              bool is_ignored) {
+    content_settings::ContentSettingConstraints constraint;
+    hcsm()->SetContentSettingDefaultScope(GURL(url), GURL(url),
+                                          notifications_type, cs, constraint);
+    hcsm()->SetWebsiteSettingDefaultScope(
+        GURL(url), GURL(url), revoked_notifications_type,
+        base::Value(base::Value::Dict().Set(
+            safety_hub::kRevokedStatusDictKeyStr,
+            is_ignored ? safety_hub::kIgnoreStr : safety_hub::kRevokeStr)),
+        constraint);
+    mock_database_manager()->SetThreatTypeForUrl(
+        GURL(url), safe_browsing::SBThreatType::SB_THREAT_TYPE_URL_PHISHING);
+  }
+
+  void AddSafeNotification(std::string url, ContentSetting cs) {
+    content_settings::ContentSettingConstraints constraint;
+    hcsm()->SetContentSettingDefaultScope(GURL(url), GURL(url),
+                                          notifications_type, cs, constraint);
+    mock_database_manager()->SetThreatTypeForUrl(
+        GURL(url), safe_browsing::SBThreatType::SB_THREAT_TYPE_SAFE);
+  }
+
+  void VerifyTimeoutCallbackNotCalled() {
+    // Verify timeout is not called even after fast forwarding.
+    task_environment_.FastForwardBy(base::Milliseconds(kCheckUrlTimeoutMs));
+    EXPECT_FALSE(mock_database_manager_->HasCalledCancelCheck());
+  }
+
+ private:
+  scoped_refptr<MockSafeBrowsingDatabaseManager> mock_database_manager_;
+  content::BrowserTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  TestingProfile profile_;
+};
+
+TEST_F(AbusiveNotificationPermissionsManagerTest,
+       AddAllowedAbusiveNotificationSitesToRevokedOriginSet) {
+  std::string url1 = "https://example1.com";
+  std::string url2 = "https://example2.com";
+  AddAbusiveNotification(url1, ContentSetting::CONTENT_SETTING_ALLOW,
+                         /*is_ignored=*/false);
+  AddAbusiveNotification(url2, ContentSetting::CONTENT_SETTING_ALLOW,
+                         /*is_ignored=*/false);
+
+  auto manager =
+      AbusiveNotificationPermissionsManager(mock_database_manager(), hcsm());
+  EXPECT_EQ(manager.GetLastAbusiveOrigins().size(), 0u);
+  manager.CheckNotificationPermissionOrigins();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(manager.GetLastAbusiveOrigins().size(), 2u);
+  EXPECT_TRUE(
+      manager.GetLastAbusiveOrigins().contains("https://example1.com/"));
+  EXPECT_TRUE(
+      manager.GetLastAbusiveOrigins().contains("https://example2.com/"));
+
+  VerifyTimeoutCallbackNotCalled();
+}
+
+TEST_F(AbusiveNotificationPermissionsManagerTest,
+       DoesNotAddSafeAbusiveNotificationSitesToRevokedOriginSet) {
+  std::string url1 = "https://example1.com";
+  std::string url2 = "https://example2.com";
+  AddSafeNotification(url1, ContentSetting::CONTENT_SETTING_ALLOW);
+  AddAbusiveNotification(url2, ContentSetting::CONTENT_SETTING_ALLOW,
+                         /*is_ignored=*/false);
+
+  auto manager =
+      AbusiveNotificationPermissionsManager(mock_database_manager(), hcsm());
+  EXPECT_EQ(manager.GetLastAbusiveOrigins().size(), 0u);
+  manager.CheckNotificationPermissionOrigins();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(manager.GetLastAbusiveOrigins().size(), 1u);
+  EXPECT_TRUE(
+      manager.GetLastAbusiveOrigins().contains("https://example2.com/"));
+
+  VerifyTimeoutCallbackNotCalled();
+}
+
+TEST_F(AbusiveNotificationPermissionsManagerTest,
+       DoesNotAddBlockedSettingToRevokedList) {
+  std::string url1 = "https://example1.com";
+  std::string url2 = "https://example2.com";
+  std::string url3 = "https://example3.com";
+  AddAbusiveNotification(url1, ContentSetting::CONTENT_SETTING_ALLOW,
+                         /*is_ignored=*/false);
+  AddAbusiveNotification(url2, ContentSetting::CONTENT_SETTING_BLOCK,
+                         /*is_ignored=*/false);
+  AddAbusiveNotification(url3, ContentSetting::CONTENT_SETTING_BLOCK,
+                         /*is_ignored=*/true);
+
+  auto manager =
+      AbusiveNotificationPermissionsManager(mock_database_manager(), hcsm());
+  EXPECT_EQ(manager.GetLastAbusiveOrigins().size(), 0u);
+  manager.CheckNotificationPermissionOrigins();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(manager.GetLastAbusiveOrigins().size(), 1u);
+  EXPECT_TRUE(
+      manager.GetLastAbusiveOrigins().contains("https://example1.com/"));
+
+  VerifyTimeoutCallbackNotCalled();
+}
+
+TEST_F(AbusiveNotificationPermissionsManagerTest,
+       DoesNotAddIgnoredSettingToRevokedList) {
+  std::string url1 = "https://example1.com";
+  std::string url2 = "https://example2.com";
+  std::string url3 = "https://example3.com";
+  AddAbusiveNotification(url1, ContentSetting::CONTENT_SETTING_ALLOW,
+                         /*is_ignored=*/false);
+  AddAbusiveNotification(url2, ContentSetting::CONTENT_SETTING_BLOCK,
+                         /*is_ignored=*/true);
+  AddAbusiveNotification(url3, ContentSetting::CONTENT_SETTING_ALLOW,
+                         /*is_ignored=*/true);
+
+  auto manager =
+      AbusiveNotificationPermissionsManager(mock_database_manager(), hcsm());
+  EXPECT_EQ(manager.GetLastAbusiveOrigins().size(), 0u);
+  manager.CheckNotificationPermissionOrigins();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(manager.GetLastAbusiveOrigins().size(), 1u);
+  EXPECT_TRUE(
+      manager.GetLastAbusiveOrigins().contains("https://example1.com/"));
+
+  VerifyTimeoutCallbackNotCalled();
+}
+
+TEST_F(AbusiveNotificationPermissionsManagerTest,
+       DoesNotAddAbusiveNotificationSitesOnTimeout) {
+  std::string url1 = "https://example1.com";
+  std::string url2 = "https://example2.com";
+  AddAbusiveNotification(url1, ContentSetting::CONTENT_SETTING_ALLOW,
+                         /*is_ignored=*/false);
+  AddAbusiveNotification(url2, ContentSetting::CONTENT_SETTING_ALLOW,
+                         /*is_ignored=*/false);
+
+  auto manager =
+      AbusiveNotificationPermissionsManager(mock_database_manager(), hcsm());
+  manager.SetNullSBCheckDelayForTesting();
+  EXPECT_EQ(manager.GetLastAbusiveOrigins().size(), 0u);
+  EXPECT_FALSE(mock_database_manager()->HasCalledCancelCheck());
+  manager.CheckNotificationPermissionOrigins();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(mock_database_manager()->HasCalledCancelCheck());
+  EXPECT_EQ(manager.GetLastAbusiveOrigins().size(), 0u);
+}
diff --git a/chrome/browser/ui/safety_hub/safety_hub_constants.cc b/chrome/browser/ui/safety_hub/safety_hub_constants.cc
index 8b024dc0..0b3a306 100644
--- a/chrome/browser/ui/safety_hub/safety_hub_constants.cc
+++ b/chrome/browser/ui/safety_hub/safety_hub_constants.cc
@@ -27,4 +27,8 @@
 
 const base::TimeDelta kMinTimeBetweenPasswordChecks = base::Hours(1);
 
+const char kRevokedStatusDictKeyStr[] = "revoked_status";
+const char kIgnoreStr[] = "ignore";
+const char kRevokeStr[] = "revoke";
+
 }  // namespace safety_hub
diff --git a/chrome/browser/ui/safety_hub/safety_hub_constants.h b/chrome/browser/ui/safety_hub/safety_hub_constants.h
index 54030e9..99b7fa2 100644
--- a/chrome/browser/ui/safety_hub/safety_hub_constants.h
+++ b/chrome/browser/ui/safety_hub/safety_hub_constants.h
@@ -85,6 +85,16 @@
   kMaxValue = kSafetyHubPage,
 };
 
+// This string is used for the key of the base::Value dictionary we assign to
+// the REVOKED_ABUSIVE_NOTIFICATION_PERMISSION value.
+extern const char kRevokedStatusDictKeyStr[];
+// When users take action to grant a permission despite warnings against doing
+// so, we should ignore the origin in future auto revocations. To do this, we
+// will assign the REVOKED_ABUSIVE_NOTIFICATION_PERMISSION permission
+// base::Value to the "ignore" string. Otherwise, the value should be "revoke".
+extern const char kIgnoreStr[];
+extern const char kRevokeStr[];
+
 }  // namespace safety_hub
 
 #endif  // CHROME_BROWSER_UI_SAFETY_HUB_SAFETY_HUB_CONSTANTS_H_
diff --git a/chrome/browser/ui/views/autofill/popup/popup_search_bar_view.cc b/chrome/browser/ui/views/autofill/popup/popup_search_bar_view.cc
new file mode 100644
index 0000000..0022335
--- /dev/null
+++ b/chrome/browser/ui/views/autofill/popup/popup_search_bar_view.cc
@@ -0,0 +1,69 @@
+// Copyright 2024 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/views/autofill/popup/popup_search_bar_view.h"
+
+#include <memory>
+#include <string>
+
+#include "chrome/browser/ui/views/chrome_layout_provider.h"
+#include "components/vector_icons/vector_icons.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
+#include "ui/views/controls/button/image_button.h"
+#include "ui/views/controls/image_view.h"
+#include "ui/views/controls/textfield/textfield.h"
+#include "ui/views/layout/flex_layout.h"
+
+namespace autofill {
+
+PopupSearchBarView::PopupSearchBarView(const std::u16string& placeholder) {
+  ChromeLayoutProvider* layout_provider = ChromeLayoutProvider::Get();
+
+  SetLayoutManager(std::make_unique<views::FlexLayout>())
+      ->SetOrientation(views::LayoutOrientation::kHorizontal)
+      .SetCrossAxisAlignment(views::LayoutAlignment::kCenter)
+      .SetCollapseMargins(true)
+      .SetDefault(
+          views::kMarginsKey,
+          gfx::Insets::VH(0, layout_provider->GetDistanceMetric(
+                                 views::DISTANCE_RELATED_LABEL_HORIZONTAL)));
+
+  AddChildView(
+      std::make_unique<views::ImageView>(ui::ImageModel::FromVectorIcon(
+          vector_icons::kSearchChromeRefreshIcon, ui::kColorIcon,
+          layout_provider->GetDistanceMetric(
+              DISTANCE_BUBBLE_HEADER_VECTOR_ICON_SIZE))));
+
+  input_ = AddChildView(
+      views::Builder<views::Textfield>()
+          // TODO(b/325246516): Set default placeholder according to approved
+          // greenlines.
+          .SetPlaceholderText(placeholder.empty() ? u"Search" : placeholder)
+          .SetBorder(nullptr)
+          .SetProperty(views::kFlexBehaviorKey,
+                       views::FlexSpecification(views::FlexSpecification(
+                           views::LayoutOrientation::kHorizontal,
+                           views::MinimumFlexSizeRule::kPreferred,
+                           views::MaximumFlexSizeRule::kUnbounded)))
+          .Build());
+
+  // TODO(b/325246516): Clarify whether the clear button should be rendered
+  // on top of the input field and rework the layout (probably with a custom
+  // LayoutManager).
+  clear_ = AddChildView(
+      views::Builder<views::ImageButton>()
+          .SetImageModel(views::Button::STATE_NORMAL,
+                         ui::ImageModel::FromVectorIcon(
+                             vector_icons::kCloseChromeRefreshIcon))
+          // TODO(b/325246516): Set the name according to approved greenlines.
+          .SetAccessibleName(u"tmp non empty name")
+          .Build());
+}
+
+PopupSearchBarView::~PopupSearchBarView() = default;
+
+BEGIN_METADATA(PopupSearchBarView)
+END_METADATA
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/popup/popup_search_bar_view.h b/chrome/browser/ui/views/autofill/popup/popup_search_bar_view.h
new file mode 100644
index 0000000..6a17e9d
--- /dev/null
+++ b/chrome/browser/ui/views/autofill/popup/popup_search_bar_view.h
@@ -0,0 +1,42 @@
+// Copyright 2024 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_VIEWS_AUTOFILL_POPUP_POPUP_SEARCH_BAR_VIEW_H_
+#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_POPUP_POPUP_SEARCH_BAR_VIEW_H_
+
+#include <string>
+
+#include "ui/views/view.h"
+
+namespace views {
+class Button;
+class Textfield;
+}  // namespace views
+
+namespace autofill {
+
+// This view enables users to filter popup suggestions. It contains
+// the necessary elements for user input (text field, controls) and offers
+// an API that allows the hosting popup to retrieve search queries and receive
+// input event notifications.
+class PopupSearchBarView : public views::View {
+  METADATA_HEADER(PopupSearchBarView, views::View)
+
+ public:
+  explicit PopupSearchBarView(const std::u16string& placeholder);
+  PopupSearchBarView(const PopupSearchBarView&) = delete;
+  PopupSearchBarView& operator=(const PopupSearchBarView&) = delete;
+  ~PopupSearchBarView() override;
+
+  // TODO(b/325246516): Add methods to support communication with its hosting
+  // poopup view.
+
+ private:
+  raw_ptr<views::Textfield> input_ = nullptr;
+  raw_ptr<views::Button> clear_ = nullptr;
+};
+
+}  // namespace autofill
+
+#endif  // CHROME_BROWSER_UI_VIEWS_AUTOFILL_POPUP_POPUP_SEARCH_BAR_VIEW_H_
diff --git a/chrome/browser/ui/views/autofill/popup/popup_view_views.cc b/chrome/browser/ui/views/autofill/popup/popup_view_views.cc
index 1168150..e528c7a 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_view_views.cc
+++ b/chrome/browser/ui/views/autofill/popup/popup_view_views.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ui/views/autofill/popup/popup_view_views.h"
 
 #include <algorithm>
+#include <memory>
 #include <string>
 #include <type_traits>
 #include <utility>
@@ -26,6 +27,7 @@
 #include "chrome/browser/ui/views/autofill/popup/popup_base_view.h"
 #include "chrome/browser/ui/views/autofill/popup/popup_row_factory_utils.h"
 #include "chrome/browser/ui/views/autofill/popup/popup_row_view.h"
+#include "chrome/browser/ui/views/autofill/popup/popup_search_bar_view.h"
 #include "chrome/browser/ui/views/autofill/popup/popup_separator_view.h"
 #include "chrome/browser/ui/views/autofill/popup/popup_title_view.h"
 #include "chrome/browser/ui/views/autofill/popup/popup_view_utils.h"
@@ -149,16 +151,17 @@
                     /*show_arrow_pointer=*/false),
       controller_(controller),
       parent_(parent) {
-  InitViews();
+  InitViews({});
 }
 
 PopupViewViews::PopupViewViews(
-    base::WeakPtr<AutofillPopupController> controller)
+    base::WeakPtr<AutofillPopupController> controller,
+    PopupViewSearchBarConfig search_bar_config)
     : PopupBaseView(controller,
                     views::Widget::GetTopLevelWidgetForNativeView(
                         controller->container_view())),
       controller_(controller) {
-  InitViews();
+  InitViews(search_bar_config);
 }
 
 PopupViewViews::~PopupViewViews() = default;
@@ -517,7 +520,7 @@
   open_sub_popup_timer_.Stop();
   SetRowWithOpenSubPopup(std::nullopt);
 
-  CreateChildViews();
+  CreateSuggestionViews();
   DoUpdateBoundsAndRedrawPopup();
 }
 
@@ -588,6 +591,11 @@
           static_cast<views::BubbleBorder*>(border)->arrow())};
 }
 
+bool PopupViewViews::HasFocus() const {
+  // TODO(b/325246516): Add checking whether the search bar has focus.
+  return false;
+}
+
 void PopupViewViews::OnWidgetVisibilityChanged(views::Widget* widget,
                                                bool visible) {
   if (!visible || !controller_) {
@@ -681,18 +689,28 @@
          absl::holds_alternative<PopupRowView*>(rows_[index]);
 }
 
-void PopupViewViews::InitViews() {
+void PopupViewViews::InitViews(PopupViewSearchBarConfig search_bar_config) {
   SetNotifyEnterExitOnChild(true);
+  SetLayoutManager(std::make_unique<views::BoxLayout>(
+      views::BoxLayout::Orientation::kVertical));
 
-  views::BoxLayout* layout =
-      SetLayoutManager(std::make_unique<views::BoxLayout>(
-          views::BoxLayout::Orientation::kVertical));
-  layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart);
+  if (search_bar_config.enabled) {
+    search_bar_ = AddChildView(
+        std::make_unique<PopupSearchBarView>(search_bar_config.placeholder));
+    search_bar_->SetProperty(views::kMarginsKey,
+                             gfx::Insets::VH(GetContentsVerticalPadding(), 0));
+    AddChildView(std::make_unique<PopupSeparatorView>(/*vertical_padding=*/0));
+  }
 
-  CreateChildViews();
+  suggestions_container_ =
+      AddChildView(views::Builder<views::BoxLayoutView>()
+                       .SetOrientation(views::BoxLayout::Orientation::kVertical)
+                       .Build());
+
+  CreateSuggestionViews();
 }
 
-void PopupViewViews::CreateChildViews() {
+void PopupViewViews::CreateSuggestionViews() {
   // Null all pointers prior to deleting the children views to avoid temporarily
   // dangling pointers that might be picked up by dangle detection builds. Also,
   // `footer_container_` is instantiated conditionally, which can make its value
@@ -701,7 +719,7 @@
   body_container_ = nullptr;
   footer_container_ = nullptr;
   rows_.clear();
-  RemoveAllChildViews();
+  suggestions_container_->RemoveAllChildViews();
 
   const int kInterItemsPadding = GetContentsVerticalPadding();
   const std::vector<Suggestion> kSuggestions = controller_->GetSuggestions();
@@ -709,13 +727,6 @@
   SetBackground(
       views::CreateThemedSolidBackground(ui::kColorDropdownBackground));
 
-  // `content_view` wraps the full content of the popup and provides vertical
-  // padding.
-  raw_ptr<views::BoxLayoutView> content_view =
-      AddChildView(views::Builder<views::BoxLayoutView>()
-                       .SetOrientation(views::BoxLayout::Orientation::kVertical)
-                       .Build());
-
   rows_.reserve(kSuggestions.size());
   size_t current_line_number = 0u;
   // Add the body rows, if there are any.
@@ -796,8 +807,8 @@
             .ClipHeightTo(0, body_container->GetPreferredSize().height())
             .Build();
     body_container_ = scroll_view->SetContents(std::move(body_container));
-    scroll_view_ = content_view->AddChildView(std::move(scroll_view));
-    content_view->SetFlexForView(scroll_view_.get(), 1);
+    scroll_view_ = suggestions_container_->AddChildView(std::move(scroll_view));
+    suggestions_container_->SetFlexForView(scroll_view_.get(), 1);
   }
 
   if (current_line_number >= kSuggestions.size()) {
@@ -819,15 +830,16 @@
     // no vertical padding as these elements have their own top/bottom paddings.
     if (kSuggestions[current_line_number].popup_item_id ==
         PopupItemId::kSeparator) {
-      rows_.push_back(content_view->AddChildView(
+      rows_.push_back(suggestions_container_->AddChildView(
           std::make_unique<PopupSeparatorView>(/*vertical_padding=*/0)));
       ++current_line_number;
     }
 
-    footer_container_ = content_view->AddChildView(std::move(footer_container));
+    footer_container_ =
+        suggestions_container_->AddChildView(std::move(footer_container));
     footer_container_->SetInsideBorderInsets(
         gfx::Insets::VH(kInterItemsPadding, 0));
-    content_view->SetFlexForView(footer_container_, 0);
+    suggestions_container_->SetFlexForView(footer_container_, 0);
   }
 
   for (; current_line_number < kSuggestions.size(); ++current_line_number) {
@@ -1021,6 +1033,9 @@
   if (body_container_ && !body_container_->children().empty()) {
     min_height += body_container_->children()[0]->GetPreferredSize().height();
   }
+  if (search_bar_) {
+    min_height += search_bar_->GetPreferredSize().height();
+  }
   if (footer_container_ && !footer_container_->children().empty() &&
       !IsFooterScrollable()) {
     // The footer is not scrollable, its full height should be considered.
diff --git a/chrome/browser/ui/views/autofill/popup/popup_view_views.h b/chrome/browser/ui/views/autofill/popup/popup_view_views.h
index a643112..937924d 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_view_views.h
+++ b/chrome/browser/ui/views/autofill/popup/popup_view_views.h
@@ -17,6 +17,7 @@
 #include "chrome/browser/ui/autofill/autofill_popup_view.h"
 #include "chrome/browser/ui/views/autofill/popup/popup_base_view.h"
 #include "chrome/browser/ui/views/autofill/popup/popup_row_view.h"
+#include "chrome/browser/ui/views/autofill/popup/popup_search_bar_view.h"
 #include "components/autofill/core/common/aliases.h"
 #include "content/public/common/input/native_web_keyboard_event.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
@@ -53,6 +54,13 @@
   virtual void OnMouseExitedInChildren() = 0;
 };
 
+struct PopupViewSearchBarConfig {
+  // This setting controls the search bar's visibility. If set to 'false',
+  // the search bar won't be displayed, and other settings become irrelevant.
+  bool enabled = false;
+  std::u16string placeholder;
+};
+
 // Views implementation for the autofill and password suggestion.
 class PopupViewViews : public PopupBaseView,
                        public AutofillPopupView,
@@ -77,10 +85,14 @@
   static constexpr base::TimeDelta kNoSelectionHideSubPopupDelay =
       base::Milliseconds(2500);
 
+  // Constructor for creating sub-popups.
   PopupViewViews(base::WeakPtr<AutofillPopupController> controller,
                  base::WeakPtr<ExpandablePopupParentView> parent,
                  views::Widget* parent_widget);
-  explicit PopupViewViews(base::WeakPtr<AutofillPopupController> controller);
+
+  // Constructor for creating root level popups.
+  explicit PopupViewViews(base::WeakPtr<AutofillPopupController> controller,
+                          PopupViewSearchBarConfig search_bar_config = {});
   PopupViewViews(const PopupViewViews&) = delete;
   PopupViewViews& operator=(const PopupViewViews&) = delete;
   ~PopupViewViews() override;
@@ -107,6 +119,7 @@
       base::WeakPtr<AutofillSuggestionController> controller) override;
   std::optional<AutofillClient::PopupScreenLocation> GetPopupScreenLocation()
       const override;
+  bool HasFocus() const override;
   base::WeakPtr<AutofillPopupView> GetWeakPtr() override;
 
   // PopupBaseView:
@@ -145,12 +158,12 @@
   bool HasPopupRowViewAt(size_t index) const;
 
   // Instantiates the content of the popup.
-  void InitViews();
+  void InitViews(PopupViewSearchBarConfig search_bar_config);
 
   // Creates child views based on the suggestions given by |controller_|.
   // This method expects that all non-footer suggestions precede footer
   // suggestions.
-  void CreateChildViews();
+  void CreateSuggestionViews();
 
   // Applies certain rounding rules to the given width, such as matching the
   // element width when possible.
@@ -234,6 +247,8 @@
   std::optional<size_t> row_with_open_sub_popup_;
 
   std::vector<RowPointer> rows_;
+  raw_ptr<PopupSearchBarView> search_bar_ = nullptr;
+  raw_ptr<views::BoxLayoutView> suggestions_container_ = nullptr;
   raw_ptr<views::ScrollView> scroll_view_ = nullptr;
   raw_ptr<views::BoxLayoutView> body_container_ = nullptr;
   raw_ptr<views::BoxLayoutView> footer_container_ = nullptr;
diff --git a/chrome/browser/ui/views/autofill/popup/popup_view_views_browsertest.cc b/chrome/browser/ui/views/autofill/popup/popup_view_views_browsertest.cc
index 181947a..07d884a 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_view_views_browsertest.cc
+++ b/chrome/browser/ui/views/autofill/popup/popup_view_views_browsertest.cc
@@ -12,6 +12,7 @@
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/ui/autofill/mock_autofill_popup_controller.h"
 #include "chrome/browser/ui/views/autofill/popup/popup_pixel_test.h"
+#include "chrome/browser/ui/views/autofill/popup/popup_search_bar_view.h"
 #include "chrome/browser/ui/views/autofill/popup/popup_view_views_test_api.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -168,6 +169,7 @@
       EXPECT_CALL(controller(), ViewDestroyed);
     }
 
+    search_bar_config_ = {};
     popup_has_parent_ = false;
     popup_parent_.reset();
     PopupPixelTest::TearDownOnMainThread();
@@ -193,8 +195,10 @@
     }
   }
 
-  void ShowAndVerifyUi(bool popup_has_parent = false) {
+  void ShowAndVerifyUi(bool popup_has_parent = false,
+                       PopupViewSearchBarConfig search_bar_config = {}) {
     popup_has_parent_ = popup_has_parent;
+    search_bar_config_ = search_bar_config;
     PopupPixelTest::ShowAndVerifyUi();
   }
 
@@ -206,7 +210,7 @@
                                 test_api(*popup_parent_).GetWeakPtr(),
                                 popup_parent_->GetWidget());
     }
-    return new PopupViewViews(controller.GetWeakPtr());
+    return new PopupViewViews(controller.GetWeakPtr(), search_bar_config_);
   }
 
  private:
@@ -215,6 +219,7 @@
 
   // Controls whether the view is created as a sub-popup (i.e. having a parent).
   bool popup_has_parent_ = false;
+  PopupViewSearchBarConfig search_bar_config_;
   std::unique_ptr<PopupViewViews> popup_parent_;
 };
 
@@ -400,6 +405,13 @@
   ShowAndVerifyUi(/*popup_has_parent=*/true);
 }
 
+IN_PROC_BROWSER_TEST_P(PopupViewViewsBrowsertest, SearchBarViewProvided) {
+  controller().set_suggestions({PopupItemId::kAddressEntry});
+  ShowAndVerifyUi(
+      /*popup_has_parent=*/false,
+      PopupViewSearchBarConfig{.enabled = true, .placeholder = u"Search"});
+}
+
 INSTANTIATE_TEST_SUITE_P(All,
                          PopupViewViewsBrowsertest,
                          Combine(Bool(), Bool()),
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
index dabe64e..6c6481d0 100644
--- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
@@ -2051,8 +2051,8 @@
 }
 
 // Test to ensure crbug.com/1513330 won't reproduce.
-// TODO(b/41492287): Flaky on Linux.
-#if BUILDFLAG(IS_LINUX)
+// TODO(b/41492287, b/336264927): Flaky on Linux and Mac.
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
 #define MAYBE_WindowSetResizableDoesntBlockMoveToAndMoveByApis \
   DISABLED_WindowSetResizableDoesntBlockMoveToAndMoveByApis
 #else
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/drive_upload_observer.cc b/chrome/browser/ui/webui/ash/cloud_upload/drive_upload_observer.cc
new file mode 100644
index 0000000..f802991
--- /dev/null
+++ b/chrome/browser/ui/webui/ash/cloud_upload/drive_upload_observer.cc
@@ -0,0 +1,230 @@
+// Copyright 2024 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/ash/cloud_upload/drive_upload_observer.h"
+
+#include "chrome/browser/ash/file_manager/delete_io_task.h"
+#include "chrome/browser/ash/file_manager/fileapi_util.h"
+#include "chrome/browser/ash/file_manager/volume_manager.h"
+#include "chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_util.h"
+#include "storage/browser/file_system/file_system_url.h"
+
+namespace ash::cloud_upload {
+
+namespace {
+
+file_manager::io_task::IOTaskController* GetIOTaskController(Profile* profile) {
+  DCHECK(profile);
+
+  file_manager::VolumeManager* volume_manager =
+      file_manager::VolumeManager::Get(profile);
+  if (!volume_manager) {
+    LOG(ERROR) << "No Volume Manager";
+    return nullptr;
+  }
+
+  return volume_manager->io_task_controller();
+}
+
+// Runs the upload callback provided to `DriveUploadObserver::Observe`.
+void OnUploadDone(scoped_refptr<DriveUploadObserver> drive_upload_observer,
+                  base::OnceCallback<void(bool)> upload_callback,
+                  bool success) {
+  std::move(upload_callback).Run(success);
+}
+
+}  // namespace
+
+// static.
+void DriveUploadObserver::Observe(
+    Profile* profile,
+    base::FilePath file_path,
+    base::RepeatingCallback<void(int)> progress_callback,
+    base::OnceCallback<void(bool)> upload_callback) {
+  scoped_refptr<DriveUploadObserver> drive_upload_observer =
+      new DriveUploadObserver(profile, file_path, std::move(progress_callback));
+
+  // Keep `drive_upload_observer` alive until the upload is done.
+  drive_upload_observer->Run(base::BindOnce(
+      &OnUploadDone, drive_upload_observer, std::move(upload_callback)));
+}
+
+DriveUploadObserver::DriveUploadObserver(
+    Profile* profile,
+    base::FilePath file_path,
+    base::RepeatingCallback<void(int)> progress_callback)
+    : profile_(profile),
+      file_system_context_(
+          file_manager::util::GetFileManagerFileSystemContext(profile)),
+      drive_integration_service_(
+          drive::DriveIntegrationServiceFactory::FindForProfile(profile)),
+      observed_local_path_(file_path),
+      progress_callback_(std::move(progress_callback)) {}
+
+DriveUploadObserver::~DriveUploadObserver() = default;
+
+void DriveUploadObserver::Run(base::OnceCallback<void(bool)> upload_callback) {
+  upload_callback_ = std::move(upload_callback);
+  if (!profile_) {
+    LOG(ERROR) << "No profile";
+    OnEndUpload(/*success=*/false);
+    return;
+  }
+
+  if (drive::util::GetDriveConnectionStatus(profile_) !=
+      drive::util::ConnectionStatus::kConnected) {
+    LOG(ERROR) << "No connection to Drive";
+    OnEndUpload(/*success=*/false);
+    return;
+  }
+
+  if (!drive_integration_service_) {
+    LOG(ERROR) << "No Drive integration service";
+    OnEndUpload(/*success=*/false);
+    return;
+  }
+
+  // Observe Drive updates.
+  drive::DriveIntegrationService::Observer::Observe(drive_integration_service_);
+  drivefs::DriveFsHost::Observer::Observe(
+      drive_integration_service_->GetDriveFsHost());
+
+  if (!drive_integration_service_->IsMounted()) {
+    LOG(ERROR) << "Google Drive is not mounted";
+    OnEndUpload(/*success=*/false);
+    return;
+  }
+
+  if (observed_local_path_.empty() ||
+      !drive_integration_service_->GetRelativeDrivePath(
+          observed_local_path_, &observed_drive_path_)) {
+    OnEndUpload(/*success=*/false);
+    return;
+  }
+
+  // TODO(ayaelattar): Handle the case when the file was already uploaded and
+  // start a timer in case the upload being stuck.
+}
+
+void DriveUploadObserver::OnEndUpload(bool success) {
+  std::vector<storage::FileSystemURL> file_urls;
+
+  // If the file sync to to Drive was unsuccessful, delete the file from the
+  // Local cache.
+  if (!success) {
+    if (!observed_delete_task_id_.has_value()) {
+      auto* io_task_controller = GetIOTaskController(profile_);
+
+      DCHECK(io_task_controller);
+      DCHECK(!io_task_controller_observer_.IsObserving());
+
+      io_task_controller_observer_.Observe(io_task_controller);
+      storage::FileSystemURL file_url = FilePathToFileSystemURL(
+          profile_, file_system_context_, observed_local_path_);
+      std::unique_ptr<file_manager::io_task::IOTask> task =
+          std::make_unique<file_manager::io_task::DeleteIOTask>(
+              std::vector<storage::FileSystemURL>{file_url},
+              file_system_context_,
+              /*show_notification=*/false);
+      observed_delete_task_id_ = io_task_controller->Add(std::move(task));
+    }
+  } else {
+    std::move(upload_callback_).Run(success);
+  }
+}
+
+void DriveUploadObserver::OnUnmounted() {
+  OnEndUpload(/*success=*/false);
+}
+
+void DriveUploadObserver::OnSyncingStatusUpdate(
+    const drivefs::mojom::SyncingStatus& syncing_status) {
+  for (const auto& item : syncing_status.item_events) {
+    if (base::FilePath(item->path) != observed_drive_path_) {
+      continue;
+    }
+
+    switch (item->state) {
+      case drivefs::mojom::ItemEvent::State::kQueued: {
+        // Tell Drive to upload the file now. If successful, we will receive a
+        // kInProgress or kCompleted event sooner. If this fails, we ignore it.
+        // The file will get uploaded eventually.
+        drive_integration_service_->ImmediatelyUpload(
+            observed_drive_path_,
+            base::BindOnce(&DriveUploadObserver::OnImmediatelyUploadDone,
+                           weak_ptr_factory_.GetWeakPtr()));
+        return;
+      }
+      case drivefs::mojom::ItemEvent::State::kInProgress:
+        if (item->bytes_transferred > 0) {
+          progress_callback_.Run(100 * item->bytes_transferred /
+                                 item->bytes_to_transfer);
+        }
+        return;
+      case drivefs::mojom::ItemEvent::State::kCompleted:
+        progress_callback_.Run(100);
+        OnEndUpload(/*success=*/true);
+        return;
+      case drivefs::mojom::ItemEvent::State::kFailed:
+        LOG(ERROR) << "Drive sync error: failed";
+        OnEndUpload(/*success=*/false);
+        return;
+      case drivefs::mojom::ItemEvent::State::kCancelledAndDeleted:
+      case drivefs::mojom::ItemEvent::State::kCancelledAndTrashed:
+        LOG(ERROR) << "Drive sync error: cancelled and deleted/trashed";
+        OnEndUpload(/*success=*/false);
+        return;
+    }
+  }
+}
+
+void DriveUploadObserver::OnError(const drivefs::mojom::DriveError& error) {
+  if (base::FilePath(error.path) != observed_drive_path_) {
+    return;
+  }
+
+  OnEndUpload(/*success=*/false);
+}
+
+void DriveUploadObserver::OnDriveConnectionStatusChanged(
+    drive::util::ConnectionStatus status) {
+  if (status != drive::util::ConnectionStatus::kConnected) {
+    LOG(ERROR) << "Lost connection to Drive during upload";
+    OnEndUpload(/*success=*/false);
+  }
+}
+
+void DriveUploadObserver::OnIOTaskStatus(
+    const ::file_manager::io_task::ProgressStatus& status) {
+  if (status.task_id != observed_delete_task_id_) {
+    return;
+  }
+
+  switch (status.state) {
+    case file_manager::io_task::State::kCancelled:
+      NOTREACHED() << "Deletion of source or destination file should not have "
+                      "been cancelled.";
+      ABSL_FALLTHROUGH_INTENDED;
+    case file_manager::io_task::State::kError:
+      LOG(ERROR) << "Deleting the file from the local cache failed.";
+      ABSL_FALLTHROUGH_INTENDED;
+    case file_manager::io_task::State::kSuccess:
+      std::move(upload_callback_).Run(false);
+      return;
+    default:
+      return;
+  }
+}
+
+void DriveUploadObserver::OnImmediatelyUploadDone(drive::FileError error) {
+  LOG_IF(ERROR, error != drive::FileError::FILE_ERROR_OK)
+      << "ImmediatelyUpload failed with status: " << error;
+  if (error == drive::FileError::FILE_ERROR_OK) {
+    OnEndUpload(/*success=*/true);
+  } else {
+    OnEndUpload(/*success=*/false);
+  }
+}
+
+}  // namespace ash::cloud_upload
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/drive_upload_observer.h b/chrome/browser/ui/webui/ash/cloud_upload/drive_upload_observer.h
new file mode 100644
index 0000000..09d0c9e
--- /dev/null
+++ b/chrome/browser/ui/webui/ash/cloud_upload/drive_upload_observer.h
@@ -0,0 +1,101 @@
+// Copyright 2024 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_ASH_CLOUD_UPLOAD_DRIVE_UPLOAD_OBSERVER_H_
+#define CHROME_BROWSER_UI_WEBUI_ASH_CLOUD_UPLOAD_DRIVE_UPLOAD_OBSERVER_H_
+
+#include "base/files/file_path.h"
+#include "base/functional/callback.h"
+#include "base/memory/raw_ptr.h"
+#include "base/memory/ref_counted.h"
+#include "chrome/browser/ash/drive/drive_integration_service.h"
+#include "chrome/browser/ash/file_manager/io_task.h"
+#include "chrome/browser/ash/file_manager/io_task_controller.h"
+#include "chromeos/ash/components/drivefs/drivefs_host.h"
+#include "storage/browser/file_system/file_system_context.h"
+
+class Profile;
+
+namespace ash::cloud_upload {
+
+// Observes the "upload to Google Drive" after the file is written to the local
+// cache of Google Drive. Immediately uploads the file to Google Drive if the
+// file is still queued. Instantiated by the static `Observe` method. Gets
+// upload status by observing Drive events. Calls the `upload_callback_` when
+// the file is successfully uploaded, which is when `DriveUploadObserver` goes
+// out of scope. If the upload to Drive fails, it'll delete the file from the
+// local cache.
+class DriveUploadObserver
+    : public base::RefCounted<DriveUploadObserver>,
+      drivefs::DriveFsHost::Observer,
+      drive::DriveIntegrationService::Observer,
+      ::file_manager::io_task::IOTaskController::Observer {
+ public:
+  // Starts observing the upload of the file specified at construct time.
+  static void Observe(Profile* profile,
+                      base::FilePath file_path,
+                      base::RepeatingCallback<void(int)> progress_callback,
+                      base::OnceCallback<void(bool)> upload_callback);
+
+  DriveUploadObserver(const DriveUploadObserver&) = delete;
+  DriveUploadObserver& operator=(const DriveUploadObserver&) = delete;
+
+ private:
+  friend base::RefCounted<DriveUploadObserver>;
+
+  DriveUploadObserver(Profile* profile,
+                      base::FilePath file_path,
+                      base::RepeatingCallback<void(int)> progress_callback);
+  ~DriveUploadObserver() override;
+
+  void Run(base::OnceCallback<void(bool)> upload_callback);
+
+  void OnEndUpload(bool success);
+
+  // DriveFsHost::Observer implementation.
+  void OnUnmounted() override;
+  void OnSyncingStatusUpdate(
+      const drivefs::mojom::SyncingStatus& status) override;
+  void OnError(const drivefs::mojom::DriveError& error) override;
+
+  // DriveIntegrationService::Observer implementation.
+  void OnDriveConnectionStatusChanged(
+      drive::util::ConnectionStatus status) override;
+
+  // IOTaskController::Observer implementation.
+  void OnIOTaskStatus(
+      const ::file_manager::io_task::ProgressStatus& status) override;
+
+  void OnImmediatelyUploadDone(drive::FileError error);
+
+  raw_ptr<Profile> profile_;
+  scoped_refptr<storage::FileSystemContext> file_system_context_;
+  const raw_ptr<drive::DriveIntegrationService> drive_integration_service_;
+
+  // The Id of the delete task. It'll have a value only if the upload fails.
+  std::optional<::file_manager::io_task::IOTaskId> observed_delete_task_id_ =
+      std::nullopt;
+
+  // The observed file local path.
+  base::FilePath observed_local_path_;
+
+  // The observed file Drive path.
+  base::FilePath observed_drive_path_;
+
+  // Progress callback repeatedly run with progress updates.
+  base::RepeatingCallback<void(int)> progress_callback_;
+
+  // Upload callback run once with upload success/failure.
+  base::OnceCallback<void(bool)> upload_callback_;
+
+  base::ScopedObservation<::file_manager::io_task::IOTaskController,
+                          ::file_manager::io_task::IOTaskController::Observer>
+      io_task_controller_observer_{this};
+
+  base::WeakPtrFactory<DriveUploadObserver> weak_ptr_factory_{this};
+};
+
+}  // namespace ash::cloud_upload
+
+#endif  // CHROME_BROWSER_UI_WEBUI_ASH_CLOUD_UPLOAD_DRIVE_UPLOAD_OBSERVER_H_
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/drive_upload_observer_browsertest.cc b/chrome/browser/ui/webui/ash/cloud_upload/drive_upload_observer_browsertest.cc
new file mode 100644
index 0000000..dbd4757a6
--- /dev/null
+++ b/chrome/browser/ui/webui/ash/cloud_upload/drive_upload_observer_browsertest.cc
@@ -0,0 +1,371 @@
+// Copyright 2024 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/ash/cloud_upload/drive_upload_observer.h"
+
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "base/test/bind.h"
+#include "base/test/gmock_callback_support.h"
+#include "base/test/mock_callback.h"
+#include "base/test/test_future.h"
+#include "chrome/browser/ash/drive/drive_integration_service.h"
+#include "chrome/browser/ash/file_manager/file_manager_test_util.h"
+#include "chrome/browser/ash/file_manager/io_task.h"
+#include "chrome/browser/ash/file_manager/io_task_controller.h"
+#include "chrome/browser/ash/file_manager/path_util.h"
+#include "chrome/browser/ash/file_manager/volume_manager.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chromeos/ash/components/drivefs/mojom/drivefs.mojom.h"
+#include "components/drive/file_errors.h"
+#include "content/public/test/browser_test.h"
+#include "storage/browser/file_system/external_mount_points.h"
+
+using storage::FileSystemURL;
+
+namespace ash::cloud_upload {
+
+using ::base::test::RunOnceCallback;
+using drive::DriveIntegrationService;
+using drive::util::ConnectionStatus;
+using drive::util::SetDriveConnectionStatusForTesting;
+using testing::_;
+
+namespace {
+
+const int64_t kFileSize = 123456;
+
+// Returns full test file path to the given |file_name|.
+base::FilePath GetTestFilePath(const std::string& file_name) {
+  // Get the path to file manager's test data directory.
+  base::FilePath source_dir;
+  CHECK(base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &source_dir));
+  base::FilePath test_data_dir = source_dir.AppendASCII("chrome")
+                                     .AppendASCII("test")
+                                     .AppendASCII("data")
+                                     .AppendASCII("chromeos")
+                                     .AppendASCII("file_manager");
+  return test_data_dir.Append(base::FilePath::FromUTF8Unsafe(file_name));
+}
+
+}  // namespace
+
+// Tests the Drive upload workflow using the static
+// `DriveUploadObserver::Observe` method. Ensures that the upload completes with
+// the expected results.
+class DriveUploadObserverTest
+    : public InProcessBrowserTest,
+      ::file_manager::io_task::IOTaskController::Observer {
+ public:
+  DriveUploadObserverTest() {
+    EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
+    drive_mount_point_ = temp_dir_.GetPath().Append("drivefs");
+    drive_root_dir_ = drive_mount_point_.AppendASCII("root");
+  }
+
+  DriveUploadObserverTest(const DriveUploadObserverTest&) = delete;
+  DriveUploadObserverTest& operator=(const DriveUploadObserverTest&) = delete;
+
+  void SetUpInProcessBrowserTestFixture() override {
+    // Setup drive integration service.
+    create_drive_integration_service_ = base::BindRepeating(
+        &DriveUploadObserverTest::CreateDriveIntegrationService,
+        base::Unretained(this));
+    service_factory_for_test_ = std::make_unique<
+        drive::DriveIntegrationServiceFactory::ScopedFactoryForTest>(
+        &create_drive_integration_service_);
+  }
+
+  void SetUpOnMainThread() override {
+    SetDriveConnectionStatusForTesting(ConnectionStatus::kConnected);
+    InProcessBrowserTest::SetUpOnMainThread();
+  }
+
+  void SetUp() override {
+    InProcessBrowserTest::SetUp();
+    // Create Drive root directory.
+    {
+      base::ScopedAllowBlockingForTesting allow_blocking;
+      EXPECT_TRUE(base::CreateDirectory(drive_root_dir_));
+    }
+  }
+
+  void TearDown() override {
+    InProcessBrowserTest::TearDown();
+    storage::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
+  }
+
+  void TearDownOnMainThread() override {
+    InProcessBrowserTest::TearDownOnMainThread();
+  }
+
+  DriveIntegrationService* CreateDriveIntegrationService(Profile* profile) {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    fake_drivefs_helpers_[profile] =
+        std::make_unique<file_manager::test::FakeSimpleDriveFsHelper>(
+            profile, drive_mount_point_);
+    return new DriveIntegrationService(
+        profile, "", drive_mount_point_,
+        fake_drivefs_helpers_[profile]->CreateFakeDriveFsListenerFactory());
+  }
+
+  // Create and add a file with |test_file_name| to the file system
+  // |source_path|. Returns the created file path.
+  base::FilePath SetUpSourceFile(const std::string& test_file_name,
+                                 base::FilePath source_path) {
+    test_file_name_ = test_file_name;
+    auto source_file_path = source_path.AppendASCII(test_file_name_);
+    const base::FilePath test_file_path = GetTestFilePath(test_file_name_);
+    {
+      base::ScopedAllowBlockingForTesting allow_blocking;
+      CHECK(base::CopyFile(test_file_path, source_file_path));
+    }
+
+    // Check that the source file exists at the intended source location and is
+    // not in Drive.
+    {
+      base::ScopedAllowBlockingForTesting allow_blocking;
+      EXPECT_TRUE(base::PathExists(source_path.AppendASCII(test_file_name)));
+    }
+
+    return test_file_path;
+  }
+
+  void CheckPathExistsOnDrive(const base::FilePath& path) {
+    base::test::TestFuture<drive::FileError, drivefs::mojom::FileMetadataPtr>
+        future;
+    drive_integration_service()->GetDriveFsInterface()->GetMetadata(
+        path, base::BindOnce(future.GetCallback()));
+    EXPECT_EQ(drive::FILE_ERROR_OK, future.Get<drive::FileError>());
+  }
+
+  void CheckPathNotFoundOnDrive(const base::FilePath& path) {
+    base::test::TestFuture<drive::FileError, drivefs::mojom::FileMetadataPtr>
+        future;
+    drive_integration_service()->GetDriveFsInterface()->GetMetadata(
+        path, base::BindOnce(future.GetCallback()));
+    EXPECT_EQ(drive::FILE_ERROR_NOT_FOUND, future.Get<drive::FileError>());
+  }
+
+  Profile* profile() { return browser()->profile(); }
+
+  mojo::Remote<drivefs::mojom::DriveFsDelegate>& drivefs_delegate() {
+    return fake_drivefs().delegate();
+  }
+
+  DriveIntegrationService* drive_integration_service() {
+    return drive::DriveIntegrationServiceFactory::FindForProfile(profile());
+  }
+
+  base::FilePath observed_relative_drive_path() {
+    base::FilePath observed_relative_drive_path;
+    drive_integration_service()->GetRelativeDrivePath(
+        drive_root_dir_.AppendASCII(test_file_name_),
+        &observed_relative_drive_path);
+    return observed_relative_drive_path;
+  }
+
+  file_manager::test::FakeSimpleDriveFs& fake_drivefs() {
+    return fake_drivefs_helpers_[profile()]->fake_drivefs();
+  }
+
+  void SetUpObservers() {
+    // Subscribe to IOTasks updates to track the delete progressprogress.
+    file_manager::VolumeManager::Get(profile())
+        ->io_task_controller()
+        ->AddObserver(this);
+  }
+
+  void RemoveObservers() {
+    file_manager::VolumeManager::Get(profile())
+        ->io_task_controller()
+        ->RemoveObserver(this);
+  }
+
+  // IOTaskController::Observer:
+  void OnIOTaskStatus(
+      const file_manager::io_task::ProgressStatus& status) override {
+    if (status.type == file_manager::io_task::OperationType::kDelete &&
+        status.sources.size() == 1 &&
+        status.sources[0].url.path() ==
+            drive_root_dir_.AppendASCII(test_file_name_) &&
+        status.state == file_manager::io_task::State::kSuccess) {
+      if (on_delete_callback_) {
+        std::move(on_delete_callback_).Run();
+      }
+    }
+  }
+
+  void SimulateDriveUploadQueued() {
+    // Set file metadata for `drivefs::mojom::DriveFs::GetMetadata`.
+    drivefs::FakeMetadata metadata;
+    metadata.path = observed_relative_drive_path();
+    metadata.original_name = test_file_name_;
+    fake_drivefs().SetMetadata(std::move(metadata));
+
+    // Simulate server sync events.
+    drivefs::mojom::SyncingStatusPtr status =
+        drivefs::mojom::SyncingStatus::New();
+    status->item_events.emplace_back(
+        std::in_place, 12, 34, observed_relative_drive_path().value(),
+        drivefs::mojom::ItemEvent::State::kQueued, 0u, kFileSize,
+        drivefs::mojom::ItemEventReason::kTransfer);
+    drivefs_delegate()->OnSyncingStatusUpdate(status.Clone());
+    drivefs_delegate().FlushForTesting();
+  }
+
+  void SimulateDriveUploadInProgress(int64_t bytes_transferred) {
+    // Set file metadata for `drivefs::mojom::DriveFs::GetMetadata`.
+    drivefs::FakeMetadata metadata;
+    metadata.path = observed_relative_drive_path();
+    metadata.original_name = test_file_name_;
+    fake_drivefs().SetMetadata(std::move(metadata));
+
+    // Simulate server sync events.
+    drivefs::mojom::SyncingStatusPtr status =
+        drivefs::mojom::SyncingStatus::New();
+    status->item_events.emplace_back(
+        std::in_place, 12, 34, observed_relative_drive_path().value(),
+        drivefs::mojom::ItemEvent::State::kInProgress, bytes_transferred,
+        kFileSize, drivefs::mojom::ItemEventReason::kTransfer);
+    drivefs_delegate()->OnSyncingStatusUpdate(status.Clone());
+    drivefs_delegate().FlushForTesting();
+  }
+
+  void SimulateDriveUploadCompleted() {
+    // Set file metadata for `drivefs::mojom::DriveFs::GetMetadata`.
+    drivefs::FakeMetadata metadata;
+    metadata.path = observed_relative_drive_path();
+    metadata.original_name = test_file_name_;
+    fake_drivefs().SetMetadata(std::move(metadata));
+
+    // Simulate server sync events.
+    drivefs::mojom::SyncingStatusPtr status =
+        drivefs::mojom::SyncingStatus::New();
+    status->item_events.emplace_back(
+        std::in_place, 12, 34, observed_relative_drive_path().value(),
+        drivefs::mojom::ItemEvent::State::kCompleted, kFileSize, kFileSize,
+        drivefs::mojom::ItemEventReason::kTransfer);
+    drivefs_delegate()->OnSyncingStatusUpdate(status.Clone());
+    drivefs_delegate().FlushForTesting();
+  }
+
+  void SimulateDriveUploadFailure() {
+    drivefs::mojom::SyncingStatusPtr fail_status =
+        drivefs::mojom::SyncingStatus::New();
+    fail_status->item_events.emplace_back(
+        std::in_place, 12, 34, observed_relative_drive_path().value(),
+        drivefs::mojom::ItemEvent::State::kFailed, 123, kFileSize,
+        drivefs::mojom::ItemEventReason::kTransfer);
+    drivefs_delegate()->OnSyncingStatusUpdate(fail_status->Clone());
+    drivefs_delegate().FlushForTesting();
+  }
+
+ protected:
+  base::FilePath drive_mount_point_;
+  base::FilePath drive_root_dir_;
+  base::ScopedTempDir temp_dir_;
+
+  base::OnceClosure on_delete_callback_;
+
+  drive::DriveIntegrationServiceFactory::FactoryCallback
+      create_drive_integration_service_;
+  std::unique_ptr<drive::DriveIntegrationServiceFactory::ScopedFactoryForTest>
+      service_factory_for_test_;
+  std::map<Profile*,
+           std::unique_ptr<file_manager::test::FakeSimpleDriveFsHelper>>
+      fake_drivefs_helpers_;
+
+  // Used to track the upload progress during the tests.
+  std::string test_file_name_;
+};
+
+// Send file queuing event, the file should be immediately uploaded.
+IN_PROC_BROWSER_TEST_F(DriveUploadObserverTest, ImmediatelyUpload) {
+  const std::string test_file_name = "archive.tar.gz";
+  base::FilePath source_file_path =
+      SetUpSourceFile(test_file_name, drive_mount_point_);
+  base::FilePath observed_relative_drive_path;
+  drive_integration_service()->GetRelativeDrivePath(
+      drive_root_dir_.AppendASCII(test_file_name_),
+      &observed_relative_drive_path);
+
+  EXPECT_CALL(fake_drivefs(), ImmediatelyUpload(_, _))
+      .WillOnce(RunOnceCallback<1>(drive::FileError::FILE_ERROR_OK));
+
+  base::MockCallback<base::RepeatingCallback<void(int)>> progress_callback;
+  base::MockCallback<base::OnceCallback<void(bool)>> upload_callback;
+  EXPECT_CALL(upload_callback, Run(/*success=*/true));
+  DriveUploadObserver::Observe(profile(),
+                               drive_root_dir_.AppendASCII(test_file_name_),
+                               progress_callback.Get(), upload_callback.Get());
+
+  SimulateDriveUploadQueued();
+
+  // Check that the source file has been moved to Drive.
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    CheckPathExistsOnDrive(observed_relative_drive_path);
+  }
+}
+
+// Send progress updates then completed sync events.
+IN_PROC_BROWSER_TEST_F(DriveUploadObserverTest, SuccessfulSync) {
+  const std::string test_file_name = "image.webp";
+  base::FilePath source_file_path =
+      SetUpSourceFile(test_file_name, drive_mount_point_);
+  base::FilePath observed_relative_drive_path;
+  drive_integration_service()->GetRelativeDrivePath(
+      drive_root_dir_.AppendASCII(test_file_name_),
+      &observed_relative_drive_path);
+
+  base::MockCallback<base::RepeatingCallback<void(int)>> progress_callback;
+  base::MockCallback<base::OnceCallback<void(bool)>> upload_callback;
+  EXPECT_CALL(progress_callback, Run(/*progress=*/25));
+  EXPECT_CALL(progress_callback, Run(/*progress=*/100));
+  EXPECT_CALL(upload_callback, Run(/*success=*/true));
+  DriveUploadObserver::Observe(profile(),
+                               drive_root_dir_.AppendASCII(test_file_name_),
+                               progress_callback.Get(), upload_callback.Get());
+
+  SimulateDriveUploadInProgress(kFileSize / 4);
+  SimulateDriveUploadCompleted();
+
+  // Check that the source file has been moved to Drive.
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    CheckPathExistsOnDrive(observed_relative_drive_path);
+  }
+}
+
+// Send syncing error event, the cached file should be deleted.
+IN_PROC_BROWSER_TEST_F(DriveUploadObserverTest, ErrorSync) {
+  const std::string test_file_name = "id3Audio.mp3";
+  base::FilePath source_file_path =
+      SetUpSourceFile(test_file_name, drive_mount_point_);
+  base::FilePath observed_relative_drive_path;
+  drive_integration_service()->GetRelativeDrivePath(
+      drive_root_dir_.AppendASCII(test_file_name_),
+      &observed_relative_drive_path);
+
+  base::MockCallback<base::RepeatingCallback<void(int)>> progress_callback;
+  base::MockCallback<base::OnceCallback<void(bool)>> upload_callback;
+  EXPECT_CALL(upload_callback, Run(/*success=*/false));
+  DriveUploadObserver::Observe(profile(),
+                               drive_root_dir_.AppendASCII(test_file_name_),
+                               progress_callback.Get(), upload_callback.Get());
+
+  SetUpObservers();
+
+  auto future = base::test::TestFuture<void>();
+  on_delete_callback_ = future.GetCallback();
+  SimulateDriveUploadFailure();
+  EXPECT_TRUE(future.Wait());
+
+  RemoveObservers();
+}
+
+}  // namespace ash::cloud_upload
diff --git a/chrome/browser/ui/webui/ash/settings/pages/a11y/accessibility_section.cc b/chrome/browser/ui/webui/ash/settings/pages/a11y/accessibility_section.cc
index 2979c443..fc42826 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/a11y/accessibility_section.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/a11y/accessibility_section.cc
@@ -1366,6 +1366,10 @@
           "ChromeOS.Settings.Accessibility.ColorCorrection.FilterAmount",
           value.GetInt());
       return true;
+    case mojom::Setting::kCaretBlinkInterval:
+      base::UmaHistogramSparse(
+          "ChromeOS.Settings.Accessibility.CaretBlinkInterval", value.GetInt());
+      return true;
     case mojom::Setting::kLiveCaption:
       base::UmaHistogramBoolean(
           "ChromeOS.Settings.Accessibility.LiveCaption.Enabled",
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc
index 6e6de94..f2d276e0 100644
--- a/chrome/browser/ui/webui/settings/people_handler.cc
+++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -219,7 +219,16 @@
       email,
       identity_manager->GetPrimaryAccountInfo(ConsentLevel::kSignin).email);
 }
+
+bool IsSigninPaused(signin::IdentityManager* identity_manager) {
+  return !identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync) &&
+         identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin) &&
+         identity_manager->HasAccountWithRefreshTokenInPersistentErrorState(
+             identity_manager->GetPrimaryAccountId(
+                 signin::ConsentLevel::kSignin));
+}
 #endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
+
 }  // namespace
 
 namespace settings {
@@ -395,7 +404,8 @@
   // If the identity manager already has a primary account, this is a
   // re-auth scenario, and we need to ensure that the user signs in with the
   // same email address.
-  if (identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync)) {
+  if (identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync) ||
+      IsSigninPaused(identity_manager)) {
     SigninErrorController* error_controller =
         SigninErrorControllerFactory::GetForProfile(profile_);
     DCHECK(error_controller->HasError());
@@ -462,11 +472,11 @@
 }
 
 void PeopleHandler::OnExtendedAccountInfoUpdated(const AccountInfo& info) {
-  FireWebUIListener("stored-accounts-updated", GetStoredAccountsList());
+  UpdateStoredAccounts();
 }
 
 void PeopleHandler::OnExtendedAccountInfoRemoved(const AccountInfo& info) {
-  FireWebUIListener("stored-accounts-updated", GetStoredAccountsList());
+  UpdateStoredAccounts();
 }
 
 void PeopleHandler::OnRefreshTokenUpdatedForAccount(
@@ -484,6 +494,18 @@
 #endif
 }
 
+void PeopleHandler::OnErrorStateOfRefreshTokenUpdatedForAccount(
+    const CoreAccountInfo& account_info,
+    const GoogleServiceAuthError& error,
+    signin_metrics::SourceForRefreshTokenOperation token_operation_source) {
+  signin::IdentityManager* identity_manager =
+      IdentityManagerFactory::GetForProfile(profile_);
+  if (identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin) ==
+      account_info) {
+    UpdateSyncStatus();
+  }
+}
+
 base::Value::List PeopleHandler::GetStoredAccountsList() {
   base::Value::List accounts;
   bool populate_accounts_list = false;
@@ -945,6 +967,8 @@
     case signin::PrimaryAccountChangeEvent::Type::kSet:
     case signin::PrimaryAccountChangeEvent::Type::kCleared:
       UpdateChromeSigninUserChoiceInfo();
+      UpdateStoredAccounts();
+      UpdateSyncStatus();
       break;
     case signin::PrimaryAccountChangeEvent::Type::kNone:
       break;
@@ -1045,6 +1069,9 @@
                   signin_ui_util::GetAuthenticatedUsername(profile_));
   sync_status.Set("hasUnrecoverableError",
                   service && service->HasUnrecoverableError());
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+  sync_status.Set("signinPaused", IsSigninPaused(identity_manager));
+#endif
   return sync_status;
 }
 
@@ -1137,6 +1164,10 @@
   FireWebUIListener("sync-status-changed", GetSyncStatusDictionary());
 }
 
+void PeopleHandler::UpdateStoredAccounts() {
+  FireWebUIListener("stored-accounts-updated", GetStoredAccountsList());
+}
+
 void PeopleHandler::MarkFirstSetupComplete() {
   syncer::SyncService* service = GetSyncService();
   // The sync service may be nullptr if it has been just disabled by policy.
diff --git a/chrome/browser/ui/webui/settings/people_handler.h b/chrome/browser/ui/webui/settings/people_handler.h
index e3591035..67fea3b6 100644
--- a/chrome/browser/ui/webui/settings/people_handler.h
+++ b/chrome/browser/ui/webui/settings/people_handler.h
@@ -68,6 +68,7 @@
  private:
   friend class PeopleHandlerTest;
   friend class PeopleHandlerSignoutTest;
+  friend class PeopleHandlerWithExplicitBrowserSigninTest;
   FRIEND_TEST_ALL_PREFIXES(PeopleHandlerTest,
                            DisplayConfigureWithEngineDisabledAndCancel);
   FRIEND_TEST_ALL_PREFIXES(
@@ -158,6 +159,11 @@
   void OnAccountsInCookieUpdated(
       const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
       const GoogleServiceAuthError& error) override;
+  void OnErrorStateOfRefreshTokenUpdatedForAccount(
+      const CoreAccountInfo& account_info,
+      const GoogleServiceAuthError& error,
+      signin_metrics::SourceForRefreshTokenOperation token_operation_source)
+      override;
 
   // syncer::SyncServiceObserver implementation.
   void OnStateChanged(syncer::SyncService* sync_service) override;
@@ -237,6 +243,9 @@
   // Sends the current sync status to the JavaScript WebUI code.
   void UpdateSyncStatus();
 
+  // Sends the computed stored accounts to the JavaScript WebUI code.
+  void UpdateStoredAccounts();
+
   // Suppresses any further signin promos, since the user has signed in once.
   void MarkFirstSetupComplete();
 
diff --git a/chrome/browser/ui/webui/settings/people_handler_unittest.cc b/chrome/browser/ui/webui/settings/people_handler_unittest.cc
index 3cd155f..58d5b69 100644
--- a/chrome/browser/ui/webui/settings/people_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/people_handler_unittest.cc
@@ -89,6 +89,9 @@
 // `PeopleHandler::UpdateChromeSigninUserChoiceInfo()`.
 constexpr char kChromeSigninUserChoiceInfoChangeEventName[] =
     "chrome-signin-user-choice-info-change";
+
+// Event fired when calling `PeopleHandler::UpdateSyncStatus()`.
+constexpr char kSyncStatusChangeEventName[] = "sync-status-changed";
 #endif
 
 // Returns a UserSelectableTypeSet with all types set.
@@ -1343,6 +1346,38 @@
     profile()->GetPrefs()->SetBoolean(prefs::kExplicitBrowserSignin, value);
   }
 
+  void TriggerPrimaryAccountInPersistentError() {
+    ASSERT_TRUE(identity_manager()->HasPrimaryAccount(ConsentLevel::kSignin));
+
+    // Inject the error.
+    identity_test_env()->UpdatePersistentErrorOfRefreshTokenForAccount(
+        identity_manager()->GetPrimaryAccountId(ConsentLevel::kSignin),
+        GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
+            GoogleServiceAuthError::InvalidGaiaCredentialsReason::
+                CREDENTIALS_REJECTED_BY_CLIENT));
+  }
+
+  bool HasSyncStatusUpdateChangedEvent() {
+    return !GetAllFiredValuesForEventName(kSyncStatusChangeEventName).empty();
+  }
+
+  void SimluateReauth() {
+    ASSERT_TRUE(
+        identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSignin));
+
+    // Clear the error.
+    identity_test_env()->UpdatePersistentErrorOfRefreshTokenForAccount(
+        identity_manager()->GetPrimaryAccountId(ConsentLevel::kSignin),
+        GoogleServiceAuthError::AuthErrorNone());
+  }
+
+  void SimulateSignout() {
+    ASSERT_TRUE(
+        identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSignin));
+
+    identity_test_env()->ClearPrimaryAccount();
+  }
+
  private:
   base::test::ScopedFeatureList scoped_feature_list_{
       switches::kExplicitBrowserSigninUIOnDesktop};
@@ -1390,8 +1425,7 @@
   ExpectChromeSigninUserChoiceInfoFromWebUiResponse(
       true, ChromeSigninUserChoice::kNoChoice, email);
 
-  // Sign out.
-  identity_test_env()->ClearPrimaryAccount();
+  SimulateSignout();
 
   ASSERT_FALSE(
       identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSignin));
@@ -1533,6 +1567,136 @@
             ChromeSigninUserChoice::kNoChoice, email);
   }
 }
+
+TEST_F(PeopleHandlerWithExplicitBrowserSigninTest, SigninPausedThenSignout) {
+  identity_test_env()->MakePrimaryAccountAvailable(kTestUser,
+                                                   ConsentLevel::kSignin);
+  SetExplicitSignin(true);
+  CreatePeopleHandler();
+
+  ASSERT_FALSE(HasSyncStatusUpdateChangedEvent());
+
+  TriggerPrimaryAccountInPersistentError();
+
+  {
+    auto values_list =
+        GetAllFiredValuesForEventName(kSyncStatusChangeEventName);
+    ASSERT_GT(values_list.size(), 0U);
+    size_t last_index = values_list.size() - 1;
+    ASSERT_TRUE(values_list[last_index]->is_dict());
+    const base::Value::Dict& sync_status_values =
+        values_list[last_index]->GetDict();
+    std::optional<bool> signenPaused =
+        sync_status_values.FindBool("signinPaused");
+    ASSERT_TRUE(signenPaused.has_value());
+    EXPECT_TRUE(signenPaused.value());
+  }
+
+  // Simulates pressing on the "Sign out" Button in the Sign in Paused state,
+  // that redirects to `PeopleHandler::HandleSignout()`. Since the test has no
+  // browser, clearing the primary account should be equivalent.
+  SimulateSignout();
+
+  {
+    auto values_list =
+        GetAllFiredValuesForEventName(kSyncStatusChangeEventName);
+    ASSERT_GT(values_list.size(), 0U);
+    size_t last_index = values_list.size() - 1;
+    ASSERT_TRUE(values_list[last_index]->is_dict());
+    const base::Value::Dict& sync_status_values =
+        values_list[last_index]->GetDict();
+    std::optional<bool> signenPaused =
+        sync_status_values.FindBool("signinPaused");
+    ASSERT_TRUE(signenPaused.has_value());
+    EXPECT_FALSE(signenPaused.value());
+  }
+}
+
+TEST_F(PeopleHandlerWithExplicitBrowserSigninTest, SigninPausedThenReauth) {
+  identity_test_env()->MakePrimaryAccountAvailable(kTestUser,
+                                                   ConsentLevel::kSignin);
+  SetExplicitSignin(true);
+  CreatePeopleHandler();
+
+  ASSERT_FALSE(HasSyncStatusUpdateChangedEvent());
+
+  TriggerPrimaryAccountInPersistentError();
+
+  {
+    auto values_list =
+        GetAllFiredValuesForEventName(kSyncStatusChangeEventName);
+    ASSERT_GT(values_list.size(), 0U);
+    size_t last_index = values_list.size() - 1;
+    ASSERT_TRUE(values_list[last_index]->is_dict());
+    const base::Value::Dict& sync_status_values =
+        values_list[last_index]->GetDict();
+    std::optional<bool> signinPaused =
+        sync_status_values.FindBool("signinPaused");
+    ASSERT_TRUE(signinPaused.has_value());
+    EXPECT_TRUE(signinPaused.value());
+  }
+
+  // Simulates pressing on the "Verify it's you" button in the Sign in Paused
+  // state, and reauth.
+  SimluateReauth();
+
+  {
+    auto values_list =
+        GetAllFiredValuesForEventName(kSyncStatusChangeEventName);
+    ASSERT_GT(values_list.size(), 0U);
+    size_t last_index = values_list.size() - 1;
+    ASSERT_TRUE(values_list[last_index]->is_dict());
+    const base::Value::Dict& sync_status_values =
+        values_list[last_index]->GetDict();
+    std::optional<bool> signinPaused =
+        sync_status_values.FindBool("signinPaused");
+    ASSERT_TRUE(signinPaused.has_value());
+    EXPECT_FALSE(signinPaused.value());
+  }
+}
+
+TEST_F(PeopleHandlerWithExplicitBrowserSigninTest, SigninPausedValueWithSync) {
+  CreatePeopleHandler();
+
+  ASSERT_FALSE(HasSyncStatusUpdateChangedEvent());
+
+  // User is syncing.
+  identity_test_env()->MakePrimaryAccountAvailable(kTestUser,
+                                                   ConsentLevel::kSync);
+
+  {
+    auto values_list =
+        GetAllFiredValuesForEventName(kSyncStatusChangeEventName);
+    ASSERT_GT(values_list.size(), 0U);
+    size_t last_index = values_list.size() - 1;
+    ASSERT_TRUE(values_list[last_index]->is_dict());
+    const base::Value::Dict& sync_status_values =
+        values_list[last_index]->GetDict();
+    std::optional<bool> signinPaused =
+        sync_status_values.FindBool("signinPaused");
+    ASSERT_TRUE(signinPaused.has_value());
+    EXPECT_FALSE(signinPaused.value());
+  }
+
+  // Invalidate the account while it is syncing.
+  TriggerPrimaryAccountInPersistentError();
+
+  // `signinPaused` is still false even when the account is in error.
+  {
+    auto values_list =
+        GetAllFiredValuesForEventName(kSyncStatusChangeEventName);
+    ASSERT_GT(values_list.size(), 0U);
+    size_t last_index = values_list.size() - 1;
+    ASSERT_TRUE(values_list[last_index]->is_dict());
+    const base::Value::Dict& sync_status_values =
+        values_list[last_index]->GetDict();
+    std::optional<bool> signinPaused =
+        sync_status_values.FindBool("signinPaused");
+    ASSERT_TRUE(signinPaused.has_value());
+    EXPECT_FALSE(signinPaused.value());
+  }
+}
+
 #endif
 
 #if BUILDFLAG(ENABLE_DICE_SUPPORT) || BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
index 55d3c47..7c7f05c 100644
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -1428,7 +1428,10 @@
 #if !BUILDFLAG(IS_CHROMEOS_LACROS)
       {"syncAdvancedPageTitle", IDS_SETTINGS_NEW_SYNC_ADVANCED_PAGE_TITLE},
 #endif
-
+      // TODO(crbug.com/330680561): Use a settings specific string or combine
+      // all the string usages of "Verify it's you" in a single translatable
+      // string.
+      {"signinPaused", IDS_AVATAR_BUTTON_SIGNIN_PAUSED},
   };
 
   html_source->AddLocalizedStrings(kLocalizedStrings);
diff --git a/chrome/browser/webauthn/change_pin_controller_impl.cc b/chrome/browser/webauthn/change_pin_controller_impl.cc
index 32e1135..2854ea0 100644
--- a/chrome/browser/webauthn/change_pin_controller_impl.cc
+++ b/chrome/browser/webauthn/change_pin_controller_impl.cc
@@ -84,10 +84,7 @@
 
 void ChangePinControllerImpl::CancelAuthenticatorRequest() {
   // User clicked "Cancel" in the GPM dialog.
-  if (!notify_pin_change_callback_.is_null()) {
-    std::move(notify_pin_change_callback_).Run(false);
-  }
-  Reset();
+  Reset(/*success=*/false);
 }
 
 void ChangePinControllerImpl::OnReauthComplete(std::string rapt) {
@@ -97,10 +94,7 @@
 
 void ChangePinControllerImpl::OnRecoverSecurityDomainClosed() {
   // User closed the reauth window.
-  if (!notify_pin_change_callback_.is_null()) {
-    std::move(notify_pin_change_callback_).Run(false);
-  }
-  Reset();
+  Reset(/*success=*/false);
 }
 
 void ChangePinControllerImpl::OnGPMPinEntered(const std::u16string& pin) {
@@ -119,8 +113,11 @@
                                : Step::kGPMCreatePin);
 }
 
-void ChangePinControllerImpl::Reset() {
-  model_observation_.Reset();
+void ChangePinControllerImpl::Reset(bool success) {
+  if (!notify_pin_change_callback_.is_null()) {
+    std::move(notify_pin_change_callback_).Run(success);
+  }
+
   model_->SetStep(Step::kNotStarted);
   rapt_.reset();
 }
@@ -130,8 +127,5 @@
     model_->SetStep(Step::kGPMError);
     return;
   }
-  Reset();
-  if (!notify_pin_change_callback_.is_null()) {
-    std::move(notify_pin_change_callback_).Run(success);
-  }
+  Reset(/*success=*/true);
 }
diff --git a/chrome/browser/webauthn/change_pin_controller_impl.h b/chrome/browser/webauthn/change_pin_controller_impl.h
index 94de0ac5..73a0006 100644
--- a/chrome/browser/webauthn/change_pin_controller_impl.h
+++ b/chrome/browser/webauthn/change_pin_controller_impl.h
@@ -92,7 +92,7 @@
 
  private:
   void OnGpmPinChanged(bool success);
-  void Reset();
+  void Reset(bool success);
 
   const bool enclave_enabled_;
   std::unique_ptr<AuthenticatorRequestDialogModel> model_;
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt
index 0310836..9c7443b 100644
--- a/chrome/build/android-arm32.pgo.txt
+++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@
-chrome-android32-main-1713765581-a920c9bf2944d44d111f9be1590b199e08d977bc-bd7c80d505f82eb64d22d357ecaceeec80dc30a9.profdata
+chrome-android32-main-1713787146-764c2e7feee05934f2ede75ed5988c91643b93af-1035b0924d4df19c3c3afe9fe312bd38ba2864ed.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt
index 3d88e938..cf20549c 100644
--- a/chrome/build/android-arm64.pgo.txt
+++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@
-chrome-android64-main-1713742736-28a7d76ad388283f061403b8b73e594a94abf8b9-2a6aba0081c720c97832a077700415a368fb2a26.profdata
+chrome-android64-main-1713787146-3732fa8bd216449b2433c57db59f653483791757-1035b0924d4df19c3c3afe9fe312bd38ba2864ed.profdata
diff --git a/chrome/build/lacros-arm64.pgo.txt b/chrome/build/lacros-arm64.pgo.txt
index 1456832..7505bf38 100644
--- a/chrome/build/lacros-arm64.pgo.txt
+++ b/chrome/build/lacros-arm64.pgo.txt
@@ -1 +1 @@
-chrome-chromeos-arm64-generic-main-1713742736-d168b7a2b53fd1987b161c558390afec7411ef7a-2a6aba0081c720c97832a077700415a368fb2a26.profdata
+chrome-chromeos-arm64-generic-main-1713787146-bc2187921b56b925911e6ed8a84d4bc8d3ccb8ad-1035b0924d4df19c3c3afe9fe312bd38ba2864ed.profdata
diff --git a/chrome/build/lacros64.pgo.txt b/chrome/build/lacros64.pgo.txt
index cec72d49..8ad8614f 100644
--- a/chrome/build/lacros64.pgo.txt
+++ b/chrome/build/lacros64.pgo.txt
@@ -1 +1 @@
-chrome-chromeos-amd64-generic-main-1713742736-7e47b7b1b1d5fe3f9772151a099b511b1764d903-2a6aba0081c720c97832a077700415a368fb2a26.profdata
+chrome-chromeos-amd64-generic-main-1713787146-48d06fa7687d0538ae517eca18f5374ac26ab108-1035b0924d4df19c3c3afe9fe312bd38ba2864ed.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 46e0884d7..cf5c26b 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1713765581-add4d3bc4a3a773aea2d7d9032be89ab542629e6-bd7c80d505f82eb64d22d357ecaceeec80dc30a9.profdata
+chrome-linux-main-1713787146-1d25cdebe05ef2c3ecbe9f14fbb5e31307538961-1035b0924d4df19c3c3afe9fe312bd38ba2864ed.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt
index 854c9afd..87db01b 100644
--- a/chrome/build/win-arm64.pgo.txt
+++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@
-chrome-win-arm64-main-1713765581-5f8d5ea1f2c649bd8cf985fc8b7810acad857555-bd7c80d505f82eb64d22d357ecaceeec80dc30a9.profdata
+chrome-win-arm64-main-1713787146-90c95b9f112870522dcfb3df2a31206696dc58b9-1035b0924d4df19c3c3afe9fe312bd38ba2864ed.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 8cea27f2..01943c23 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1713765581-61e03b99577fed20a2194c759794fbba4df7a6cf-bd7c80d505f82eb64d22d357ecaceeec80dc30a9.profdata
+chrome-win32-main-1713787146-be15fe3f3927946971bb5f0dd6e565b3417b36c6-1035b0924d4df19c3c3afe9fe312bd38ba2864ed.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index cd08e0f..ee9555a5 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1713765581-bb0cbe9c007cde0b28b999445a0c62c07e06fc53-bd7c80d505f82eb64d22d357ecaceeec80dc30a9.profdata
+chrome-win64-main-1713787146-6e649455503a5dd8e4434a692e4fa92724ac0764-1035b0924d4df19c3c3afe9fe312bd38ba2864ed.profdata
diff --git a/chrome/renderer/autofill/form_autofill_browsertest.cc b/chrome/renderer/autofill/form_autofill_browsertest.cc
index 4586b92..db623e3 100644
--- a/chrome/renderer/autofill/form_autofill_browsertest.cc
+++ b/chrome/renderer/autofill/form_autofill_browsertest.cc
@@ -484,7 +484,8 @@
       } else {
         expected.set_label({});
       }
-      expected.autocomplete_attribute = field_cases[i].autocomplete_attribute;
+      expected.set_autocomplete_attribute(
+          field_cases[i].autocomplete_attribute);
       EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[i]);
       // Fill the form_data for the field.
       form.fields[i].set_value(ASCIIToUTF16(field_cases[i].autofill_value));
@@ -725,9 +726,9 @@
     expected.set_name(expected.id_attribute());
     expected.set_value(u"john@example.com");
     expected.set_label(u"john@example.com");
-    expected.autocomplete_attribute = "off";
+    expected.set_autocomplete_attribute("off");
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
-    expected.autocomplete_attribute = {};
+    expected.set_autocomplete_attribute({});
 
     expected.set_id_attribute(u"phone");
     expected.set_name(expected.id_attribute());
@@ -785,11 +786,11 @@
     expected.set_name(expected.id_attribute());
     expected.set_value(u"john@example.com");
     expected.set_label(u"john@example.com");
-    expected.autocomplete_attribute = "off";
+    expected.set_autocomplete_attribute("off");
     expected.set_form_control_type(FormControlType::kInputText);
     expected.set_max_length(FormFieldData::kDefaultMaxLength);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
-    expected.autocomplete_attribute = {};
+    expected.set_autocomplete_attribute({});
 
     expected.set_id_attribute(u"street-address");
     expected.set_name(expected.id_attribute());
@@ -1177,7 +1178,7 @@
     expected.set_value(u"Wy");
     if (placeholder_firstname) {
       expected.set_label(ASCIIToUTF16(placeholder_firstname));
-      expected.placeholder = ASCIIToUTF16(placeholder_firstname);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_firstname));
     }
     expected.set_is_autofilled(false);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]);
@@ -1189,7 +1190,7 @@
       expected.set_value(ASCIIToUTF16(initial_lastname));
     } else if (placeholder_lastname) {
       expected.set_label(ASCIIToUTF16(placeholder_lastname));
-      expected.placeholder = ASCIIToUTF16(placeholder_lastname);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_lastname));
       expected.set_value(ASCIIToUTF16(placeholder_lastname));
     } else {
       expected.set_label({});
@@ -1205,7 +1206,7 @@
       expected.set_value(ASCIIToUTF16(initial_email));
     } else if (placeholder_email) {
       expected.set_label(ASCIIToUTF16(placeholder_email));
-      expected.placeholder = ASCIIToUTF16(placeholder_email);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_email));
       expected.set_value(ASCIIToUTF16(placeholder_email));
     } else {
       expected.set_label({});
@@ -1249,10 +1250,10 @@
     expected.set_value(u"Wyatt");
     if (placeholder_firstname) {
       expected.set_label(ASCIIToUTF16(placeholder_firstname));
-      expected.placeholder = ASCIIToUTF16(placeholder_firstname);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_firstname));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(true);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]);
@@ -1262,10 +1263,10 @@
     expected.set_value(u"Earp");
     if (placeholder_lastname) {
       expected.set_label(ASCIIToUTF16(placeholder_lastname));
-      expected.placeholder = ASCIIToUTF16(placeholder_lastname);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_lastname));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(true);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]);
@@ -1275,10 +1276,10 @@
     expected.set_value(u"wyatt@example.com");
     if (placeholder_email) {
       expected.set_label(ASCIIToUTF16(placeholder_email));
-      expected.placeholder = ASCIIToUTF16(placeholder_email);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_email));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(true);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]);
@@ -1396,13 +1397,13 @@
     expected.set_value(u"Wyatt");
     if (placeholder_firstname) {
       expected.set_label(ASCIIToUTF16(placeholder_firstname));
-      expected.placeholder = ASCIIToUTF16(placeholder_firstname);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_firstname));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(true);
-    expected.is_user_edited = false;
+    expected.set_is_user_edited(false);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]);
 
     // The last name field is not filled, because there is a value in it.
@@ -1411,13 +1412,13 @@
     expected.set_value(u"Earp");
     if (placeholder_lastname) {
       expected.set_label(ASCIIToUTF16(placeholder_lastname));
-      expected.placeholder = ASCIIToUTF16(placeholder_lastname);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_lastname));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(false);
-    expected.is_user_edited = true;
+    expected.set_is_user_edited(true);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]);
 
     expected.set_id_attribute(u"phone");
@@ -1425,13 +1426,13 @@
     expected.set_value(u"888-123-4567");
     if (placeholder_phone) {
       expected.set_label(ASCIIToUTF16(placeholder_phone));
-      expected.placeholder = ASCIIToUTF16(placeholder_phone);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_phone));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(true);
-    expected.is_user_edited = false;
+    expected.set_is_user_edited(false);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]);
 
     expected.set_id_attribute(u"cc");
@@ -1439,13 +1440,13 @@
     expected.set_value(u"1111-2222-3333-4444");
     if (placeholder_creditcard) {
       expected.set_label(ASCIIToUTF16(placeholder_creditcard));
-      expected.placeholder = ASCIIToUTF16(placeholder_creditcard);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_creditcard));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(true);
-    expected.is_user_edited = false;
+    expected.set_is_user_edited(false);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[3]);
 
     expected.set_id_attribute(u"city");
@@ -1453,13 +1454,13 @@
     expected.set_value(u"Montreal");
     if (placeholder_city) {
       expected.set_label(ASCIIToUTF16(placeholder_city));
-      expected.placeholder = ASCIIToUTF16(placeholder_city);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_city));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(true);
-    expected.is_user_edited = false;
+    expected.set_is_user_edited(false);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[4]);
 
     expected.set_form_control_type(FormControlType::kSelectOne);
@@ -1469,13 +1470,13 @@
     expected.set_value(u"AA");
     if (placeholder_state) {
       expected.set_label(ASCIIToUTF16(placeholder_state));
-      expected.placeholder = ASCIIToUTF16(placeholder_state);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_state));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(true);
-    expected.is_user_edited = false;
+    expected.set_is_user_edited(false);
     expected.set_max_length(0);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[5]);
   }
@@ -1555,10 +1556,10 @@
     expected.set_value(u"Wyatt");
     if (placeholder_firstname) {
       expected.set_label(ASCIIToUTF16(placeholder_firstname));
-      expected.placeholder = ASCIIToUTF16(placeholder_firstname);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_firstname));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(true);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]);
@@ -1568,10 +1569,10 @@
     expected.set_value(u"Earpagus");
     if (placeholder_lastname) {
       expected.set_label(ASCIIToUTF16(placeholder_lastname));
-      expected.placeholder = ASCIIToUTF16(placeholder_lastname);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_lastname));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(true);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]);
@@ -1582,10 +1583,10 @@
     expected.set_value(u"john@smith.com");
     if (placeholder_email) {
       expected.set_label(ASCIIToUTF16(placeholder_email));
-      expected.placeholder = ASCIIToUTF16(placeholder_email);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_email));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(false);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]);
@@ -1669,10 +1670,10 @@
     expected.set_value(u"1111-2222-3333-4444");
     if (placeholder_creditcard) {
       expected.set_label(ASCIIToUTF16(placeholder_creditcard));
-      expected.placeholder = ASCIIToUTF16(placeholder_creditcard);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_creditcard));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(true);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]);
@@ -1682,10 +1683,10 @@
     expected.set_value(u"03/2030");
     if (placeholder_expiration) {
       expected.set_label(ASCIIToUTF16(placeholder_expiration));
-      expected.placeholder = ASCIIToUTF16(placeholder_expiration);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_expiration));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(true);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]);
@@ -1695,13 +1696,13 @@
     expected.set_value(u"John Smith");
     if (placeholder_name) {
       expected.set_label(ASCIIToUTF16(placeholder_name));
-      expected.placeholder = ASCIIToUTF16(placeholder_name);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_name));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(false);
-    expected.is_user_edited = true;
+    expected.set_is_user_edited(true);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]);
 
     // Verify that the cursor position has been updated.
@@ -1791,10 +1792,10 @@
     expected.set_value(u"1111-2222-3333-4444");
     if (placeholder_creditcard) {
       expected.set_label(ASCIIToUTF16(placeholder_creditcard));
-      expected.placeholder = ASCIIToUTF16(placeholder_creditcard);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_creditcard));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(true);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]);
@@ -1804,10 +1805,10 @@
     expected.set_value(u"03/2030");
     if (placeholder_expiration) {
       expected.set_label(ASCIIToUTF16(placeholder_expiration));
-      expected.placeholder = ASCIIToUTF16(placeholder_expiration);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_expiration));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(true);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]);
@@ -1817,13 +1818,13 @@
     expected.set_value(u"John Smith");
     if (placeholder_name) {
       expected.set_label(ASCIIToUTF16(placeholder_name));
-      expected.placeholder = ASCIIToUTF16(placeholder_name);
+      expected.set_placeholder(ASCIIToUTF16(placeholder_name));
     } else {
       expected.set_label({});
-      expected.placeholder = {};
+      expected.set_placeholder({});
     }
     expected.set_is_autofilled(false);
-    expected.is_user_edited = true;
+    expected.set_is_user_edited(true);
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]);
 
     // Verify that the cursor position has been updated.
@@ -1892,9 +1893,9 @@
     expected.set_name(expected.id_attribute());
     expected.set_value(u"one");
     expected.set_label(u"one");
-    expected.autocomplete_attribute = "off";
+    expected.set_autocomplete_attribute("off");
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]);
-    expected.autocomplete_attribute = {};
+    expected.set_autocomplete_attribute({});
 
     expected.set_id_attribute(u"notenabled");
     expected.set_name(expected.id_attribute());
@@ -1932,9 +1933,9 @@
     expected.set_id_attribute(u"textarea-noAC");
     expected.set_name(expected.id_attribute());
     expected.set_value(u"Carrot?");
-    expected.autocomplete_attribute = "off";
+    expected.set_autocomplete_attribute("off");
     EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[8]);
-    expected.autocomplete_attribute = {};
+    expected.set_autocomplete_attribute({});
 
     // Verify that the cursor position has been updated.
     EXPECT_EQ(0u, firstname.SelectionStart());
@@ -2406,7 +2407,7 @@
   expected.set_name(expected.id_attribute());
   expected.set_value(u"value");
   expected.set_form_control_type(FormControlType::kInputText);
-  expected.autocomplete_attribute = "off";
+  expected.set_autocomplete_attribute("off");
   expected.set_max_length(FormFieldData::kDefaultMaxLength);
   EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
 }
@@ -2477,7 +2478,7 @@
   expected.set_form_control_type(FormControlType::kInputCheckbox);
   expected.set_max_length(0);
   expected.set_is_autofilled(true);
-  expected.check_status = FormFieldData::CheckStatus::kChecked;
+  expected.set_check_status(FormFieldData::CheckStatus::kChecked);
   EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
 
   element = GetInputElementById("radio");
@@ -2490,7 +2491,7 @@
   expected.set_form_control_type(FormControlType::kInputRadio);
   expected.set_max_length(0);
   expected.set_is_autofilled(true);
-  expected.check_status = FormFieldData::CheckStatus::kCheckableButUnchecked;
+  expected.set_check_status(FormFieldData::CheckStatus::kCheckableButUnchecked);
   EXPECT_FORM_FIELD_DATA_EQUALS(expected, result);
 }
 
@@ -2531,11 +2532,11 @@
   expected.set_value({});
   EXPECT_FORM_FIELD_DATA_EQUALS(expected, result3);
 
-  ASSERT_EQ(2U, result3.options.size());
-  EXPECT_EQ(u"CA", result3.options[0].value);
-  EXPECT_EQ(u"California", result3.options[0].content);
-  EXPECT_EQ(u"TX", result3.options[1].value);
-  EXPECT_EQ(u"Texas", result3.options[1].content);
+  ASSERT_EQ(2U, result3.options().size());
+  EXPECT_EQ(u"CA", result3.options()[0].value);
+  EXPECT_EQ(u"California", result3.options()[0].content);
+  EXPECT_EQ(u"TX", result3.options()[1].value);
+  EXPECT_EQ(u"Texas", result3.options()[1].content);
 }
 
 // We copy extra attributes for the select field.
@@ -2563,11 +2564,11 @@
   expected.set_form_control_type(FormControlType::kSelectOne);
   // We check that the extra attributes have been copied to `result1`.
   expected.set_is_autofilled(true);
-  expected.autocomplete_attribute = "off";
-  expected.should_autocomplete = false;
-  expected.is_focusable = true;
-  expected.is_visible = true;
-  expected.text_direction = base::i18n::LEFT_TO_RIGHT;
+  expected.set_autocomplete_attribute("off");
+  expected.set_should_autocomplete(false);
+  expected.set_is_focusable(true);
+  expected.set_is_visible(true);
+  expected.set_text_direction(base::i18n::LEFT_TO_RIGHT);
 
   expected.set_value(u"CA");
   EXPECT_FORM_FIELD_DATA_EQUALS(expected, result1);
@@ -2594,7 +2595,7 @@
   WebFormControlElementToFormField(WebFormElement(), element, nullptr,
                                    {ExtractOption::kOptions}, &result);
 
-  EXPECT_TRUE(result.options.empty());
+  EXPECT_TRUE(result.options().empty());
 }
 
 // Test that we use the aria-label as the content if the <option> has no text.
@@ -2612,9 +2613,9 @@
   FormFieldData result;
   WebFormControlElementToFormField(WebFormElement(), element, nullptr,
                                    {ExtractOption::kOptions}, &result);
-  ASSERT_EQ(2u, result.options.size());
-  EXPECT_EQ(u"usa", result.options[0].content);
-  EXPECT_EQ(u"uk", result.options[1].content);
+  ASSERT_EQ(2u, result.options().size());
+  EXPECT_EQ(u"usa", result.options()[0].content);
+  EXPECT_EQ(u"uk", result.options()[1].content);
 }
 
 // Test that the content for the <option> can be computed when the <option>s
@@ -2633,8 +2634,8 @@
   FormFieldData result;
   WebFormControlElementToFormField(WebFormElement(), element, nullptr,
                                    {ExtractOption::kOptions}, &result);
-  ASSERT_EQ(1u, result.options.size());
-  EXPECT_EQ(u"+1 (Canada)", result.options[0].content);
+  ASSERT_EQ(1u, result.options().size());
+  EXPECT_EQ(u"+1 (Canada)", result.options()[0].content);
 }
 
 // We should be able to extract a <textarea> field.
@@ -2789,7 +2790,7 @@
          test_case.form_control_type == FormControlType::kTextArea)
             ? FormFieldData::kDefaultMaxLength
             : 0);
-    expected.autocomplete_attribute = test_case.autocomplete_attribute;
+    expected.set_autocomplete_attribute(test_case.autocomplete_attribute);
     expected.set_parsed_autocomplete(
         ParseAutocompleteAttribute(test_case.autocomplete_attribute));
 
@@ -2811,7 +2812,7 @@
   FormFieldData result;
   WebFormControlElementToFormField(element.Form(), element, nullptr,
                                    {ExtractOption::kValue}, &result);
-  EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction);
+  EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction());
 }
 
 TEST_F(FormAutofillTest, DetectTextDirectionFromDirectDIRAttribute) {
@@ -2826,7 +2827,7 @@
   FormFieldData result;
   WebFormControlElementToFormField(element.Form(), element, nullptr,
                                    {ExtractOption::kValue}, &result);
-  EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction);
+  EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction());
 }
 
 TEST_F(FormAutofillTest, DetectTextDirectionFromParentStyle) {
@@ -2842,7 +2843,7 @@
   FormFieldData result;
   WebFormControlElementToFormField(element.Form(), element, nullptr,
                                    {ExtractOption::kValue}, &result);
-  EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction);
+  EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction());
 }
 
 TEST_F(FormAutofillTest, DetectTextDirectionFromParentDIRAttribute) {
@@ -2857,7 +2858,7 @@
   FormFieldData result;
   WebFormControlElementToFormField(element.Form(), element, nullptr,
                                    {ExtractOption::kValue}, &result);
-  EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction);
+  EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction());
 }
 
 TEST_F(FormAutofillTest, DetectTextDirectionWhenStyleAndDIRAttributeMixed) {
@@ -2873,7 +2874,7 @@
   FormFieldData result;
   WebFormControlElementToFormField(element.Form(), element, nullptr,
                                    {ExtractOption::kValue}, &result);
-  EXPECT_EQ(base::i18n::LEFT_TO_RIGHT, result.text_direction);
+  EXPECT_EQ(base::i18n::LEFT_TO_RIGHT, result.text_direction());
 }
 
 TEST_F(FormAutofillTest, TextAlignOverridesDirection) {
@@ -2890,7 +2891,7 @@
   FormFieldData result;
   WebFormControlElementToFormField(element.Form(), element, nullptr,
                                    {ExtractOption::kValue}, &result);
-  EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction);
+  EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction());
 
   // text-align: left
   LoadHTML(R"(<style>input{direction:rtl;text-align:left}</style>
@@ -2904,7 +2905,7 @@
   element = GetFormControlElementById("element");
   WebFormControlElementToFormField(element.Form(), element, nullptr,
                                    {ExtractOption::kValue}, &result);
-  EXPECT_EQ(base::i18n::LEFT_TO_RIGHT, result.text_direction);
+  EXPECT_EQ(base::i18n::LEFT_TO_RIGHT, result.text_direction());
 }
 
 TEST_F(FormAutofillTest,
@@ -2921,7 +2922,7 @@
   FormFieldData result;
   WebFormControlElementToFormField(element.Form(), element, nullptr,
                                    {ExtractOption::kValue}, &result);
-  EXPECT_EQ(base::i18n::LEFT_TO_RIGHT, result.text_direction);
+  EXPECT_EQ(base::i18n::LEFT_TO_RIGHT, result.text_direction());
 }
 
 TEST_F(FormAutofillTest, DetectTextDirectionWhenAncestorHasInlineStyle) {
@@ -2938,7 +2939,7 @@
   FormFieldData result;
   WebFormControlElementToFormField(element.Form(), element, nullptr,
                                    {ExtractOption::kValue}, &result);
-  EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction);
+  EXPECT_EQ(base::i18n::RIGHT_TO_LEFT, result.text_direction());
 }
 
 TEST_F(FormAutofillTest, WebFormElementToFormData) {
@@ -3116,7 +3117,7 @@
                                    *base::MakeRefCounted<FieldDataManager>(),
                                    /*extract_options=*/{});
   for (const FormFieldData& field : form.fields) {
-    EXPECT_FALSE(field.should_autocomplete);
+    EXPECT_FALSE(field.should_autocomplete());
   }
 }
 
@@ -3146,9 +3147,9 @@
 
   ASSERT_EQ(3U, form.fields.size());
 
-  EXPECT_FALSE(form.fields[0].should_autocomplete);
-  EXPECT_TRUE(form.fields[1].should_autocomplete);
-  EXPECT_TRUE(form.fields[2].should_autocomplete);
+  EXPECT_FALSE(form.fields[0].should_autocomplete());
+  EXPECT_TRUE(form.fields[1].should_autocomplete());
+  EXPECT_TRUE(form.fields[2].should_autocomplete());
 }
 
 // `should_autocomplete` must be set to false for the field with
@@ -3170,7 +3171,7 @@
                                    /*extract_options=*/{});
 
   ASSERT_EQ(1U, form.fields.size());
-  EXPECT_FALSE(form.fields[0].should_autocomplete);
+  EXPECT_FALSE(form.fields[0].should_autocomplete());
 }
 
 // Tests CSS classes are set.
@@ -3194,9 +3195,9 @@
                                    /*extract_options=*/{});
 
   ASSERT_EQ(3U, form.fields.size());
-  EXPECT_EQ(u"firstname_field", form.fields[0].css_classes);
-  EXPECT_EQ(u"lastname_field", form.fields[1].css_classes);
-  EXPECT_EQ(std::u16string(), form.fields[2].css_classes);
+  EXPECT_EQ(u"firstname_field", form.fields[0].css_classes());
+  EXPECT_EQ(u"lastname_field", form.fields[1].css_classes());
+  EXPECT_EQ(std::u16string(), form.fields[2].css_classes());
 }
 
 // Tests id attributes are set.
@@ -3607,7 +3608,7 @@
   FormFieldData& form_field_data = form.fields[0];
 
   EXPECT_EQ(form_field_data.label(), u"foo bar");
-  EXPECT_EQ(form_field_data.label_source, FormFieldData::LabelSource::kForId);
+  EXPECT_EQ(form_field_data.label_source(), FormFieldData::LabelSource::kForId);
 }
 
 // Tests that when a label is assigned to an input, text behind it is considered
@@ -5604,16 +5605,16 @@
   ASSERT_EQ(3U, fields.size());
 
   // Field 0
-  EXPECT_EQ(u"inline aria label", fields[0].aria_label);
-  EXPECT_EQ(u"", fields[0].aria_description);
+  EXPECT_EQ(u"inline aria label", fields[0].aria_label());
+  EXPECT_EQ(u"", fields[0].aria_description());
 
   // Field 1
-  EXPECT_EQ(u"aria label", fields[1].aria_label);
-  EXPECT_EQ(u"", fields[1].aria_description);
+  EXPECT_EQ(u"aria label", fields[1].aria_label());
+  EXPECT_EQ(u"", fields[1].aria_description());
 
   // Field 2
-  EXPECT_EQ(u"", fields[2].aria_label);
-  EXPECT_EQ(u"aria description", fields[2].aria_description);
+  EXPECT_EQ(u"", fields[2].aria_label());
+  EXPECT_EQ(u"aria description", fields[2].aria_description());
 }
 
 TEST_F(FormAutofillTest, AriaLabelAndDescription2) {
@@ -5647,16 +5648,16 @@
   ASSERT_EQ(3U, fields.size());
 
   // Field 0
-  EXPECT_EQ(u"inline aria label", fields[0].aria_label);
-  EXPECT_EQ(u"", fields[0].aria_description);
+  EXPECT_EQ(u"inline aria label", fields[0].aria_label());
+  EXPECT_EQ(u"", fields[0].aria_description());
 
   // Field 1
-  EXPECT_EQ(u"aria label", fields[1].aria_label);
-  EXPECT_EQ(u"", fields[1].aria_description);
+  EXPECT_EQ(u"aria label", fields[1].aria_label());
+  EXPECT_EQ(u"", fields[1].aria_description());
 
   // Field 2
-  EXPECT_EQ(u"", fields[2].aria_label);
-  EXPECT_EQ(u"aria description", fields[2].aria_description);
+  EXPECT_EQ(u"", fields[2].aria_label());
+  EXPECT_EQ(u"aria description", fields[2].aria_description());
 }
 
 }  // namespace
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
index b87d0cb..45f85cab 100644
--- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
+++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -358,8 +358,9 @@
     if (field.value() == value) {
       return true;
     }
-    if (field.user_input == value)
+    if (field.user_input() == value) {
       return true;
+    }
   }
   return false;
 }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index d75e310..01a36e14 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -4961,6 +4961,7 @@
         "../browser/ui/webui/ash/cloud_upload/cloud_upload_dialog_browsertest.cc",
         "../browser/ui/webui/ash/cloud_upload/cloud_upload_dialog_browsertest.h",
         "../browser/ui/webui/ash/cloud_upload/drive_upload_handler_browsertest.cc",
+        "../browser/ui/webui/ash/cloud_upload/drive_upload_observer_browsertest.cc",
         "../browser/ui/webui/ash/cloud_upload/one_drive_upload_handler_browsertest.cc",
         "../browser/ui/webui/ash/cros_components_browsertest.cc",
         "../browser/ui/webui/ash/crostini_upgrader/crostini_upgrader_dialog_browsertest.cc",
@@ -7019,6 +7020,7 @@
     "//components/safe_browsing/core/browser:verdict_cache_manager",
     "//components/safe_browsing/core/browser/db",
     "//components/safe_browsing/core/browser/db:test_database_manager",
+    "//components/safe_browsing/core/browser/db:v4_local_database_manager",
     "//components/safe_browsing/core/browser/sync",
     "//components/safe_browsing/core/common",
     "//components/safe_browsing/core/common/proto:client_model_proto",
@@ -7976,6 +7978,7 @@
       "../browser/ui/performance_controls/tab_resource_usage_tab_helper_unittest.cc",
       "../browser/ui/qrcode_generator/qrcode_generator_bubble_controller_unittest.cc",
       "../browser/ui/recently_audible_helper_unittest.cc",
+      "../browser/ui/safety_hub/abusive_notification_permissions_manager_unittest.cc",
       "../browser/ui/safety_hub/extensions_result_unittest.cc",
       "../browser/ui/safety_hub/password_status_check_result_unittest.cc",
       "../browser/ui/safety_hub/password_status_check_service_unittest.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/browser/history/StubbedHistoryProvider.java b/chrome/test/android/javatests/src/org/chromium/chrome/browser/history/StubbedHistoryProvider.java
index 9c32c3f..db58e15 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/browser/history/StubbedHistoryProvider.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/browser/history/StubbedHistoryProvider.java
@@ -33,6 +33,8 @@
     private int mPaging = 5;
     private boolean mHostOnly;
 
+    private boolean mQueryAppsTriggered;
+
     @Override
     public void setObserver(BrowsingHistoryObserver observer) {
         mObserver = observer;
@@ -99,7 +101,13 @@
     }
 
     @Override
-    public void getAllAppIds() {}
+    public void queryApps() {
+        mQueryAppsTriggered = true;
+    }
+
+    public boolean isQueryAppsTriggered() {
+        return mQueryAppsTriggered;
+    }
 
     @Override
     public void getLastVisitToHostBeforeRecentNavigations(
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/browser/history/TestBrowsingHistoryObserver.java b/chrome/test/android/javatests/src/org/chromium/chrome/browser/history/TestBrowsingHistoryObserver.java
index 4a320cd..91d498fd 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/browser/history/TestBrowsingHistoryObserver.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/browser/history/TestBrowsingHistoryObserver.java
@@ -33,6 +33,9 @@
     @Override
     public void hasOtherFormsOfBrowsingData(boolean hasOtherForms) {}
 
+    @Override
+    public void onQueryAppsComplete(List<String> items) {}
+
     /**
      * Simple accessor to the internal CallbackHelper.
      *
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/BUILD.gn b/chrome/test/data/webui/chromeos/shimless_rma/BUILD.gn
index 3ed2fdd..bc9c4076 100644
--- a/chrome/test/data/webui/chromeos/shimless_rma/BUILD.gn
+++ b/chrome/test/data/webui/chromeos/shimless_rma/BUILD.gn
@@ -42,7 +42,7 @@
     "wrapup_finalize_page_test.ts",
     "wrapup_repair_complete_page_test.ts",
     "wrapup_restock_page_test.ts",
-    "wrapup_wait_for_manual_wp_enable_page_test.js",
+    "wrapup_wait_for_manual_wp_enable_page_test.ts",
   ]
 
   ts_deps = [
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_browsertest.cc b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_browsertest.cc
index af23866..69c3a0e 100644
--- a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_browsertest.cc
+++ b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_browsertest.cc
@@ -166,6 +166,11 @@
           "mocha.run()");
 }
 
+IN_PROC_BROWSER_TEST_F(ShimlessRmaBrowserTest, WaitForManualWpEnable) {
+  RunTest("chromeos/shimless_rma/wrapup_wait_for_manual_wp_enable_page_test.js",
+          "mocha.run()");
+}
+
 }  // namespace
 
 }  // namespace ash
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_browsertest.js b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_browsertest.js
index fc9ad59..572579fb 100644
--- a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_browsertest.js
+++ b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_browsertest.js
@@ -34,10 +34,6 @@
 
 const tests = [
   ['Shimless3pDiagTest', 'shimless_3p_diag_test.js'],
-  [
-    'WrapupWaitForManualWpEnablePageTest',
-    'wrapup_wait_for_manual_wp_enable_page_test.js'
-  ],
 ];
 
 tests.forEach(test => registerTest(...test));
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/wrapup_wait_for_manual_wp_enable_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/wrapup_wait_for_manual_wp_enable_page_test.js
deleted file mode 100644
index a85bbba..0000000
--- a/chrome/test/data/webui/chromeos/shimless_rma/wrapup_wait_for_manual_wp_enable_page_test.js
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2021 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {PromiseResolver} from 'chrome://resources/ash/common/promise_resolver.js';
-import {FakeShimlessRmaService} from 'chrome://shimless-rma/fake_shimless_rma_service.js';
-import {setShimlessRmaServiceForTesting} from 'chrome://shimless-rma/mojo_interface_provider.js';
-import {ShimlessRma} from 'chrome://shimless-rma/shimless_rma.js';
-import {WrapupWaitForManualWpEnablePage} from 'chrome://shimless-rma/wrapup_wait_for_manual_wp_enable_page.js';
-import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
-
-import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js';
-
-suite('wrapupWaitForManualWpEnablePageTest', function() {
-  /**
-   * ShimlessRma is needed to handle the 'transition-state' used to signal write
-   * write protect is enabled.
-   * @type {?ShimlessRma}
-   */
-  let shimlessRmaComponent = null;
-
-  /** @type {?WrapupWaitForManualWpEnablePage} */
-  let component = null;
-
-  /** @type {?FakeShimlessRmaService} */
-  let service = null;
-
-  setup(() => {
-    document.body.innerHTML = trustedTypes.emptyHTML;
-    service = new FakeShimlessRmaService();
-    setShimlessRmaServiceForTesting(service);
-  });
-
-  teardown(() => {
-    shimlessRmaComponent.remove();
-    shimlessRmaComponent = null;
-    component.remove();
-    component = null;
-    service.reset();
-  });
-
-  /**
-   * @return {!Promise}
-   */
-  function initializeWaitForManualWpEnablePage() {
-    assertFalse(!!component);
-
-    shimlessRmaComponent =
-        /** @type {!ShimlessRma} */ (document.createElement('shimless-rma'));
-    assertTrue(!!shimlessRmaComponent);
-    document.body.appendChild(shimlessRmaComponent);
-
-    component = /** @type {!WrapupWaitForManualWpEnablePage} */ (
-        document.createElement('wrapup-wait-for-manual-wp-enable-page'));
-    assertTrue(!!component);
-    document.body.appendChild(component);
-
-    return flushTasks();
-  }
-
-  test('WaitForManualWpEnablePageInitializes', async () => {
-    await initializeWaitForManualWpEnablePage();
-    const manualEnableComponent =
-        component.shadowRoot.querySelector('#manuallyEnableHwwpInstructions');
-    assertFalse(manualEnableComponent.hidden);
-  });
-
-  test('WriteProtectEnabledAutoTransitions', async () => {
-    const resolver = new PromiseResolver();
-    await initializeWaitForManualWpEnablePage();
-
-    let callCount = 0;
-    service.writeProtectManuallyEnabled = () => {
-      callCount++;
-      return resolver.promise;
-    };
-    service.triggerHardwareWriteProtectionObserver(true, 0);
-    await flushTasks();
-
-    assertEquals(1, callCount);
-  });
-});
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/wrapup_wait_for_manual_wp_enable_page_test.ts b/chrome/test/data/webui/chromeos/shimless_rma/wrapup_wait_for_manual_wp_enable_page_test.ts
new file mode 100644
index 0000000..f353c63
--- /dev/null
+++ b/chrome/test/data/webui/chromeos/shimless_rma/wrapup_wait_for_manual_wp_enable_page_test.ts
@@ -0,0 +1,80 @@
+// Copyright 2021 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://shimless-rma/shimless_rma.js';
+
+import {PromiseResolver} from 'chrome://resources/ash/common/promise_resolver.js';
+import {strictQuery} from 'chrome://resources/ash/common/typescript_utils/strict_query.js';
+import {assert} from 'chrome://resources/js/assert.js';
+import {FakeShimlessRmaService} from 'chrome://shimless-rma/fake_shimless_rma_service.js';
+import {setShimlessRmaServiceForTesting} from 'chrome://shimless-rma/mojo_interface_provider.js';
+import {ShimlessRma} from 'chrome://shimless-rma/shimless_rma.js';
+import {StateResult} from 'chrome://shimless-rma/shimless_rma.mojom-webui.js';
+import {WrapupWaitForManualWpEnablePage} from 'chrome://shimless-rma/wrapup_wait_for_manual_wp_enable_page.js';
+import {assertEquals, assertFalse} from 'chrome://webui-test/chromeos/chai_assert.js';
+import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
+
+suite('wrapupWaitForManualWpEnablePageTest', function() {
+  let component: WrapupWaitForManualWpEnablePage|null = null;
+
+  const service: FakeShimlessRmaService = new FakeShimlessRmaService();
+
+  // ShimlessRma is needed to handle the 'transition-state' event.
+  let shimlessRmaComponent: ShimlessRma|null = null;
+
+  setup(() => {
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    setShimlessRmaServiceForTesting(service);
+  });
+
+  teardown(() => {
+    component?.remove();
+    component = null;
+    shimlessRmaComponent?.remove();
+    shimlessRmaComponent = null;
+    service.reset();
+  });
+
+  function initializeWaitForManualWpEnablePage(): Promise<void> {
+    assert(!shimlessRmaComponent);
+    shimlessRmaComponent = document.createElement(ShimlessRma.is);
+    assert(shimlessRmaComponent);
+    document.body.appendChild(shimlessRmaComponent);
+
+    assert(!component);
+    component = document.createElement(WrapupWaitForManualWpEnablePage.is);
+    assert(component);
+    document.body.appendChild(component);
+
+    return flushTasks();
+  }
+
+  // Verify the component initializes with instructions.
+  test('WaitForManualWpEnablePageInitializes', async () => {
+    await initializeWaitForManualWpEnablePage();
+
+    assert(component);
+    assertFalse(strictQuery(
+                    '#manuallyEnableHwwpInstructions', component.shadowRoot,
+                    HTMLElement)
+                    .hidden);
+  });
+
+  // Verify the page auto transitions if WP is detected as enabled.
+  test('WriteProtectEnabledAutoTransitions', async () => {
+    await initializeWaitForManualWpEnablePage();
+
+    const resolver = new PromiseResolver<{stateResult: StateResult}>();
+    let callCount = 0;
+    service.writeProtectManuallyEnabled = () => {
+      ++callCount;
+      return resolver.promise;
+    };
+
+    service.triggerHardwareWriteProtectionObserver(
+        /* enabled= */ true, /* delayMs= */ 0);
+    await flushTasks();
+    assertEquals(1, callCount);
+  });
+});
diff --git a/chrome/test/data/webui/settings/sync_account_control_test.ts b/chrome/test/data/webui/settings/sync_account_control_test.ts
index c0a8b532..e1f5bb2 100644
--- a/chrome/test/data/webui/settings/sync_account_control_test.ts
+++ b/chrome/test/data/webui/settings/sync_account_control_test.ts
@@ -5,8 +5,9 @@
 // clang-format off
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 // <if expr="not chromeos_ash">
-import type {CrActionMenuElement} from 'chrome://settings/settings.js';
+import type {CrActionMenuElement, StoredAccount} from 'chrome://settings/settings.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
+import {assertNotEquals} from 'chrome://webui-test/chai_assert.js';
 // </if>
 
 import type {SettingsSyncAccountControlElement} from 'chrome://settings/settings.js';
@@ -619,4 +620,55 @@
     flush();
     assertTrue(testElement.$.signIn.disabled);
   });
+
+  // <if expr="not chromeos_ash">
+  test('signinPaused effects', function() {
+    // <if expr="chromeos_lacros">
+    // For Lacros, force the page to be loaded as if it was a secondary user so
+    // that it is similar to other platforms. E.g. the drowdown menu would not
+    // show on lacros main user.
+    loadTimeData.overrideValues({isSecondaryUser: true});
+    // </if>
+
+    const signedInAccount: StoredAccount = {
+      fullName: 'fooName',
+      givenName: 'foo',
+      email: 'foo@foo.com',
+      isPrimaryAccount: true,
+    };
+    // Set primary account.
+    simulateStoredAccounts([signedInAccount]);
+
+    // Signed in but not syncing.
+    testElement.syncStatus = {
+      statusAction: StatusAction.NO_ACTION,
+      signedIn: false,
+      signinPaused: false,
+    };
+
+    assertTrue(isChildVisible(testElement, '#avatar-row'));
+    const userInfo =
+        testElement.shadowRoot!.querySelector<HTMLElement>('#user-info')!;
+    const secondaryContentSignedIn = userInfo.children[1]!.textContent!;
+    assertNotEquals(secondaryContentSignedIn.trim(), signedInAccount.email);
+    assertFalse(isChildVisible(testElement, '#signin-paused-buttons'));
+    assertTrue(isChildVisible(testElement, '#dropdown-arrow'));
+    assertTrue(isChildVisible(testElement, '#sync-button'));
+
+    // Set Signed in Paused state.
+    testElement.syncStatus = {
+      statusAction: StatusAction.NO_ACTION,
+      signedIn: false,
+      signinPaused: true,
+    };
+
+    assertTrue(isChildVisible(testElement, '#avatar-row'));
+    const secondaryContentSigninPaused = userInfo.children[1]!.textContent!;
+    assertNotEquals(secondaryContentSignedIn, secondaryContentSigninPaused);
+    assertEquals(secondaryContentSigninPaused.trim(), signedInAccount.email);
+    assertTrue(isChildVisible(testElement, '#signin-paused-buttons'));
+    assertFalse(isChildVisible(testElement, '#dropdown-arrow'));
+    assertFalse(isChildVisible(testElement, '#sync-button'));
+  });
+  // </if>
 });
diff --git a/chrome/test/data/webui/side_panel/read_anything/app_receives_toolbar_changes_test.ts b/chrome/test/data/webui/side_panel/read_anything/app_receives_toolbar_changes_test.ts
index c3d45a52..ee1458d9 100644
--- a/chrome/test/data/webui/side_panel/read_anything/app_receives_toolbar_changes_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/app_receives_toolbar_changes_test.ts
@@ -321,13 +321,13 @@
       });
 
       test('first press plays', () => {
-        app.$.appFlexParent!.dispatchEvent(kPress);
+        app.$.flexParent!.dispatchEvent(kPress);
         assertFalse(app.speechPlayingState.paused);
       });
 
       test('second press pauses', () => {
-        app.$.appFlexParent!.dispatchEvent(kPress);
-        app.$.appFlexParent!.dispatchEvent(kPress);
+        app.$.flexParent!.dispatchEvent(kPress);
+        app.$.flexParent!.dispatchEvent(kPress);
         assertTrue(app.speechPlayingState.paused);
       });
     });
diff --git a/chrome/test/data/webui/side_panel/read_anything/connected_callback_show_loading_screen.js b/chrome/test/data/webui/side_panel/read_anything/connected_callback_show_loading_screen.js
index f0f49fe..2a61f5e 100644
--- a/chrome/test/data/webui/side_panel/read_anything/connected_callback_show_loading_screen.js
+++ b/chrome/test/data/webui/side_panel/read_anything/connected_callback_show_loading_screen.js
@@ -11,7 +11,8 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
   const emptyState = readAnythingApp.querySelector('sp-empty-state');
   let result = true;
 
@@ -37,7 +38,8 @@
     return contains;
   };
 
-  assertEquals(document.getElementById('empty-state-container').hidden, false);
+  assertEquals(
+      readAnythingApp.getElementById('empty-state-container').hidden, false);
   assertEquals(emptyState.heading, 'Getting ready');
   assertEquals(emptyState.body, '');
   assertStringContains(emptyState.imagePath, 'throbber');
diff --git a/chrome/test/data/webui/side_panel/read_anything/connected_callback_test.ts b/chrome/test/data/webui/side_panel/read_anything/connected_callback_test.ts
index 43ac911e..de1a4a3 100644
--- a/chrome/test/data/webui/side_panel/read_anything/connected_callback_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/connected_callback_test.ts
@@ -30,9 +30,10 @@
 
   test('shows loading page', () => {
     assertEquals(
-        app.querySelector<HTMLElement>('#empty-state-container')!.hidden,
+        app.shadowRoot!.querySelector<HTMLElement>(
+                           '#empty-state-container')!.hidden,
         false);
-    const emptyState = app.querySelector('sp-empty-state')!;
+    const emptyState = app.shadowRoot!.querySelector('sp-empty-state')!;
     assertEquals(emptyState.heading, 'Getting ready');
     assertEquals(emptyState.body, '');
     assertStringContains(emptyState.imagePath, 'throbber');
diff --git a/chrome/test/data/webui/side_panel/read_anything/e2e_test_executor.js b/chrome/test/data/webui/side_panel/read_anything/e2e_test_executor.js
index 28844029..929d7ea 100644
--- a/chrome/test/data/webui/side_panel/read_anything/e2e_test_executor.js
+++ b/chrome/test/data/webui/side_panel/read_anything/e2e_test_executor.js
@@ -23,8 +23,8 @@
     }
   }
 
-  const container =
-      document.querySelector('read-anything-app')?.querySelector('#container');
+  const container = document.querySelector('read-anything-app')
+                        ?.shadowRoot?.querySelector('#container');
   assert(container);
   prune(container);
 
diff --git a/chrome/test/data/webui/side_panel/read_anything/on_selection_change_nothing_selected_on_loading_screen_selection.js b/chrome/test/data/webui/side_panel/read_anything/on_selection_change_nothing_selected_on_loading_screen_selection.js
index cd0c111..c128240 100644
--- a/chrome/test/data/webui/side_panel/read_anything/on_selection_change_nothing_selected_on_loading_screen_selection.js
+++ b/chrome/test/data/webui/side_panel/read_anything/on_selection_change_nothing_selected_on_loading_screen_selection.js
@@ -12,7 +12,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const emptyState = document.getElementById('empty-state-container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const emptyState = readAnythingApp.getElementById('empty-state-container');
 
   let result = true;
   const assertEquals = (actual, expected) => {
@@ -30,14 +32,19 @@
   const range = new Range();
   range.setStartBefore(emptyState);
   range.setEndAfter(emptyState);
-  const selection = document.getSelection();
+  const selection = readAnythingApp.getSelection();
   selection.removeAllRanges();
   selection.addRange(range);
 
   return new Promise(resolve => {
-    setTimeout(async () => {
-      const retrieved_selection = document.getSelection();
-      assertEquals(retrieved_selection.toString(), '');
+    setTimeout(() => {
+      const retrieved_selection = readAnythingApp.getSelection();
+      assertEquals(retrieved_selection.rangeCount, 0);
+      assertEquals(retrieved_selection.anchorNode, null);
+      assertEquals(retrieved_selection.focusNode, null);
+      assertEquals(retrieved_selection.anchorOffset, 0);
+      assertEquals(retrieved_selection.anchorOffset, 0);
+      assertEquals(retrieved_selection.focusOffset, 0);
       resolve(result);
     }, 1000);
   });
diff --git a/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection.ts b/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection.ts
index b9de641..ddfb2a7 100644
--- a/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection.ts
@@ -6,7 +6,7 @@
 import {BrowserProxy} from '//resources/cr_components/color_change_listener/browser_proxy.js';
 import type {ReadAnythingElement} from 'chrome-untrusted://read-anything-side-panel.top-chrome/app.js';
 import {PauseActionSource} from 'chrome-untrusted://read-anything-side-panel.top-chrome/app.js';
-import {assertEquals, assertFalse, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js';
+import {assertEquals, assertFalse, assertNull, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js';
 
 import {suppressInnocuousErrors} from './common.js';
 import {TestColorUpdaterBrowserProxy} from './test_color_updater_browser_proxy.js';
@@ -109,10 +109,10 @@
     test('selection in reading mode panel correct', () => {
       // Calling shadowRoot.getSelection directly is not supported in TS tests,
       // so use a helper to get the selection from the app instead.
-      const selection = document.getSelection()!;
+      const selection = app.getSelection();
       assertTrue(selection != null);
-      assertEquals(selection.anchorNode!.textContent, 'World');
-      assertEquals(selection.focusNode!.textContent, 'Friend');
+      assertEquals(selection.anchorNode.textContent, 'World');
+      assertEquals(selection.focusNode.textContent, 'Friend');
       assertEquals(selection.anchorOffset, 1);
       assertEquals(selection.focusOffset, 2);
     });
@@ -145,8 +145,13 @@
     });
 
     test('selection in reading model panel cleared', () => {
-      const selection = document.getSelection()!;
-      assertEquals(selection.toString(), '');
+      // Calling shadowRoot.getSelection directly is not supported in TS tests,
+      // so use a helper to get the selection from the app instead.
+      const selection = app.getSelection();
+      assertNull(selection.anchorNode);
+      assertNull(selection.focusNode);
+      assertEquals(selection.anchorOffset, 0);
+      assertEquals(selection.focusOffset, 0);
     });
 
 
@@ -181,15 +186,15 @@
     test('selection in reading mode container correct', () => {
       // Calling shadowRoot.getSelection directly is not supported in TS tests,
       // so use a helper to get the selection from the app instead.
-      const selection = document.getSelection()!;
+      const selection = app.getSelection();
       assertTrue(selection != null);
 
       // TODO(b/327519645): Playing Read Aloud slightly adjusts what's
       // selected. This happened before disabling selection when Read Aloud
       // was playing, but adding tests for disabled selection makes this bug
       // more apparent.
-      assertEquals(selection.anchorNode!.textContent, 'World');
-      assertEquals(selection.focusNode!.textContent, 'Friend!');
+      assertEquals(selection.anchorNode.textContent, 'World');
+      assertEquals(selection.focusNode.textContent, 'Friend!');
       assertEquals(selection.anchorOffset, 0);
       assertEquals(selection.focusOffset, 0);
     });
diff --git a/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection_pdf.ts b/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection_pdf.ts
index 18e2fb2..c14c5236 100644
--- a/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection_pdf.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/read_aloud_update_content_selection_pdf.ts
@@ -6,7 +6,7 @@
 import {BrowserProxy} from '//resources/cr_components/color_change_listener/browser_proxy.js';
 import type {ReadAnythingElement} from 'chrome-untrusted://read-anything-side-panel.top-chrome/app.js';
 import {PauseActionSource} from 'chrome-untrusted://read-anything-side-panel.top-chrome/app.js';
-import {assertEquals, assertFalse, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js';
+import {assertEquals, assertFalse, assertNull, assertTrue} from 'chrome-untrusted://webui-test/chai_assert.js';
 
 import {suppressInnocuousErrors} from './common.js';
 import {TestColorUpdaterBrowserProxy} from './test_color_updater_browser_proxy.js';
@@ -112,10 +112,10 @@
     test('selection in reading mode panel correct', () => {
       // Calling shadowRoot.getSelection directly is not supported in TS tests,
       // so use a helper to get the selection from the app instead.
-      const selection = document.getSelection()!;
+      const selection = app.getSelection();
       assertTrue(selection != null);
-      assertEquals(selection.anchorNode!.textContent, 'World');
-      assertEquals(selection.focusNode!.textContent, 'Friend');
+      assertEquals(selection.anchorNode.textContent, 'World');
+      assertEquals(selection.focusNode.textContent, 'Friend');
       assertEquals(selection.anchorOffset, 1);
       assertEquals(selection.focusOffset, 2);
     });
@@ -148,8 +148,13 @@
     });
 
     test('selection in reading model panel cleared', () => {
-      const selection = document.getSelection()!;
-      assertEquals(selection.toString(), '');
+      // Calling shadowRoot.getSelection directly is not supported in TS tests,
+      // so use a helper to get the selection from the app instead.
+      const selection = app.getSelection();
+      assertNull(selection.anchorNode);
+      assertNull(selection.focusNode);
+      assertEquals(selection.anchorOffset, 0);
+      assertEquals(selection.focusOffset, 0);
     });
 
 
@@ -184,15 +189,15 @@
     test('selection in reading mode container correct', () => {
       // Calling shadowRoot.getSelection directly is not supported in TS tests,
       // so use a helper to get the selection from the app instead.
-      const selection = document.getSelection()!;
+      const selection = app.getSelection();
       assertTrue(selection != null);
 
       // TODO(b/327519645): Playing Read Aloud slightly adjusts what's
       // selected. This happened before disabling selection when Read Aloud
       // was playing, but adding tests for disabled selection makes this bug
       // more apparent.
-      assertEquals(selection.anchorNode!.textContent, 'World');
-      assertEquals(selection.focusNode!.textContent, 'Friend!');
+      assertEquals(selection.anchorNode.textContent, 'World');
+      assertEquals(selection.focusNode.textContent, 'Friend!');
       assertEquals(selection.anchorOffset, 0);
       assertEquals(selection.focusOffset, 0);
     });
diff --git a/chrome/test/data/webui/side_panel/read_anything/toolbar_flag_test.ts b/chrome/test/data/webui/side_panel/read_anything/toolbar_flag_test.ts
index 66dc1f4..cd424c6 100644
--- a/chrome/test/data/webui/side_panel/read_anything/toolbar_flag_test.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/toolbar_flag_test.ts
@@ -33,7 +33,8 @@
     chrome.readingMode.isWebUIToolbarVisible = true;
     createApp();
 
-    const container = app.querySelector<HTMLElement>('#toolbar-container');
+    const container =
+        app.shadowRoot!.querySelector<HTMLElement>('#toolbar-container');
 
     assertTrue(!!container);
     assertFalse(container.hidden);
@@ -43,7 +44,8 @@
     chrome.readingMode.isWebUIToolbarVisible = false;
     createApp();
 
-    const container = app.querySelector<HTMLElement>('#toolbar-container');
+    const container =
+        app.shadowRoot!.querySelector<HTMLElement>('#toolbar-container');
 
     assertTrue(!!container);
     assertTrue(container.hidden);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_all_headings.js b/chrome/test/data/webui/side_panel/read_anything/update_content_all_headings.js
index 8501237..7560a32 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_all_headings.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_all_headings.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_clear_container.js b/chrome/test/data/webui/side_panel/read_anything/update_content_clear_container.js
index e5003644..f346ab3 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_clear_container.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_clear_container.js
@@ -13,8 +13,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_heading.js b/chrome/test/data/webui/side_panel/read_anything/update_content_heading.js
index 65b0c7a..cdec0168 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_heading.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_heading.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_hides_loading_screen.js b/chrome/test/data/webui/side_panel/read_anything/update_content_hides_loading_screen.js
index c5142f6..76968b2 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_hides_loading_screen.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_hides_loading_screen.js
@@ -11,7 +11,8 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
   let result = true;
 
   const assertEquals = (actual, expected) => {
@@ -52,7 +53,8 @@
   };
   chrome.readingMode.setContentForTesting(axTree, [2]);
 
-  assertEquals(document.getElementById('empty-state-container').hidden, true);
+  assertEquals(
+      readAnythingApp.getElementById('empty-state-container').hidden, true);
 
   return result;
 })();
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_interactive_element.js b/chrome/test/data/webui/side_panel/read_anything/update_content_interactive_element.js
index ca5d3a4f..6f4ade6 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_interactive_element.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_interactive_element.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_language_child_node_diff_lang.js b/chrome/test/data/webui/side_panel/read_anything/update_content_language_child_node_diff_lang.js
index 3c6ea27..ab7fea921 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_language_child_node_diff_lang.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_language_child_node_diff_lang.js
@@ -12,8 +12,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_language_parent_lang_set.js b/chrome/test/data/webui/side_panel/read_anything/update_content_language_parent_lang_set.js
index 1c9981e..8aa8651 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_language_parent_lang_set.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_language_parent_lang_set.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_link.js b/chrome/test/data/webui/side_panel/read_anything/update_content_link.js
index 1a60b21a..761db336 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_link.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_link.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_link_bad_input.js b/chrome/test/data/webui/side_panel/read_anything/update_content_link_bad_input.js
index 899819c9..c466ee3bc 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_link_bad_input.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_link_bad_input.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_no_content_nodes.js b/chrome/test/data/webui/side_panel/read_anything/update_content_no_content_nodes.js
index cfb65a56..5dba870 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_no_content_nodes.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_no_content_nodes.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_paragraph.js b/chrome/test/data/webui/side_panel/read_anything/update_content_paragraph.js
index 06aa2ca..7768c00 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_paragraph.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_paragraph.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_selection.ts b/chrome/test/data/webui/side_panel/read_anything/update_content_selection.ts
index e2b47975..525e520f 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_selection.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_selection.ts
@@ -102,6 +102,8 @@
     });
 
     test('CorrectContentSelected', () => {
+      // Calling shadowRoot.getSelection directly is not supported in TS tests,
+      // so use a helper to get the selection from the app instead.
       const selection = app.getSelection();
       assertEquals(selection.anchorNode.textContent, 'World');
       assertEquals(selection.focusNode.textContent, 'Friend');
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_backwards.js b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_backwards.js
index 85f23f6..e561d1c 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_backwards.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_backwards.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
@@ -124,7 +125,7 @@
   // selection.
   const expected = '<div><p>Hello</p><p>World</p><p>Friend!</p></div>';
   assertContainerInnerHTML(expected);
-  const selection = document.getSelection();
+  const selection = readAnythingApp.getSelection();
   assertEquals(selection.anchorNode.textContent, 'Hello');
   assertEquals(selection.focusNode.textContent, 'Friend');
   assertEquals(selection.anchorOffset, 1);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_backwards_with_inline_text.js b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_backwards_with_inline_text.js
index 0f45141..b6dbfc3 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_backwards_with_inline_text.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_backwards_with_inline_text.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
@@ -120,7 +121,7 @@
   // selection.
   const expected = '<div><p>World<a>Friend</a></p></div>';
   assertContainerInnerHTML(expected);
-  const selection = document.getSelection();
+  const selection = readAnythingApp.getSelection();
   assertEquals(selection.anchorNode.textContent, 'Friend');
   assertEquals(selection.focusNode.textContent, 'Friend');
   assertEquals(selection.anchorOffset, 0);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_outside_distilled_content.js b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_outside_distilled_content.js
index f008ae1..c36f03f9 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_outside_distilled_content.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_outside_distilled_content.js
@@ -12,8 +12,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_partially_outside_distilled_content.js b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_partially_outside_distilled_content.js
index 6777c48..6317f412 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_partially_outside_distilled_content.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_partially_outside_distilled_content.js
@@ -12,8 +12,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_highlights.ts b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_highlights.ts
index b65191e..29f91c7 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_highlights.ts
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_highlights.ts
@@ -120,7 +120,8 @@
 
     // Looks for the node containing the given text inside the given selectors
     function getTextNode(selector: string, text: string): Node {
-      const nodesToCheck = Array.from(app.querySelectorAll(selector));
+      const nodesToCheck =
+          Array.from(app.shadowRoot!.querySelectorAll(selector));
       const parentNodeWithText =
           nodesToCheck.find((element) => element.textContent!.includes(text));
       return parentNodeWithText!.firstChild!;
@@ -288,7 +289,7 @@
 
       // select node starting after the end of the highlight
       const selectedText = texts[2]!.slice(highlightEnd);
-      const nodesToCheck = Array.from(app.querySelectorAll('span'));
+      const nodesToCheck = Array.from(app.shadowRoot!.querySelectorAll('span'));
       const parentNodeWithText = nodesToCheck.find(
           (element) => element.textContent!.includes(selectedText));
       const textNode = parentNodeWithText!.lastChild!;
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_inline_text.js b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_inline_text.js
index 328786e..7472c49 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_inline_text.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_selection_with_inline_text.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
@@ -119,7 +120,7 @@
   // selection.
   const expected = '<div><p>World<a>Friend</a></p></div>';
   assertContainerInnerHTML(expected);
-  const selection = document.getSelection();
+  const selection = readAnythingApp.getSelection();
   assertEquals(selection.anchorNode.textContent, 'Friend');
   assertEquals(selection.focusNode.textContent, 'Friend');
   assertEquals(selection.anchorOffset, 0);
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_set_selected_text.js b/chrome/test/data/webui/side_panel/read_anything/update_content_set_selected_text.js
index b210bfa..ef5f411 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_set_selected_text.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_set_selected_text.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
@@ -113,7 +114,7 @@
   const range = new Range();
   range.setStart(outerDiv.firstChild, 1);
   range.setEnd(outerDiv.lastChild, 2);
-  const selection = document.getSelection();
+  const selection = readAnythingApp.getSelection();
   selection.removeAllRanges();
   selection.addRange(range);
 
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_static_text.js b/chrome/test/data/webui/side_panel/read_anything/update_content_static_text.js
index eb46862..6fea34f 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_static_text.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_static_text.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_static_text_bad_input.js b/chrome/test/data/webui/side_panel/read_anything/update_content_static_text_bad_input.js
index 67e401c7..3f1feec6 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_static_text_bad_input.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_static_text_bad_input.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction.js b/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction.js
index 15ac4bc..83d5afa 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction_parent_node_diff_dir.js b/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction_parent_node_diff_dir.js
index 8fd99522..7f6cf6e8 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction_parent_node_diff_dir.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction_parent_node_diff_dir.js
@@ -12,8 +12,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction_vertical_dir.js b/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction_vertical_dir.js
index 2b7f082..2c10709 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction_vertical_dir.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_text_direction_vertical_dir.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_text_style_bold.js b/chrome/test/data/webui/side_panel/read_anything/update_content_text_style_bold.js
index d1ed785..cc34b58 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_text_style_bold.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_text_style_bold.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_content_text_style_overline.js b/chrome/test/data/webui/side_panel/read_anything/update_content_text_style_overline.js
index c1ea9a1..245c433e 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_content_text_style_overline.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_content_text_style_overline.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_background_color.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_background_color.js
index 793743c..73c0e4c 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_theme_background_color.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_theme_background_color.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
 
   chrome.readingMode.setThemeForTesting(
       'f', 1, true, 0, /* SkColorSetRGB(0xFD, 0xE2, 0x93) = */ 4294828691, 1,
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_font_name.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_font_name.js
index de51467..88abc27 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_theme_font_name.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_theme_font_name.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
   let result = true;
 
   const assertEquals = (actual, expected) => {
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_font_size.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_font_size.js
index f22df16..9cc27d1 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_theme_font_size.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_theme_font_size.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
 
   chrome.readingMode.setThemeForTesting('Poppins', 1.0, true, 0, 0, 1, 0);
   const expected = '16px';  // 1em = 16px
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_foreground_color.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_foreground_color.js
index df1a820..6474f649 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_theme_foreground_color.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_theme_foreground_color.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
 
   chrome.readingMode.setThemeForTesting(
       'f', 1, true, /* SkColorSetRGB(0x33, 0x36, 0x39) = */ 4281546297, 0, 1,
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_letter_spacing.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_letter_spacing.js
index 2b653b0..32e5d29 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_theme_letter_spacing.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_theme_letter_spacing.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
 
   chrome.readingMode.setThemeForTesting('f', 1, true, 0, 0, 1, 3);
   // Very loose letter letter spacing = 0.1em, font size = 1em = 16px
diff --git a/chrome/test/data/webui/side_panel/read_anything/update_theme_line_spacing.js b/chrome/test/data/webui/side_panel/read_anything/update_theme_line_spacing.js
index b8af076..3f84b910 100644
--- a/chrome/test/data/webui/side_panel/read_anything/update_theme_line_spacing.js
+++ b/chrome/test/data/webui/side_panel/read_anything/update_theme_line_spacing.js
@@ -11,8 +11,9 @@
 (() => {
   chrome.readingMode.onConnected = () => {};
 
-  const readAnythingApp = document.querySelector('read-anything-app');
-  const container = document.getElementById('container');
+  const readAnythingApp =
+      document.querySelector('read-anything-app').shadowRoot;
+  const container = readAnythingApp.getElementById('container');
 
   chrome.readingMode.setThemeForTesting('Poppins', 1.0, true, 0, 0, 2, 0);
   const expected = '24px';  // 1.5 times the 1em (16px) font size
diff --git a/chrome/updater/app/app_recover.cc b/chrome/updater/app/app_recover.cc
index 7c87a19e..ca8c441 100644
--- a/chrome/updater/app/app_recover.cc
+++ b/chrome/updater/app/app_recover.cc
@@ -137,9 +137,6 @@
   int exit_code = -1;
   base::CommandLine uninstall_command(setup_path);
   uninstall_command.AppendSwitch(kUninstallSwitch);
-  uninstall_command.AppendSwitch(kEnableLoggingSwitch);
-  uninstall_command.AppendSwitchASCII(kLoggingModuleSwitch,
-                                      kLoggingModuleSwitchValue);
   if (IsSystemInstall(updater_scope())) {
     uninstall_command.AppendSwitch(kSystemSwitch);
   }
@@ -154,9 +151,6 @@
   base::CommandLine install_command(setup_path);
   install_command.AppendSwitch(kInstallSwitch);
   install_command.AppendSwitch(kSilentSwitch);
-  install_command.AppendSwitch(kEnableLoggingSwitch);
-  install_command.AppendSwitchASCII(kLoggingModuleSwitch,
-                                    kLoggingModuleSwitchValue);
   if (IsSystemInstall(updater_scope())) {
     install_command.AppendSwitch(kSystemSwitch);
   }
diff --git a/chrome/updater/app/app_server.cc b/chrome/updater/app/app_server.cc
index 4aa8514a..1efcb19 100644
--- a/chrome/updater/app/app_server.cc
+++ b/chrome/updater/app/app_server.cc
@@ -199,9 +199,6 @@
       if (IsSystemInstall(updater_scope())) {
         command_line.AppendSwitch(kSystemSwitch);
       }
-      command_line.AppendSwitch(kEnableLoggingSwitch);
-      command_line.AppendSwitchASCII(kLoggingModuleSwitch,
-                                     kLoggingModuleSwitchValue);
       VLOG(2) << "Launching uninstall command: "
               << command_line.GetCommandLineString();
 
diff --git a/chrome/updater/app/app_server_win.cc b/chrome/updater/app/app_server_win.cc
index 46b28ce..c49d669 100644
--- a/chrome/updater/app/app_server_win.cc
+++ b/chrome/updater/app/app_server_win.cc
@@ -160,9 +160,6 @@
         if (IsSystemInstall(scope)) {
           uninstall_if_unused_command.AppendSwitch(kSystemSwitch);
         }
-        uninstall_if_unused_command.AppendSwitch(kEnableLoggingSwitch);
-        uninstall_if_unused_command.AppendSwitchASCII(
-            kLoggingModuleSwitch, kLoggingModuleSwitchValue);
         return uninstall_if_unused_command.GetCommandLineString();
       }(),
       true);
diff --git a/chrome/updater/app/app_uninstall.cc b/chrome/updater/app/app_uninstall.cc
index bdfdb25..cce17a9f 100644
--- a/chrome/updater/app/app_uninstall.cc
+++ b/chrome/updater/app/app_uninstall.cc
@@ -92,9 +92,6 @@
   if (IsSystemInstall(scope)) {
     command_line.AppendSwitch(kSystemSwitch);
   }
-  command_line.AppendSwitch(kEnableLoggingSwitch);
-  command_line.AppendSwitchASCII(kLoggingModuleSwitch,
-                                 kLoggingModuleSwitchValue);
   return command_line;
 }
 
diff --git a/chrome/updater/app/app_wakeall.cc b/chrome/updater/app/app_wakeall.cc
index f773218..5be53de 100644
--- a/chrome/updater/app/app_wakeall.cc
+++ b/chrome/updater/app/app_wakeall.cc
@@ -61,9 +61,6 @@
                   if (IsSystemInstall(scope)) {
                     command.AppendSwitch(kSystemSwitch);
                   }
-                  command.AppendSwitch(kEnableLoggingSwitch);
-                  command.AppendSwitchASCII(kLoggingModuleSwitch,
-                                            kLoggingModuleSwitchValue);
                   VLOG(1) << "Launching `" << command.GetCommandLineString()
                           << "`";
                   int exit = 0;
diff --git a/chrome/updater/app/server/win/service_main.cc b/chrome/updater/app/server/win/service_main.cc
index c92dc4e..2688ad5f 100644
--- a/chrome/updater/app/server/win/service_main.cc
+++ b/chrome/updater/app/server/win/service_main.cc
@@ -36,9 +36,6 @@
       base::CommandLine::ForCurrentProcess()->GetProgram());
   run_updater_wake_command.AppendSwitch(kWakeSwitch);
   run_updater_wake_command.AppendSwitch(kSystemSwitch);
-  run_updater_wake_command.AppendSwitch(kEnableLoggingSwitch);
-  run_updater_wake_command.AppendSwitchASCII(kLoggingModuleSwitch,
-                                             kLoggingModuleSwitchValue);
   VLOG(2) << "Launching Wake command: "
           << run_updater_wake_command.GetCommandLineString();
 
diff --git a/chrome/updater/crash_reporter.cc b/chrome/updater/crash_reporter.cc
index bb001fa06..e41cbd1c 100644
--- a/chrome/updater/crash_reporter.cc
+++ b/chrome/updater/crash_reporter.cc
@@ -44,9 +44,6 @@
 std::vector<std::string> MakeCrashHandlerArgs(UpdaterScope updater_scope) {
   base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
   command_line.AppendSwitch(kCrashHandlerSwitch);
-  command_line.AppendSwitch(kEnableLoggingSwitch);
-  command_line.AppendSwitchASCII(kLoggingModuleSwitch,
-                                 kLoggingModuleSwitchValue);
   if (IsSystemInstall(updater_scope)) {
     command_line.AppendSwitch(kSystemSwitch);
   }
diff --git a/chrome/updater/ipc/update_service_dialer_linux.cc b/chrome/updater/ipc/update_service_dialer_linux.cc
index 8dd0f977..dff56f3 100644
--- a/chrome/updater/ipc/update_service_dialer_linux.cc
+++ b/chrome/updater/ipc/update_service_dialer_linux.cc
@@ -59,8 +59,6 @@
     if (scope == UpdaterScope::kSystem) {
       command.AppendSwitch(kSystemSwitch);
     }
-    command.AppendSwitch(kEnableLoggingSwitch);
-    command.AppendSwitchASCII(kLoggingModuleSwitch, kLoggingModuleSwitchValue);
     base::LaunchProcess(command, {});
   }
   return true;
diff --git a/chrome/updater/linux/systemd_util.cc b/chrome/updater/linux/systemd_util.cc
index acb2a99..1ca225aa 100644
--- a/chrome/updater/linux/systemd_util.cc
+++ b/chrome/updater/linux/systemd_util.cc
@@ -153,9 +153,6 @@
   if (scope == UpdaterScope::kSystem) {
     command.AppendSwitch(kSystemSwitch);
   }
-  command.AppendSwitch(kEnableLoggingSwitch);
-  command.AppendSwitchASCII(kLoggingModuleSwitch, kLoggingModuleSwitchValue);
-
   return command.GetCommandLineString();
 }
 
diff --git a/chrome/updater/mac/keystone/agent_main.cc b/chrome/updater/mac/keystone/agent_main.cc
index 5362f113..197d637 100644
--- a/chrome/updater/mac/keystone/agent_main.cc
+++ b/chrome/updater/mac/keystone/agent_main.cc
@@ -197,8 +197,6 @@
     if (scope == UpdaterScope::kSystem) {
       command.AppendSwitch(kSystemSwitch);
     }
-    command.AppendSwitch(kEnableLoggingSwitch);
-    command.AppendSwitchNative(kLoggingModuleSwitch, kLoggingModuleSwitchValue);
     VLOG(0) << "Launching " << command.GetCommandLineString();
     base::Process process = base::LaunchProcess(command, {});
     if (process.IsValid()) {
diff --git a/chrome/updater/mac/keystone/ksadmin.mm b/chrome/updater/mac/keystone/ksadmin.mm
index 4e11208..f2dd230 100644
--- a/chrome/updater/mac/keystone/ksadmin.mm
+++ b/chrome/updater/mac/keystone/ksadmin.mm
@@ -217,9 +217,6 @@
 
   base::CommandLine install_command(setup_path.value());
   install_command.AppendSwitch(kInstallSwitch);
-  install_command.AppendSwitch(kEnableLoggingSwitch);
-  install_command.AppendSwitchASCII(kLoggingModuleSwitch,
-                                    kLoggingModuleSwitchValue);
   if (IsSystemInstall(scope)) {
     install_command.AppendSwitch(kSystemSwitch);
   }
diff --git a/chrome/updater/mac/keystone/ksadmin_unittest.cc b/chrome/updater/mac/keystone/ksadmin_unittest.cc
index 763f329..a3d21b10 100644
--- a/chrome/updater/mac/keystone/ksadmin_unittest.cc
+++ b/chrome/updater/mac/keystone/ksadmin_unittest.cc
@@ -216,8 +216,7 @@
             RunKSAdmin(&out, {"--register", "--version", "1.2.3.4", "--xcpath",
                               "/xc_path", "--tag-key", "tag_key", "--tag-path",
                               "tag_path", "--version-key", "version_key",
-                              "--version-path", "version_path",
-                              "--enable-logging", "--vmodule", "*=2", "-P",
+                              "--version-path", "version_path", "-P",
                               "org.chromium.KSAdminTest.Register"}),
             0);
       }),
diff --git a/chrome/updater/mac/launcher_main.c b/chrome/updater/mac/launcher_main.c
index 31f81f7..d67107e 100644
--- a/chrome/updater/mac/launcher_main.c
+++ b/chrome/updater/mac/launcher_main.c
@@ -530,8 +530,6 @@
       (char*)kExecutableName,  // posix_spawn will not overwrite the argv.
       is_qualifying ? "--test" : "--server",
       is_internal ? "--service=update-internal" : "--service=update",
-      "--enable-logging",
-      "--vmodule=*/components/update_client/*=2,*/chrome/updater/*=2",
       is_system ? "--system" : NULL,
       NULL};
   static char* const env[] = {"PWD=/", "PATH=/usr/bin:/bin:/usr/sbin:/sbin",
diff --git a/chrome/updater/mac/privileged_helper/service.mm b/chrome/updater/mac/privileged_helper/service.mm
index 49eb0f4..55a61542 100644
--- a/chrome/updater/mac/privileged_helper/service.mm
+++ b/chrome/updater/mac/privileged_helper/service.mm
@@ -229,8 +229,6 @@
   ksadmin_command.AppendArg("--xcpath");
   ksadmin_command.AppendArgPath(browser_path);
   ksadmin_command.AppendArg("--system-store");
-  ksadmin_command.AppendSwitch(
-      base::StrCat({kLoggingModuleSwitch, kLoggingModuleSwitchValue}));
   if (!base::GetAppOutputWithExitCode(ksadmin_command, &output, &exit_code)) {
     return kFailedToRegister;
   }
diff --git a/chrome/updater/mac/setup/wake_task.mm b/chrome/updater/mac/setup/wake_task.mm
index 3cbdcf3..261f441 100644
--- a/chrome/updater/mac/setup/wake_task.mm
+++ b/chrome/updater/mac/setup/wake_task.mm
@@ -57,6 +57,10 @@
   }
 
   // See the man page for launchd.plist.
+  // Explicitly logging switches are no longer necessary but are not removed
+  // because updating the plist file could cause a popup on newer macOS. We
+  // can remove the logging switches the next time when we have to change the
+  // plist file.
   NSMutableArray<NSString*>* program_arguments =
       [NSMutableArray<NSString*> array];
   [program_arguments addObjectsFromArray:@[
diff --git a/chrome/updater/mac/signing/postinstall.in b/chrome/updater/mac/signing/postinstall.in
index 9ef3b977..6e58f0c 100755
--- a/chrome/updater/mac/signing/postinstall.in
+++ b/chrome/updater/mac/signing/postinstall.in
@@ -17,7 +17,7 @@
 else readonly SYSTEM="--system"
 fi
 
-"${2}/@PRODUCT_FULLNAME@.app/Contents/MacOS/@PRODUCT_FULLNAME@" "--install" "$SYSTEM" "--enable-logging" "--vmodule=*/updater/*=2"
+"${2}/@PRODUCT_FULLNAME@.app/Contents/MacOS/@PRODUCT_FULLNAME@" "--install" "$SYSTEM"
 
 # We don't need the .app in /tmp anymore.
 rm -rf "${2}/@PRODUCT_FULLNAME@.app"
diff --git a/chrome/updater/test/integration_tests_impl.cc b/chrome/updater/test/integration_tests_impl.cc
index a340baf4..545cd1e 100644
--- a/chrome/updater/test/integration_tests_impl.cc
+++ b/chrome/updater/test/integration_tests_impl.cc
@@ -955,9 +955,6 @@
 
 void Run(UpdaterScope scope, base::CommandLine command_line, int* exit_code) {
   base::ScopedAllowBaseSyncPrimitivesForTesting allow_wait_process;
-  command_line.AppendSwitch(kEnableLoggingSwitch);
-  command_line.AppendSwitchASCII(kLoggingModuleSwitch,
-                                 kLoggingModuleSwitchValue);
   if (IsSystemInstall(scope)) {
     command_line.AppendSwitch(kSystemSwitch);
     command_line = MakeElevated(command_line);
@@ -1033,10 +1030,8 @@
       GetUpdateResponse(
           kUpdaterAppId, "", test_server->download_url().spec(),
           base::Version(kUpdaterVersion), crx_path, kSelfUpdateCRXRun,
-          base::StrCat({"--update", IsSystemInstall(scope) ? " --system" : "",
-                        " --", kEnableLoggingSwitch, " --",
-                        kLoggingModuleSwitch, "=",
-                        kLoggingModuleSwitchValue})));
+          base::StrCat(
+              {"--update", IsSystemInstall(scope) ? " --system" : ""})));
 
   // Second request: update download.
   std::string crx_bytes;
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc
index 91770ea..7dd9dbf 100644
--- a/chrome/updater/test/integration_tests_win.cc
+++ b/chrome/updater/test/integration_tests_win.cc
@@ -328,11 +328,7 @@
     ASSERT_EQ(task_info.exec_actions.size(), 1u);
     EXPECT_EQ(
         task_info.exec_actions[0].arguments,
-        base::StrCat({L"--wake ", IsSystemInstall(scope) ? L"--system " : L"",
-                      L"--enable-logging "
-                      L"--vmodule=*/components/winhttp/*=1,"
-                      L"*/components/update_client/*=2,"
-                      L"*/chrome/updater/*=2"}));
+        base::StrCat({L"--wake", IsSystemInstall(scope) ? L" --system" : L""}));
 
     EXPECT_EQ(task_info.trigger_types,
               TaskScheduler::TriggerType::TRIGGER_TYPE_HOURLY |
@@ -406,13 +402,6 @@
     std::vector<std::wstring> install_cmd_args = {
         base::CommandLine::QuoteForCommandLineToArgvW(exe_path.value()),
 
-        build_legacy_switch(updater::kEnableLoggingSwitch),
-
-        // This switch and its value must be connected by '=' because logging
-        // switch does not support legacy format.
-        base::StrCat({build_legacy_switch(updater::kLoggingModuleSwitch), L"=",
-                      base::ASCIIToWide(updater::kLoggingModuleSwitchValue)}),
-
         IsSystemInstall(install_scope)
             ? build_legacy_switch(updater::kSystemSwitch)
             : L"",
@@ -434,10 +423,6 @@
 
   auto launch_offline_install = [&] {
     base::CommandLine install_cmd(exe_path);
-
-    install_cmd.AppendSwitch(kEnableLoggingSwitch);
-    install_cmd.AppendSwitchASCII(kLoggingModuleSwitch,
-                                  kLoggingModuleSwitchValue);
     if (IsSystemInstall(install_scope)) {
       install_cmd.AppendSwitch(kSystemSwitch);
     }
diff --git a/chrome/updater/updater.cc b/chrome/updater/updater.cc
index fbe0d3d..5753d3f 100644
--- a/chrome/updater/updater.cc
+++ b/chrome/updater/updater.cc
@@ -292,6 +292,17 @@
 #endif
 }
 
+void EnableLoggingByDefault() {
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (!command_line->HasSwitch(kEnableLoggingSwitch)) {
+    command_line->AppendSwitch(kEnableLoggingSwitch);
+  }
+  if (!command_line->HasSwitch(kLoggingModuleSwitch)) {
+    command_line->AppendSwitchASCII(kLoggingModuleSwitch,
+                                    kLoggingModuleSwitchValue);
+  }
+}
+
 }  // namespace
 
 int UpdaterMain(int argc, const char* const* argv) {
@@ -308,6 +319,7 @@
 #if BUILDFLAG(IS_WIN)
   *command_line = GetCommandLineLegacyCompatible();
 #endif
+  EnableLoggingByDefault();
   InitializeCrashKeys(*command_line);
   const UpdaterScope updater_scope = GetUpdaterScope();
   InitLogging(updater_scope);
diff --git a/chrome/updater/win/setup/setup.cc b/chrome/updater/win/setup/setup.cc
index a2e96097..354bbf76 100644
--- a/chrome/updater/win/setup/setup.cc
+++ b/chrome/updater/win/setup/setup.cc
@@ -143,9 +143,6 @@
   if (IsSystemInstall(scope)) {
     run_updater_wake_command.AppendSwitch(kSystemSwitch);
   }
-  run_updater_wake_command.AppendSwitch(kEnableLoggingSwitch);
-  run_updater_wake_command.AppendSwitchASCII(kLoggingModuleSwitch,
-                                             kLoggingModuleSwitchValue);
 
   if (!IsSystemInstall(scope)) {
     RegisterUserRunAtStartup(GetTaskNamePrefix(scope), run_updater_wake_command,
diff --git a/chrome/updater/win/setup/setup_util.cc b/chrome/updater/win/setup/setup_util.cc
index 5f82c31..643a7bd 100644
--- a/chrome/updater/win/setup/setup_util.cc
+++ b/chrome/updater/win/setup/setup_util.cc
@@ -351,9 +351,6 @@
       kServerServiceSwitch, internal_service
                                 ? kServerUpdateServiceInternalSwitchValue
                                 : kServerUpdateServiceSwitchValue);
-  run_com_server_command.AppendSwitch(kEnableLoggingSwitch);
-  run_com_server_command.AppendSwitchASCII(kLoggingModuleSwitch,
-                                           kLoggingModuleSwitchValue);
   list->AddSetRegValueWorkItem(
       root, local_server32_reg_path, WorkItem::kWow64Default, L"",
       run_com_server_command.GetCommandLineString(), true);
@@ -400,9 +397,6 @@
       kServerServiceSwitch, internal_service
                                 ? kServerUpdateServiceInternalSwitchValue
                                 : kServerUpdateServiceSwitchValue);
-  com_service_command.AppendSwitch(kEnableLoggingSwitch);
-  com_service_command.AppendSwitchASCII(kLoggingModuleSwitch,
-                                        kLoggingModuleSwitchValue);
 
   base::CommandLine com_switch(base::CommandLine::NO_PROGRAM);
   com_switch.AppendSwitch(kComServiceSwitch);
diff --git a/chrome/updater/win/test/test_executables.cc b/chrome/updater/win/test/test_executables.cc
index 0e5cdfd7..d2c45a5 100644
--- a/chrome/updater/win/test/test_executables.cc
+++ b/chrome/updater/win/test/test_executables.cc
@@ -69,9 +69,6 @@
     command_line.AppendSwitch(kSystemSwitch);
   }
 
-  command_line.AppendSwitch(kEnableLoggingSwitch);
-  command_line.AppendSwitchASCII(kLoggingModuleSwitch,
-                                 kLoggingModuleSwitchValue);
   command_line.AppendSwitchASCII(kTestName, test_name);
   return command_line;
 }
diff --git a/chromeos/ash/components/audio/cras_audio_handler.cc b/chromeos/ash/components/audio/cras_audio_handler.cc
index 7095aa7..7d3b84650 100644
--- a/chromeos/ash/components/audio/cras_audio_handler.cc
+++ b/chromeos/ash/components/audio/cras_audio_handler.cc
@@ -1436,6 +1436,8 @@
         survey->set_type(SurveyType::kGeneral);
       } else if (it.second == CrasAudioHandler::kSurveyNameBluetooth) {
         survey->set_type(SurveyType::kBluetooth);
+      } else if (it.second == CrasAudioHandler::kSurveyNameOutputProc) {
+        survey->set_type(SurveyType::kOutputProc);
       }
     } else {
       survey->AddData(it.first, it.second);
diff --git a/chromeos/ash/components/audio/cras_audio_handler.h b/chromeos/ash/components/audio/cras_audio_handler.h
index 7fbfd52..0561188 100644
--- a/chromeos/ash/components/audio/cras_audio_handler.h
+++ b/chromeos/ash/components/audio/cras_audio_handler.h
@@ -74,11 +74,13 @@
   enum class SurveyType {
     kGeneral,
     kBluetooth,
+    kOutputProc,
   };
 
   static constexpr char kSurveyNameKey[] = "SurveyName";
   static constexpr char kSurveyNameGeneral[] = "GENERAL";
   static constexpr char kSurveyNameBluetooth[] = "BLUETOOTH";
+  static constexpr char kSurveyNameOutputProc[] = "OUTPUTPROC";
 
   // Key-value mapping type for audio survey specific data.
   // For audio satisfaction survey, it contains
diff --git a/chromeos/ash/components/audio/cras_audio_handler_unittest.cc b/chromeos/ash/components/audio/cras_audio_handler_unittest.cc
index 92122a0d..7a8b8073 100644
--- a/chromeos/ash/components/audio/cras_audio_handler_unittest.cc
+++ b/chromeos/ash/components/audio/cras_audio_handler_unittest.cc
@@ -6686,4 +6686,22 @@
       /*expected_count=*/1);
 }
 
+TEST_P(CrasAudioHandlerTest, AudioSurveyOutputProc) {
+  AudioNodeList audio_nodes = GenerateAudioNodeList(
+      {kInternalSpeaker, kHeadphone, kInternalMic, kUSBMic1});
+  base::flat_map<std::string, std::string> survey_specific_data = {
+      {CrasAudioHandler::kSurveyNameKey,
+       CrasAudioHandler::kSurveyNameOutputProc}};
+
+  SetUpCrasAudioHandler(audio_nodes);
+
+  // Simulate an audio survey gets triggered.
+  fake_cras_audio_client()->NotifySurveyTriggered(survey_specific_data);
+
+  EXPECT_EQ(test_observer_->survey_triggerd_count(), 1);
+  EXPECT_EQ(test_observer_->survey_triggerd_recv().type(),
+            CrasAudioHandler::SurveyType::kOutputProc);
+  EXPECT_EQ(test_observer_->survey_triggerd_recv().data().size(), 0u);
+}
+
 }  // namespace ash
diff --git a/chromeos/ash/components/auth_panel/impl/BUILD.gn b/chromeos/ash/components/auth_panel/impl/BUILD.gn
index 252ee7f3..df64592 100644
--- a/chromeos/ash/components/auth_panel/impl/BUILD.gn
+++ b/chromeos/ash/components/auth_panel/impl/BUILD.gn
@@ -7,9 +7,7 @@
 assert(is_chromeos_ash)
 
 source_set("impl") {
-  public_deps = [
-    "//chromeos/ash/components/auth_panel/public",
-  ]
+  public_deps = [ "//chromeos/ash/components/auth_panel/public" ]
 
   deps = [
     "//ash/resources/vector_icons",
diff --git a/chromeos/ash/components/auth_panel/impl/views/login_textfield.h b/chromeos/ash/components/auth_panel/impl/views/login_textfield.h
index 2a38f5b..634df848 100644
--- a/chromeos/ash/components/auth_panel/impl/views/login_textfield.h
+++ b/chromeos/ash/components/auth_panel/impl/views/login_textfield.h
@@ -39,7 +39,7 @@
       const AuthFactorStore::State::PasswordViewState& password_view_state);
 
  private:
-  raw_ptr<AuthPanelEventDispatcher> dispatcher_;
+  raw_ptr<AuthPanelEventDispatcher, DanglingUntriaged> dispatcher_;
 };
 
 }  // namespace ash
diff --git a/chromeos/ash/components/auth_panel/impl/views/password_auth_view.h b/chromeos/ash/components/auth_panel/impl/views/password_auth_view.h
index 6ee5e970..17df381a 100644
--- a/chromeos/ash/components/auth_panel/impl/views/password_auth_view.h
+++ b/chromeos/ash/components/auth_panel/impl/views/password_auth_view.h
@@ -96,7 +96,7 @@
   void OnDisplayPasswordButtonPressed();
   void SetCapsLockIconHighlighted(bool highlight);
 
-  raw_ptr<AuthPanelEventDispatcher> dispatcher_ = nullptr;
+  raw_ptr<AuthPanelEventDispatcher, DanglingUntriaged> dispatcher_ = nullptr;
 
   raw_ptr<LoginPasswordRow> password_row_ = nullptr;
 
diff --git a/chromeos/strings/chromeos_strings_ar.xtb b/chromeos/strings/chromeos_strings_ar.xtb
index c90bb1f..aeab4464 100644
--- a/chromeos/strings/chromeos_strings_ar.xtb
+++ b/chromeos/strings/chromeos_strings_ar.xtb
@@ -857,6 +857,8 @@
 <translation id="5946538341867151940">‏لم يتصل جهازك بالشبكة بعد. إذا اقترح مشغّل شبكة الجوّال اسمًا مخصصًا لنقطة الوصول (APN)، أدخِل معلومات APN من خلال اختيار "إضافة اسم نقطة وصول جديد".</translation>
 <translation id="5947266287934282605">إذا كان آخر يوم من الشهر قبل هذا اليوم، ستتم إعادة ضبط البيانات في آخر يوم من الشهر</translation>
 <translation id="5948460390109837040">كلاب</translation>
+<translation id="594989847980441553">‏انقر على "إنشاء" لإنشاء صورة باستخدام الذكاء الاصطناعي (AI).
+        ستظهر هنا تلقائيًا جميع الصور التي تم إنشاؤها.</translation>
 <translation id="5972388717451707488">Update Engine</translation>
 <translation id="5975130252842127517">مرجاني</translation>
 <translation id="5984145644188835034">خلفية تلقائية</translation>
diff --git a/chromeos/strings/chromeos_strings_id.xtb b/chromeos/strings/chromeos_strings_id.xtb
index 4e8bd1a..d3ddd6e 100644
--- a/chromeos/strings/chromeos_strings_id.xtb
+++ b/chromeos/strings/chromeos_strings_id.xtb
@@ -381,6 +381,7 @@
 <translation id="3170673040743561620">Letakkan dokumen Anda pada pemindai</translation>
 <translation id="3174321110679064523">Wallpaper Fajar ke petang</translation>
 <translation id="3178532070248519384">avant-garde</translation>
+<translation id="3182676044300231689">Masukkan perintah seperti "buat terdengar lebih percaya diri"</translation>
 <translation id="3188257591659621405">File saya</translation>
 <translation id="319101249942218879">Gambar avatar diubah</translation>
 <translation id="3192947282887913208">File Audio</translation>
@@ -586,6 +587,7 @@
 <translation id="4394049700291259645">Nonaktifkan</translation>
 <translation id="439429847087949098">Memulai ulang <ph name="DEVICE_NAME" /></translation>
 <translation id="4395835743215824109">sesuaikan keyboard</translation>
+<translation id="439946595190720558">Latar belakang ini dibuat dengan AI menggunakan teks berikut: "<ph name="PROMPT" />".</translation>
 <translation id="4415951057168511744">Avatar Saat Ini</translation>
 <translation id="4417830657741848074">Administrator Anda telah menyiapkan beberapa aplikasi agar dimulai secara otomatis. Anda tidak dapat menutup beberapa aplikasi tersebut.</translation>
 <translation id="4422041425070339732">panah bawah</translation>
@@ -1034,6 +1036,7 @@
 <translation id="6905724422583748843">Kembali ke <ph name="PAGE_NAME" /></translation>
 <translation id="6910312834584889076">Penutup pemindai terbuka. Tutup penutup dan coba lagi.</translation>
 <translation id="6911383237894364323">Tidak dapat terhubung ke server media</translation>
+<translation id="6930597342185648547">Tentang latar belakang</translation>
 <translation id="6939766318048400022">Kafe</translation>
 <translation id="6943893908656559156">Identitas jarak jauh (opsional)</translation>
 <translation id="6953137545147683679">emas</translation>
diff --git a/chromeos/strings/chromeos_strings_ru.xtb b/chromeos/strings/chromeos_strings_ru.xtb
index db5f4b6..7f1c11a 100644
--- a/chromeos/strings/chromeos_strings_ru.xtb
+++ b/chromeos/strings/chromeos_strings_ru.xtb
@@ -653,7 +653,7 @@
 <translation id="4835901797422965222">Нет активных сетей.</translation>
 <translation id="4838825304062068169">ледник</translation>
 <translation id="48409034532829769">Администратор настроил автоматический запуск приложения "<ph name="APP_NAME" />". Его нельзя закрыть.</translation>
-<translation id="484462545196658690">Выбрать автоматически</translation>
+<translation id="484462545196658690">Авто</translation>
 <translation id="4847902821209177679">Выбран вариант "<ph name="TOPIC_SOURCE" />" (<ph name="TOPIC_SOURCE_DESC" />). Нажмите Ввод, чтобы выбрать альбомы отсюда: <ph name="TOPIC_SOURCE" />.</translation>
 <translation id="484790837831576105">DNS-преобразование (Android)</translation>
 <translation id="4848429997038228357">ВЫПОЛНЯЕТСЯ</translation>
diff --git a/clank b/clank
index 71700ce..6c89ab9 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit 71700ce427b7af336a88a02a0767b1ee1af7512b
+Subproject commit 6c89ab97e91680ad99a18c4763e0c7815d4a30ba
diff --git a/components/android_autofill/browser/android_autofill_provider.cc b/components/android_autofill/browser/android_autofill_provider.cc
index 80b6426f..7efe6610 100644
--- a/components/android_autofill/browser/android_autofill_provider.cc
+++ b/components/android_autofill/browser/android_autofill_provider.cc
@@ -183,7 +183,7 @@
       .render_frame_host()
       ->ForEachRenderFrameHost([this, &field](content::RenderFrameHost* rfh) {
         LocalFrameToken frame_token(rfh->GetFrameToken().value());
-        if (frame_token == field.host_frame) {
+        if (frame_token == field.host_frame()) {
           last_queried_field_rfh_id_ = rfh->GetGlobalId();
         }
       });
@@ -197,11 +197,12 @@
     last_focused_field_id_ = field.global_id();
   }
 
-  if (field.datalist_options.empty()) {
+  if (field.datalist_options().empty()) {
     return;
   }
-  bridge_->ShowDatalistPopup(field.datalist_options,
-                             field.text_direction == base::i18n::RIGHT_TO_LEFT);
+  bridge_->ShowDatalistPopup(
+      field.datalist_options(),
+      field.text_direction() == base::i18n::RIGHT_TO_LEFT);
 }
 
 bool AndroidAutofillProvider::IsFormSimilarToCachedForm(
@@ -255,7 +256,7 @@
 
   last_focused_field_id_ = field.global_id();
   field_type_group_ = manager->ComputeFieldTypeGroupForField(form, field);
-  triggered_origin_ = field.origin;
+  triggered_origin_ = field.origin();
   check_submission_ = false;
   manager_ = manager->GetWeakPtrToLeafClass();
 
diff --git a/components/android_autofill/browser/android_autofill_provider_unittest.cc b/components/android_autofill/browser/android_autofill_provider_unittest.cc
index a360192..315b4bb 100644
--- a/components/android_autofill/browser/android_autofill_provider_unittest.cc
+++ b/components/android_autofill/browser/android_autofill_provider_unittest.cc
@@ -406,14 +406,14 @@
   FormData form = CreateFormDataForFrame(
       CreateTestPersonalInformationFormData(), main_frame_token());
   // For Android Autofill, focusability is the same as visibility.
-  form.fields[0].is_focusable = false;
-  form.fields[2].is_focusable = false;
+  form.fields[0].set_is_focusable(false);
+  form.fields[2].set_is_focusable(false);
 
   // Start an Autofill session.
   android_autofill_manager().SimulateOnAskForValuesToFill(form, form.fields[1]);
 
-  form.fields[0].is_focusable = true;
-  form.fields[2].is_focusable = true;
+  form.fields[0].set_is_focusable(true);
+  form.fields[2].set_is_focusable(true);
 
   EXPECT_CALL(provider_bridge(), OnFormFieldVisibilitiesDidChange(
                                      /*indices=*/UnorderedElementsAre(0, 2)));
diff --git a/components/android_autofill/browser/form_data_android_unittest.cc b/components/android_autofill/browser/form_data_android_unittest.cc
index 486b674..125cbcc2 100644
--- a/components/android_autofill/browser/form_data_android_unittest.cc
+++ b/components/android_autofill/browser/form_data_android_unittest.cc
@@ -53,9 +53,9 @@
   f.set_name_attribute(f.name());
   f.set_id_attribute(u"some_id");
   f.set_form_control_type(FormControlType::kInputText);
-  f.check_status = FormFieldData::CheckStatus::kChecked;
-  f.role = FormFieldData::RoleAttribute::kOther;
-  f.is_focusable = true;
+  f.set_check_status(FormFieldData::CheckStatus::kChecked);
+  f.set_role(FormFieldData::RoleAttribute::kOther);
+  f.set_is_focusable(true);
   f.set_renderer_id(FieldRendererId(renderer_id++));
   return f;
 }
@@ -395,8 +395,8 @@
 TEST_F(FormDataAndroidTest, UpdateFieldVisibilities) {
   FormData form = CreateTestForm();
   form.fields = {CreateTestField(), CreateTestField(), CreateTestField()};
-  form.fields[0].role = FormFieldData::RoleAttribute::kPresentation;
-  form.fields[1].is_focusable = false;
+  form.fields[0].set_role(FormFieldData::RoleAttribute::kPresentation);
+  form.fields[1].set_is_focusable(false);
   EXPECT_FALSE(form.fields[0].IsFocusable());
   EXPECT_FALSE(form.fields[1].IsFocusable());
   EXPECT_TRUE(form.fields[2].IsFocusable());
@@ -409,8 +409,8 @@
 
   // `form_android` created a copy of `form` - therefore modifying the fields
   // here does not change the values inside `form_android`.
-  form.fields[0].role = FormFieldData::RoleAttribute::kOther;
-  form.fields[1].is_focusable = true;
+  form.fields[0].set_role(FormFieldData::RoleAttribute::kOther);
+  form.fields[1].set_is_focusable(true);
   EXPECT_TRUE(form.fields[0].IsFocusable());
   EXPECT_TRUE(form.fields[1].IsFocusable());
   EXPECT_TRUE(form.fields[2].IsFocusable());
diff --git a/components/android_autofill/browser/form_field_data_android.cc b/components/android_autofill/browser/form_field_data_android.cc
index 5acc192..71f3d96 100644
--- a/components/android_autofill/browser/form_field_data_android.cc
+++ b/components/android_autofill/browser/form_field_data_android.cc
@@ -78,8 +78,8 @@
 
 void FormFieldDataAndroid::OnFormFieldVisibilityDidChange(
     const FormFieldData& field) {
-  field_->is_focusable = field.is_focusable;
-  field_->role = field.role;
+  field_->set_is_focusable(field.is_focusable());
+  field_->set_role(field.role());
   CHECK_EQ(field_->IsFocusable(), field.IsFocusable());
   bridge_->UpdateVisible(field_->IsFocusable());
 }
@@ -87,9 +87,9 @@
 bool FormFieldDataAndroid::SimilarFieldAs(const FormFieldData& field) const {
   auto SimilarityTuple = [](const FormFieldData& f) {
     return std::tuple_cat(
-        std::tie(f.host_frame, f.renderer_id(), f.name(), f.name_attribute(),
+        std::tie(f.host_frame(), f.renderer_id(), f.name(), f.name_attribute(),
                  f.id_attribute(), f.form_control_type()),
-        std::make_tuple(IsCheckable(f.check_status)));
+        std::make_tuple(IsCheckable(f.check_status())));
   };
 
   // For Android Autofill, labels are considered similar if they meet one of the
@@ -99,8 +99,8 @@
   //    was not `LabelSource::kLabelTag`.
   auto LabelsAreSimilar = [](const FormFieldData& f1, const FormFieldData& f2) {
     return f1.label() == f2.label() ||
-           (f1.label_source != FormFieldData::LabelSource::kLabelTag &&
-            f1.label_source == f2.label_source);
+           (f1.label_source() != FormFieldData::LabelSource::kLabelTag &&
+            f1.label_source() == f2.label_source());
   };
 
   return SimilarityTuple(*field_) == SimilarityTuple(field) &&
diff --git a/components/android_autofill/browser/form_field_data_android_bridge_impl.cc b/components/android_autofill/browser/form_field_data_android_bridge_impl.cc
index 740f9e1..0c7e106 100644
--- a/components/android_autofill/browser/form_field_data_android_bridge_impl.cc
+++ b/components/android_autofill/browser/form_field_data_android_bridge_impl.cc
@@ -72,15 +72,16 @@
       env, ConvertUTF16ToJavaString(env, field.name()),
       ConvertUTF16ToJavaString(env, field.label()),
       ConvertUTF16ToJavaString(env, field.value()),
-      ConvertUTF8ToJavaString(env, field.autocomplete_attribute),
-      field.should_autocomplete,
-      ConvertUTF16ToJavaString(env, field.placeholder),
+      ConvertUTF8ToJavaString(env, field.autocomplete_attribute()),
+      field.should_autocomplete(),
+      ConvertUTF16ToJavaString(env, field.placeholder()),
       ConvertUTF8ToJavaString(
           env, FormControlTypeToString(field.form_control_type())),
       ConvertUTF16ToJavaString(env, field.id_attribute()),
-      /*optionValues=*/ProjectOptions(field.options, &SelectOption::value),
-      /*optionContents=*/ProjectOptions(field.options, &SelectOption::content),
-      IsCheckable(field.check_status), IsChecked(field.check_status),
+      /*optionValues=*/ProjectOptions(field.options(), &SelectOption::value),
+      /*optionContents=*/
+      ProjectOptions(field.options(), &SelectOption::content),
+      IsCheckable(field.check_status()), IsChecked(field.check_status()),
       field.max_length(),
       /*heuristicType=*/field_types.heuristic_type.IsUnknown()
           ? nullptr
@@ -89,12 +90,12 @@
       ConvertUTF8ToJavaString(env, field_types.server_type.ToStringView()),
       ConvertUTF8ToJavaString(env, field_types.computed_type.ToStringView()),
       ToJavaArrayOfPredictionStrings(env, field_types.server_predictions),
-      field.bounds.x(), field.bounds.y(), field.bounds.right(),
-      field.bounds.bottom(),
+      field.bounds().x(), field.bounds().y(), field.bounds().right(),
+      field.bounds().bottom(),
       /*datalistValues=*/
-      ProjectOptions(field.datalist_options, &SelectOption::value),
+      ProjectOptions(field.datalist_options(), &SelectOption::value),
       /*datalistLabels=*/
-      ProjectOptions(field.datalist_options, &SelectOption::content),
+      ProjectOptions(field.datalist_options(), &SelectOption::content),
       /*visible=*/field.IsFocusable(), field.is_autofilled());
   java_ref_ = JavaObjectWeakGlobalRef(env, obj);
   return obj;
@@ -109,7 +110,7 @@
   }
 
   field.set_is_autofilled(Java_FormFieldData_isAutofilled(env, obj));
-  if (IsCheckable(field.check_status)) {
+  if (IsCheckable(field.check_status())) {
     SetCheckStatus(&field, true, Java_FormFieldData_isChecked(env, obj));
     return;
   }
diff --git a/components/android_autofill/browser/form_field_data_android_unittest.cc b/components/android_autofill/browser/form_field_data_android_unittest.cc
index 332b72d9..ac2b6321 100644
--- a/components/android_autofill/browser/form_field_data_android_unittest.cc
+++ b/components/android_autofill/browser/form_field_data_android_unittest.cc
@@ -25,7 +25,7 @@
   f.set_name_attribute(f.name());
   f.set_id_attribute(u"some_id");
   f.set_form_control_type(FormControlType::kInputText);
-  f.check_status = FormFieldData::CheckStatus::kChecked;
+  f.set_check_status(FormFieldData::CheckStatus::kChecked);
   return f;
 }
 
@@ -117,8 +117,8 @@
 // updates the underlying `FormFieldData` object.
 TEST_F(FormFieldDataAndroidTest, OnFormFieldVisibilityDidChange) {
   FormFieldData field;
-  field.is_focusable = false;
-  field.role = FormFieldData::RoleAttribute::kOther;
+  field.set_is_focusable(false);
+  field.set_role(FormFieldData::RoleAttribute::kOther);
   EXPECT_FALSE(field.IsFocusable());
 
   FormFieldDataAndroid field_android(&field);
@@ -127,13 +127,13 @@
   // A field with `is_focusable=true` and a non-presentation role is focusable
   // in Autofill terms and therefore visible in Android Autofill terms.
   EXPECT_CALL(bridge(), UpdateVisible(true));
-  field_copy.is_focusable = true;
+  field_copy.set_is_focusable(true);
   field_android.OnFormFieldVisibilityDidChange(field_copy);
   EXPECT_TRUE(FormFieldData::DeepEqual(field, field_copy));
 
   // A field with a presentation role is not focusable in Autofill terms.
   EXPECT_CALL(bridge(), UpdateVisible(false));
-  field_copy.role = FormFieldData::RoleAttribute::kPresentation;
+  field_copy.set_role(FormFieldData::RoleAttribute::kPresentation);
   field_android.OnFormFieldVisibilityDidChange(field_copy);
   EXPECT_TRUE(FormFieldData::DeepEqual(field, field_copy));
 }
@@ -178,15 +178,15 @@
 TEST_F(FormFieldDataAndroidTest, SimilarFieldsAs_Checkable) {
   FormFieldData f1 = CreateTestField();
   FormFieldData f2 = CreateTestField();
-  f1.check_status = FormFieldData::CheckStatus::kCheckableButUnchecked;
+  f1.set_check_status(FormFieldData::CheckStatus::kCheckableButUnchecked);
   FormFieldDataAndroid af(&f1);
 
   // If they are both checkable, they are similar (even if one is checked and
   // the other is not).
-  f2.check_status = FormFieldData::CheckStatus::kChecked;
+  f2.set_check_status(FormFieldData::CheckStatus::kChecked);
   EXPECT_TRUE(af.SimilarFieldAs(f2));
 
-  f2.check_status = FormFieldData::CheckStatus::kNotCheckable;
+  f2.set_check_status(FormFieldData::CheckStatus::kNotCheckable);
   EXPECT_FALSE(af.SimilarFieldAs(f2));
 }
 
@@ -198,9 +198,9 @@
   FormFieldDataAndroid af(&f1);
 
   f1.set_label(u"SomeLabel");
-  f1.label_source = FormFieldData::LabelSource::kTdTag;
+  f1.set_label_source(FormFieldData::LabelSource::kTdTag);
   f2.set_label(f1.label());
-  f2.label_source = FormFieldData::LabelSource::kAriaLabel;
+  f2.set_label_source(FormFieldData::LabelSource::kAriaLabel);
 
   EXPECT_TRUE(af.SimilarFieldAs(f2));
 
@@ -209,12 +209,12 @@
   EXPECT_FALSE(af.SimilarFieldAs(f2));
 
   // Similar because the label source are equal not not a label tag.
-  f2.label_source = f1.label_source;
+  f2.set_label_source(f1.label_source());
   EXPECT_TRUE(af.SimilarFieldAs(f2));
 
   // Not similar because the labels differ and the label sources are label tags.
-  f1.label_source = FormFieldData::LabelSource::kLabelTag;
-  f2.label_source = FormFieldData::LabelSource::kLabelTag;
+  f1.set_label_source(FormFieldData::LabelSource::kLabelTag);
+  f2.set_label_source(FormFieldData::LabelSource::kLabelTag);
   EXPECT_FALSE(af.SimilarFieldAs(f2));
 }
 
diff --git a/components/autofill/content/browser/content_autofill_driver.cc b/components/autofill/content/browser/content_autofill_driver.cc
index e477954..578cc9f 100644
--- a/components/autofill/content/browser/content_autofill_driver.cc
+++ b/components/autofill/content/browser/content_autofill_driver.cc
@@ -667,11 +667,11 @@
   FormSignature form_signature = CalculateFormSignature(form);
 
   auto SetFieldMetaData = [&](FormFieldData& f) {
-    f.host_frame = form.host_frame;
-    f.host_form_id = form.renderer_id;
-    f.origin = render_frame_host_->GetLastCommittedOrigin();
-    f.host_form_signature = form_signature;
-    f.bounds = TransformBoundingBoxToViewportCoordinates(f.bounds);
+    f.set_host_frame(form.host_frame);
+    f.set_host_form_id(form.renderer_id);
+    f.set_origin(render_frame_host_->GetLastCommittedOrigin());
+    f.set_host_form_signature(form_signature);
+    f.set_bounds(TransformBoundingBoxToViewportCoordinates(f.bounds()));
   };
 
   for (FormFieldData& f : form.fields) {
diff --git a/components/autofill/content/browser/content_autofill_driver_unittest.cc b/components/autofill/content/browser/content_autofill_driver_unittest.cc
index 6f023bd..f22f4fe 100644
--- a/components/autofill/content/browser/content_autofill_driver_unittest.cc
+++ b/components/autofill/content/browser/content_autofill_driver_unittest.cc
@@ -86,10 +86,10 @@
   FormFieldData::FillData rhs_field = std::get<1>(arg);
   return lhs_field.value() == rhs_field.value &&
          lhs_field.renderer_id() == rhs_field.renderer_id &&
-         lhs_field.host_form_id == rhs_field.host_form_id &&
+         lhs_field.host_form_id() == rhs_field.host_form_id &&
          lhs_field.section() == rhs_field.section &&
          lhs_field.is_autofilled() == rhs_field.is_autofilled &&
-         lhs_field.force_override == rhs_field.force_override;
+         lhs_field.force_override() == rhs_field.force_override;
 }
 
 class FakeAutofillAgent : public mojom::AutofillAgent {
@@ -568,14 +568,15 @@
   EXPECT_EQ(form.main_frame_origin,
             url::Origin::CreateFromNormalizedTuple("https", "hostname", 443));
   ASSERT_EQ(form.fields.size(), 1u);
-  EXPECT_EQ(form.fields.front().host_frame, frame_token());
+  EXPECT_EQ(form.fields.front().host_frame(), frame_token());
 
   EXPECT_EQ(form2.host_frame, form.host_frame);
   EXPECT_EQ(form2.url, form.url);
   EXPECT_EQ(form2.full_url, form.full_url);
   EXPECT_EQ(form2.main_frame_origin, form.main_frame_origin);
   ASSERT_EQ(form2.fields.size(), 1u);
-  EXPECT_EQ(form2.fields.front().host_frame, form2.fields.front().host_frame);
+  EXPECT_EQ(form2.fields.front().host_frame(),
+            form2.fields.front().host_frame());
 }
 
 // Test that forms in "about:" without parents have an empty FormData::url.
@@ -647,13 +648,14 @@
   test_api(driver()).SetFrameAndFormMetaData(form, &field);
 
   EXPECT_NE(signature_without_meta_data, CalculateFormSignature(form));
-  EXPECT_EQ(field.host_frame, frame_token());
-  EXPECT_EQ(field.host_form_id, form.renderer_id);
-  EXPECT_EQ(field.host_form_signature, CalculateFormSignature(form));
+  EXPECT_EQ(field.host_frame(), frame_token());
+  EXPECT_EQ(field.host_form_id(), form.renderer_id);
+  EXPECT_EQ(field.host_form_signature(), CalculateFormSignature(form));
 
-  EXPECT_EQ(field.host_frame, form.fields.front().host_frame);
-  EXPECT_EQ(field.host_form_id, form.fields.front().host_form_id);
-  EXPECT_EQ(field.host_form_signature, form.fields.front().host_form_signature);
+  EXPECT_EQ(field.host_frame(), form.fields.front().host_frame());
+  EXPECT_EQ(field.host_form_id(), form.fields.front().host_form_id());
+  EXPECT_EQ(field.host_form_signature(),
+            form.fields.front().host_form_signature());
 }
 
 // Tests that FormsSeen() for an updated form arrives in the AutofillManager.
@@ -713,7 +715,7 @@
        FormDataSentToRenderer_FillForm) {
   url::Origin triggered_origin;
   for (FormFieldData& field : address_form().fields) {
-    field.origin = triggered_origin;
+    field.set_origin(triggered_origin);
     field.set_value(u"dummy_value");
   }
   base::RunLoop run_loop;
@@ -736,7 +738,7 @@
        FormDataSentToRenderer_PreviewForm) {
   url::Origin triggered_origin;
   for (FormFieldData& field : address_form().fields) {
-    field.origin = triggered_origin;
+    field.set_origin(triggered_origin);
     field.set_value(u"dummy_value");
   }
   ASSERT_TRUE(base::ranges::all_of(
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
index ec557ee..7967f391 100644
--- a/components/autofill/content/renderer/autofill_agent.cc
+++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -367,7 +367,7 @@
               MaybeExtractDatalist({form_util::ExtractOption::kBounds}))) {
     auto& [form, field] = *form_and_field;
     if (auto* autofill_driver = unsafe_autofill_driver()) {
-      autofill_driver->TextFieldDidScroll(form, field, field.bounds);
+      autofill_driver->TextFieldDidScroll(form, field, field.bounds());
     }
   }
 
@@ -444,7 +444,7 @@
               MaybeExtractDatalist({form_util::ExtractOption::kBounds}))) {
     auto& [form, field] = *form_and_field;
     if (auto* autofill_driver = unsafe_autofill_driver()) {
-      autofill_driver->FocusOnFormField(form, field, field.bounds);
+      autofill_driver->FocusOnFormField(form, field, field.bounds());
     }
   }
 }
@@ -510,7 +510,7 @@
           form_util::FindFormForContentEditable(element)) {
     const FormFieldData& field = form->fields.front();
     if (auto* autofill_driver = unsafe_autofill_driver()) {
-      autofill_driver->TextFieldDidChange(*form, field, field.bounds,
+      autofill_driver->TextFieldDidChange(*form, field, field.bounds(),
                                           base::TimeTicks::Now());
     }
   }
@@ -553,7 +553,7 @@
               MaybeExtractDatalist({form_util::ExtractOption::kBounds}))) {
     auto& [form, field] = *form_and_field;
     if (auto* autofill_driver = unsafe_autofill_driver()) {
-      autofill_driver->TextFieldDidChange(form, field, field.bounds,
+      autofill_driver->TextFieldDidChange(form, field, field.bounds(),
                                           base::TimeTicks::Now());
     }
   }
@@ -1076,8 +1076,8 @@
   CHECK_EQ(form->fields.size(), 1u);
   if (auto* autofill_driver = unsafe_autofill_driver()) {
     is_popup_possibly_visible_ = true;
-    autofill_driver->AskForValuesToFill(*form, form->fields[0],
-                                        form->fields[0].bounds, trigger_source);
+    autofill_driver->AskForValuesToFill(
+        *form, form->fields[0], form->fields[0].bounds(), trigger_source);
   }
 }
 
@@ -1129,13 +1129,13 @@
       // Find the datalist values and send them to the browser process.
       std::vector<SelectOption> datalist_options;
       form_util::GetDataListSuggestions(input_element, &datalist_options);
-      field.datalist_options = std::move(datalist_options);
+      field.set_datalist_options(std::move(datalist_options));
     }
   }
 
   is_popup_possibly_visible_ = true;
   if (auto* autofill_driver = unsafe_autofill_driver()) {
-    autofill_driver->AskForValuesToFill(form, field, field.bounds,
+    autofill_driver->AskForValuesToFill(form, field, field.bounds(),
                                         trigger_source);
   }
 }
@@ -1378,7 +1378,7 @@
               /*extract_options=*/{})) {
     auto& [form, field] = *form_and_field;
     if (auto* autofill_driver = unsafe_autofill_driver();
-        autofill_driver && !field.options.empty()) {
+        autofill_driver && !field.options().empty()) {
       autofill_driver->SelectOrSelectListFieldOptionsDidChange(form);
     }
   }
@@ -1603,7 +1603,7 @@
                   MaybeExtractDatalist({form_util::ExtractOption::kBounds}))) {
         auto& [form, field] = *form_and_field;
         if (auto* autofill_driver = unsafe_autofill_driver()) {
-          autofill_driver->SelectControlDidChange(form, field, field.bounds);
+          autofill_driver->SelectControlDidChange(form, field, field.bounds());
         }
       }
       break;
diff --git a/components/autofill/content/renderer/form_autofill_issues.cc b/components/autofill/content/renderer/form_autofill_issues.cc
index 6c23779..1dbe599f 100644
--- a/components/autofill/content/renderer/form_autofill_issues.cc
+++ b/components/autofill/content/renderer/form_autofill_issues.cc
@@ -274,7 +274,7 @@
 
   std::set<std::u16string> elements_whose_name_match_a_label_for_attr;
   for (const FormFieldData& field : fields) {
-    if (field.label_source == FormFieldData::LabelSource::kForName) {
+    if (field.label_source() == FormFieldData::LabelSource::kForName) {
       elements_whose_name_match_a_label_for_attr.insert(field.name_attribute());
     }
   }
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc
index 10ba59f..3b8b248 100644
--- a/components/autofill/content/renderer/form_autofill_util.cc
+++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -1260,7 +1260,7 @@
       field_data->set_label(field_data->label() + u" ");
     }
     field_data->set_label(field_data->label() + label_text);
-    field_data->label_source = label_source;
+    field_data->set_label_source(label_source);
   }
 }
 
@@ -1462,8 +1462,9 @@
         control_elements[element_index];
     FormFieldData& field = form.fields[field_index++];
     if (field.label().empty()) {
-      field.set_label(
-          InferLabelForElement(control_element, field.label_source));
+      FormFieldData::LabelSource label_source = field.label_source();
+      field.set_label(InferLabelForElement(control_element, label_source));
+      field.set_label_source(label_source);
     }
     field.set_label(std::move(field.label()).substr(0, kMaxStringLength));
   }
@@ -1927,23 +1928,23 @@
   field->set_id_attribute(element.GetIdAttribute().Utf16());
   field->set_name_attribute(GetAttribute<kName>(element).Utf16());
   field->set_renderer_id(renderer_id);
-  field->host_form_id = GetFormRendererId(form_element);
-  field->form_control_ax_id = element.GetAxId();
+  field->set_host_form_id(GetFormRendererId(form_element));
+  field->set_form_control_ax_id(element.GetAxId());
   field->set_form_control_type(
       ToAutofillFormControlType(element.FormControlTypeForAutofill()));
   field->set_max_length(GetMaxLength(element));
-  field->autocomplete_attribute = GetAutocompleteAttribute(element);
+  field->set_autocomplete_attribute(GetAutocompleteAttribute(element));
   field->set_parsed_autocomplete(
-      ParseAutocompleteAttribute(field->autocomplete_attribute));
+      ParseAutocompleteAttribute(field->autocomplete_attribute()));
 
   if (base::EqualsCaseInsensitiveASCII(GetAttribute<kRole>(element).Utf16(),
                                        "presentation")) {
-    field->role = FormFieldData::RoleAttribute::kPresentation;
+    field->set_role(FormFieldData::RoleAttribute::kPresentation);
   }
 
-  field->placeholder = GetAttribute<kPlaceholder>(element).Utf16();
+  field->set_placeholder(GetAttribute<kPlaceholder>(element).Utf16());
   if (HasAttribute<kClass>(element)) {
-    field->css_classes = GetAttribute<kClass>(element).Utf16();
+    field->set_css_classes(GetAttribute<kClass>(element).Utf16());
   }
 
   if (field_data_manager && field_data_manager->HasFieldData(renderer_id)) {
@@ -1951,8 +1952,9 @@
         field_data_manager->GetFieldPropertiesMask(renderer_id));
   }
 
-  field->aria_label = GetAriaLabel(element.GetDocument(), element);
-  field->aria_description = GetAriaDescription(element.GetDocument(), element);
+  field->set_aria_label(GetAriaLabel(element.GetDocument(), element));
+  field->set_aria_description(
+      GetAriaDescription(element.GetDocument(), element));
 
   const bool kAutofillDetectFieldVisibilityEnabled =
       base::FeatureList::IsEnabled(features::kAutofillDetectFieldVisibility);
@@ -1986,35 +1988,37 @@
                           ? field->id_attribute()
                           : field->name_attribute());
     }
-    if (field->autocomplete_attribute.empty()) {
-      field->autocomplete_attribute = GetAutocompleteAttribute(host);
+    if (field->autocomplete_attribute().empty()) {
+      field->set_autocomplete_attribute(GetAutocompleteAttribute(host));
       field->set_parsed_autocomplete(
-          ParseAutocompleteAttribute(field->autocomplete_attribute));
+          ParseAutocompleteAttribute(field->autocomplete_attribute()));
     }
-    if (field->css_classes.empty() && HasAttribute<kClass>(host)) {
-      field->css_classes = GetAttribute<kClass>(host).Utf16();
+    if (field->css_classes().empty() && HasAttribute<kClass>(host)) {
+      field->set_css_classes(GetAttribute<kClass>(host).Utf16());
     }
-    if (field->aria_label.empty())
-      field->aria_label = GetAriaLabel(host.GetDocument(), host);
-    if (field->aria_description.empty())
-      field->aria_description = GetAriaDescription(host.GetDocument(), host);
+    if (field->aria_label().empty()) {
+      field->set_aria_label(GetAriaLabel(host.GetDocument(), host));
+    }
+    if (field->aria_description().empty()) {
+      field->set_aria_description(GetAriaDescription(host.GetDocument(), host));
+    }
   }
 
   // The browser doesn't need to differentiate between preview and autofill.
   field->set_is_autofilled(element.IsAutofilled());
-  field->is_user_edited = element.UserHasEditedTheField();
-  field->is_focusable = IsWebElementFocusableForAutofill(element);
-  field->is_visible = kAutofillDetectFieldVisibilityEnabled
-                          ? IsWebElementVisible(element)
-                          : field->is_focusable;
-  field->should_autocomplete =
+  field->set_is_user_edited(element.UserHasEditedTheField());
+  field->set_is_focusable(IsWebElementFocusableForAutofill(element));
+  field->set_is_visible(kAutofillDetectFieldVisibilityEnabled
+                            ? IsWebElementVisible(element)
+                            : field->is_focusable());
+  field->set_should_autocomplete(
       element.AutoComplete() &&
       !(field->parsed_autocomplete().has_value() &&
         field->parsed_autocomplete().value().field_type ==
-            HtmlFieldType::kOneTimeCode);
-  field->text_direction = GetTextDirectionForElement(element);
-  field->is_enabled = element.IsEnabled();
-  field->is_readonly = element.IsReadOnly();
+            HtmlFieldType::kOneTimeCode));
+  field->set_text_direction(GetTextDirectionForElement(element));
+  field->set_is_enabled(element.IsEnabled());
+  field->set_is_readonly(element.IsReadOnly());
 
   if (auto input_element = element.DynamicTo<WebInputElement>();
       IsAutofillableInputElement(input_element)) {
@@ -2029,13 +2033,13 @@
         GetListItemsForSelectOrSelectList(element);
     std::vector<SelectOption> options;
     FilterOptionElementsAndGetOptionStrings(element_list_items, &options);
-    field->options = std::move(options);
+    field->set_options(std::move(options));
   }
   if (extract_options.contains(ExtractOption::kBounds)) {
     if (auto* local_frame = element.GetDocument().GetFrame()) {
       if (auto* render_frame =
               content::RenderFrame::FromWebFrame(local_frame)) {
-        field->bounds = render_frame->ElementBoundsInWindow(element);
+        field->set_bounds(render_frame->ElementBoundsInWindow(element));
       }
     }
   }
@@ -2044,7 +2048,7 @@
         !input.IsNull()) {
       std::vector<SelectOption> datalist_options;
       GetDataListSuggestions(input, &datalist_options);
-      field->datalist_options = std::move(datalist_options);
+      field->set_datalist_options(std::move(datalist_options));
     }
   }
 
@@ -2072,8 +2076,8 @@
   }
 
   field->set_value(std::move(value).substr(0, kMaxStringLength));
-  field->selected_text =
-      element.SelectedText().Utf16().substr(0, kMaxSelectedTextLength);
+  field->set_selected_text(
+      element.SelectedText().Utf16().substr(0, kMaxSelectedTextLength));
 
   // If the field was autofilled or the user typed into it, check the value
   // stored in |field_data_manager| against the value property of the DOM
@@ -2093,7 +2097,7 @@
     if (field->form_control_type() == FormControlType::kInputPassword ||
         !ScriptModifiedUsernameOrCreditCardNumberAcceptable(
             field->value(), user_input, *field_data_manager)) {
-      field->user_input = user_input.substr(0, kMaxStringLength);
+      field->set_user_input(user_input.substr(0, kMaxStringLength));
     }
   }
 }
@@ -2190,25 +2194,25 @@
   field.set_name(!field.id_attribute().empty() ? field.id_attribute()
                                                : field.name_attribute());
   field.set_renderer_id(GetFieldRendererId(content_editable));
-  field.host_form_id = GetFormRendererId(content_editable);
+  field.set_host_form_id(GetFormRendererId(content_editable));
   field.set_form_control_type(FormControlType::kContentEditable);
-  field.autocomplete_attribute = GetAutocompleteAttribute(content_editable);
+  field.set_autocomplete_attribute(GetAutocompleteAttribute(content_editable));
   field.set_parsed_autocomplete(
-      ParseAutocompleteAttribute(field.autocomplete_attribute));
+      ParseAutocompleteAttribute(field.autocomplete_attribute()));
   if (auto* local_frame = document.GetFrame()) {
     if (auto* render_frame = content::RenderFrame::FromWebFrame(local_frame)) {
-      field.bounds = render_frame->ElementBoundsInWindow(content_editable);
+      field.set_bounds(render_frame->ElementBoundsInWindow(content_editable));
     }
   }
   if (base::EqualsCaseInsensitiveASCII(
           GetAttribute<kRole>(content_editable).Utf16(), "presentation")) {
-    field.role = FormFieldData::RoleAttribute::kPresentation;
+    field.set_role(FormFieldData::RoleAttribute::kPresentation);
   }
   if (HasAttribute<kClass>(content_editable)) {
-    field.css_classes = GetAttribute<kClass>(content_editable).Utf16();
+    field.set_css_classes(GetAttribute<kClass>(content_editable).Utf16());
   }
-  field.aria_label = GetAriaLabel(document, content_editable);
-  field.aria_description = GetAriaDescription(document, content_editable);
+  field.set_aria_label(GetAriaLabel(document, content_editable));
+  field.set_aria_description(GetAriaDescription(document, content_editable));
   // TextContentAbridged() includes hidden elements and does not add linebreaks.
   // If this is not sufficient in the future, consider calling
   // HTMLElement::innerText(), which returns the text "as rendered" (i.e., it
@@ -2218,8 +2222,8 @@
   field.set_value(
       content_editable.TextContentAbridged(kMaxStringLength).Utf16());
   DCHECK_LE(field.value().length(), kMaxStringLength);
-  field.selected_text =
-      content_editable.SelectedText().Utf16().substr(0, kMaxSelectedTextLength);
+  field.set_selected_text(content_editable.SelectedText().Utf16().substr(
+      0, kMaxSelectedTextLength));
   return form;
 }
 
diff --git a/components/autofill/content/renderer/form_autofill_util_browsertest.cc b/components/autofill/content/renderer/form_autofill_util_browsertest.cc
index d94562b..c61a10a7 100644
--- a/components/autofill/content/renderer/form_autofill_util_browsertest.cc
+++ b/components/autofill/content/renderer/form_autofill_util_browsertest.cc
@@ -255,10 +255,10 @@
                                         {ExtractOption::kOptions});
 
   ASSERT_EQ(form_data.fields.size(), 1u);
-  ASSERT_EQ(form_data.fields[0].options.size(), 1u);
-  EXPECT_EQ(form_data.fields[0].options[0].value, trimmed_option);
-  EXPECT_EQ(form_data.fields[0].options[0].content, trimmed_option);
-  EXPECT_TRUE(IsValidOption(form_data.fields[0].options[0]));
+  ASSERT_EQ(form_data.fields[0].options().size(), 1u);
+  EXPECT_EQ(form_data.fields[0].options()[0].value, trimmed_option);
+  EXPECT_EQ(form_data.fields[0].options()[0].content, trimmed_option);
+  EXPECT_TRUE(IsValidOption(form_data.fields[0].options()[0]));
 }
 
 TEST_F(FormAutofillUtilsTest, FindChildTextTest) {
@@ -566,17 +566,17 @@
       web_frame->GetDocument(), WebFormElement(), field_data_manager(),
       /*extract_options=*/{});
   EXPECT_THAT(
-      form,
-      Optional(Field(
-          &FormData::fields,
-          ElementsAre(AllOf(Property(&FormFieldData::name, u"name1"),
-                            Field(&FormFieldData::is_enabled, IsTrue())),
-                      AllOf(Property(&FormFieldData::name, u"name2"),
-                            Field(&FormFieldData::is_enabled, IsFalse())),
-                      AllOf(Property(&FormFieldData::name, u"name3"),
-                            Field(&FormFieldData::is_enabled, IsTrue())),
-                      AllOf(Property(&FormFieldData::name, u"name4"),
-                            Field(&FormFieldData::is_enabled, IsFalse()))))));
+      form, Optional(Field(
+                &FormData::fields,
+                ElementsAre(
+                    AllOf(Property(&FormFieldData::name, u"name1"),
+                          Property(&FormFieldData::is_enabled, IsTrue())),
+                    AllOf(Property(&FormFieldData::name, u"name2"),
+                          Property(&FormFieldData::is_enabled, IsFalse())),
+                    AllOf(Property(&FormFieldData::name, u"name3"),
+                          Property(&FormFieldData::is_enabled, IsTrue())),
+                    AllOf(Property(&FormFieldData::name, u"name4"),
+                          Property(&FormFieldData::is_enabled, IsFalse()))))));
 }
 
 TEST_F(FormAutofillUtilsTest, IsReadonly) {
@@ -590,17 +590,17 @@
       web_frame->GetDocument(), WebFormElement(), field_data_manager(),
       /*extract_options=*/{});
   EXPECT_THAT(
-      form,
-      Optional(Field(
-          &FormData::fields,
-          ElementsAre(AllOf(Property(&FormFieldData::name, u"name1"),
-                            Field(&FormFieldData::is_readonly, IsFalse())),
-                      AllOf(Property(&FormFieldData::name, u"name2"),
-                            Field(&FormFieldData::is_readonly, IsTrue())),
-                      AllOf(Property(&FormFieldData::name, u"name3"),
-                            Field(&FormFieldData::is_readonly, IsFalse())),
-                      AllOf(Property(&FormFieldData::name, u"name4"),
-                            Field(&FormFieldData::is_readonly, IsTrue()))))));
+      form, Optional(Field(
+                &FormData::fields,
+                ElementsAre(
+                    AllOf(Property(&FormFieldData::name, u"name1"),
+                          Property(&FormFieldData::is_readonly, IsFalse())),
+                    AllOf(Property(&FormFieldData::name, u"name2"),
+                          Property(&FormFieldData::is_readonly, IsTrue())),
+                    AllOf(Property(&FormFieldData::name, u"name3"),
+                          Property(&FormFieldData::is_readonly, IsFalse())),
+                    AllOf(Property(&FormFieldData::name, u"name4"),
+                          Property(&FormFieldData::is_readonly, IsTrue()))))));
 }
 
 TEST_F(FormAutofillUtilsTest, IsFocusable) {
@@ -615,10 +615,11 @@
       form,
       Optional(Field(
           &FormData::fields,
-          ElementsAre(AllOf(Property(&FormFieldData::name, u"name1"),
-                            Field(&FormFieldData::is_focusable, IsTrue())),
-                      AllOf(Property(&FormFieldData::name, u"name2"),
-                            Field(&FormFieldData::is_focusable, IsFalse()))))));
+          ElementsAre(
+              AllOf(Property(&FormFieldData::name, u"name1"),
+                    Property(&FormFieldData::is_focusable, IsTrue())),
+              AllOf(Property(&FormFieldData::name, u"name2"),
+                    Property(&FormFieldData::is_focusable, IsFalse()))))));
 }
 
 TEST_F(FormAutofillUtilsTest, FindFormByUniqueId) {
@@ -852,7 +853,7 @@
 
   ASSERT_TRUE(form_and_field);
   auto& [form, field] = *form_and_field;
-  EXPECT_FALSE(form.fields.back().bounds.IsEmpty());
+  EXPECT_FALSE(form.fields.back().bounds().IsEmpty());
 }
 
 TEST_F(FormAutofillUtilsTest, NotExtractBounds) {
@@ -865,7 +866,7 @@
 
   ASSERT_TRUE(form_and_field);
   auto& [form, field] = *form_and_field;
-  EXPECT_TRUE(form.fields.back().bounds.IsEmpty());
+  EXPECT_TRUE(form.fields.back().bounds().IsEmpty());
 }
 
 TEST_F(FormAutofillUtilsTest, ExtractUnownedBounds) {
@@ -878,7 +879,7 @@
 
   ASSERT_TRUE(form_and_field);
   auto& [form, field] = *form_and_field;
-  EXPECT_FALSE(form.fields.back().bounds.IsEmpty());
+  EXPECT_FALSE(form.fields.back().bounds().IsEmpty());
 }
 
 TEST_F(FormAutofillUtilsTest, GetDataListSuggestions) {
@@ -926,13 +927,13 @@
 
   ASSERT_TRUE(form_and_field);
   auto& [form, field] = *form_and_field;
-  auto& options = form.fields.back().datalist_options;
+  auto& options = form.fields.back().datalist_options();
   ASSERT_EQ(options.size(), 2u);
   EXPECT_EQ(options[0].value, u"1");
   EXPECT_EQ(options[1].value, u"2");
   EXPECT_EQ(options[0].content, u"one");
   EXPECT_EQ(options[1].content, u"two");
-  EXPECT_EQ(field.datalist_options.size(), options.size());
+  EXPECT_EQ(field.datalist_options().size(), options.size());
 }
 
 TEST_F(FormAutofillUtilsTest, NotExtractDataList) {
@@ -948,7 +949,7 @@
 
   ASSERT_TRUE(form_and_field);
   auto& [form, field] = *form_and_field;
-  EXPECT_TRUE(form.fields.back().datalist_options.empty());
+  EXPECT_TRUE(form.fields.back().datalist_options().empty());
 }
 
 // Tests the visibility detection of iframes.
@@ -1398,7 +1399,7 @@
     WebElement element = GetElementById(doc, field.id);
     ASSERT_FALSE(element.IsNull());
     ASSERT_TRUE(element.IsFormControlElement());
-    EXPECT_EQ(form_data->fields[i].host_form_id, host_form);
+    EXPECT_EQ(form_data->fields[i].host_form_id(), host_form);
     EXPECT_TRUE(HaveSameFormControlId(element.To<WebFormControlElement>(),
                                       form_data->fields[i]));
     ++i;
@@ -1937,12 +1938,12 @@
   const FormFieldData& field = form->fields[0];
   EXPECT_TRUE(form->renderer_id);
   EXPECT_EQ(*form->renderer_id, *field.renderer_id());
-  EXPECT_EQ(form->renderer_id, field.host_form_id);
+  EXPECT_EQ(form->renderer_id, field.host_form_id());
   EXPECT_EQ(field.parsed_autocomplete()->field_type, HtmlFieldType::kGivenName);
   EXPECT_EQ(field.name(), u"my-id");
   EXPECT_EQ(field.id_attribute(), u"my-id");
   EXPECT_EQ(field.name_attribute(), u"my-name");
-  EXPECT_EQ(field.css_classes, u"my-class");
+  EXPECT_EQ(field.css_classes(), u"my-class");
   EXPECT_EQ(field.value(),
             u"\n            This is the textContent!\n         ");
 }
@@ -1965,12 +1966,12 @@
   const FormFieldData& field = form->fields[0];
   EXPECT_TRUE(form->renderer_id);
   EXPECT_EQ(*form->renderer_id, *field.renderer_id());
-  EXPECT_EQ(form->renderer_id, field.host_form_id);
+  EXPECT_EQ(form->renderer_id, field.host_form_id());
   EXPECT_EQ(field.parsed_autocomplete()->field_type, HtmlFieldType::kGivenName);
   EXPECT_EQ(field.name(), u"my-id");
   EXPECT_EQ(field.id_attribute(), u"my-id");
   EXPECT_EQ(field.name_attribute(), u"my-name");
-  EXPECT_EQ(field.css_classes, u"my-class");
+  EXPECT_EQ(field.css_classes(), u"my-class");
   // Only extract 1024 characters from the div.
   EXPECT_EQ(field.value().length(), 1024u);
   EXPECT_EQ(
diff --git a/components/autofill/content/renderer/form_cache.cc b/components/autofill/content/renderer/form_cache.cc
index 27ced197e..4fbce845 100644
--- a/components/autofill/content/renderer/form_cache.cc
+++ b/components/autofill/content/renderer/form_cache.cc
@@ -403,7 +403,7 @@
           "\nfield renderer id: ",
           field_id_str,
           "\nvisible: ",
-          field_data.is_visible ? "true" : "false",
+          field_data.is_visible() ? "true" : "false",
           "\nfocusable: ",
           field_data.IsFocusable() ? "true" : "false",
           "\nfield rank: ",
@@ -456,7 +456,7 @@
     } else if (form_util::IsCheckable(field.form_control_type())) {
       initial_checked_state_.insert(
           {field.renderer_id(),
-           field.check_status == FormFieldData::CheckStatus::kChecked});
+           field.check_status() == FormFieldData::CheckStatus::kChecked});
     }
   }
 }
diff --git a/components/autofill/content/renderer/form_cache_browsertest.cc b/components/autofill/content/renderer/form_cache_browsertest.cc
index ec4ced1..2ff7f3d 100644
--- a/components/autofill/content/renderer/form_cache_browsertest.cc
+++ b/components/autofill/content/renderer/form_cache_browsertest.cc
@@ -442,7 +442,7 @@
     FormFieldData* value_to_fill =
         FindFieldByName(values_to_fill, checkbox_element->NameForAutofill());
     ASSERT_TRUE(value_to_fill != nullptr);
-    value_to_fill->check_status = fill_checkbox_check_status;
+    value_to_fill->set_check_status(fill_checkbox_check_status);
     value_to_fill->set_is_autofilled(true);
   }
 
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
index 0687a5fd..6840e30 100644
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -1136,7 +1136,7 @@
                     : GetFormDataFromWebForm(form);
   // TODO(crbug.com/1465793): Use FormFieldData::parsed_autocomplete.
   auto has_webauthn_attribute = [](const FormFieldData& field) {
-    return field.autocomplete_attribute.find(
+    return field.autocomplete_attribute().find(
                password_manager::constants::kAutocompleteWebAuthn) !=
            std::string::npos;
   };
@@ -1736,7 +1736,7 @@
   GetPasswordManagerDriver().ShowPasswordSuggestions(PasswordSuggestionRequest(
       field.renderer_id(), form, trigger_source,
       GetIndexOfElement(form, username_element),
-      GetIndexOfElement(form, password_element), field.text_direction,
+      GetIndexOfElement(form, password_element), field.text_direction(),
       typed_username, show_webauthn_credentials,
       render_frame()->ElementBoundsInWindow(user_input)));
 }
@@ -2113,8 +2113,8 @@
     FormFieldInfo& field_info = result.fields[i];
     field_info.renderer_id = form_field.renderer_id();
     field_info.form_control_type = form_field.form_control_type();
-    field_info.autocomplete_attribute = form_field.autocomplete_attribute;
-    field_info.is_focusable = form_field.is_focusable;
+    field_info.autocomplete_attribute = form_field.autocomplete_attribute();
+    field_info.is_focusable = form_field.is_focusable();
   }
 
   return result;
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index 9cf9fc7..93efb41 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -828,6 +828,7 @@
   testonly = true
   sources = [
     "address_data_cleaner_test_api.h",
+    "address_data_manager_test_api.h",
     "autofill_form_test_utils.cc",
     "autofill_form_test_utils.h",
     "autofill_manager_test_api.h",
diff --git a/components/autofill/core/browser/address_data_manager.h b/components/autofill/core/browser/address_data_manager.h
index 26c4e371..fdfbd19 100644
--- a/components/autofill/core/browser/address_data_manager.h
+++ b/components/autofill/core/browser/address_data_manager.h
@@ -278,7 +278,13 @@
     sync_service_ = sync_service;
   }
 
+  bool auto_accept_address_imports_for_testing() const {
+    return auto_accept_address_imports_for_testing_;
+  }
+
  protected:
+  friend class AddressDataManagerTestApi;
+
   // Profiles of different sources are stored in different vectors.
   // Several function need to read/write from the correct vector, depending
   // on the source of the profile they are dealing with. This helper function
@@ -427,6 +433,10 @@
   // TODO(b/322170538): Remove once the PDM observer is split.
   base::RepeatingClosure notify_pdm_observers_;
 
+  // If true, new addresses imports are automatically accepted without a prompt.
+  // Only to be used for testing.
+  bool auto_accept_address_imports_for_testing_ = false;
+
   const std::string app_locale_;
 
   base::WeakPtrFactory<AddressDataManager> weak_factory_{this};
diff --git a/components/autofill/core/browser/address_data_manager_test_api.h b/components/autofill/core/browser/address_data_manager_test_api.h
new file mode 100644
index 0000000..11646d31
--- /dev/null
+++ b/components/autofill/core/browser/address_data_manager_test_api.h
@@ -0,0 +1,32 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_DATA_MANAGER_TEST_API_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_DATA_MANAGER_TEST_API_H_
+
+#include "base/memory/raw_ref.h"
+#include "components/autofill/core/browser/address_data_manager.h"
+
+namespace autofill {
+
+class AddressDataManagerTestApi {
+ public:
+  explicit AddressDataManagerTestApi(AddressDataManager& adm) : adm_(adm) {}
+
+  // Used to automatically import addresses without a prompt.
+  void set_auto_accept_address_imports(bool auto_accept) {
+    adm_->auto_accept_address_imports_for_testing_ = auto_accept;
+  }
+
+ private:
+   raw_ref<AddressDataManager> adm_;
+};
+
+inline AddressDataManagerTestApi test_api(AddressDataManager& adm) {
+  return AddressDataManagerTestApi(adm);
+}
+
+}  // namespace autofill
+
+#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_ADDRESS_DATA_MANAGER_TEST_API_H_
diff --git a/components/autofill/core/browser/address_profile_save_manager.cc b/components/autofill/core/browser/address_profile_save_manager.cc
index 3d4085a..0bf9ff1 100644
--- a/components/autofill/core/browser/address_profile_save_manager.cc
+++ b/components/autofill/core/browser/address_profile_save_manager.cc
@@ -87,7 +87,8 @@
     case AutofillProfileImportType::kConfirmableMergeAndSilentUpdate:
     case AutofillProfileImportType::kProfileMigration:
     case AutofillProfileImportType::kProfileMigrationAndSilentUpdate:
-      if (personal_data_manager_->auto_accept_address_imports_for_testing()) {
+      if (personal_data_manager_->address_data_manager()
+              .auto_accept_address_imports_for_testing()) {
         import_process->AcceptWithoutEdits();
         FinalizeProfileImport(std::move(import_process));
         return;
diff --git a/components/autofill/core/browser/autocomplete_history_manager.cc b/components/autofill/core/browser/autocomplete_history_manager.cc
index 1f6e9cde..f77729c 100644
--- a/components/autofill/core/browser/autocomplete_history_manager.cc
+++ b/components/autofill/core/browser/autocomplete_history_manager.cc
@@ -73,8 +73,9 @@
     const AutofillClient& client,
     OnSuggestionsReturnedCallback on_suggestions_returned,
     const SuggestionsContext& context) {
-  if (!field.should_autocomplete)
+  if (!field.should_autocomplete()) {
     return false;
+  }
 
   CancelPendingQueries();
 
@@ -303,10 +304,10 @@
          !field.name().empty() && field.IsTextInputElement() &&
          !field.IsPasswordInputElement() &&
          field.form_control_type() != FormControlType::kInputNumber &&
-         field.should_autocomplete && !IsValidCreditCardNumber(field.value()) &&
-         !IsSSN(field.value()) &&
-         (field.properties_mask() & kUserTyped || field.is_focusable) &&
-         field.role != FormFieldData::RoleAttribute::kPresentation;
+         field.should_autocomplete() &&
+         !IsValidCreditCardNumber(field.value()) && !IsSSN(field.value()) &&
+         (field.properties_mask() & kUserTyped || field.is_focusable()) &&
+         field.role() != FormFieldData::RoleAttribute::kPresentation;
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/autocomplete_history_manager_unittest.cc b/components/autofill/core/browser/autocomplete_history_manager_unittest.cc
index 34e656c..c954ac31 100644
--- a/components/autofill/core/browser/autocomplete_history_manager_unittest.cc
+++ b/components/autofill/core/browser/autocomplete_history_manager_unittest.cc
@@ -291,7 +291,7 @@
   field.set_value(u"a truly esoteric value, I assure you");
   field.set_properties_mask(field.properties_mask() | kUserTyped);
   field.set_form_control_type(FormControlType::kInputText);
-  field.should_autocomplete = false;
+  field.set_should_autocomplete(false);
   form.fields.push_back(field);
 
   EXPECT_CALL(*web_data_service_, AddFormFields(_)).Times(0);
@@ -341,7 +341,7 @@
   search_field.set_value(u"my favorite query");
   search_field.set_form_control_type(FormControlType::kInputSearch);
   search_field.set_properties_mask(search_field.properties_mask() | kUserTyped);
-  search_field.is_focusable = false;
+  search_field.set_is_focusable(false);
   form.fields.push_back(search_field);
 
   EXPECT_CALL(*(web_data_service_.get()), AddFormFields(_));
@@ -366,7 +366,7 @@
   field.set_value(u"a truly esoteric value, I assure you");
   field.set_properties_mask(field.properties_mask() | kUserTyped);
   field.set_form_control_type(FormControlType::kInputText);
-  field.role = FormFieldData::RoleAttribute::kPresentation;
+  field.set_role(FormFieldData::RoleAttribute::kPresentation);
   form.fields.push_back(field);
 
   EXPECT_CALL(*web_data_service_, AddFormFields(_)).Times(0);
@@ -435,7 +435,7 @@
 // Make sure suggestions are not returned if the field should not autocomplete.
 TEST_F(AutocompleteHistoryManagerTest,
        OnGetSingleFieldSuggestions_FieldShouldNotAutocomplete) {
-  test_field_.should_autocomplete = false;
+  test_field_.set_should_autocomplete(false);
 
   // Setting up mock to verify that call to the handler's OnSuggestionsReturned
   // is not triggered.
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc
index 8978f89c..f9b6e9b 100644
--- a/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -277,7 +277,7 @@
   }
 
   // Send to display.
-  if (query_field_.is_focusable && manager_->driver().CanShowAutofillUi()) {
+  if (query_field_.is_focusable() && manager_->driver().CanShowAutofillUi()) {
     if (shortcut_test_suggestion_index_ >= 0) {
       const Suggestion* test_suggestion = FindTestSuggestion(
           manager_->client(), suggestions, shortcut_test_suggestion_index_);
@@ -286,8 +286,8 @@
       return;
     }
     AutofillClient::PopupOpenArgs open_args(
-        element_bounds_, query_field_.text_direction, suggestions,
-        trigger_source_, query_field_.form_control_ax_id);
+        element_bounds_, query_field_.text_direction(), suggestions,
+        trigger_source_, query_field_.form_control_ax_id());
     manager_->client().ShowAutofillPopup(open_args, GetWeakPtr());
   }
 }
diff --git a/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
index 427b2c9..a0a22aa5 100644
--- a/components/autofill/core/browser/autofill_external_delegate_unittest.cc
+++ b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -2295,8 +2295,8 @@
 TEST_F(AutofillExternalDelegateUnitTest, IgnoreAutocompleteOffForAutofill) {
   const FormData form;
   FormFieldData field;
-  field.is_focusable = true;
-  field.should_autocomplete = false;
+  field.set_is_focusable(true);
+  field.set_should_autocomplete(false);
 
   external_delegate().OnQuery(form, field, gfx::RectF(), kDefaultTriggerSource);
 
diff --git a/components/autofill/core/browser/autofill_feedback_data.cc b/components/autofill/core/browser/autofill_feedback_data.cc
index 327cd5f..fdfc17c 100644
--- a/components/autofill/core/browser/autofill_feedback_data.cc
+++ b/components/autofill/core/browser/autofill_feedback_data.cc
@@ -37,12 +37,12 @@
   field_data.Set("fieldSignature",
                  base::NumberToString(field->GetFieldSignature().value()));
   field_data.Set("hostFormSignature",
-                 base::NumberToString(field->host_form_signature.value()));
+                 base::NumberToString(field->host_form_signature().value()));
   field_data.Set("idAttribute", field->id_attribute());
   field_data.Set("parseableNameAttribute", field->name_attribute());
-  field_data.Set("autocompleteAttribute", field->autocomplete_attribute);
+  field_data.Set("autocompleteAttribute", field->autocomplete_attribute());
   field_data.Set("labelAttribute", field->label());
-  field_data.Set("placeholderAttribute", field->placeholder);
+  field_data.Set("placeholderAttribute", field->placeholder());
   field_data.Set("fieldType", field->Type().ToStringView());
   field_data.Set("heuristicType",
                  FieldTypeToStringView(field->heuristic_type()));
@@ -62,7 +62,7 @@
 
   field_data.Set("isEmpty", field->IsEmpty());
   field_data.Set("isFocusable", field->IsFocusable());
-  field_data.Set("isVisible", field->is_visible);
+  field_data.Set("isVisible", field->is_visible());
   return field_data;
 }
 
diff --git a/components/autofill/core/browser/autofill_feedback_data_unittest.cc b/components/autofill/core/browser/autofill_feedback_data_unittest.cc
index dc5edb7..ec26fc3d 100644
--- a/components/autofill/core/browser/autofill_feedback_data_unittest.cc
+++ b/components/autofill/core/browser/autofill_feedback_data_unittest.cc
@@ -115,7 +115,7 @@
                           FormControlType::kInputText, "cc-family-name"),
       CreateTestFormField("Email", "email", "", FormControlType::kInputEmail)};
   for (FormFieldData& field : form.fields) {
-    field.host_frame = form.host_frame;
+    field.set_host_frame(form.host_frame);
   }
   return form;
 }
diff --git a/components/autofill/core/browser/autofill_field_unittest.cc b/components/autofill/core/browser/autofill_field_unittest.cc
index 27382b1f..663f76e 100644
--- a/components/autofill/core/browser/autofill_field_unittest.cc
+++ b/components/autofill/core/browser/autofill_field_unittest.cc
@@ -83,7 +83,7 @@
 
   // Field has autocomplete="off" set. Since autofill was able to make a
   // prediction, it is still considered a fillable field.
-  field.should_autocomplete = false;
+  field.set_should_autocomplete(false);
   EXPECT_TRUE(field.IsFieldFillable());
 }
 
diff --git a/components/autofill/core/browser/autofill_form_test_utils.cc b/components/autofill/core/browser/autofill_form_test_utils.cc
index ebda52c..54138b3 100644
--- a/components/autofill/core/browser/autofill_form_test_utils.cc
+++ b/components/autofill/core/browser/autofill_form_test_utils.cc
@@ -90,23 +90,23 @@
   ff.set_form_control_type(fd.form_control_type);
   if (ff.form_control_type() == FormControlType::kSelectOne &&
       !fd.select_options.empty()) {
-    ff.options = fd.select_options;
+    ff.set_options(fd.select_options);
   }
 
   ff.set_renderer_id(fd.renderer_id.value_or(MakeFieldRendererId()));
-  ff.host_form_id = MakeFormRendererId();
-  ff.is_focusable = fd.is_focusable;
-  ff.is_visible = fd.is_visible;
+  ff.set_host_form_id(MakeFormRendererId());
+  ff.set_is_focusable(fd.is_focusable);
+  ff.set_is_visible(fd.is_visible);
   if (!fd.autocomplete_attribute.empty()) {
-    ff.autocomplete_attribute = fd.autocomplete_attribute;
+    ff.set_autocomplete_attribute(fd.autocomplete_attribute);
     ff.set_parsed_autocomplete(
         ParseAutocompleteAttribute(fd.autocomplete_attribute));
   }
   if (fd.host_frame) {
-    ff.host_frame = *fd.host_frame;
+    ff.set_host_frame(*fd.host_frame);
   }
   if (fd.host_form_signature) {
-    ff.host_form_signature = *fd.host_form_signature;
+    ff.set_host_form_signature(*fd.host_form_signature);
   }
   if (fd.label) {
     ff.set_label(*fd.label);
@@ -118,18 +118,18 @@
     ff.set_value(*fd.value);
   }
   if (fd.placeholder) {
-    ff.placeholder = *fd.placeholder;
+    ff.set_placeholder(*fd.placeholder);
   }
   if (fd.max_length) {
     ff.set_max_length(*fd.max_length);
   }
   if (fd.origin) {
-    ff.origin = *fd.origin;
+    ff.set_origin(*fd.origin);
   }
   ff.set_is_autofilled(fd.is_autofilled.value_or(false));
-  ff.should_autocomplete = fd.should_autocomplete;
+  ff.set_should_autocomplete(fd.should_autocomplete);
   ff.set_properties_mask(fd.properties_mask);
-  ff.check_status = fd.check_status;
+  ff.set_check_status(fd.check_status);
   return ff;
 }
 
@@ -145,9 +145,9 @@
   f.fields.reserve(d.fields.size());
   for (const FieldDescription& dd : d.fields) {
     FormFieldData ff = GetFormFieldData(dd);
-    ff.host_frame = dd.host_frame.value_or(f.host_frame);
-    ff.origin = dd.origin.value_or(f.main_frame_origin);
-    ff.host_form_id = f.renderer_id;
+    ff.set_host_frame(dd.host_frame.value_or(f.host_frame));
+    ff.set_origin(dd.origin.value_or(f.main_frame_origin));
+    ff.set_host_form_id(f.renderer_id);
     f.fields.push_back(ff);
   }
   return f;
diff --git a/components/autofill/core/browser/autofill_merge_unittest.cc b/components/autofill/core/browser/autofill_merge_unittest.cc
index b001825..45c9789 100644
--- a/components/autofill/core/browser/autofill_merge_unittest.cc
+++ b/components/autofill/core/browser/autofill_merge_unittest.cc
@@ -19,6 +19,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/task_environment.h"
 #include "build/build_config.h"
+#include "components/autofill/core/browser/address_data_manager_test_api.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/autofill_type.h"
 #include "components/autofill/core/browser/form_data_importer.h"
@@ -154,7 +155,8 @@
 
 void AutofillMergeTest::SetUp() {
   test::DisableSystemServices(nullptr);
-  personal_data_.set_auto_accept_address_imports_for_testing(true);
+  test_api(personal_data_.address_data_manager())
+      .set_auto_accept_address_imports(true);
   form_data_importer_ = std::make_unique<FormDataImporter>(
       &autofill_client_, &personal_data_, /*history_service=*/nullptr, "en");
 }
@@ -202,7 +204,7 @@
       field.set_name(field_type);
       field.set_value(value);
       field.set_form_control_type(FormControlType::kInputText);
-      field.is_focusable = true;
+      field.set_is_focusable(true);
       form.fields.push_back(field);
     }
 
diff --git a/components/autofill/core/browser/autofill_test_utils.cc b/components/autofill/core/browser/autofill_test_utils.cc
index 30995b0c..13e272c 100644
--- a/components/autofill/core/browser/autofill_test_utils.cc
+++ b/components/autofill/core/browser/autofill_test_utils.cc
@@ -853,10 +853,10 @@
   FormFieldData field;
   form.host_frame = MakeLocalFrameToken();
   form.renderer_id = MakeFormRendererId();
-  field.host_frame = MakeLocalFrameToken();
+  field.set_host_frame(MakeLocalFrameToken());
   field.set_renderer_id(MakeFieldRendererId());
-  field.is_focusable = true;
-  field.should_autocomplete = true;
+  field.set_is_focusable(true);
+  field.set_should_autocomplete(true);
   autofill_external_delegate->OnQuery(
       form, field, gfx::RectF(100.f, 100.f),
       AutofillSuggestionTriggerSource::kFormControlElementClicked);
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc
index 9124db2..6ecf7ef 100644
--- a/components/autofill/core/browser/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -400,8 +400,8 @@
   auto autocomplete_state = AutofillMetrics::AutocompleteState::kNone;
   // autocomplete=on is ignored as well. But for the purposes of metrics we care
   // about cases where the developer tries to disable autocomplete.
-  if (field.autocomplete_attribute != "on" &&
-      ShouldIgnoreAutocompleteAttribute(field.autocomplete_attribute)) {
+  if (field.autocomplete_attribute() != "on" &&
+      ShouldIgnoreAutocompleteAttribute(field.autocomplete_attribute())) {
     autocomplete_state = AutofillMetrics::AutocompleteState::kOff;
   } else if (field.parsed_autocomplete()) {
     autocomplete_state =
@@ -409,8 +409,8 @@
             ? AutofillMetrics::AutocompleteState::kValid
             : AutofillMetrics::AutocompleteState::kGarbage;
 
-    if (field.autocomplete_attribute == "new-password" ||
-        field.autocomplete_attribute == "current-password") {
+    if (field.autocomplete_attribute() == "new-password" ||
+        field.autocomplete_attribute() == "current-password") {
       autocomplete_state = AutofillMetrics::AutocompleteState::kPassword;
     }
   }
@@ -797,7 +797,7 @@
         CREDIT_CARD_VERIFICATION_CODE) {
       // However, if Autofill has recognized a field as CVC, that shouldn't be
       // saved.
-      form_for_autocomplete.fields[i].should_autocomplete = false;
+      form_for_autocomplete.fields[i].set_should_autocomplete(false);
     }
     if (plus_address_delegate &&
         plus_address_delegate->IsPlusAddress(
@@ -805,11 +805,11 @@
       // Similarly to CVC, any plus addresses needn't be saved to autocomplete.
       // Note that the feature is experimental, and `plus_address_delegate`
       // will be null if the feature is not enabled (it's disabled by default).
-      form_for_autocomplete.fields[i].should_autocomplete = false;
+      form_for_autocomplete.fields[i].set_should_autocomplete(false);
     }
 
 #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
-    if (autofill_field->autocomplete_attribute == "off" &&
+    if (autofill_field->autocomplete_attribute() == "off" &&
         autofill_field->did_trigger_suggestions() &&
         !autofill_field->is_autofilled() &&
         !autofill_field->previously_autofilled() &&
@@ -1088,7 +1088,7 @@
     client().NotifyAutofillManualFallbackUsed();
   }
 
-  external_delegate_->SetCurrentDataListValues(field.datalist_options);
+  external_delegate_->SetCurrentDataListValues(field.datalist_options());
   external_delegate_->OnQuery(form, field, transformed_box, trigger_source);
 
   std::vector<Suggestion> suggestions;
@@ -2314,7 +2314,8 @@
         !four_digit_combinations_in_dom_.empty()) {
       base::flat_map<std::string, VirtualCardUsageData::VirtualCardLastFour>
           virtual_card_guid_to_last_four_map =
-              GetVirtualCreditCardsForStandaloneCvcField(trigger_field.origin);
+              GetVirtualCreditCardsForStandaloneCvcField(
+                  trigger_field.origin());
       if (!virtual_card_guid_to_last_four_map.empty()) {
         suggestions =
             suggestion_generator_->GetSuggestionsForVirtualCardStandaloneCvc(
@@ -2789,13 +2790,13 @@
   if (num_text_fields == 1) {
     auto it = base::ranges::find_if(form_structure.fields(),
                                     is_focusable_predicted_text_field);
-    if (base::ToLowerASCII((*it)->placeholder).find(u"search") !=
+    if (base::ToLowerASCII((*it)->placeholder()).find(u"search") !=
             std::string::npos ||
         base::ToLowerASCII((*it)->name()).find(u"search") !=
             std::string::npos ||
         base::ToLowerASCII((*it)->label()).find(u"search") !=
             std::string::npos ||
-        base::ToLowerASCII((*it)->aria_label).find(u"search") !=
+        base::ToLowerASCII((*it)->aria_label()).find(u"search") !=
             std::string::npos) {
       return false;
     }
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
index afa3ed4..b6e4f0fa 100644
--- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -32,6 +32,7 @@
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "components/autofill/core/browser/address_data_manager_test_api.h"
 #include "components/autofill/core/browser/autofill_compose_delegate.h"
 #include "components/autofill/core/browser/autofill_experiments.h"
 #include "components/autofill/core/browser/autofill_form_test_utils.h"
@@ -676,7 +677,8 @@
     task_environment_.FastForwardBy(year2020 - AutofillClock::Now());
 
     autofill_client_.SetPrefs(test::PrefServiceForTesting());
-    personal_data().set_auto_accept_address_imports_for_testing(true);
+    test_api(personal_data().address_data_manager())
+        .set_auto_accept_address_imports(true);
     personal_data().SetPrefService(autofill_client_.GetPrefs());
     personal_data().SetSyncServiceForTest(&sync_service_);
 
@@ -4673,7 +4675,7 @@
   FormsSeen({form});
   // The first field is "Name on card", which should autocomplete.
   FormFieldData field = form.fields[0];
-  field.should_autocomplete = true;
+  field.set_should_autocomplete(true);
 
   // SingleFieldFormFillRouter is called for suggestions.
   EXPECT_CALL(single_field_form_fill_router(), OnGetSingleFieldSuggestions);
@@ -4703,7 +4705,7 @@
   FormsSeen({form});
   // The second field is "Card Number", which should not autocomplete.
   FormFieldData field = form.fields[1];
-  field.should_autocomplete = true;
+  field.set_should_autocomplete(true);
 
   // SingleFieldFormFillRouter is not called for suggestions.
   EXPECT_CALL(single_field_form_fill_router(), OnGetSingleFieldSuggestions)
@@ -4726,7 +4728,7 @@
   // No suggestions matching "donkey".
   FormFieldData field = CreateTestFormField("Email", "email", "donkey",
                                             FormControlType::kInputEmail);
-  field.should_autocomplete = false;
+  field.set_should_autocomplete(false);
 
   // Autocomplete is set to off, so suggestions should not get returned from
   // single_field_form_fill_router()|.
@@ -4755,7 +4757,7 @@
   FormData form = CreateTestAddressFormData();
   FormsSeen({form});
   FormFieldData& field = form.fields[0];
-  field.should_autocomplete = false;
+  field.set_should_autocomplete(false);
 
   // Autocomplete is set to off, so suggestions should not get returned from
   // |single_field_form_fill_router()|.
@@ -5511,7 +5513,7 @@
   ASSERT_EQ(std::size(test_fields), form_seen_by_ahm.fields.size());
   for (size_t i = 0; i < std::size(test_fields); ++i) {
     EXPECT_EQ(
-        form_seen_by_ahm.fields[i].should_autocomplete,
+        form_seen_by_ahm.fields[i].should_autocomplete(),
         test_fields[i].expected_field_type != CREDIT_CARD_VERIFICATION_CODE);
   }
 }
@@ -5602,7 +5604,7 @@
 
   // Has less than 3 fields but has autocomplete attribute.
   constexpr char autocomplete[] = "given-name";
-  form.fields[0].autocomplete_attribute = autocomplete;
+  form.fields[0].set_autocomplete_attribute(autocomplete);
   form.fields[0].set_parsed_autocomplete(
       ParseAutocompleteAttribute(autocomplete));
 
@@ -5615,7 +5617,7 @@
   EXPECT_TRUE(browser_autofill_manager_->ShouldUploadForm(FormStructure(form)));
 
   // Has more than 3 fields and at least one autocomplete attribute.
-  form.fields[0].autocomplete_attribute = autocomplete;
+  form.fields[0].set_autocomplete_attribute(autocomplete);
   form.fields[0].set_parsed_autocomplete(
       ParseAutocompleteAttribute(autocomplete));
   EXPECT_TRUE(browser_autofill_manager_->ShouldUploadForm(FormStructure(form)));
@@ -5655,7 +5657,7 @@
   mixed_form.action = GURL("https://myform.com/submit.html");
   mixed_form.fields.push_back(CreateTestFormField("First name", "firstname", "",
                                                   FormControlType::kInputText));
-  mixed_form.fields.back().should_autocomplete = false;
+  mixed_form.fields.back().set_should_autocomplete(false);
   mixed_form.fields.push_back(CreateTestFormField("Last name", "lastname", "",
                                                   FormControlType::kInputText));
   mixed_form.fields.push_back(CreateTestFormField("Address", "address", "",
@@ -5685,12 +5687,12 @@
   mixed_form.action = GURL("https://myform.com/submit.html");
   mixed_form.fields = {CreateTestFormField("Name on Card", "nameoncard", "",
                                            FormControlType::kInputText)};
-  mixed_form.fields.back().should_autocomplete = false;
+  mixed_form.fields.back().set_should_autocomplete(false);
   mixed_form.fields.push_back(CreateTestFormField(
       "Card Number", "cardnumber", "", FormControlType::kInputText));
   mixed_form.fields.push_back(CreateTestFormField(
       "Expiration Month", "ccexpiresmonth", "", FormControlType::kInputText));
-  mixed_form.fields.back().should_autocomplete = false;
+  mixed_form.fields.back().set_should_autocomplete(false);
   FormsSeen({mixed_form});
 
   // Suggestions should always be displayed.
@@ -5701,7 +5703,7 @@
     // to the field not having a type that would route to any of the other
     // single field form fillers.
     ON_CALL(single_field_form_fill_router(), OnGetSingleFieldSuggestions)
-        .WillByDefault(Return(mixed_form_field.should_autocomplete));
+        .WillByDefault(Return(mixed_form_field.should_autocomplete()));
     GetAutofillSuggestions(mixed_form, mixed_form_field);
 
     EXPECT_TRUE(external_delegate()->on_suggestions_returned_seen());
@@ -5746,7 +5748,7 @@
   }
 
   // Modify one of the fields in the original form.
-  form.fields[0].css_classes += u"a";
+  form.fields[0].set_css_classes(form.fields[0].css_classes() + u"a");
 
   // Expect the form still can be autofilled.
   for (const FormFieldData& form_field : form.fields) {
@@ -7115,7 +7117,7 @@
       // Set an autocomplete=off attribute for the last name.
       CreateTestFormField("Last Name", "lastname", "",
                           FormControlType::kInputText, "given-name")};
-  form.fields.back().should_autocomplete = false;
+  form.fields.back().set_should_autocomplete(false);
   FormsSeen({form});
 
   browser_autofill_manager_->OnFocusOnFormFieldImpl(form, form.fields[1],
@@ -7787,8 +7789,8 @@
   FormSubmitted(form);
 
   EXPECT_EQ(form.fields.size(), form_seen_by_autocomplete.fields.size());
-  EXPECT_FALSE(form_seen_by_autocomplete.fields[0].should_autocomplete);
-  EXPECT_TRUE(form_seen_by_autocomplete.fields[1].should_autocomplete);
+  EXPECT_FALSE(form_seen_by_autocomplete.fields[0].should_autocomplete());
+  EXPECT_TRUE(form_seen_by_autocomplete.fields[1].should_autocomplete());
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc
index 3761785..047dab9 100644
--- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc
+++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc
@@ -270,34 +270,34 @@
                           /*include_checksum=*/false,
                           metadata->mutable_label());
   }
-  if (!field.aria_label.empty()) {
-    EncodeRandomizedValue(encoder, form_signature, field_signature,
-                          RandomizedEncoder::FIELD_ARIA_LABEL, field.aria_label,
-                          /*include_checksum=*/false,
-                          metadata->mutable_aria_label());
-  }
-  if (!field.aria_description.empty()) {
-    EncodeRandomizedValue(encoder, form_signature, field_signature,
-                          RandomizedEncoder::FIELD_ARIA_DESCRIPTION,
-                          field.aria_description, /*include_checksum=*/false,
-                          metadata->mutable_aria_description());
-  }
-  if (!field.css_classes.empty()) {
-    EncodeRandomizedValue(encoder, form_signature, field_signature,
-                          RandomizedEncoder::FIELD_CSS_CLASS, field.css_classes,
-                          /*include_checksum=*/false,
-                          metadata->mutable_css_class());
-  }
-  if (!field.placeholder.empty()) {
-    EncodeRandomizedValue(encoder, form_signature, field_signature,
-                          RandomizedEncoder::FIELD_PLACEHOLDER,
-                          field.placeholder, /*include_checksum=*/false,
-                          metadata->mutable_placeholder());
-  }
-  if (!field.autocomplete_attribute.empty()) {
+  if (!field.aria_label().empty()) {
     EncodeRandomizedValue(
         encoder, form_signature, field_signature,
-        RandomizedEncoder::FIELD_AUTOCOMPLETE, field.autocomplete_attribute,
+        RandomizedEncoder::FIELD_ARIA_LABEL, field.aria_label(),
+        /*include_checksum=*/false, metadata->mutable_aria_label());
+  }
+  if (!field.aria_description().empty()) {
+    EncodeRandomizedValue(encoder, form_signature, field_signature,
+                          RandomizedEncoder::FIELD_ARIA_DESCRIPTION,
+                          field.aria_description(), /*include_checksum=*/false,
+                          metadata->mutable_aria_description());
+  }
+  if (!field.css_classes().empty()) {
+    EncodeRandomizedValue(
+        encoder, form_signature, field_signature,
+        RandomizedEncoder::FIELD_CSS_CLASS, field.css_classes(),
+        /*include_checksum=*/false, metadata->mutable_css_class());
+  }
+  if (!field.placeholder().empty()) {
+    EncodeRandomizedValue(encoder, form_signature, field_signature,
+                          RandomizedEncoder::FIELD_PLACEHOLDER,
+                          field.placeholder(), /*include_checksum=*/false,
+                          metadata->mutable_placeholder());
+  }
+  if (!field.autocomplete_attribute().empty()) {
+    EncodeRandomizedValue(
+        encoder, form_signature, field_signature,
+        RandomizedEncoder::FIELD_AUTOCOMPLETE, field.autocomplete_attribute(),
         /*include_checksum=*/false, metadata->mutable_autocomplete());
   }
 }
@@ -311,7 +311,7 @@
 
   for (AutofillField* field : upload_fields) {
     // Don't upload checkable fields.
-    if (IsCheckable(field->check_status)) {
+    if (IsCheckable(field->check_status())) {
       continue;
     }
     // Do not upload fields that were filled with a fallback type, as this would
@@ -396,7 +396,8 @@
         queried_form_signatures.push_back(form);
 
         for (const auto& field : fields) {
-          if (IsCheckable(field->check_status) || !necessary_condition(field)) {
+          if (IsCheckable(field->check_status()) ||
+              !necessary_condition(field)) {
             continue;
           }
 
@@ -410,10 +411,11 @@
             form.alternative_form_signature(), [](auto& f) { return true; });
 
   for (const auto& field : form.fields()) {
-    if (field->host_form_signature) {
-      AddFormIf(form.fields(), field->host_form_signature,
+    if (field->host_form_signature()) {
+      AddFormIf(form.fields(), field->host_form_signature(),
                 form.alternative_form_signature(), [&](const auto& f) {
-                  return f->host_form_signature == field->host_form_signature;
+                  return f->host_form_signature() ==
+                         field->host_form_signature();
                 });
     }
   }
@@ -509,7 +511,7 @@
   std::optional<FieldSuggestion> main_frame_field_suggestion =
       get_suggestion(form.form_signature(), field.GetFieldSignature());
   std::optional<FieldSuggestion> iframe_field_suggestion =
-      get_suggestion(field.host_form_signature, field.GetFieldSignature());
+      get_suggestion(field.host_form_signature(), field.GetFieldSignature());
   // NOTE: Suggestions from alternative form signatures are always overrides.
   std::optional<FieldSuggestion> alternative_field_suggestion = get_suggestion(
       form.alternative_form_signature(), field.GetFieldSignature());
@@ -666,8 +668,8 @@
   std::erase_if(upload_fields, [&form](const AutofillField* field) {
     // Autofill on iOS and the Password Manager in general have a null
     // FormFieldData::host_form_signature.
-    return !field->host_form_signature ||
-           field->host_form_signature == form.form_signature();
+    return !field->host_form_signature() ||
+           field->host_form_signature() == form.form_signature();
   });
   // Partition `upload_fields` with respect to the forms' renderer id.
   base::ranges::stable_sort(upload_fields, /*comp=*/{},
@@ -679,7 +681,7 @@
     upload_content.set_client_version(
         std::string(version_info::GetProductNameAndVersionForUserAgent()));
     upload_content.set_form_signature(
-        (*subform_begin)->host_form_signature.value());
+        (*subform_begin)->host_form_signature().value());
     upload_content.set_autofill_used(false);
     upload_content.set_data_present(data_present);
 
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding_unittest.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding_unittest.cc
index 4f860df..416e549 100644
--- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding_unittest.cc
+++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding_unittest.cc
@@ -241,7 +241,7 @@
       SubmissionIndicatorEvent::HTML_FORM_SUBMISSION);
   for (const std::unique_ptr<autofill::AutofillField>& fs_field :
        *form_structure) {
-    fs_field->host_form_signature = form_structure->form_signature();
+    fs_field->set_host_form_signature(form_structure->form_signature());
   }
 
   ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
@@ -293,8 +293,8 @@
       SubmissionIndicatorEvent::HTML_FORM_SUBMISSION);
   ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
   for (size_t i = 0; i < form_structure->field_count(); ++i) {
-    form_structure->field(i)->host_form_signature =
-        form_structure->form_signature();
+    form_structure->field(i)->set_host_form_signature(
+        form_structure->form_signature());
     form_structure->field(i)->set_possible_types(possible_field_types[i]);
   }
 
@@ -365,7 +365,7 @@
 
   form_structure = std::make_unique<FormStructure>(form);
   for (auto& fs_field : *form_structure) {
-    fs_field->host_form_signature = form_structure->form_signature();
+    fs_field->set_host_form_signature(form_structure->form_signature());
   }
 
   ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
@@ -448,7 +448,7 @@
                                             "given-name"));
   form.fields.back().set_name_attribute(form.fields.back().name());
   form.fields.back().set_id_attribute(u"first_name");
-  form.fields.back().css_classes = u"class1 class2";
+  form.fields.back().set_css_classes(u"class1 class2");
   form.fields.back().set_properties_mask(FieldPropertiesFlags::kHadFocus);
   test::InitializePossibleTypes(possible_field_types, {NAME_FIRST});
 
@@ -456,7 +456,7 @@
       "Last Name", "lastname", "", FormControlType::kInputText, "family-name"));
   form.fields.back().set_name_attribute(form.fields.back().name());
   form.fields.back().set_id_attribute(u"last_name");
-  form.fields.back().css_classes = u"class1 class2";
+  form.fields.back().set_css_classes(u"class1 class2");
   form.fields.back().set_properties_mask(FieldPropertiesFlags::kHadFocus |
                                          FieldPropertiesFlags::kUserTyped);
   test::InitializePossibleTypes(possible_field_types, {NAME_LAST});
@@ -465,14 +465,14 @@
       "Email", "email", "", FormControlType::kInputEmail, "email"));
   form.fields.back().set_name_attribute(form.fields.back().name());
   form.fields.back().set_id_attribute(u"e-mail");
-  form.fields.back().css_classes = u"class1 class2";
+  form.fields.back().set_css_classes(u"class1 class2");
   form.fields.back().set_properties_mask(FieldPropertiesFlags::kHadFocus |
                                          FieldPropertiesFlags::kUserTyped);
   test::InitializePossibleTypes(possible_field_types, {EMAIL_ADDRESS});
 
   form_structure = std::make_unique<FormStructure>(form);
   for (auto& fs_field : *form_structure) {
-    fs_field->host_form_signature = form_structure->form_signature();
+    fs_field->set_host_form_signature(form_structure->form_signature());
   }
 
   ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
@@ -536,7 +536,7 @@
       std::make_unique<FormStructure>(form);
   for (const std::unique_ptr<autofill::AutofillField>& fs_field :
        *form_structure) {
-    fs_field->host_form_signature = form_structure->form_signature();
+    fs_field->set_host_form_signature(form_structure->form_signature());
   }
 
   ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
@@ -592,7 +592,7 @@
       std::make_unique<FormStructure>(form);
   for (const std::unique_ptr<autofill::AutofillField>& fs_field :
        *form_structure) {
-    fs_field->host_form_signature = form_structure->form_signature();
+    fs_field->set_host_form_signature(form_structure->form_signature());
   }
 
   ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
@@ -650,7 +650,7 @@
       std::make_unique<FormStructure>(form);
   for (const std::unique_ptr<autofill::AutofillField>& fs_field :
        *form_structure) {
-    fs_field->host_form_signature = form_structure->form_signature();
+    fs_field->set_host_form_signature(form_structure->form_signature());
   }
 
   ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
@@ -759,7 +759,7 @@
     AutofillUploadContents upload;
     upload.set_client_version(
         std::string(GetProductNameAndVersionForUserAgent()));
-    upload.set_form_signature(form.fields[0].host_form_signature.value());
+    upload.set_form_signature(form.fields[0].host_form_signature().value());
     upload.set_autofill_used(false);
     upload.set_data_present("0000000000001850");
     test::FillUploadField(upload.add_field(), 3340391946, 51);
@@ -771,7 +771,7 @@
     AutofillUploadContents upload;
     upload.set_client_version(
         std::string(GetProductNameAndVersionForUserAgent()));
-    upload.set_form_signature(form.fields[1].host_form_signature.value());
+    upload.set_form_signature(form.fields[1].host_form_signature().value());
     upload.set_autofill_used(false);
     upload.set_data_present("0000000000001850");
     test::FillUploadField(upload.add_field(), 1415886167, 52);
@@ -782,7 +782,7 @@
     AutofillUploadContents upload;
     upload.set_client_version(
         std::string(GetProductNameAndVersionForUserAgent()));
-    upload.set_form_signature(form.fields[3].host_form_signature.value());
+    upload.set_form_signature(form.fields[3].host_form_signature().value());
     upload.set_autofill_used(false);
     upload.set_data_present("0000000000001850");
     test::FillUploadField(upload.add_field(), 917221285, 59);
@@ -807,7 +807,7 @@
   FormStructure form_structure(form);
   form_structure.set_submission_source(SubmissionSource::FORM_SUBMISSION);
   for (auto& fs_field : form_structure) {
-    fs_field->host_form_signature = form_structure.form_signature();
+    fs_field->set_host_form_signature(form_structure.form_signature());
   }
 
   std::vector<FieldTypeSet> possible_field_types;
@@ -1045,8 +1045,8 @@
   auto form_structure = std::make_unique<FormStructure>(form);
   form_structure->set_submission_source(SubmissionSource::XHR_SUCCEEDED);
   for (size_t i = 0; i < form_structure->field_count(); ++i) {
-    form_structure->field(i)->host_form_signature =
-        form_structure->form_signature();
+    form_structure->field(i)->set_host_form_signature(
+        form_structure->form_signature());
     form_structure->field(i)->set_possible_types(possible_field_types[i]);
   }
 
@@ -1124,7 +1124,7 @@
 
   FormStructure form_structure(form);
   for (auto& fs_field : form_structure) {
-    fs_field->host_form_signature = form_structure.form_signature();
+    fs_field->set_host_form_signature(form_structure.form_signature());
   }
 
   std::vector<AutofillUploadContents> uploads = EncodeUploadRequest(
@@ -1142,7 +1142,7 @@
 
     FormStructure form_structure(form);
     for (auto& fs_field : form_structure) {
-      fs_field->host_form_signature = form_structure.form_signature();
+      fs_field->set_host_form_signature(form_structure.form_signature());
     }
     std::vector<AutofillUploadContents> uploads =
         EncodeUploadRequest(form_structure, {{}} /* available_field_types */,
@@ -1185,11 +1185,11 @@
     field.set_name_attribute(ASCIIToUTF16(f.name));
     field.set_name(field.name_attribute());
     field.set_label(ASCIIToUTF16(f.label));
-    field.placeholder = ASCIIToUTF16(f.placeholder);
-    field.aria_label = ASCIIToUTF16(f.aria_label);
-    field.aria_description = ASCIIToUTF16(f.aria_description);
-    field.css_classes = ASCIIToUTF16(f.css_classes);
-    field.autocomplete_attribute = f.autocomplete;
+    field.set_placeholder(ASCIIToUTF16(f.placeholder));
+    field.set_aria_label(ASCIIToUTF16(f.aria_label));
+    field.set_aria_description(ASCIIToUTF16(f.aria_description));
+    field.set_css_classes(ASCIIToUTF16(f.css_classes));
+    field.set_autocomplete_attribute(f.autocomplete);
     field.set_parsed_autocomplete(ParseAutocompleteAttribute(f.autocomplete));
     field.set_renderer_id(test::MakeFieldRendererId());
     form.fields.push_back(field);
@@ -1202,7 +1202,7 @@
   form_structure.set_randomized_encoder(
       std::make_unique<RandomizedEncoder>(encoder));
   for (auto& field : form_structure) {
-    field->host_form_signature = form_structure.form_signature();
+    field->set_host_form_signature(form_structure.form_signature());
   }
 
   std::vector<AutofillUploadContents> uploads = EncodeUploadRequest(
@@ -1282,47 +1282,47 @@
                                          RandomizedEncoder::FIELD_LABEL,
                                          field.label()));
     }
-    if (field.aria_label.empty()) {
+    if (field.aria_label().empty()) {
       EXPECT_FALSE(metadata.has_aria_label());
     } else {
       EXPECT_EQ(metadata.aria_label().encoded_bits(),
                 encoder.EncodeForTesting(form_signature, field_signature,
                                          RandomizedEncoder::FIELD_ARIA_LABEL,
-                                         field.aria_label));
+                                         field.aria_label()));
     }
-    if (field.aria_description.empty()) {
+    if (field.aria_description().empty()) {
       EXPECT_FALSE(metadata.has_aria_description());
     } else {
       EXPECT_EQ(
           metadata.aria_description().encoded_bits(),
           encoder.EncodeForTesting(form_signature, field_signature,
                                    RandomizedEncoder::FIELD_ARIA_DESCRIPTION,
-                                   field.aria_description));
+                                   field.aria_description()));
     }
-    if (field.css_classes.empty()) {
+    if (field.css_classes().empty()) {
       EXPECT_FALSE(metadata.has_css_class());
     } else {
       EXPECT_EQ(metadata.css_class().encoded_bits(),
                 encoder.EncodeForTesting(form_signature, field_signature,
                                          RandomizedEncoder::FIELD_CSS_CLASS,
-                                         field.css_classes));
+                                         field.css_classes()));
     }
-    if (field.placeholder.empty()) {
+    if (field.placeholder().empty()) {
       EXPECT_FALSE(metadata.has_placeholder());
     } else {
       EXPECT_EQ(metadata.placeholder().encoded_bits(),
                 encoder.EncodeForTesting(form_signature, field_signature,
                                          RandomizedEncoder::FIELD_PLACEHOLDER,
-                                         field.placeholder));
+                                         field.placeholder()));
     }
-    if (field.autocomplete_attribute.empty()) {
+    if (field.autocomplete_attribute().empty()) {
       EXPECT_FALSE(metadata.has_autocomplete());
     } else {
       EXPECT_EQ(metadata.autocomplete().encoded_bits(),
                 encoder.EncodeForTesting(
                     form_signature, field_signature,
                     RandomizedEncoder::FIELD_AUTOCOMPLETE,
-                    base::UTF8ToUTF16(field.autocomplete_attribute)));
+                    base::UTF8ToUTF16(field.autocomplete_attribute())));
     }
   }
 }
@@ -1378,7 +1378,7 @@
   form_structure.field(0)->set_is_most_recent_single_username_candidate(
       IsMostRecentSingleUsernameCandidate::kMostRecentCandidate);
   for (auto& fs_field : form_structure) {
-    fs_field->host_form_signature = form_structure.form_signature();
+    fs_field->set_host_form_signature(form_structure.form_signature());
   }
 
   std::vector<AutofillUploadContents> uploads = EncodeUploadRequest(
@@ -1402,7 +1402,7 @@
 
   FormStructure form_structure(form);
   for (auto& field : form_structure) {
-    field->host_form_signature = form_structure.form_signature();
+    field->set_host_form_signature(form_structure.form_signature());
   }
 
   AutofillUploadContents::SingleUsernameData single_username_data;
@@ -1435,7 +1435,7 @@
           FormSignature(1234),
           {FieldSignature(1), FieldSignature(10), FieldSignature(100)});
   for (auto& field : *form) {
-    field->host_form_signature = form->form_signature();
+    field->set_host_form_signature(form->form_signature());
   }
   EXPECT_EQ(FormSignature(1234u), form->form_signature());
   ASSERT_EQ(3u, form->field_count());
@@ -1456,7 +1456,7 @@
       FormStructure::CreateForPasswordManagerUpload(FormSignature(1234),
                                                     {FieldSignature(1)});
   for (auto& field : *form) {
-    field->host_form_signature = form->form_signature();
+    field->set_host_form_signature(form->form_signature());
   }
   std::vector<AutofillUploadContents> uploads = EncodeUploadRequest(
       *form, {} /* available_field_types */, "" /*login_form_signature*/,
@@ -1566,41 +1566,41 @@
   field.set_label(u"Name on Card");
   field.set_name(u"name_on_card");
   field.set_renderer_id(test::MakeFieldRendererId());
-  field.host_form_signature = form_signature;
+  field.set_host_form_signature(form_signature);
   form.fields.push_back(field);
 
   field.set_label(u"Address");
   field.set_name(u"billing_address");
   field.set_renderer_id(test::MakeFieldRendererId());
-  field.host_form_signature = FormSignature(12345UL);
+  field.set_host_form_signature(FormSignature(12345UL));
   form.fields.push_back(field);
 
   field.set_label(u"Card Number");
   field.set_name(u"card_number");
   field.set_renderer_id(test::MakeFieldRendererId());
-  field.host_form_signature = FormSignature(67890UL);
+  field.set_host_form_signature(FormSignature(67890UL));
   form.fields.push_back(field);
 
   field.set_label(u"Expiration Date");
   field.set_name(u"expiration_month");
   field.set_renderer_id(test::MakeFieldRendererId());
-  field.host_form_signature = FormSignature(12345UL);
+  field.set_host_form_signature(FormSignature(12345UL));
   form.fields.push_back(field);
 
   field.set_label(u"Expiration Year");
   field.set_name(u"expiration_year");
   field.set_renderer_id(test::MakeFieldRendererId());
-  field.host_form_signature = FormSignature(12345UL);
+  field.set_host_form_signature(FormSignature(12345UL));
   form.fields.push_back(field);
 
   // Add checkable field.
   FormFieldData checkable_field;
-  checkable_field.check_status =
-      FormFieldData::CheckStatus::kCheckableButUnchecked;
+  checkable_field.set_check_status(
+      FormFieldData::CheckStatus::kCheckableButUnchecked);
   checkable_field.set_label(u"Checkable1");
   checkable_field.set_name(u"Checkable1");
   checkable_field.set_renderer_id(test::MakeFieldRendererId());
-  checkable_field.host_form_signature = form_signature;
+  checkable_field.set_host_form_signature(form_signature);
   form.fields.push_back(checkable_field);
 
   FormStructure form_structure(form);
@@ -1661,15 +1661,15 @@
   // Add 5 address fields - this should be still a valid form.
   FormSignature form_signature3(2608858059775241169UL);
   for (auto& f : form.fields) {
-    if (f.host_form_signature == form_signature) {
-      f.host_form_signature = form_signature3;
+    if (f.host_form_signature() == form_signature) {
+      f.set_host_form_signature(form_signature3);
     }
   }
   for (size_t i = 0; i < 5; ++i) {
     field.set_label(u"Address");
     field.set_name(u"address");
     field.set_renderer_id(test::MakeFieldRendererId());
-    field.host_form_signature = form_signature3;
+    field.set_host_form_signature(form_signature3);
     form.fields.push_back(field);
   }
 
@@ -1879,7 +1879,7 @@
 
   FormStructure form_structure(form);
   for (auto& fs_field : form_structure) {
-    fs_field->host_form_signature = form_structure.form_signature();
+    fs_field->set_host_form_signature(form_structure.form_signature());
   }
 
   std::vector<raw_ptr<FormStructure, VectorExperimental>> forms;
@@ -2236,7 +2236,7 @@
     field.set_form_control_type(FormControlType::kInputText);
     field.set_name(u"name");
     field.set_renderer_id(test::MakeFieldRendererId());
-    field.host_form_signature = FormSignature(host_form_signature);
+    field.set_host_form_signature(FormSignature(host_form_signature));
     fields.push_back(field);
 
     // Creating the main frame form.
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc
index 5b06de76..832d3270 100644
--- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc
+++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc
@@ -95,7 +95,7 @@
 // `form_structure` to the signature of the `form_structure`.
 void SetCorrectFieldHostFormSignatures(FormStructure& form_structure) {
   for (const std::unique_ptr<AutofillField>& field : form_structure) {
-    field->host_form_signature = form_structure.form_signature();
+    field->set_host_form_signature(form_structure.form_signature());
   }
 }
 
@@ -1487,11 +1487,11 @@
   field.set_name_attribute(u"field-name-attribute-1");
   field.set_name(field.name_attribute());
   field.set_label(u"field-label");
-  field.aria_label = u"field-aria-label";
-  field.aria_description = u"field-aria-description";
+  field.set_aria_label(u"field-aria-label");
+  field.set_aria_description(u"field-aria-description");
   field.set_form_control_type(FormControlType::kInputText);
-  field.css_classes = u"field-css-classes";
-  field.placeholder = u"field-placeholder";
+  field.set_css_classes(u"field-css-classes");
+  field.set_placeholder(u"field-placeholder");
   form.fields.push_back(field);
 
   // Add field 1.
@@ -1499,11 +1499,11 @@
   field.set_name_attribute(u"field-name-attribute-2");
   field.set_name(field.name_attribute());
   field.set_label(u"field-label");
-  field.aria_label = u"field-aria-label";
-  field.aria_description = u"field-aria-description";
+  field.set_aria_label(u"field-aria-label");
+  field.set_aria_description(u"field-aria-description");
   field.set_form_control_type(FormControlType::kInputText);
-  field.css_classes = u"field-css-classes";
-  field.placeholder = u"field-placeholder";
+  field.set_css_classes(u"field-css-classes");
+  field.set_placeholder(u"field-placeholder");
   form.fields.push_back(field);
 
   // Add field 2.
@@ -1511,11 +1511,11 @@
   field.set_name_attribute(u"field-name-attribute-3");
   field.set_name(field.name_attribute());
   field.set_label(u"field-label");
-  field.aria_label = u"field-aria-label";
-  field.aria_description = u"field-aria-description";
+  field.set_aria_label(u"field-aria-label");
+  field.set_aria_description(u"field-aria-description");
   field.set_form_control_type(FormControlType::kInputText);
-  field.css_classes = u"field-css-classes";
-  field.placeholder = u"field-placeholder";
+  field.set_css_classes(u"field-css-classes");
+  field.set_placeholder(u"field-placeholder");
   form.fields.push_back(field);
 
   // Setup the form structures to query.
@@ -1574,33 +1574,33 @@
   field.set_name_attribute(u"field-name-attribute-1");
   field.set_name(field.name_attribute());
   field.set_label(u"field-label");
-  field.aria_label = u"field-aria-label";
-  field.aria_description = u"field-aria-descriptionm";
+  field.set_aria_label(u"field-aria-label");
+  field.set_aria_description(u"field-aria-descriptionm");
   field.set_form_control_type(FormControlType::kInputText);
-  field.css_classes = u"field-css-classes";
-  field.placeholder = u"field-placeholder";
+  field.set_css_classes(u"field-css-classes");
+  field.set_placeholder(u"field-placeholder");
   form.fields.push_back(field);
 
   field.set_id_attribute(u"field-id-attribute-2");
   field.set_name_attribute(u"field-name-attribute-2");
   field.set_name(field.name_attribute());
   field.set_label(u"field-label");
-  field.aria_label = u"field-aria-label";
-  field.aria_description = u"field-aria-descriptionm";
+  field.set_aria_label(u"field-aria-label");
+  field.set_aria_description(u"field-aria-descriptionm");
   field.set_form_control_type(FormControlType::kInputText);
-  field.css_classes = u"field-css-classes";
-  field.placeholder = u"field-placeholder";
+  field.set_css_classes(u"field-css-classes");
+  field.set_placeholder(u"field-placeholder");
   form.fields.push_back(field);
 
   field.set_id_attribute(u"field-id-attribute-3");
   field.set_name_attribute(u"field-name-attribute-3");
   field.set_name(field.name_attribute());
   field.set_label(u"field-label");
-  field.aria_label = u"field-aria-label";
-  field.aria_description = u"field-aria-descriptionm";
+  field.set_aria_label(u"field-aria-label");
+  field.set_aria_description(u"field-aria-descriptionm");
   field.set_form_control_type(FormControlType::kInputText);
-  field.css_classes = u"field-css-classes";
-  field.placeholder = u"field-placeholder";
+  field.set_css_classes(u"field-css-classes");
+  field.set_placeholder(u"field-placeholder");
   form.fields.push_back(field);
 
   AutofillCrowdsourcingManager crowdsourcing_manager(
diff --git a/components/autofill/core/browser/field_filling_address_util.cc b/components/autofill/core/browser/field_filling_address_util.cc
index 54e0a8b7..bc1a662 100644
--- a/components/autofill/core/browser/field_filling_address_util.cc
+++ b/components/autofill/core/browser/field_filling_address_util.cc
@@ -491,7 +491,7 @@
 
   if (field_data.IsSelectOrSelectListElement() && !value.empty()) {
     value = GetValueForProfileSelectControl(
-        profile, value, app_locale, field_data.options,
+        profile, value, app_locale, field_data.options(),
         filling_type.GetStorableType(), address_normalizer, failure_to_fill);
   }
 
diff --git a/components/autofill/core/browser/field_filling_address_util_unittest.cc b/components/autofill/core/browser/field_filling_address_util_unittest.cc
index 5c451d1..1c3e346 100644
--- a/components/autofill/core/browser/field_filling_address_util_unittest.cc
+++ b/components/autofill/core/browser/field_filling_address_util_unittest.cc
@@ -70,7 +70,7 @@
 TEST_F(FieldFillingAddressUtilTest,
        FillFormField_AutocompleteOffNotRespected_AddressField) {
   AutofillField field;
-  field.should_autocomplete = false;
+  field.set_should_autocomplete(false);
   field.set_heuristic_type(GetActiveHeuristicSource(), NAME_FIRST);
 
   AutofillProfile profile(i18n_model_definition::kLegacyHierarchyCountryCode);
@@ -461,7 +461,7 @@
   AutofillField field(test::CreateTestSelectOrSelectListField(
       /*label=*/"", /*name=*/"", /*value=*/"", /*autocomplete=*/"",
       /*values=*/{}, /*contents=*/{}, field_type));
-  field.options = test_case.phone_country_code_selection_options;
+  field.set_options(test_case.phone_country_code_selection_options);
   field.set_heuristic_type(GetActiveHeuristicSource(), PHONE_HOME_COUNTRY_CODE);
 
   AutofillProfile profile(AddressCountryCode("US"));
diff --git a/components/autofill/core/browser/field_filling_payments_util.cc b/components/autofill/core/browser/field_filling_payments_util.cc
index 4fd9de56..35d4446 100644
--- a/components/autofill/core/browser/field_filling_payments_util.cc
+++ b/components/autofill/core/browser/field_filling_payments_util.cc
@@ -449,15 +449,15 @@
   switch (field.Type().GetStorableType()) {
     case CREDIT_CARD_EXP_MONTH:
       return GetExpirationMonthSelectControlValue(
-          value, app_locale, field.options, failure_to_fill);
+          value, app_locale, field.options(), failure_to_fill);
     case CREDIT_CARD_EXP_2_DIGIT_YEAR:
     case CREDIT_CARD_EXP_4_DIGIT_YEAR:
-      return GetYearSelectControlValue(value, field.options, failure_to_fill);
+      return GetYearSelectControlValue(value, field.options(), failure_to_fill);
     case CREDIT_CARD_TYPE:
-      return GetCreditCardTypeSelectControlValue(value, field.options,
+      return GetCreditCardTypeSelectControlValue(value, field.options(),
                                                  failure_to_fill);
     default:
-      return GetSelectControlValue(value, field.options, failure_to_fill)
+      return GetSelectControlValue(value, field.options(), failure_to_fill)
           .value_or(u"");
   }
 }
diff --git a/components/autofill/core/browser/field_filling_payments_util_unittest.cc b/components/autofill/core/browser/field_filling_payments_util_unittest.cc
index aee1b26..d31da71 100644
--- a/components/autofill/core/browser/field_filling_payments_util_unittest.cc
+++ b/components/autofill/core/browser/field_filling_payments_util_unittest.cc
@@ -117,8 +117,8 @@
                                    mojom::ActionPersistence::kFill, field);
 
   ASSERT_FALSE(value_to_fill.empty());
-  content_index = GetIndexOfValue(field.options, value_to_fill);
-  EXPECT_EQ(u"Mar", field.options[content_index].content);
+  content_index = GetIndexOfValue(field.options(), value_to_fill);
+  EXPECT_EQ(u"Mar", field.options()[content_index].content);
 
   // Try a two-digit month.
   credit_card.SetExpirationMonth(11);
@@ -127,8 +127,8 @@
                                    mojom::ActionPersistence::kFill, field);
 
   ASSERT_FALSE(value_to_fill.empty());
-  content_index = GetIndexOfValue(field.options, value_to_fill);
-  EXPECT_EQ(u"Nov", field.options[content_index].content);
+  content_index = GetIndexOfValue(field.options(), value_to_fill);
+  EXPECT_EQ(u"Nov", field.options()[content_index].content);
 }
 
 struct CreditCardTestCase {
@@ -160,7 +160,7 @@
 TEST_F(FieldFillingPaymentsUtilTest,
        FillFormField_AutocompleteOff_CreditCardField) {
   AutofillField field;
-  field.should_autocomplete = false;
+  field.set_should_autocomplete(false);
   field.set_heuristic_type(GetActiveHeuristicSource(), CREDIT_CARD_NUMBER);
 
   CreditCard credit_card;
diff --git a/components/autofill/core/browser/form_data_importer.cc b/components/autofill/core/browser/form_data_importer.cc
index 9fa7de7..617ecd4 100644
--- a/components/autofill/core/browser/form_data_importer.cc
+++ b/components/autofill/core/browser/form_data_importer.cc
@@ -1011,7 +1011,7 @@
 
     std::u16string value_view = field->value();
     std::u16string_view user_input_view =
-        base::TrimWhitespace(field->user_input, base::TRIM_ALL);
+        base::TrimWhitespace(field->user_input(), base::TRIM_ALL);
     if (base::FeatureList::IsEnabled(
             features::kAutofillUseTypedCreditCardNumber) &&
         field_type == FieldType::CREDIT_CARD_NUMBER &&
@@ -1045,7 +1045,7 @@
     // month. Attempt to save with the option value. First find the index of the
     // option text in the select options and try the corresponding value.
     if (!saved && field_type == CREDIT_CARD_EXP_MONTH) {
-      for (const SelectOption& option : field->options) {
+      for (const SelectOption& option : field->options()) {
         if (value == option.content) {
           result.card.SetInfo(autofill_type, option.value, app_locale_);
           break;
@@ -1071,7 +1071,7 @@
     std::u16string_view value_view =
         base::TrimWhitespace(field.value(), base::TRIM_ALL);
     std::u16string_view user_input_view =
-        base::TrimWhitespace(field.user_input, base::TRIM_ALL);
+        base::TrimWhitespace(field.user_input(), base::TRIM_ALL);
     if (!user_input_view.empty() &&
         field.Type().GetStorableType() == FieldType::CREDIT_CARD_NUMBER &&
         base::FeatureList::IsEnabled(
@@ -1099,9 +1099,9 @@
         // expiration month. Attempt to save with the option value. First find
         // the index of the option text in the select options and try the
         // corresponding value.
-        if (auto it = base::ranges::find(field.options, value,
+        if (auto it = base::ranges::find(field.options(), value,
                                          &SelectOption::content);
-            it != field.options.end()) {
+            it != field.options().end()) {
           result.card.SetInfo(field.Type(), it->value, app_locale);
         }
       }
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc
index 9d431f05..b590db0 100644
--- a/components/autofill/core/browser/form_data_importer_unittest.cc
+++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -30,6 +30,7 @@
 #include "base/test/task_environment.h"
 #include "base/uuid.h"
 #include "build/build_config.h"
+#include "components/autofill/core/browser/address_data_manager_test_api.h"
 #include "components/autofill/core/browser/autofill_experiments.h"
 #include "components/autofill/core/browser/autofill_field.h"
 #include "components/autofill/core/browser/autofill_form_test_utils.h"
@@ -369,7 +370,7 @@
   FormData form =
       ConstructFormDateFromTypeValuePairs({{EMAIL_ADDRESS, kDefaultMail}});
   const char* autocomplete = "email";
-  form.fields[0].autocomplete_attribute = autocomplete;
+  form.fields[0].set_autocomplete_attribute(autocomplete);
   form.fields[0].set_parsed_autocomplete(
       ParseAutocompleteAttribute(autocomplete));
   return ConstructFormStructureFromFormData(form);
@@ -550,7 +551,8 @@
     test::DisableSystemServices(prefs_.get());
 
     personal_data_manager_ = autofill_client_->GetPersonalDataManager();
-    personal_data_manager_->set_auto_accept_address_imports_for_testing(true);
+    test_api(personal_data_manager_->address_data_manager())
+        .set_auto_accept_address_imports(true);
     personal_data_manager_->SetPrefService(prefs_.get());
     personal_data_manager_->SetSyncServiceForTest(&sync_service_);
 
@@ -1541,7 +1543,7 @@
   std::unique_ptr<FormStructure> form_structure =
       ConstructDefaultProfileFormStructure();
   // Set the Address line field as unfocusable.
-  form_structure->field(4)->is_focusable = false;
+  form_structure->field(4)->set_is_focusable(false);
   ExtractAddressProfileAndVerifyExtractionOfDefaultProfile(*form_structure);
 }
 
@@ -1598,7 +1600,7 @@
   for (FormFieldData& field : hidden_second_form.fields) {
     // Reset the values and make the field non focusable.
     field.set_value(u"");
-    field.is_focusable = false;
+    field.set_is_focusable(false);
   }
 
   // Append the fields of the second form to the first form.
@@ -1886,13 +1888,13 @@
 
   FormFieldData* card_number_field = form.FindFieldByName(u"card_number");
   ASSERT_TRUE(card_number_field != nullptr);
-  card_number_field->user_input = u"4444333322221111";
+  card_number_field->set_user_input(u"4444333322221111");
 
   // FormFieldData::user_input for non-credit card fields should be ignored.
   ASSERT_EQ(nullptr, form.FindFieldByName(u"cvc"));
   FormFieldData cvc_field =
       CreateTestFormField("CVC", "cvc", "001", FormControlType::kInputText);
-  cvc_field.user_input = u"002";
+  cvc_field.set_user_input(u"002");
   form.fields.push_back(cvc_field);
 
   FormStructure form_structure(form);
@@ -1955,11 +1957,11 @@
       "Biggie Smalls", "4111-1111-1111-1111", "Feb (2)", "2999");
   // Add option values and contents to the expiration month field.
   ASSERT_EQ(u"exp_month", form.fields[2].name());
-  form.fields[2].options = {
+  form.fields[2].set_options({
       {.value = u"1", .content = u"Jan (1)"},
       {.value = u"2", .content = u"Feb (2)"},
       {.value = u"3", .content = u"Mar (3)"},
-  };
+  });
 
   FormStructure form_structure(form);
   form_structure.DetermineHeuristicTypes(GeoIpCountryCode(""), nullptr,
@@ -3341,7 +3343,7 @@
       CreateTestFormField("Exp Year:", "exp_year", "2999",
                           FormControlType::kInputText)};
   for (FormFieldData& field : form.fields) {
-    field.is_focusable = false;
+    field.set_is_focusable(false);
   }
 
   FormStructure form_structure(form);
@@ -4381,7 +4383,7 @@
     f.set_server_predictions({test::CreateFieldPrediction(field_type)});
     f.set_value(std::move(value));
     f.set_is_autofilled(mode == Mode::kAutofilled);
-    f.is_user_edited = mode == Mode::kUserEdited;
+    f.set_is_user_edited(mode == Mode::kUserEdited);
   }
 
   FormStructure form_{/*form=*/{}};
diff --git a/components/autofill/core/browser/form_filler.cc b/components/autofill/core/browser/form_filler.cc
index ad3a76a0..6f4f0d9 100644
--- a/components/autofill/core/browser/form_filler.cc
+++ b/components/autofill/core/browser/form_filler.cc
@@ -267,7 +267,7 @@
     base::optional_ref<const std::u16string> cvc)
     : filled_field_id(field.global_id()),
       filled_field_signature(field.GetFieldSignature()),
-      filled_origin(field.origin),
+      filled_origin(field.origin()),
       original_fill_time(base::TimeTicks::Now()) {
   DCHECK(absl::holds_alternative<const CreditCard*>(profile_or_credit_card) ||
          !cvc.has_value());
@@ -595,7 +595,7 @@
       LOG_AF(buffer) << Tr{} << base::StringPrintf("Field %zu", i)
                      << GetSkipFieldFillLogMessage(
                             skip_reasons[autofill_field->global_id()]);
-      if (fill_event_id && !IsCheckable(autofill_field->check_status)) {
+      if (fill_event_id && !IsCheckable(autofill_field->check_status())) {
         // This lambda calculates a hash of the value Autofill would have used
         // if the field was skipped due to being pre-filled on page load. If the
         // field was not skipped due to being pre-filled, `std::nullopt` is
@@ -684,7 +684,7 @@
 
     // Log when the suggestion is selected and log on non-checkable fields that
     // have been filled.
-    if (fill_event_id && !IsCheckable(autofill_field->check_status)) {
+    if (fill_event_id && !IsCheckable(autofill_field->check_status())) {
       autofill_field->AppendLogEventIfNotRepeated(FillFieldLogEvent{
           .fill_event_id = *fill_event_id,
           .had_value_before_filling = ToOptionalBoolean(has_value_before),
@@ -726,7 +726,7 @@
   base::flat_set<FieldGlobalId> safe_fields =
       manager_->driver().ApplyFormAction(mojom::FormActionType::kFill,
                                          action_persistence, result_form,
-                                         trigger_field.origin, field_types);
+                                         trigger_field.origin(), field_types);
 
   // This will hold the fields (and autofill_fields) in the intersection of
   // safe_fields and newly_filled_fields_id.
@@ -750,7 +750,7 @@
       CHECK(newly_filled_field);
       safe_newly_filled_fields.cached.push_back(newly_filled_field);
 
-      if (fill_event_id && !IsCheckable(newly_filled_field->check_status)) {
+      if (fill_event_id && !IsCheckable(newly_filled_field->check_status())) {
         // The field's last field log event should be a type of
         // FillFieldLogEvent. Record in this FillFieldLogEvent object that this
         // newly filled field was actually filled after checking the iframe
@@ -783,7 +783,7 @@
       AutofillField* not_filled_field =
           form_structure->GetFieldById(it->global_id());
       CHECK(not_filled_field);
-      if (fill_event_id && !IsCheckable(not_filled_field->check_status)) {
+      if (fill_event_id && !IsCheckable(not_filled_field->check_status())) {
         base::optional_ref<AutofillField::FieldLogEventType>
             last_field_log_event = not_filled_field->last_field_log_event();
         CHECK(last_field_log_event.has_value());
@@ -897,7 +897,7 @@
   auto comparison_attributes =
       [&](const std::unique_ptr<AutofillField>& field) {
         return std::make_tuple(
-            field->origin == filling_context->filled_origin,
+            field->origin() == filling_context->filled_origin,
             field->IsFocusable(),
             field->global_id() == filling_context->filled_field_id,
             field->GetFieldSignature() ==
@@ -910,7 +910,7 @@
       it != form_structure->end() ? it->get() : nullptr;
   bool found_matching_element =
       autofill_field &&
-      autofill_field->origin == filling_context->filled_origin &&
+      autofill_field->origin() == filling_context->filled_origin &&
       (autofill_field->global_id() == filling_context->filled_field_id ||
        autofill_field->GetFieldSignature() ==
            filling_context->filled_field_signature);
@@ -1058,7 +1058,7 @@
     return false;
   }
   field_data.set_value(filling_content.value_to_fill);
-  field_data.force_override = filling_content.value_is_an_override;
+  field_data.set_force_override(filling_content.value_is_an_override);
 
   if (failure_to_fill) {
     *failure_to_fill = "Decided to fill";
diff --git a/components/autofill/core/browser/form_filler_unittest.cc b/components/autofill/core/browser/form_filler_unittest.cc
index 0871ec677..73f0fe0 100644
--- a/components/autofill/core/browser/form_filler_unittest.cc
+++ b/components/autofill/core/browser/form_filler_unittest.cc
@@ -834,7 +834,7 @@
   // Create a form where the middle name field has autocomplete=off.
   FormData form = test::CreateTestCreditCardFormData(/*is_https=*/true,
                                                      /*use_month_type=*/false);
-  form.fields.front().autocomplete_attribute = "unrecognized";
+  form.fields.front().set_autocomplete_attribute("unrecognized");
   FormsSeen({form});
 
   CreditCard credit_card = test::GetCreditCard();
@@ -850,7 +850,7 @@
 TEST_F(FormFillerTest, FillCreditCardForm_AutocompleteOffBehavior) {
   FormData form = test::CreateTestCreditCardFormData(/*is_https=*/true,
                                                      /*use_month_type=*/false);
-  form.fields.front().autocomplete_attribute = "off";
+  form.fields.front().set_autocomplete_attribute("off");
   FormsSeen({form});
 
   CreditCard credit_card = test::GetCreditCard();
@@ -927,15 +927,15 @@
       {.fields = {{.role = NAME_FULL, .autocomplete_attribute = "name"},
                   {.role = ADDRESS_HOME_COUNTRY,
                    .autocomplete_attribute = "country"}}});
-  form.fields.back().is_focusable = false;
+  form.fields.back().set_is_focusable(false);
   form.fields.push_back(test::CreateTestSelectOrSelectListField(
       "Country", "country", "", "country", {"CA", "US"},
       {"Canada", "United States"}, FormControlType::kSelectList));
-  form.fields.back().is_focusable = false;
+  form.fields.back().set_is_focusable(false);
   form.fields.push_back(test::CreateTestSelectOrSelectListField(
       "Country", "country", "", "country", {"CA", "US"},
       {"Canada", "United States"}, FormControlType::kSelectOne));
-  form.fields.back().is_focusable = false;
+  form.fields.back().set_is_focusable(false);
   FormsSeen({form});
 
   AutofillProfile profile = test::GetFullProfile();
@@ -1170,7 +1170,7 @@
     form_with_us_number_max_length.fields.push_back(field);
 
     field.set_max_length(default_max_length);
-    field.autocomplete_attribute = test_field.autocomplete_attribute;
+    field.set_autocomplete_attribute(test_field.autocomplete_attribute);
     field.set_parsed_autocomplete(
         ParseAutocompleteAttribute(test_field.autocomplete_attribute));
     form_with_autocompletetype.fields.push_back(field);
@@ -1442,18 +1442,18 @@
   form.fields.push_back(
       test::CreateTestSelectField("Country", "country", "", "country",
                                   {"CA", "US"}, {"Canada", "United States"}));
-  form.fields.back().is_focusable = false;
+  form.fields.back().set_is_focusable(false);
   form.fields.push_back(
       test::CreateTestSelectField("State", "state", "", "address-level1",
                                   {"NY", "CA"}, {"New York", "California"}));
-  form.fields.back().role = FormFieldData::RoleAttribute::kPresentation;
+  form.fields.back().set_role(FormFieldData::RoleAttribute::kPresentation);
 
   form.fields.push_back(test::CreateTestFormField("City", "city", "",
                                                   FormControlType::kInputText));
-  form.fields.back().is_focusable = false;
+  form.fields.back().set_is_focusable(false);
   form.fields.push_back(test::CreateTestFormField(
       "Street Address", "address", "", FormControlType::kInputText, "address"));
-  form.fields.back().role = FormFieldData::RoleAttribute::kPresentation;
+  form.fields.back().set_role(FormFieldData::RoleAttribute::kPresentation);
   FormsSeen({form});
 
   base::HistogramTester histogram_tester;
@@ -1577,8 +1577,8 @@
   // Two other fields will show up. Select the second profile. The fields that
   // were already filled, would be left unchanged, and the rest would be filled
   // with the second profile.
-  filled_form.fields[2].is_focusable = true;
-  filled_form.fields[3].is_focusable = true;
+  filled_form.fields[2].set_is_focusable(true);
+  filled_form.fields[3].set_is_focusable(true);
 
   // Reparse the form to validate the visibility changes. Fast forward so that
   // no refill is triggered automatically.
@@ -1785,7 +1785,7 @@
     EXPECT_EQ(refilled_form.fields[0].global_id(), form.fields[2].global_id());
     EXPECT_THAT(refilled_form.fields[0],
                 AutofilledWith(test_case.refilled_exp_date));
-    EXPECT_TRUE(refilled_form.fields[0].force_override);
+    EXPECT_TRUE(refilled_form.fields[0].force_override());
   }
 }
 
diff --git a/components/autofill/core/browser/form_forest.cc b/components/autofill/core/browser/form_forest.cc
index e776d90..0488dda 100644
--- a/components/autofill/core/browser/form_forest.cc
+++ b/components/autofill/core/browser/form_forest.cc
@@ -590,8 +590,8 @@
           };
       const url::Origin& main_origin = browser_form.main_frame_origin;
       return security_options.all_origins_are_trusted() ||
-             field.origin == security_options.triggered_origin() ||
-             (field.origin == main_origin &&
+             field.origin() == security_options.triggered_origin() ||
+             (field.origin() == main_origin &&
               !IsSensitiveFieldType(
                   security_options.GetFieldType(field.global_id())) &&
               HasSharedAutofillPermission(renderer_form->host_frame)) ||
diff --git a/components/autofill/core/browser/form_forest_test_api.cc b/components/autofill/core/browser/form_forest_test_api.cc
index 2b19739..db80c8d 100644
--- a/components/autofill/core/browser/form_forest_test_api.cc
+++ b/components/autofill/core/browser/form_forest_test_api.cc
@@ -99,8 +99,8 @@
   i = 0;
   for (const FormFieldData& field : form.fields) {
     os << prefix << std::setfill(' ') << std::setw(2) << ++i << ". Field "
-       << *field.renderer_id() << " at " << field.host_frame << " at "
-       << field.origin.Serialize() << std::endl;
+       << *field.renderer_id() << " at " << field.host_frame() << " at "
+       << field.origin().Serialize() << std::endl;
     if (!field.id_attribute().empty()) {
       os << prefix << "    ID " << field.id_attribute() << std::endl;
     }
diff --git a/components/autofill/core/browser/form_forest_unittest.cc b/components/autofill/core/browser/form_forest_unittest.cc
index d7dc27f4..04970b05 100644
--- a/components/autofill/core/browser/form_forest_unittest.cc
+++ b/components/autofill/core/browser/form_forest_unittest.cc
@@ -75,14 +75,15 @@
   return AllOf(
       Property("global_id", &FormFieldData::global_id, exp.global_id()),
       Property("name", &FormFieldData::name, exp.name()),
-      Field("host_form_id", &FormFieldData::host_form_id, exp.host_form_id),
-      Field("origin", &FormFieldData::origin, exp.origin),
+      Property("host_form_id", &FormFieldData::host_form_id,
+               exp.host_form_id()),
+      Property("origin", &FormFieldData::origin, exp.origin()),
       Property("form_control_type", &FormFieldData::form_control_type,
                exp.form_control_type()),
       Property("value", &FormFieldData::value, exp.value()),
       Property("label", &FormFieldData::label, exp.label()),
-      Field("host_form_signature", &FormFieldData::host_form_signature,
-            exp.host_form_signature));
+      Property("host_form_signature", &FormFieldData::host_form_signature,
+               exp.host_form_signature()));
 }
 
 // The relevant attributes are FormData::global_id(), FormData::fields.
@@ -315,9 +316,9 @@
     form.host_frame = GetFrameToken();
     form.main_frame_origin = origin_;
     for (FormFieldData& field : form.fields) {
-      field.host_frame = form.host_frame;
-      field.host_form_id = form.renderer_id;
-      field.origin = origin_;
+      field.set_host_frame(form.host_frame);
+      field.set_host_form_id(form.renderer_id);
+      field.set_origin(origin_);
     }
   }
 
@@ -1190,7 +1191,7 @@
     size_t target_index = p.target.field_index;
 
     FormFieldData field = source_form.fields[source_index];
-    field.host_form_id = target_form.renderer_id;
+    field.set_host_form_id(target_form.renderer_id);
 
     if (source_index > target_index) {
       source_form.fields.erase(source_form.fields.begin() + source_index);
diff --git a/components/autofill/core/browser/form_parsing/credit_card_field_parser.cc b/components/autofill/core/browser/form_parsing/credit_card_field_parser.cc
index 18233fc..6f147a2e 100644
--- a/components/autofill/core/browser/form_parsing/credit_card_field_parser.cc
+++ b/components/autofill/core/browser/form_parsing/credit_card_field_parser.cc
@@ -293,8 +293,9 @@
     return false;
   }
 
-  if (field->options.size() < 12 || field->options.size() > 13)
+  if (field->options().size() < 12 || field->options().size() > 13) {
     return false;
+  }
 
   auto matches_december = [](const SelectOption& option) {
     static constexpr char16_t kNumericalDecemberRe[] = u"12";
@@ -308,8 +309,8 @@
            MatchesRegex<kNumericalYearRe>(option.content);
   };
   // If in doubt, return false.
-  return matches_december(field->options.back()) &&
-         !base::ranges::any_of(field->options, matches_year);
+  return matches_december(field->options().back()) &&
+         !base::ranges::any_of(field->options(), matches_year);
 }
 
 // static
@@ -333,8 +334,9 @@
     static constexpr char16_t kSingleDigitDateRe[] = u"\\b[1-9]\\b";
     return MatchesRegex<kSingleDigitDateRe>(option.content);
   };
-  if (base::ranges::any_of(field->options, matches_single_digit_date))
+  if (base::ranges::any_of(field->options(), matches_single_digit_date)) {
     return false;
+  }
 
   // Another way to eliminate days - filter out 'day' fields.
   base::span<const MatchPatternRef> day_patterns =
@@ -353,8 +355,9 @@
     static constexpr char16_t kBirthYearRe[] = u"(1999|99)";
     return MatchesRegex<kBirthYearRe>(option.content);
   };
-  if (base::ranges::any_of(field->options, matches_birth_year))
+  if (base::ranges::any_of(field->options(), matches_birth_year)) {
     return false;
+  }
 
   // Test if three consecutive items in `field->options` mention three
   // consecutive year dates.
@@ -379,15 +382,15 @@
     // While 23 is a valid expiration year, the selector is not a expiration
     // year selector. In case we find a single-digit entry, we reject this as
     // an expiration year selector.
-    if (base::Contains(field->options, u"2", option_projection)) {
+    if (base::Contains(field->options(), u"2", option_projection)) {
       return false;
     }
     auto is_substring = [](std::u16string_view option,
                            std::u16string_view year_needle) {
       return option.find(year_needle) != std::u16string_view::npos;
     };
-    return base::ranges::search(field->options, year_needles, is_substring,
-                                option_projection) != field->options.end();
+    return base::ranges::search(field->options(), year_needles, is_substring,
+                                option_projection) != field->options().end();
   };
   return OptionsContain(years_to_check_2_digit, &SelectOption::value) ||
          OptionsContain(years_to_check_2_digit, &SelectOption::content);
@@ -412,10 +415,10 @@
   // a pretty common mistake; e.g., "Master card" instead of "Mastercard".
   bool isSelect = (FindShortestSubstringMatchInSelect(
                        l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_VISA), true,
-                       field->options) >= 0) ||
+                       field->options()) >= 0) ||
                   (FindShortestSubstringMatchInSelect(
                        l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_MASTERCARD),
-                       true, field->options) >= 0);
+                       true, field->options()) >= 0);
   return isSelect;
 }
 
@@ -689,12 +692,12 @@
     // If you add new languages, also update other places labeled with
     // [EXP_DATE_FORMAT].
     static constexpr char16_t kYYYYRegex[] = u"yyyy|aaaa|jjjj";
-    if (MatchesRegex<kYYYYRegex>(field.placeholder, nullptr) ||
+    if (MatchesRegex<kYYYYRegex>(field.placeholder(), nullptr) ||
         MatchesRegex<kYYYYRegex>(field.label(), nullptr)) {
       return CREDIT_CARD_EXP_4_DIGIT_YEAR;
     }
     static constexpr char16_t kYYRegex[] = u"yy|aa|jj";
-    if (MatchesRegex<kYYRegex>(field.placeholder, nullptr) ||
+    if (MatchesRegex<kYYRegex>(field.placeholder(), nullptr) ||
         MatchesRegex<kYYRegex>(field.label(), nullptr)) {
       return CREDIT_CARD_EXP_2_DIGIT_YEAR;
     }
@@ -716,13 +719,14 @@
     // While 23 is a valid expiration year, the selector is not a expiration
     // year selector. In case we find a single-digit entry, we reject this as
     // an expiration year selector.
-    if (base::Contains(field.options, u"2", option_projection)) {
+    if (base::Contains(field.options(), u"2", option_projection)) {
       return false;
     }
     auto is_substring = [&year_needle](std::u16string_view option) {
       return option.find(year_needle) != std::u16string_view::npos;
     };
-    return base::ranges::any_of(field.options, is_substring, option_projection);
+    return base::ranges::any_of(field.options(), is_substring,
+                                option_projection);
   };
   if (field.IsSelectOrSelectListElement()) {
     base::Time::Exploded time_exploded;
@@ -810,13 +814,13 @@
     //           ^^^^^ opt separator
     //                ^^^ opt white space
     //                       ^^^^^^^^^^^^^^ year
-    matches = MatchesRegex<kFormatRegex>(field.placeholder, &groups) ||
+    matches = MatchesRegex<kFormatRegex>(field.placeholder(), &groups) ||
               MatchesRegex<kFormatRegex>(field.label(), &groups);
     // Support "--/--" and "--/----" as recognized placeholders.
     if (!matches) {
       static constexpr char16_t kFormatRegEx2[] =
           u"(?:--|__)(\\s?/\\s?)(-{2,4}|_{2,4})";
-      matches = MatchesRegex<kFormatRegEx2>(field.placeholder, &groups) ||
+      matches = MatchesRegex<kFormatRegEx2>(field.placeholder(), &groups) ||
                 MatchesRegex<kFormatRegEx2>(field.label(), &groups);
     }
   } else {
@@ -825,7 +829,7 @@
     //                                                  ^^^^^ opt separator
     //                                                       ^^^ opt white space
     //                                                         year ^^^^^^^
-    matches = MatchesRegex<kFormatRegEx>(field.placeholder, &groups) ||
+    matches = MatchesRegex<kFormatRegEx>(field.placeholder(), &groups) ||
               MatchesRegex<kFormatRegEx>(field.label(), &groups);
   }
 
diff --git a/components/autofill/core/browser/form_parsing/credit_card_field_parser_unittest.cc b/components/autofill/core/browser/form_parsing/credit_card_field_parser_unittest.cc
index 50a1a11..6655e228 100644
--- a/components/autofill/core/browser/form_parsing/credit_card_field_parser_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/credit_card_field_parser_unittest.cc
@@ -150,7 +150,7 @@
   AddTextFormFieldData("card_number", "Card Number", CREDIT_CARD_NUMBER);
   AddTextFormFieldData("ccmonth", "Exp Month", CREDIT_CARD_EXP_MONTH);
   AddTextFormFieldData("ccyear", "Exp Year", CREDIT_CARD_EXP_2_DIGIT_YEAR);
-  fields_.back()->placeholder = u"YY";
+  fields_.back()->set_placeholder(u"YY");
   ClassifyAndVerify(ParseResult::kParsed);
 }
 
@@ -164,7 +164,7 @@
   // Even though the placehodler indicates YYYY, the max-length only enables
   // a YY expiration format.
   fields_.back()->set_max_length(2u);
-  fields_.back()->placeholder = u"YYYY";
+  fields_.back()->set_placeholder(u"YYYY");
   ClassifyAndVerify(ParseResult::kParsed);
 }
 
diff --git a/components/autofill/core/browser/form_parsing/form_field_parser.cc b/components/autofill/core/browser/form_parsing/form_field_parser.cc
index 6695b72..16c6b854 100644
--- a/components/autofill/core/browser/form_parsing/form_field_parser.cc
+++ b/components/autofill/core/browser/form_parsing/form_field_parser.cc
@@ -567,8 +567,8 @@
     // interferes with correctly understanding ADDRESS_LINE2.
     // Ignore fields marked as presentational, unless for 'select' fields (for
     // synthetic fields.)
-    if (IsCheckable(field->check_status) ||
-        (field->role == FormFieldData::RoleAttribute::kPresentation &&
+    if (IsCheckable(field->check_status()) ||
+        (field->role() == FormFieldData::RoleAttribute::kPresentation &&
          !field->IsSelectElement())) {
       continue;
     }
@@ -612,7 +612,7 @@
     value = name;
   } else if (match_label && pattern != kEmptyLabelRegex &&
              context.autofill_always_parse_placeholders &&
-             MatchesRegexWithCache(context, field->placeholder, pattern,
+             MatchesRegexWithCache(context, field->placeholder(), pattern,
                                    capture_destination)) {
     // Placeholders are matched against the same regexes as labels. However, to
     // prevent false positives in `ParseEmptyLabel()`, matches in placeholders
@@ -623,7 +623,7 @@
     // Reorder once the change is rolled out.
     found_match = true;
     match_type_string = "Match in placeholder";
-    value = field->placeholder;
+    value = field->placeholder();
   }
 
   if (found_match && capture_destination) {
diff --git a/components/autofill/core/browser/form_parsing/parsing_test_utils.cc b/components/autofill/core/browser/form_parsing/parsing_test_utils.cc
index 02f3003..2583f3ec7 100644
--- a/components/autofill/core/browser/form_parsing/parsing_test_utils.cc
+++ b/components/autofill/core/browser/form_parsing/parsing_test_utils.cc
@@ -82,7 +82,7 @@
     FieldType expected_type) {
   AddFormFieldData(FormControlType::kSelectOne, name, label, expected_type);
   FormFieldData* field_data = fields_.back().get();
-  field_data->options = options;
+  field_data->set_options(options);
 }
 
 // Convenience wrapper for text control elements.
diff --git a/components/autofill/core/browser/form_parsing/phone_field_parser.cc b/components/autofill/core/browser/form_parsing/phone_field_parser.cc
index 36835726..3ca1b3f 100644
--- a/components/autofill/core/browser/form_parsing/phone_field_parser.cc
+++ b/components/autofill/core/browser/form_parsing/phone_field_parser.cc
@@ -173,18 +173,19 @@
 
   // If the number of the options is less than the minimum limit or more than
   // the maximum limit, return false.
-  if (field->options.size() < kMinSelectOptionsForCountryCode ||
-      field->options.size() >= kMaxSelectOptionsForCountryCode)
+  if (field->options().size() < kMinSelectOptionsForCountryCode ||
+      field->options().size() >= kMaxSelectOptionsForCountryCode) {
     return false;
+  }
 
   // |total_covered_options| stores the count of the options that are
   // compared with the regex.
-  int total_num_options = static_cast<int>(field->options.size());
+  int total_num_options = static_cast<int>(field->options().size());
 
   // |total_positive_options| stores the count of the options that match the
   // regex.
   int total_positive_options =
-      base::ranges::count_if(field->options, [](const SelectOption& option) {
+      base::ranges::count_if(field->options(), [](const SelectOption& option) {
         return MatchesRegex<kAugmentedPhoneCountryCodeRe>(option.content);
       });
 
@@ -330,8 +331,8 @@
             features::kAutofillDefaultToCityAndNumber)) {
       const AutofillField* field = parsed_phone_fields_[FIELD_PHONE];
       if (field->label().find(u"+") != std::u16string::npos ||
-          field->placeholder.find(u"+") != std::u16string::npos ||
-          field->aria_description.find(u"+") != std::u16string::npos) {
+          field->placeholder().find(u"+") != std::u16string::npos ||
+          field->aria_description().find(u"+") != std::u16string::npos) {
         AddClassification(field, PHONE_HOME_WHOLE_NUMBER, kBasePhoneParserScore,
                           field_candidates);
       } else {
diff --git a/components/autofill/core/browser/form_parsing/phone_field_parser_unittest.cc b/components/autofill/core/browser/form_parsing/phone_field_parser_unittest.cc
index bbb842f3..54cbc91 100644
--- a/components/autofill/core/browser/form_parsing/phone_field_parser_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/phone_field_parser_unittest.cc
@@ -122,10 +122,11 @@
   field.set_label(field_data.label);
   field.set_name(field_data.name);
   field.set_max_length(field_data.max_length);
+  std::vector<SelectOption> options;
   for (auto* const element : field_data.options) {
-    field.options.push_back(
-        {.value = u"", .content = base::UTF8ToUTF16(element)});
+    options.push_back({.value = u"", .content = base::UTF8ToUTF16(element)});
   }
+  field.set_options(std::move(options));
   field.set_renderer_id(MakeFieldRendererId());
   list_.push_back(std::make_unique<AutofillField>(field));
   return list_.back()->global_id();
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index 8344ad2e..2ccaf129 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -130,7 +130,7 @@
       child_frames_(form.child_frames) {
   // Copy the form fields.
   for (const FormFieldData& field : form.fields) {
-    if (!IsCheckable(field.check_status)) {
+    if (!IsCheckable(field.check_status())) {
       ++active_field_count_;
     }
 
@@ -281,7 +281,7 @@
     for (const auto& field : form_structure->fields_) {
       FormFieldDataPredictions annotated_field;
       annotated_field.host_form_signature =
-          base::NumberToString(field->host_form_signature.value());
+          base::NumberToString(field->host_form_signature().value());
       annotated_field.signature = field->FieldSignatureAsStr();
       annotated_field.heuristic_type =
           FieldTypeToStringView(field->heuristic_type());
@@ -1176,13 +1176,13 @@
     buffer << "\n Field " << i << ": ";
     const AutofillField* field = form.field(i);
     buffer << "\n  Identifiers:"
-           << base::StrCat({"renderer id: ",
-                            base::NumberToString(field->renderer_id().value()),
-                            ", host frame: ",
-                            field->renderer_form_id().frame_token.ToString(),
-                            " (", field->origin.Serialize(),
-                            "), host form renderer id: ",
-                            base::NumberToString(field->host_form_id.value())});
+           << base::StrCat(
+                  {"renderer id: ",
+                   base::NumberToString(field->renderer_id().value()),
+                   ", host frame: ",
+                   field->renderer_form_id().frame_token.ToString(), " (",
+                   field->origin().Serialize(), "), host form renderer id: ",
+                   base::NumberToString(field->host_form_id().value())});
     buffer << "\n  Signature: "
            << base::StrCat(
                   {base::NumberToString(field->GetFieldSignature().value()),
@@ -1190,10 +1190,10 @@
                    base::NumberToString(
                        HashFieldSignature(field->GetFieldSignature())),
                    ", host form signature: ",
-                   base::NumberToString(field->host_form_signature.value()),
+                   base::NumberToString(field->host_form_signature().value()),
                    " - ",
                    base::NumberToString(
-                       HashFormSignature(field->host_form_signature))});
+                       HashFormSignature(field->host_form_signature()))});
     buffer << "\n  Name: " << field->parseable_name();
 
     auto type = field->Type().ToStringView();
@@ -1257,13 +1257,13 @@
     buffer << Tag{"td"};
     buffer << Tag{"table"};
     buffer << Tr{} << "Identifiers:"
-           << base::StrCat({"renderer id: ",
-                            base::NumberToString(field->renderer_id().value()),
-                            ", host frame: ",
-                            field->renderer_form_id().frame_token.ToString(),
-                            " (", field->origin.Serialize(),
-                            "), host form renderer id: ",
-                            base::NumberToString(field->host_form_id.value())});
+           << base::StrCat(
+                  {"renderer id: ",
+                   base::NumberToString(field->renderer_id().value()),
+                   ", host frame: ",
+                   field->renderer_form_id().frame_token.ToString(), " (",
+                   field->origin().Serialize(), "), host form renderer id: ",
+                   base::NumberToString(field->host_form_id().value())});
     buffer << Tr{} << "Signature:"
            << base::StrCat(
                   {base::NumberToString(field->GetFieldSignature().value()),
@@ -1271,12 +1271,12 @@
                    base::NumberToString(
                        HashFieldSignature(field->GetFieldSignature())),
                    ", host form signature: ",
-                   base::NumberToString(field->host_form_signature.value()),
+                   base::NumberToString(field->host_form_signature().value()),
                    " - ",
                    base::NumberToString(
-                       HashFormSignature(field->host_form_signature))});
+                       HashFormSignature(field->host_form_signature()))});
     buffer << Tr{} << "Name:" << field->parseable_name();
-    buffer << Tr{} << "Placeholder:" << field->placeholder;
+    buffer << Tr{} << "Placeholder:" << field->placeholder();
 
     auto type = field->Type().ToStringView();
     auto heuristic_type = FieldTypeToStringView(field->heuristic_type());
@@ -1313,7 +1313,7 @@
     buffer << Tr{} << "Is focusable:"
            << (field->IsFocusable() ? "Yes (focusable)" : "No (unfocusable)");
     buffer << Tr{} << "Is visible:"
-           << (field->is_visible ? "Yes (visible)" : "No (invisible)");
+           << (field->is_visible() ? "Yes (visible)" : "No (invisible)");
     buffer << Tr{} << "Ranks: "
            << base::StringPrintf(
                   "Field rank: %zu, rank in signature group: %zu, "
diff --git a/components/autofill/core/browser/form_structure_rationalizer.cc b/components/autofill/core/browser/form_structure_rationalizer.cc
index 86b2930..998a47f 100644
--- a/components/autofill/core/browser/form_structure_rationalizer.cc
+++ b/components/autofill/core/browser/form_structure_rationalizer.cc
@@ -435,7 +435,7 @@
     const url::Origin& main_origin,
     LogManager* log_manager) {
   auto is_in_subframe = [&main_origin](const FormFieldData& field) {
-    return field.origin != main_origin;
+    return field.origin() != main_origin;
   };
   auto rationalize = [&](FieldType relevant_type) {
     auto is_relevant = [relevant_type](const AutofillField& field) {
diff --git a/components/autofill/core/browser/form_structure_rationalizer_unittest.cc b/components/autofill/core/browser/form_structure_rationalizer_unittest.cc
index d3d64590..f4cf91dc 100644
--- a/components/autofill/core/browser/form_structure_rationalizer_unittest.cc
+++ b/components/autofill/core/browser/form_structure_rationalizer_unittest.cc
@@ -101,16 +101,16 @@
           {.section = std::string(field_template.section)}));
     }
     field.set_form_control_type(field_template.form_control_type);
-    field.is_focusable = field_template.is_focusable;
+    field.set_is_focusable(field_template.is_focusable);
     field.set_max_length(field_template.max_length);
     field.set_parsed_autocomplete(field_template.parsed_autocomplete);
-    field.role = field_template.role;
-    field.origin =
-        field_template.subframe_origin.value_or(form.main_frame_origin);
-    field.host_frame =
-        field_template.host_form.value_or(form.global_id()).frame_token;
-    field.host_form_id =
-        field_template.host_form.value_or(form.global_id()).renderer_id;
+    field.set_role(field_template.role);
+    field.set_origin(
+        field_template.subframe_origin.value_or(form.main_frame_origin));
+    field.set_host_frame(
+        field_template.host_form.value_or(form.global_id()).frame_token);
+    field.set_host_form_id(
+        field_template.host_form.value_or(form.global_id()).renderer_id);
     field.set_renderer_id(test::MakeFieldRendererId());
     form.fields.push_back(std::move(field));
   }
diff --git a/components/autofill/core/browser/form_structure_sectioning_util_unittest.cc b/components/autofill/core/browser/form_structure_sectioning_util_unittest.cc
index e1d342c..98b3af2 100644
--- a/components/autofill/core/browser/form_structure_sectioning_util_unittest.cc
+++ b/components/autofill/core/browser/form_structure_sectioning_util_unittest.cc
@@ -67,7 +67,7 @@
       f->set_parsed_autocomplete(AutocompleteParsingResult{
           .section = t.autocomplete_section, .mode = t.autocomplete_mode});
     }
-    f->is_focusable = t.is_focusable;
+    f->set_is_focusable(t.is_focusable);
   }
   return result;
 }
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc
index 92ba841..747d534 100644
--- a/components/autofill/core/browser/form_structure_unittest.cc
+++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -345,7 +345,7 @@
   // Start with a single checkable field.
   {
     FormFieldData field;
-    field.check_status = FormFieldData::CheckStatus::kCheckableButUnchecked;
+    field.set_check_status(FormFieldData::CheckStatus::kCheckableButUnchecked);
     field.set_form_control_type(FormControlType::kInputRadio);
     AddField(field);
   }
@@ -356,7 +356,7 @@
   // Add a second checkable field.
   {
     FormFieldData field;
-    field.check_status = FormFieldData::CheckStatus::kCheckableButUnchecked;
+    field.set_check_status(FormFieldData::CheckStatus::kCheckableButUnchecked);
     field.set_form_control_type(FormControlType::kInputCheckbox);
     AddField(field);
   }
@@ -2137,7 +2137,7 @@
   field.set_label(u"Select");
   field.set_name(u"Select");
   field.set_form_control_type(FormControlType::kInputCheckbox);
-  field.check_status = FormFieldData::CheckStatus::kCheckableButUnchecked;
+  field.set_check_status(FormFieldData::CheckStatus::kCheckableButUnchecked);
   field.set_renderer_id(test::MakeFieldRendererId());
   form.fields.push_back(field);
 
@@ -2165,7 +2165,7 @@
             form_structure->FormSignatureAsStr());
 
   // Checks how digits are removed from field names.
-  field.check_status = FormFieldData::CheckStatus::kNotCheckable;
+  field.set_check_status(FormFieldData::CheckStatus::kNotCheckable);
   field.set_label(u"Random Field label");
   field.set_name(u"random1234");
   field.set_form_control_type(FormControlType::kInputText);
@@ -2672,7 +2672,7 @@
                                             kFieldMaxLength));
   form.fields.push_back(CreateTestFormField(
       "Phone", "phone", "", FormControlType::kInputText, "", kFieldMaxLength));
-  form.fields.back().is_focusable = false;  // hidden
+  form.fields.back().set_is_focusable(false);  // hidden
   form.fields.push_back(CreateTestFormField("Full Name", "fullName", "",
                                             FormControlType::kInputText,
                                             "shipping name", kFieldMaxLength));
@@ -2781,8 +2781,8 @@
     field.set_form_control_type(FormControlType::kInputText);
     field.set_name(name);
     field.set_renderer_id(test::MakeFieldRendererId());
-    field.host_frame = frame_token;
-    field.host_form_id = host_form_id;
+    field.set_host_frame(frame_token);
+    field.set_host_form_id(host_form_id);
     form.fields.push_back(field);
   };
 
diff --git a/components/autofill/core/browser/heuristic_classification_unittests.cc b/components/autofill/core/browser/heuristic_classification_unittests.cc
index cbd01152..8c2ad70 100644
--- a/components/autofill/core/browser/heuristic_classification_unittests.cc
+++ b/components/autofill/core/browser/heuristic_classification_unittests.cc
@@ -346,33 +346,35 @@
   }
   if (const std::string* autocomplete =
           field_dict.FindString("autocomplete_attr")) {
-    field.autocomplete_attribute = *autocomplete;
+    field.set_autocomplete_attribute(*autocomplete);
     field.set_parsed_autocomplete(ParseAutocompleteAttribute(*autocomplete));
   }
   if (const std::string* placeholder =
           field_dict.FindString("placeholder_attr")) {
-    field.placeholder = base::UTF8ToUTF16(*placeholder);
+    field.set_placeholder(base::UTF8ToUTF16(*placeholder));
   }
   if (const std::string* maxlength = field_dict.FindString("maxlength_attr")) {
     uint64_t max_length = 0;
     base::StringToUint64(*maxlength, &max_length);
     field.set_max_length(max_length);
   }
-  field.is_focusable = true;
-  field.role = FormFieldData::RoleAttribute::kOther;
-  field.origin = form_data.main_frame_origin;
-  field.host_frame = form_data.host_frame;
-  field.host_form_id = form_data.renderer_id;
+  field.set_is_focusable(true);
+  field.set_role(FormFieldData::RoleAttribute::kOther);
+  field.set_origin(form_data.main_frame_origin);
+  field.set_host_frame(form_data.host_frame);
+  field.set_host_form_id(form_data.renderer_id);
   field.set_renderer_id(test::MakeFieldRendererId());
-  if (const base::Value::List* options =
+  std::vector<SelectOption> options;
+  if (const base::Value::List* select_options =
           field_dict.FindList("select_options")) {
-    for (const base::Value& option : *options) {
+    for (const base::Value& option : *select_options) {
       const base::Value::Dict& option_dict = option.GetDict();
-      field.options.push_back(SelectOption{
+      options.push_back(SelectOption{
           .value = base::UTF8ToUTF16(*option_dict.FindString("value")),
           .content = base::UTF8ToUTF16(*option_dict.FindString("label"))});
     }
   }
+  field.set_options(std::move(options));
   return field;
 }
 
diff --git a/components/autofill/core/browser/metrics/autofill_metrics.cc b/components/autofill/core/browser/metrics/autofill_metrics.cc
index 57d6e71b..9a4a4da 100644
--- a/components/autofill/core/browser/metrics/autofill_metrics.cc
+++ b/components/autofill/core/browser/metrics/autofill_metrics.cc
@@ -1245,7 +1245,7 @@
   FormType form_type = FieldTypeGroupToFormType(field.Type().group());
   if (form_type == FormType::kAddressForm ||
       form_type == FormType::kCreditCardForm) {
-    bool autocomplete_off = field.autocomplete_attribute == "off";
+    bool autocomplete_off = field.autocomplete_attribute() == "off";
     const std::string autocomplete_histogram = base::StrCat(
         {"Autofill.Autocomplete.", autocomplete_off ? "Off" : "NotOff",
          ".EditedAutofilledFieldAtSubmission2.",
@@ -1680,8 +1680,9 @@
         continue;
       if (only_after_security_policy && !p.safe_fields->contains(id))
         continue;
-      if (only_visible_fields && !field->is_visible)
+      if (only_visible_fields && !field->is_visible()) {
         continue;
+      }
       autofilled_types.insert(field->Type().GetStorableType());
     }
     return CreditCardSeamlessness(autofilled_types);
@@ -1771,9 +1772,9 @@
       }
     };
     const url::Origin& main_origin = p.form->main_frame_origin();
-    const url::Origin& triggered_origin = p.field->origin;
-    return field.origin != triggered_origin &&
-           (field.origin != main_origin ||
+    const url::Origin& triggered_origin = p.field->origin();
+    return field.origin() != triggered_origin &&
+           (field.origin() != main_origin ||
             IsSensitiveFieldType(field.Type().GetStorableType())) &&
            triggered_origin == main_origin;
   };
@@ -2330,7 +2331,7 @@
   SetStatusVector(AutofillStatus::kWasFocused,
                   OptionalBooleanToBool(was_focused));
   SetStatusVector(AutofillStatus::kIsInSubFrame,
-                  form.ToFormData().host_frame != field.host_frame);
+                  form.ToFormData().host_frame != field.host_frame());
 
   if (filling_prevented_by_iframe_security_policy !=
       OptionalBoolean::kUndefined) {
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc b/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc
index c67be5b..3543b281 100644
--- a/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc
+++ b/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc
@@ -4,6 +4,7 @@
 
 #include "components/autofill/core/browser/metrics/autofill_metrics_test_base.h"
 
+#include "components/autofill/core/browser/address_data_manager_test_api.h"
 #include "components/autofill/core/browser/autofill_form_test_utils.h"
 #include "components/autofill/core/browser/data_model/credit_card.h"
 #include "components/autofill/core/browser/payments/credit_card_access_manager.h"
@@ -51,7 +52,8 @@
   autofill_client_ = std::make_unique<MockAutofillClient>();
   autofill_client_->SetPrefs(test::PrefServiceForTesting());
 
-  personal_data().set_auto_accept_address_imports_for_testing(true);
+  test_api(personal_data().address_data_manager())
+      .set_auto_accept_address_imports(true);
   personal_data().SetPrefService(autofill_client_->GetPrefs());
   personal_data().SetSyncServiceForTest(&sync_service_);
 
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
index 81cc21a9..47349fa 100644
--- a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
+++ b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
@@ -214,7 +214,7 @@
                    .value = u"Elvis Aaron Presley",
                    .is_autofilled = true},
                   {.role = CREDIT_CARD_NUMBER, .value = u"01230123012399"}}});
-  payments_form.fields.back().is_user_edited = true;
+  payments_form.fields.back().set_is_user_edited(true);
   autofill_manager().AddSeenForm(address_form, {NAME_FULL, ADDRESS_HOME_LINE1});
   autofill_manager().AddSeenForm(payments_form,
                                  {CREDIT_CARD_NAME_FULL, CREDIT_CARD_NUMBER});
@@ -328,10 +328,10 @@
                           FormControlType::kSelectOne)  // doesn't skip
   });
 
-  form.fields[1].is_focusable = false;
-  form.fields[2].role = FormFieldData::RoleAttribute::kPresentation;
-  form.fields[3].is_focusable = false;
-  form.fields[4].role = FormFieldData::RoleAttribute::kPresentation;
+  form.fields[1].set_is_focusable(false);
+  form.fields[2].set_role(FormFieldData::RoleAttribute::kPresentation);
+  form.fields[3].set_is_focusable(false);
+  form.fields[4].set_role(FormFieldData::RoleAttribute::kPresentation);
 
   std::vector<FieldType> field_types = {NAME_FULL, ADDRESS_HOME_LINE1,
                                         ADDRESS_HOME_CITY, ADDRESS_HOME_STATE,
@@ -555,7 +555,7 @@
 
   field.set_label(u"State");
   field.set_name(u"state");
-  field.is_focusable = false;
+  field.set_is_focusable(false);
   field.set_form_control_type(FormControlType::kSelectOne);
   form.fields.push_back(field);
   // Regardless of the order of appearance, hidden fields are rationalized
@@ -5354,8 +5354,8 @@
     FormFieldData checkable_field;
     checkable_field.set_label(u"radio_button");
     checkable_field.set_form_control_type(FormControlType::kInputRadio);
-    checkable_field.check_status =
-        FormFieldData::CheckStatus::kCheckableButUnchecked;
+    checkable_field.set_check_status(
+        FormFieldData::CheckStatus::kCheckableButUnchecked);
     form.fields.push_back(checkable_field);
 
     owned_forms_.push_back(std::make_unique<FormStructure>(form));
@@ -6139,11 +6139,11 @@
          .renderer_id = test::MakeFormRendererId(),
          .main_frame_origin = main_origin});
 
-    ASSERT_EQ(form_.main_frame_origin, form_.fields[0].origin);
-    ASSERT_EQ(form_.main_frame_origin, form_.fields[2].origin);
-    ASSERT_NE(form_.main_frame_origin, form_.fields[1].origin);
-    ASSERT_NE(form_.main_frame_origin, form_.fields[3].origin);
-    ASSERT_EQ(form_.fields[1].origin, form_.fields[3].origin);
+    ASSERT_EQ(form_.main_frame_origin, form_.fields[0].origin());
+    ASSERT_EQ(form_.main_frame_origin, form_.fields[2].origin());
+    ASSERT_NE(form_.main_frame_origin, form_.fields[1].origin());
+    ASSERT_NE(form_.main_frame_origin, form_.fields[3].origin());
+    ASSERT_EQ(form_.fields[1].origin(), form_.fields[3].origin());
 
     // Mock a simplified security model which allows to filter (only) fields
     // from the same origin.
@@ -6151,7 +6151,7 @@
         [](AutofillMetricsCrossFrameFormTest* self,
            const url::Origin& triggered_origin, FieldGlobalId field,
            FieldType) {
-          return triggered_origin == self->GetFieldById(field).origin;
+          return triggered_origin == self->GetFieldById(field).origin();
         },
         this));
   }
@@ -7247,7 +7247,7 @@
   FormData form = CreateForm({CreateTestFormField(
       "Search", "Search", "", FormControlType::kInputText)});
   // The form only has one field which has a placeholder of 'Search'.
-  form.fields[0].placeholder = u"Search";
+  form.fields[0].set_placeholder(u"Search");
 
   SeeForm(form);
   SubmitForm(form);
diff --git a/components/autofill/core/browser/metrics/form_events/form_event_logger_base.cc b/components/autofill/core/browser/metrics/form_events/form_event_logger_base.cc
index 583b622..b0a8640 100644
--- a/components/autofill/core/browser/metrics/form_events/form_event_logger_base.cc
+++ b/components/autofill/core/browser/metrics/form_events/form_event_logger_base.cc
@@ -145,7 +145,7 @@
     OnSuggestionsShownOnce(form);
   }
 
-  has_logged_autocomplete_off_ |= field.autocomplete_attribute == "off";
+  has_logged_autocomplete_off_ |= field.autocomplete_attribute() == "off";
 
   RecordShowSuggestions();
 }
diff --git a/components/autofill/core/browser/metrics/quality_metrics.cc b/components/autofill/core/browser/metrics/quality_metrics.cc
index bb0f905..514afa8 100644
--- a/components/autofill/core/browser/metrics/quality_metrics.cc
+++ b/components/autofill/core/browser/metrics/quality_metrics.cc
@@ -87,7 +87,7 @@
     // The form was not perfectly filled if a field was user-edited. Notice that
     // this means that in a perfect filling, a field must either be autofilled,
     // empty, have same value as pageload or have value set by JavaScript.
-    if (field->is_user_edited && !field->is_autofilled()) {
+    if (field->is_user_edited() && !field->is_autofilled()) {
       perfect_filling = false;
     }
 
@@ -202,17 +202,17 @@
     }
 
     // Keep track of the frames of detected and autofilled (credit card) fields.
-    frames_of_detected_fields.insert(field->host_frame);
+    frames_of_detected_fields.insert(field->host_frame());
     if (group == FieldTypeGroup::kCreditCard) {
-      frames_of_detected_credit_card_fields.insert(field->host_frame);
+      frames_of_detected_credit_card_fields.insert(field->host_frame());
       if (field->is_autofilled()) {
-        frames_of_autofilled_credit_card_fields.insert(field->host_frame);
+        frames_of_autofilled_credit_card_fields.insert(field->host_frame());
       }
     }
     if (observed_submission) {
       base::UmaHistogramEnumeration(
           "Autofill.LabelInference.InferredLabelSource.AtSubmission2",
-          field->label_source);
+          field->label_source());
     }
   }
 
diff --git a/components/autofill/core/browser/metrics/quality_metrics_unittest.cc b/components/autofill/core/browser/metrics/quality_metrics_unittest.cc
index 22f7f31..75c67a2 100644
--- a/components/autofill/core/browser/metrics/quality_metrics_unittest.cc
+++ b/components/autofill/core/browser/metrics/quality_metrics_unittest.cc
@@ -904,14 +904,14 @@
   FormFieldData name_field;
   name_field.set_value(
       profile.GetInfo(NAME_FULL, personal_data().app_locale()));
-  name_field.label_source = FormFieldData::LabelSource::kUnknown;
+  name_field.set_label_source(FormFieldData::LabelSource::kUnknown);
   FormFieldData street_field;
   street_field.set_value(u"unknown");
-  street_field.label_source = FormFieldData::LabelSource::kForId;
+  street_field.set_label_source(FormFieldData::LabelSource::kForId);
   FormFieldData country_field;
   country_field.set_value(
       profile.GetInfo(ADDRESS_HOME_COUNTRY, personal_data().app_locale()));
-  country_field.label_source = FormFieldData::LabelSource::kLabelTag;
+  country_field.set_label_source(FormFieldData::LabelSource::kLabelTag);
   const FormData form = CreateForm({name_field, street_field, country_field});
   autofill_manager().AddSeenForm(
       form, {NAME_FIRST, ADDRESS_HOME_LINE1, ADDRESS_HOME_COUNTRY});
@@ -922,8 +922,8 @@
   SubmitForm(form);
   EXPECT_THAT(histogram_tester.GetAllSamples(
                   "Autofill.LabelInference.InferredLabelSource.AtSubmission2"),
-              BucketsAre(Bucket(name_field.label_source, 1),
-                         Bucket(country_field.label_source, 1)));
+              BucketsAre(Bucket(name_field.label_source(), 1),
+                         Bucket(country_field.label_source(), 1)));
 }
 
 // Tests that precision metric is recorded for email field predictions.
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
index 8c14629d..23da935 100644
--- a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
@@ -23,6 +23,7 @@
 #include "base/test/task_environment.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "components/autofill/core/browser/address_data_manager_test_api.h"
 #include "components/autofill/core/browser/autofill_experiments.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
 #include "components/autofill/core/browser/data_model/autofill_profile.h"
@@ -202,7 +203,8 @@
     autofill_client_.SetPrefs(test::PrefServiceForTesting());
     autofill_client_.set_test_strike_database(
         std::make_unique<TestStrikeDatabase>());
-    personal_data().set_auto_accept_address_imports_for_testing(true);
+    test_api(personal_data().address_data_manager())
+        .set_auto_accept_address_imports(true);
     personal_data().SetPrefService(autofill_client_.GetPrefs());
     personal_data().SetSyncServiceForTest(&sync_service_);
     autofill_driver_ = std::make_unique<TestAutofillDriver>(&autofill_client_);
@@ -300,7 +302,7 @@
     }
     form.fields.push_back(CreateTestFormField("Card Number", "cardnumber", "",
                                               FormControlType::kInputText, ""));
-    form.fields.back().is_focusable = !options.is_from_non_focusable_form;
+    form.fields.back().set_is_focusable(!options.is_from_non_focusable_form);
     form.fields.push_back(CreateTestFormField("Expiration Date", "ccmonth", "",
                                               FormControlType::kInputText));
     form.fields.push_back(
@@ -495,7 +497,7 @@
       CreditCardFormOptions().with_is_https(false));
 
   // Set "autocomplete=off" for cardnumber field.
-  form.fields[1].should_autocomplete = false;
+  form.fields[1].set_should_autocomplete(false);
 
   std::vector<FormData> forms(1, form);
   FormsSeen(forms);
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h
index 90aedb5b..809fea8a 100644
--- a/components/autofill/core/browser/personal_data_manager.h
+++ b/components/autofill/core/browser/personal_data_manager.h
@@ -240,16 +240,6 @@
   // Returns true if either Profile or CreditCard Autofill is enabled.
   bool IsAutofillEnabled() const;
 
-  // Used to automatically import addresses without a prompt. Should only be
-  // set to true in tests.
-  // TODO(b/322170538): Move to `address_data_manager()`.
-  void set_auto_accept_address_imports_for_testing(bool auto_accept) {
-    auto_accept_address_imports_for_testing_ = auto_accept;
-  }
-  bool auto_accept_address_imports_for_testing() {
-    return auto_accept_address_imports_for_testing_;
-  }
-
   AlternativeStateNameMapUpdater*
   get_alternative_state_name_map_updater_for_testing() {
     return alternative_state_name_map_updater_.get();
@@ -292,10 +282,6 @@
   // during construction.
   const GeoIpCountryCode variations_country_code_;
 
-  // If true, new addresses imports are automatically accepted without a prompt.
-  // Only to be used for testing.
-  bool auto_accept_address_imports_for_testing_ = false;
-
   // The HistoryService to be observed by the personal data manager. Must
   // outlive this instance. This unowned pointer is retained so the PDM can
   // remove itself from the history service's observer list on shutdown.
diff --git a/components/autofill/core/browser/rationalization_util.cc b/components/autofill/core/browser/rationalization_util.cc
index 7cf113f..c7a6703 100644
--- a/components/autofill/core/browser/rationalization_util.cc
+++ b/components/autofill/core/browser/rationalization_util.cc
@@ -45,11 +45,13 @@
   for (AutofillField* field : fields_in_section) {
     if (base::FeatureList::IsEnabled(
             features::kAutofillUseParameterizedSectioning)) {
-      if (!field->is_visible)
+      if (!field->is_visible()) {
         continue;
+      }
     } else {
-      if (!field->is_focusable)
+      if (!field->is_focusable()) {
         continue;
+      }
     }
     FieldType current_field_type = field->Type().GetStorableType();
     switch (current_field_type) {
diff --git a/components/autofill/core/browser/rationalization_util_unittest.cc b/components/autofill/core/browser/rationalization_util_unittest.cc
index b79639d9..9d304d2 100644
--- a/components/autofill/core/browser/rationalization_util_unittest.cc
+++ b/components/autofill/core/browser/rationalization_util_unittest.cc
@@ -127,8 +127,8 @@
                   {PHONE_HOME_WHOLE_NUMBER, false}});
   // With the `kAutofillUseParameterizedSectioning` `!FormFieldData::is_visible`
   // fields are skipped.
-  fields[2]->is_visible = false;
-  fields[2]->is_focusable = false;
+  fields[2]->set_is_visible(false);
+  fields[2]->set_is_focusable(false);
   rationalization_util::RationalizePhoneNumberFields(ToPointers(fields));
   EXPECT_THAT(GetOnlyFilledWhenFocused(fields),
               ::testing::Eq(expected_only_fill_when_focused));
diff --git a/components/autofill/core/browser/select_control_util_unittest.cc b/components/autofill/core/browser/select_control_util_unittest.cc
index a8d357c2..90fa7dd 100644
--- a/components/autofill/core/browser/select_control_util_unittest.cc
+++ b/components/autofill/core/browser/select_control_util_unittest.cc
@@ -34,31 +34,33 @@
   AutofillField field{test::CreateTestSelectField({"États-Unis", "Canada"})};
 
   // Case 1: Exact match
-  int ret = FindShortestSubstringMatchInSelect(u"Canada", false, field.options);
+  int ret =
+      FindShortestSubstringMatchInSelect(u"Canada", false, field.options());
   EXPECT_EQ(1, ret);
 
   // Case 2: Case-insensitive
-  ret = FindShortestSubstringMatchInSelect(u"CANADA", false, field.options);
+  ret = FindShortestSubstringMatchInSelect(u"CANADA", false, field.options());
   EXPECT_EQ(1, ret);
 
   // Case 3: Proper substring
-  ret = FindShortestSubstringMatchInSelect(u"États", false, field.options);
+  ret = FindShortestSubstringMatchInSelect(u"États", false, field.options());
   EXPECT_EQ(0, ret);
 
   // Case 4: Accent-insensitive
-  ret = FindShortestSubstringMatchInSelect(u"Etats-Unis", false, field.options);
+  ret =
+      FindShortestSubstringMatchInSelect(u"Etats-Unis", false, field.options());
   EXPECT_EQ(0, ret);
 
   // Case 5: Whitespace-insensitive
-  ret = FindShortestSubstringMatchInSelect(u"Ca na da", true, field.options);
+  ret = FindShortestSubstringMatchInSelect(u"Ca na da", true, field.options());
   EXPECT_EQ(1, ret);
 
   // Case 6: No match (whitespace-sensitive)
-  ret = FindShortestSubstringMatchInSelect(u"Ca Na Da", false, field.options);
+  ret = FindShortestSubstringMatchInSelect(u"Ca Na Da", false, field.options());
   EXPECT_EQ(-1, ret);
 
   // Case 7: No match (not present)
-  ret = FindShortestSubstringMatchInSelect(u"Canadia", true, field.options);
+  ret = FindShortestSubstringMatchInSelect(u"Canadia", true, field.options());
   EXPECT_EQ(-1, ret);
 }
 
@@ -74,12 +76,14 @@
 
   // Set semantically empty contents for each option, so that only the values
   // can be used for matching.
-  for (size_t i = 0; i < field.options.size(); ++i) {
-    field.options[i].content = base::NumberToString16(i);
+  std::vector<SelectOption> options = field.options();
+  for (size_t i = 0; i < field.options().size(); ++i) {
+    options[i].content = base::NumberToString16(i);
   }
+  field.set_options(std::move(options));
 
   std::u16string match_value =
-      GetSelectControlValue(u"Meenie", field.options,
+      GetSelectControlValue(u"Meenie", field.options(),
                             /*failure_to_fill=*/nullptr)
           .value_or(u"");
   EXPECT_EQ(u"Meenie", match_value);
@@ -96,12 +100,14 @@
 
   // Set semantically empty values for each option, so that only the contents
   // can be used for matching.
-  for (size_t i = 0; i < field.options.size(); ++i) {
-    field.options[i].value = base::NumberToString16(i);
+  std::vector<SelectOption> options = field.options();
+  for (size_t i = 0; i < field.options().size(); ++i) {
+    options[i].value = base::NumberToString16(i);
   }
+  field.set_options(std::move(options));
 
   std::u16string match_value =
-      GetSelectControlValue(u"Miney", field.options,
+      GetSelectControlValue(u"Miney", field.options(),
                             /*failure_to_fill=*/nullptr)
           .value_or(u"");
   EXPECT_EQ(u"2", match_value);
diff --git a/components/autofill/core/browser/single_field_form_fill_router_unittest.cc b/components/autofill/core/browser/single_field_form_fill_router_unittest.cc
index 59d4326..9c98acd 100644
--- a/components/autofill/core/browser/single_field_form_fill_router_unittest.cc
+++ b/components/autofill/core/browser/single_field_form_fill_router_unittest.cc
@@ -75,7 +75,7 @@
   for (bool test_field_should_autocomplete : {true, false}) {
     SCOPED_TRACE(testing::Message() << "test_field_should_autocomplete = "
                                     << test_field_should_autocomplete);
-    test_field_.should_autocomplete = test_field_should_autocomplete;
+    test_field_.set_should_autocomplete(test_field_should_autocomplete);
 
     // If `test_field_.should_autocomplete` is true, that means autocomplete is
     // turned on for the given test field and
@@ -85,9 +85,9 @@
     // AutocompleteHistoryManager::OnGetSingleFieldSuggestions() should return
     // false.
     EXPECT_CALL(autocomplete_history_manager_, OnGetSingleFieldSuggestions)
-        .WillOnce(testing::Return(test_field_.should_autocomplete));
+        .WillOnce(testing::Return(test_field_.should_autocomplete()));
 
-    EXPECT_EQ(test_field_.should_autocomplete,
+    EXPECT_EQ(test_field_.should_autocomplete(),
               single_field_form_fill_router_.OnGetSingleFieldSuggestions(
                   test_field_, autofill_client_, base::DoNothing(),
                   /*context=*/SuggestionsContext()));
@@ -200,7 +200,7 @@
   for (bool test_field_should_autocomplete : {true, false}) {
     SCOPED_TRACE(testing::Message() << "test_field_should_autocomplete = "
                                     << test_field_should_autocomplete);
-    test_field_.should_autocomplete = test_field_should_autocomplete;
+    test_field_.set_should_autocomplete(test_field_should_autocomplete);
 
     // `test_field_.should_autocomplete` should not affect merchant promo code
     // autofill, so MerchantPromoCodeManager::OnGetSingleFieldSuggestions()
diff --git a/components/autofill/core/common/autocomplete_parsing_util_unittest.cc b/components/autofill/core/common/autocomplete_parsing_util_unittest.cc
index d79c3ff0..de076c5 100644
--- a/components/autofill/core/common/autocomplete_parsing_util_unittest.cc
+++ b/components/autofill/core/common/autocomplete_parsing_util_unittest.cc
@@ -88,9 +88,9 @@
                << "autocomplete=\"" << test.autocomplete << "\"");
 
   FormFieldData field;
-  field.autocomplete_attribute = std::string(test.autocomplete);
+  field.set_autocomplete_attribute(std::string(test.autocomplete));
 
-  auto result = ParseAutocompleteAttribute(field.autocomplete_attribute);
+  auto result = ParseAutocompleteAttribute(field.autocomplete_attribute());
   EXPECT_EQ(result, test.expected_result);
 }
 
diff --git a/components/autofill/core/common/autofill_data_validation.cc b/components/autofill/core/common/autofill_data_validation.cc
index bdb79f5..5128bea 100644
--- a/components/autofill/core/common/autofill_data_validation.cc
+++ b/components/autofill/core/common/autofill_data_validation.cc
@@ -38,8 +38,8 @@
              base::to_underlying(FormControlType::kMinValue) &&
          base::to_underlying(field.form_control_type()) <=
              base::to_underlying(FormControlType::kMaxValue) &&
-         IsValidString(field.autocomplete_attribute) &&
-         IsValidOptionVector(field.options);
+         IsValidString(field.autocomplete_attribute()) &&
+         IsValidOptionVector(field.options());
 }
 
 bool IsValidFormData(const FormData& form) {
diff --git a/components/autofill/core/common/autofill_test_utils.cc b/components/autofill/core/common/autofill_test_utils.cc
index 4477ccc..8eeba28 100644
--- a/components/autofill/core/common/autofill_test_utils.cc
+++ b/components/autofill/core/common/autofill_test_utils.cc
@@ -99,7 +99,7 @@
 FormData CreateFormDataForFrame(FormData form, LocalFrameToken frame_token) {
   form.host_frame = frame_token;
   for (FormFieldData& field : form.fields) {
-    field.host_frame = frame_token;
+    field.set_host_frame(frame_token);
   }
   return form;
 }
@@ -129,7 +129,7 @@
 }
 
 FormFieldData WithoutUnserializedData(FormFieldData field) {
-  field.host_frame = {};
+  field.set_host_frame({});
   return field;
 }
 
@@ -138,13 +138,13 @@
                                   std::string_view value,
                                   FormControlType type) {
   FormFieldData field;
-  field.host_frame = MakeLocalFrameToken();
+  field.set_host_frame(MakeLocalFrameToken());
   field.set_renderer_id(MakeFieldRendererId());
   field.set_label(base::UTF8ToUTF16(label));
   field.set_name(base::UTF8ToUTF16(name));
   field.set_value(base::UTF8ToUTF16(value));
   field.set_form_control_type(type);
-  field.is_focusable = true;
+  field.set_is_focusable(true);
   return field;
 }
 
@@ -154,7 +154,7 @@
                                   FormControlType type,
                                   std::string_view autocomplete) {
   FormFieldData field = CreateTestFormField(label, name, value, type);
-  field.autocomplete_attribute = autocomplete;
+  field.set_autocomplete_attribute(std::string(autocomplete));
   field.set_parsed_autocomplete(ParseAutocompleteAttribute(autocomplete));
   return field;
 }
@@ -169,7 +169,7 @@
   // First, set the `max_length`, as the `parsed_autocomplete` is set based on
   // this value.
   field.set_max_length(max_length);
-  field.autocomplete_attribute = autocomplete;
+  field.set_autocomplete_attribute(std::string(autocomplete));
   field.set_parsed_autocomplete(ParseAutocompleteAttribute(autocomplete));
   return field;
 }
@@ -211,17 +211,19 @@
   CHECK(type == FormControlType::kSelectOne ||
         type == FormControlType::kSelectList);
   FormFieldData field = CreateTestFormField(label, name, value, type);
-  field.autocomplete_attribute = autocomplete;
+  field.set_autocomplete_attribute(std::string(autocomplete));
   field.set_parsed_autocomplete(ParseAutocompleteAttribute(autocomplete));
 
   CHECK_EQ(values.size(), contents.size());
-  field.options.reserve(values.size());
+  std::vector<SelectOption> options;
+  options.reserve(values.size());
   for (size_t i = 0; i < values.size(); ++i) {
-    field.options.push_back({
+    options.push_back({
         .value = base::UTF8ToUTF16(values[i]),
         .content = base::UTF8ToUTF16(contents[i]),
     });
   }
+  field.set_options(std::move(options));
   return field;
 }
 
@@ -233,12 +235,13 @@
   // Fill the base attributes.
   FormFieldData field =
       CreateTestFormField(label, name, value, FormControlType::kInputText);
-
-  field.datalist_options.reserve(std::min(values.size(), labels.size()));
+  std::vector<SelectOption> datalist_options;
+  datalist_options.reserve(std::min(values.size(), labels.size()));
   for (size_t i = 0; i < std::min(values.size(), labels.size()); ++i) {
-    field.datalist_options.push_back({.value = base::UTF8ToUTF16(values[i]),
-                                      .content = base::UTF8ToUTF16(labels[i])});
+    datalist_options.push_back({.value = base::UTF8ToUTF16(values[i]),
+                                .content = base::UTF8ToUTF16(labels[i])});
   }
+  field.set_datalist_options(std::move(datalist_options));
   return field;
 }
 
diff --git a/components/autofill/core/common/autofill_util.cc b/components/autofill/core/common/autofill_util.cc
index 91b00a9..43ba508 100644
--- a/components/autofill/core/common/autofill_util.cc
+++ b/components/autofill/core/common/autofill_util.cc
@@ -92,13 +92,14 @@
                     bool isCheckable,
                     bool isChecked) {
   if (isChecked) {
-    form_field_data->check_status = FormFieldData::CheckStatus::kChecked;
+    form_field_data->set_check_status(FormFieldData::CheckStatus::kChecked);
   } else {
     if (isCheckable) {
-      form_field_data->check_status =
-          FormFieldData::CheckStatus::kCheckableButUnchecked;
+      form_field_data->set_check_status(
+          FormFieldData::CheckStatus::kCheckableButUnchecked);
     } else {
-      form_field_data->check_status = FormFieldData::CheckStatus::kNotCheckable;
+      form_field_data->set_check_status(
+          FormFieldData::CheckStatus::kNotCheckable);
     }
   }
 }
diff --git a/components/autofill/core/common/form_data.cc b/components/autofill/core/common/form_data.cc
index 5bd97af7..f967da6 100644
--- a/components/autofill/core/common/form_data.cc
+++ b/components/autofill/core/common/form_data.cc
@@ -132,7 +132,7 @@
 bool FormHasNonEmptyPasswordField(const FormData& form) {
   for (const auto& field : form.fields) {
     if (field.IsPasswordInputElement()) {
-      if (!field.value().empty() || !field.user_input.empty()) {
+      if (!field.value().empty() || !field.user_input().empty()) {
         return true;
       }
     }
diff --git a/components/autofill/core/common/form_data_fuzzed_producer.cc b/components/autofill/core/common/form_data_fuzzed_producer.cc
index 8dc7abbb6..5ee38ea 100644
--- a/components/autofill/core/common/form_data_fuzzed_producer.cc
+++ b/components/autofill/core/common/form_data_fuzzed_producer.cc
@@ -59,12 +59,12 @@
     // Empty values are interesting from the parsing perspective. Ensure that
     // at least half of the cases ends up with an empty value.
     const bool force_empty_value = bools[1];
-    result.fields[i].is_focusable = bools[2];
+    result.fields[i].set_is_focusable(bools[2]);
 
     result.fields[i].set_form_control_type(
         provider.ConsumeEnum<FormControlType>());
-    result.fields[i].autocomplete_attribute =
-        provider.ConsumeRandomLengthString();
+    result.fields[i].set_autocomplete_attribute(
+        provider.ConsumeRandomLengthString());
     result.fields[i].set_label(ConsumeU16String(provider));
     result.fields[i].set_name(ConsumeU16String(provider));
     result.fields[i].set_name_attribute(result.fields[i].name());
diff --git a/components/autofill/core/common/form_data_unittest.cc b/components/autofill/core/common/form_data_unittest.cc
index 201855e..e185c38 100644
--- a/components/autofill/core/common/form_data_unittest.cc
+++ b/components/autofill/core/common/form_data_unittest.cc
@@ -155,20 +155,20 @@
   field_data.set_name(u"name");
   field_data.set_value(u"value");
   field_data.set_form_control_type(FormControlType::kInputPassword);
-  field_data.autocomplete_attribute = "off";
+  field_data.set_autocomplete_attribute("off");
   field_data.set_max_length(200);
   field_data.set_is_autofilled(true);
-  field_data.check_status = FormFieldData::CheckStatus::kChecked;
-  field_data.is_focusable = true;
-  field_data.should_autocomplete = false;
-  field_data.text_direction = base::i18n::RIGHT_TO_LEFT;
-  field_data.options = {{.value = u"First", .content = u"First"},
-                        {.value = u"Second", .content = u"Second"}};
+  field_data.set_check_status(FormFieldData::CheckStatus::kChecked);
+  field_data.set_is_focusable(true);
+  field_data.set_should_autocomplete(false);
+  field_data.set_text_direction(base::i18n::RIGHT_TO_LEFT);
+  field_data.set_options({{.value = u"First", .content = u"First"},
+                          {.value = u"Second", .content = u"Second"}});
   data->fields.push_back(field_data);
 
   // Change a few fields.
   field_data.set_max_length(150);
-  field_data.options = {{.value = u"Third", .content = u"Third"}};
+  field_data.set_options({{.value = u"Third", .content = u"Third"}});
   data->fields.push_back(field_data);
 }
 
diff --git a/components/autofill/core/common/form_field_data.cc b/components/autofill/core/common/form_field_data.cc
index bb7bfe7..8ab8c82a 100644
--- a/components/autofill/core/common/form_field_data.cc
+++ b/components/autofill/core/common/form_field_data.cc
@@ -109,7 +109,7 @@
     field_data->set_label(std::move(label));
     field_data->set_name(std::move(name));
     field_data->set_value(std::move(value));
-    field_data->autocomplete_attribute = std::move(autocomplete_attribute);
+    field_data->set_autocomplete_attribute(std::move(autocomplete_attribute));
     field_data->set_max_length(max_length);
     field_data->set_is_autofilled(std::move(is_autofilled));
     // Form control types are serialized as strings for legacy reasons.
@@ -142,7 +142,7 @@
   if (!ReadAsInt(iter, &check_status)) {
     return false;
   }
-  field_data->check_status = check_status;
+  field_data->set_check_status(check_status);
   return true;
 }
 
@@ -153,8 +153,8 @@
   if (!iter->ReadBool(&is_focusable) || !iter->ReadBool(&should_autocomplete)) {
     return false;
   }
-  field_data->is_focusable = std::move(is_focusable);
-  field_data->should_autocomplete = std::move(should_autocomplete);
+  field_data->set_is_focusable(std::move(is_focusable));
+  field_data->set_should_autocomplete(std::move(should_autocomplete));
   return true;
 }
 
@@ -169,11 +169,13 @@
       option_values.size() != option_contents.size()) {
     return false;
   }
-  field_data->text_direction = text_direction;
+  field_data->set_text_direction(text_direction);
+  std::vector<SelectOption> options;
   for (size_t i = 0; i < option_values.size(); ++i) {
-    field_data->options.push_back({.value = std::move(option_values[i]),
-                                   .content = std::move(option_contents[i])});
+    options.push_back({.value = std::move(option_values[i]),
+                       .content = std::move(option_contents[i])});
   }
+  field_data->set_options(std::move(options));
   return true;
 }
 
@@ -185,8 +187,8 @@
       !ReadSelectOptionVector(iter, &options)) {
     return false;
   }
-  field_data->text_direction = std::move(text_direction);
-  field_data->options = std::move(options);
+  field_data->set_text_direction(std::move(text_direction));
+  field_data->set_options(std::move(options));
   return true;
 }
 
@@ -196,7 +198,7 @@
   if (!ReadAsInt(iter, &role)) {
     return false;
   }
-  field_data->role = role;
+  field_data->set_role(role);
   return true;
 }
 
@@ -206,7 +208,7 @@
   if (!iter->ReadString16(&placeholder)) {
     return false;
   }
-  field_data->placeholder = std::move(placeholder);
+  field_data->set_placeholder(std::move(placeholder));
   return true;
 }
 
@@ -216,7 +218,7 @@
   if (!iter->ReadString16(&css_classes)) {
     return false;
   }
-  field_data->css_classes = std::move(css_classes);
+  field_data->set_css_classes(std::move(css_classes));
   return true;
 }
 
@@ -253,10 +255,11 @@
 auto IdentityTuple(const FormFieldData& f) {
   return std::tuple_cat(
       std::tie(f.label(), f.name(), f.name_attribute(), f.id_attribute(),
-               f.form_control_type(), f.autocomplete_attribute, f.placeholder,
-               f.max_length(), f.css_classes, f.is_focusable,
-               f.should_autocomplete, f.role, f.text_direction, f.options),
-      std::make_tuple(IsCheckable(f.check_status)));
+               f.form_control_type(), f.autocomplete_attribute(),
+               f.placeholder(), f.max_length(), f.css_classes(),
+               f.is_focusable(), f.should_autocomplete(), f.role(),
+               f.text_direction(), f.options()),
+      std::make_tuple(IsCheckable(f.check_status())));
 }
 
 }  // namespace
@@ -284,7 +287,7 @@
   //
   // TODO(crbug.com/1257141): Remove special handling of FrameTokens.
   size_t generated_frame_id =
-      frame_token_ids.emplace(field.host_frame, frame_token_ids.size())
+      frame_token_ids.emplace(field.host_frame(), frame_token_ids.size())
           .first->second;
   section.value_ = FieldIdentifier(base::UTF16ToUTF8(field.name()),
                                    generated_frame_id, field.renderer_id());
@@ -417,10 +420,10 @@
 FormFieldData::FillData::FillData(const FormFieldData& field)
     : value(field.value()),
       renderer_id(field.renderer_id()),
-      host_form_id(field.host_form_id),
+      host_form_id(field.host_form_id()),
       section(field.section()),
       is_autofilled(field.is_autofilled()),
-      force_override(field.force_override) {}
+      force_override(field.force_override()) {}
 
 FormFieldData::FillData::FillData(const FillData&) = default;
 
@@ -487,17 +490,17 @@
   pickle->WriteString16(field_data.value());
   pickle->WriteString(FormControlTypeToString(field_data.form_control_type()));
   // We don't serialize the `parsed_autocomplete`. See http://crbug.com/1353392.
-  pickle->WriteString(field_data.autocomplete_attribute);
+  pickle->WriteString(field_data.autocomplete_attribute());
   pickle->WriteUInt64(field_data.max_length());
   pickle->WriteBool(field_data.is_autofilled());
-  pickle->WriteInt(static_cast<int>(field_data.check_status));
-  pickle->WriteBool(field_data.is_focusable);
-  pickle->WriteBool(field_data.should_autocomplete);
-  pickle->WriteInt(static_cast<int>(field_data.role));
-  pickle->WriteInt(field_data.text_direction);
-  WriteSelectOptionVector(field_data.options, pickle);
-  pickle->WriteString16(field_data.placeholder);
-  pickle->WriteString16(field_data.css_classes);
+  pickle->WriteInt(static_cast<int>(field_data.check_status()));
+  pickle->WriteBool(field_data.is_focusable());
+  pickle->WriteBool(field_data.should_autocomplete());
+  pickle->WriteInt(static_cast<int>(field_data.role()));
+  pickle->WriteInt(field_data.text_direction());
+  WriteSelectOptionVector(field_data.options(), pickle);
+  pickle->WriteString16(field_data.placeholder());
+  pickle->WriteString16(field_data.css_classes());
   pickle->WriteUInt32(field_data.properties_mask());
   pickle->WriteString16(field_data.id_attribute());
   pickle->WriteString16(field_data.name_attribute());
@@ -644,30 +647,30 @@
 std::ostream& operator<<(std::ostream& os, const FormFieldData& field) {
   return os << "label='" << field.label() << "' "
             << "unique_Id=" << field.global_id() << " " << "origin='"
-            << field.origin.Serialize() << "' " << "name='" << field.name()
+            << field.origin().Serialize() << "' " << "name='" << field.name()
             << "' " << "id_attribute='" << field.id_attribute() << "' "
             << "name_attribute='" << field.name_attribute() << "' " << "value='"
             << field.value() << "' " << "control='" << field.form_control_type()
-            << "' " << "autocomplete='" << field.autocomplete_attribute << "' "
-            << "parsed_autocomplete='"
+            << "' " << "autocomplete='" << field.autocomplete_attribute()
+            << "' " << "parsed_autocomplete='"
             << (field.parsed_autocomplete()
                     ? field.parsed_autocomplete()->ToString()
                     : "")
-            << "' " << "placeholder='" << field.placeholder << "' "
+            << "' " << "placeholder='" << field.placeholder() << "' "
             << "max_length=" << field.max_length() << " " << "css_classes='"
-            << field.css_classes << "' "
+            << field.css_classes() << "' "
             << "autofilled=" << field.is_autofilled() << " "
-            << "check_status=" << field.check_status << " "
-            << "is_focusable=" << field.is_focusable << " "
-            << "should_autocomplete=" << field.should_autocomplete << " "
-            << "role=" << field.role << " "
-            << "text_direction=" << field.text_direction << " "
-            << "is_enabled=" << field.is_enabled << " "
-            << "is_readonly=" << field.is_readonly << " "
-            << "user_input=" << field.user_input << " "
+            << "check_status=" << field.check_status() << " "
+            << "is_focusable=" << field.is_focusable() << " "
+            << "should_autocomplete=" << field.should_autocomplete() << " "
+            << "role=" << field.role() << " "
+            << "text_direction=" << field.text_direction() << " "
+            << "is_enabled=" << field.is_enabled() << " "
+            << "is_readonly=" << field.is_readonly() << " "
+            << "user_input=" << field.user_input() << " "
             << "properties_mask=" << field.properties_mask() << " "
-            << "label_source=" << field.label_source << " "
-            << "bounds=" << field.bounds.ToString();
+            << "label_source=" << field.label_source() << " "
+            << "bounds=" << field.bounds().ToString();
 }
 
 LogBuffer& operator<<(LogBuffer& buffer, const FormFieldData& field) {
@@ -678,10 +681,10 @@
                           base::NumberToString(field.renderer_id().value()),
                           ", host frame: ",
                           field.renderer_form_id().frame_token.ToString(), " (",
-                          field.origin.Serialize(),
+                          field.origin().Serialize(),
                           "), host form renderer id: ",
-                          base::NumberToString(field.host_form_id.value())});
-  buffer << Tr{} << "Origin:" << field.origin.Serialize();
+                          base::NumberToString(field.host_form_id().value())});
+  buffer << Tr{} << "Origin:" << field.origin().Serialize();
   buffer << Tr{} << "Name attribute:" << field.name_attribute();
   buffer << Tr{} << "Id attribute:" << field.id_attribute();
   constexpr size_t kMaxLabelSize = 100;
@@ -689,17 +692,17 @@
       field.label().substr(0, std::min(field.label().length(), kMaxLabelSize));
   buffer << Tr{} << "Label:" << truncated_label;
   buffer << Tr{} << "Form control type:" << field.form_control_type();
-  buffer << Tr{} << "Autocomplete attribute:" << field.autocomplete_attribute;
+  buffer << Tr{} << "Autocomplete attribute:" << field.autocomplete_attribute();
   buffer << Tr{} << "Parsed autocomplete attribute:"
          << (field.parsed_autocomplete()
                  ? field.parsed_autocomplete()->ToString()
                  : "");
-  buffer << Tr{} << "Aria label:" << field.aria_label;
-  buffer << Tr{} << "Aria description:" << field.aria_description;
+  buffer << Tr{} << "Aria label:" << field.aria_label();
+  buffer << Tr{} << "Aria description:" << field.aria_description();
   buffer << Tr{} << "Section:" << field.section();
-  buffer << Tr{} << "Is focusable:" << field.is_focusable;
-  buffer << Tr{} << "Is enabled:" << field.is_enabled;
-  buffer << Tr{} << "Is readonly:" << field.is_readonly;
+  buffer << Tr{} << "Is focusable:" << field.is_focusable();
+  buffer << Tr{} << "Is enabled:" << field.is_enabled();
+  buffer << Tr{} << "Is readonly:" << field.is_readonly();
   buffer << Tr{} << "Is empty:" << (field.value().empty() ? "Yes" : "No");
   buffer << CTag{"table"};
   return buffer;
diff --git a/components/autofill/core/common/form_field_data.h b/components/autofill/core/common/form_field_data.h
index 2c8c667..3db572e 100644
--- a/components/autofill/core/common/form_field_data.h
+++ b/components/autofill/core/common/form_field_data.h
@@ -217,14 +217,16 @@
   // for details.
   //
   // Must not be leaked to renderer process. See FieldGlobalId for details.
-  FieldGlobalId global_id() const { return {host_frame, renderer_id()}; }
+  FieldGlobalId global_id() const { return {host_frame(), renderer_id()}; }
 
   // An identifier of the renderer form that contained this field.
   // This may be different from the browser form that contains this field in the
   // case of a frame-transcending form. See AutofillDriverRouter and
   // internal::FormForest for details on the distinction between renderer and
   // browser forms.
-  FormGlobalId renderer_form_id() const { return {host_frame, host_form_id}; }
+  FormGlobalId renderer_form_id() const {
+    return {host_frame(), host_form_id()};
+  }
 
   // TODO(crbug/1211834): This function is deprecated. Use
   // FormFieldData::DeepEqual() instead.
@@ -256,7 +258,7 @@
   // Returns true if the field is focusable to the user.
   // This is an approximation of visibility with false positives.
   bool IsFocusable() const {
-    return is_focusable && role != RoleAttribute::kPresentation;
+    return is_focusable() && role() != RoleAttribute::kPresentation;
   }
 
   bool DidUserType() const;
@@ -298,7 +300,10 @@
   // truncated, and because for rich-text contenteditables the selection and
   // text content differ in whitespace.
   // TODO(crbug.com/1501362): Extract on iOS.
-  std::u16string selected_text;
+  const std::u16string& selected_text() const { return selected_text_; }
+  void set_selected_text(std::u16string selected_text) {
+    selected_text_ = std::move(selected_text);
+  }
 
   const FormControlType& form_control_type() const {
     return form_control_type_;
@@ -306,7 +311,12 @@
   void set_form_control_type(FormControlType form_control_type) {
     form_control_type_ = std::move(form_control_type);
   }
-  std::string autocomplete_attribute;
+  const std::string& autocomplete_attribute() const {
+    return autocomplete_attribute_;
+  }
+  void set_autocomplete_attribute(std::string autocomplete_attribute) {
+    autocomplete_attribute_ = std::move(autocomplete_attribute);
+  }
   const std::optional<AutocompleteParsingResult>& parsed_autocomplete() const {
     return parsed_autocomplete_;
   }
@@ -314,16 +324,31 @@
       std::optional<AutocompleteParsingResult> parsed_autocomplete) {
     parsed_autocomplete_ = std::move(parsed_autocomplete);
   }
-  std::u16string placeholder;
-  std::u16string css_classes;
-  std::u16string aria_label;
-  std::u16string aria_description;
+  const std::u16string& placeholder() const { return placeholder_; }
+  void set_placeholder(std::u16string placeholder) {
+    placeholder_ = std::move(placeholder);
+  }
+  const std::u16string& css_classes() const { return css_classes_; }
+  void set_css_classes(std::u16string css_classes) {
+    css_classes_ = std::move(css_classes);
+  }
+  const std::u16string& aria_label() const { return aria_label_; }
+  void set_aria_label(std::u16string aria_label) {
+    aria_label_ = std::move(aria_label);
+  }
+  const std::u16string& aria_description() const { return aria_description_; }
+  void set_aria_description(std::u16string aria_description) {
+    aria_description_ = std::move(aria_description);
+  }
 
   // A unique identifier of the containing frame. This value is not serialized
   // because LocalFrameTokens must not be leaked to other renderer processes.
   // It is not persistent between page loads and therefore not used in
   // comparison in SameFieldAs().
-  LocalFrameToken host_frame;
+  const LocalFrameToken& host_frame() const { return host_frame_; }
+  void set_host_frame(LocalFrameToken host_frame) {
+    host_frame_ = std::move(host_frame);
+  }
 
   // Uniquely identifies the DOM element that this field represents among the
   // field DOM elements in the same frame.
@@ -335,7 +360,10 @@
   }
 
   // Renderer ID of the owning form in the same frame.
-  FormRendererId host_form_id;
+  const FormRendererId& host_form_id() const { return host_form_id_; }
+  void set_host_form_id(FormRendererId host_form_id) {
+    host_form_id_ = std::move(host_form_id);
+  }
 
   // The signature of the field's renderer form, that is, the signature of the
   // FormData that contained this field when it was received by the
@@ -345,13 +373,22 @@
   // and in the Password Manager.
   // This value is written and read only in the browser for voting of
   // cross-frame forms purposes. It is therefore not sent via mojo.
-  FormSignature host_form_signature;
+  const FormSignature& host_form_signature() const {
+    return host_form_signature_;
+  }
+  void set_host_form_signature(FormSignature host_form_signature) {
+    host_form_signature_ = std::move(host_form_signature);
+  }
 
   // The origin of the frame that hosts the field.
-  url::Origin origin;
+  const url::Origin& origin() const { return origin_; }
+  void set_origin(url::Origin origin) { origin_ = std::move(origin); }
 
   // The ax node id of the form control in the accessibility tree.
-  int32_t form_control_ax_id = 0;
+  const int32_t& form_control_ax_id() const { return form_control_ax_id_; }
+  void set_form_control_ax_id(int32_t form_control_ax_id) {
+    form_control_ax_id_ = std::move(form_control_ax_id);
+  }
 
   // The unique identifier of the section (e.g. billing vs. shipping address)
   // of this field.
@@ -408,14 +445,33 @@
   // when the form is reset (JavaScript's HTMLFormElement.reset()).
   // TODO(crbug.com/1501627): On iOS, also non-trusted events reset the
   // property.
-  bool is_user_edited = false;
+  const bool& is_user_edited() const { return is_user_edited_; }
+  void set_is_user_edited(bool is_user_edited) {
+    is_user_edited_ = std::move(is_user_edited);
+  }
 
-  CheckStatus check_status = CheckStatus::kNotCheckable;
-  bool is_focusable = true;
-  bool is_visible = true;  // See `features::kAutofillDetectFieldVisibility`.
-  bool should_autocomplete = true;
-  RoleAttribute role = RoleAttribute::kOther;
-  base::i18n::TextDirection text_direction = base::i18n::UNKNOWN_DIRECTION;
+  const CheckStatus& check_status() const { return check_status_; }
+  void set_check_status(CheckStatus check_status) {
+    check_status_ = std::move(check_status);
+  }
+  const bool& is_focusable() const { return is_focusable_; }
+  void set_is_focusable(bool is_focusable) {
+    is_focusable_ = std::move(is_focusable);
+  }
+  const bool& is_visible() const { return is_visible_; }
+  void set_is_visible(bool is_visible) { is_visible_ = std::move(is_visible); }
+  const bool& should_autocomplete() const { return should_autocomplete_; }
+  void set_should_autocomplete(bool should_autocomplete) {
+    should_autocomplete_ = std::move(should_autocomplete);
+  }
+  const RoleAttribute& role() const { return role_; }
+  void set_role(RoleAttribute role) { role_ = std::move(role); }
+  const base::i18n::TextDirection& text_direction() const {
+    return text_direction_;
+  }
+  void set_text_direction(base::i18n::TextDirection text_direction) {
+    text_direction_ = std::move(text_direction);
+  }
   const FieldPropertiesMask& properties_mask() const {
     return properties_mask_;
   }
@@ -425,33 +481,55 @@
 
   // Data members from the next block are used for parsing only, they are not
   // serialised for storage.
-  bool is_enabled = false;
-  bool is_readonly = false;
+  const bool& is_enabled() const { return is_enabled_; }
+  void set_is_enabled(bool is_enabled) { is_enabled_ = std::move(is_enabled); }
+  const bool& is_readonly() const { return is_readonly_; }
+  void set_is_readonly(bool is_readonly) {
+    is_readonly_ = std::move(is_readonly);
+  }
   // Contains password, username or credit card number value that was either
   // manually typed or autofilled on user trigger into a text-mode input field.
-  std::u16string user_input;
+  const std::u16string& user_input() const { return user_input_; }
+  void set_user_input(std::u16string user_input) {
+    user_input_ = std::move(user_input);
+  }
 
   // The options of a select box.
-  std::vector<SelectOption> options;
+  const std::vector<SelectOption>& options() const { return options_; }
+  void set_options(std::vector<SelectOption> options) {
+    options_ = std::move(options);
+  }
 
   // Password Manager doesn't use labels nor client side nor server side, so
   // label_source isn't in serialize methods.
-  LabelSource label_source = LabelSource::kUnknown;
+  const LabelSource& label_source() const { return label_source_; }
+  void set_label_source(LabelSource label_source) {
+    label_source_ = std::move(label_source);
+  }
 
   // The bounds of this field in current frame coordinates at the
   // form-extraction time. It is valid if not empty, will not be synced to the
   // server side or be used for field comparison and isn't in serialize methods.
-  gfx::RectF bounds;
+  const gfx::RectF& bounds() const { return bounds_; }
+  void set_bounds(gfx::RectF bounds) { bounds_ = std::move(bounds); }
 
   // The datalist is associated with this field, if any. Will not be synced to
   // the server side or be used for field comparison and aren't in serialize
   // methods.
-  std::vector<SelectOption> datalist_options;
+  const std::vector<SelectOption>& datalist_options() const {
+    return datalist_options_;
+  }
+  void set_datalist_options(std::vector<SelectOption> datalist_options) {
+    datalist_options_ = std::move(datalist_options);
+  }
 
   // When sent from browser to renderer, this bit indicates whether a field
   // should be filled even though it is already considered autofilled OR
   // user modified.
-  bool force_override = false;
+  const bool& force_override() const { return force_override_; }
+  void set_force_override(bool force_override) {
+    force_override_ = std::move(force_override);
+  }
 
  private:
   std::u16string name_;
@@ -459,13 +537,39 @@
   std::u16string name_attribute_;
   std::u16string label_;
   std::u16string value_;
+  std::u16string selected_text_;
   FormControlType form_control_type_ = FormControlType::kInputText;
+  std::string autocomplete_attribute_;
   std::optional<AutocompleteParsingResult> parsed_autocomplete_;
+  std::u16string placeholder_;
+  std::u16string css_classes_;
+  std::u16string aria_label_;
+  std::u16string aria_description_;
+  LocalFrameToken host_frame_;
   FieldRendererId renderer_id_;
+  FormRendererId host_form_id_;
+  FormSignature host_form_signature_;
+  url::Origin origin_;
+  int32_t form_control_ax_id_ = 0;
   uint64_t max_length_ = std::numeric_limits<uint32_t>::max();
   Section section_;
   bool is_autofilled_ = false;
+  bool is_user_edited_ = false;
+  CheckStatus check_status_ = CheckStatus::kNotCheckable;
+  bool is_focusable_ = true;
+  bool is_visible_ = true;  // See `features::kAutofillDetectFieldVisibility`.
+  bool should_autocomplete_ = true;
+  RoleAttribute role_ = RoleAttribute::kOther;
+  base::i18n::TextDirection text_direction_ = base::i18n::UNKNOWN_DIRECTION;
   FieldPropertiesMask properties_mask_ = 0;
+  bool is_enabled_ = false;
+  bool is_readonly_ = false;
+  std::u16string user_input_;
+  std::vector<SelectOption> options_;
+  LabelSource label_source_ = LabelSource::kUnknown;
+  gfx::RectF bounds_;
+  std::vector<SelectOption> datalist_options_;
+  bool force_override_ = false;
 };
 
 // Structure containing necessary information to be sent from the browser to the
@@ -540,24 +644,25 @@
 // Prefer to use this macro in place of |EXPECT_EQ()| for comparing
 // |FormFieldData|s in test code.
 // TODO(crbug.com/40765988): Replace this with FormData::DeepEqual().
-#define EXPECT_FORM_FIELD_DATA_EQUALS(expected, actual)                        \
-  do {                                                                         \
-    EXPECT_EQ(expected.label(), actual.label());                               \
-    EXPECT_EQ(expected.name(), actual.name());                                 \
-    EXPECT_EQ(expected.value(), actual.value());                               \
-    EXPECT_EQ(expected.form_control_type(), actual.form_control_type());       \
-    EXPECT_EQ(expected.autocomplete_attribute, actual.autocomplete_attribute); \
-    EXPECT_EQ(expected.parsed_autocomplete(), actual.parsed_autocomplete());   \
-    EXPECT_EQ(expected.placeholder, actual.placeholder);                       \
-    EXPECT_EQ(expected.max_length(), actual.max_length());                     \
-    EXPECT_EQ(expected.css_classes, actual.css_classes);                       \
-    EXPECT_EQ(expected.is_autofilled(), actual.is_autofilled());               \
-    EXPECT_EQ(expected.is_user_edited, actual.is_user_edited);                 \
-    EXPECT_EQ(expected.section(), actual.section());                           \
-    EXPECT_EQ(expected.check_status, actual.check_status);                     \
-    EXPECT_EQ(expected.properties_mask(), actual.properties_mask());           \
-    EXPECT_EQ(expected.id_attribute(), actual.id_attribute());                 \
-    EXPECT_EQ(expected.id_attribute(), actual.id_attribute());                 \
+#define EXPECT_FORM_FIELD_DATA_EQUALS(expected, actual)                      \
+  do {                                                                       \
+    EXPECT_EQ(expected.label(), actual.label());                             \
+    EXPECT_EQ(expected.name(), actual.name());                               \
+    EXPECT_EQ(expected.value(), actual.value());                             \
+    EXPECT_EQ(expected.form_control_type(), actual.form_control_type());     \
+    EXPECT_EQ(expected.autocomplete_attribute(),                             \
+              actual.autocomplete_attribute());                              \
+    EXPECT_EQ(expected.parsed_autocomplete(), actual.parsed_autocomplete()); \
+    EXPECT_EQ(expected.placeholder(), actual.placeholder());                 \
+    EXPECT_EQ(expected.max_length(), actual.max_length());                   \
+    EXPECT_EQ(expected.css_classes(), actual.css_classes());                 \
+    EXPECT_EQ(expected.is_autofilled(), actual.is_autofilled());             \
+    EXPECT_EQ(expected.is_user_edited(), actual.is_user_edited());           \
+    EXPECT_EQ(expected.section(), actual.section());                         \
+    EXPECT_EQ(expected.check_status(), actual.check_status());               \
+    EXPECT_EQ(expected.properties_mask(), actual.properties_mask());         \
+    EXPECT_EQ(expected.id_attribute(), actual.id_attribute());               \
+    EXPECT_EQ(expected.name_attribute(), actual.name_attribute());           \
   } while (0)
 
 // Produces a <table> element with information about the form.
diff --git a/components/autofill/core/common/form_field_data_unittest.cc b/components/autofill/core/common/form_field_data_unittest.cc
index 46d6384..af43d90 100644
--- a/components/autofill/core/common/form_field_data_unittest.cc
+++ b/components/autofill/core/common/form_field_data_unittest.cc
@@ -19,27 +19,27 @@
   data->set_name(u"name");
   data->set_value(u"value");
   data->set_form_control_type(FormControlType::kInputPassword);
-  data->autocomplete_attribute = "off";
+  data->set_autocomplete_attribute("off");
   data->set_max_length(200);
   data->set_is_autofilled(true);
-  data->check_status = FormFieldData::CheckStatus::kChecked;
-  data->is_focusable = true;
-  data->should_autocomplete = false;
-  data->text_direction = base::i18n::RIGHT_TO_LEFT;
-  data->options = {{.value = u"First", .content = u"First"},
-                   {.value = u"Second", .content = u"Second"}};
+  data->set_check_status(FormFieldData::CheckStatus::kChecked);
+  data->set_is_focusable(true);
+  data->set_should_autocomplete(false);
+  data->set_text_direction(base::i18n::RIGHT_TO_LEFT);
+  data->set_options({{.value = u"First", .content = u"First"},
+                     {.value = u"Second", .content = u"Second"}});
 }
 
 void FillVersion2Fields(FormFieldData* data) {
-  data->role = FormFieldData::RoleAttribute::kPresentation;
+  data->set_role(FormFieldData::RoleAttribute::kPresentation);
 }
 
 void FillVersion3Fields(FormFieldData* data) {
-  data->placeholder = u"placeholder";
+  data->set_placeholder(u"placeholder");
 }
 
 void FillVersion5Fields(FormFieldData* data) {
-  data->css_classes = u"class1 class2";
+  data->set_css_classes(u"class1 class2");
 }
 
 void FillVersion6Fields(FormFieldData* data) {
@@ -60,54 +60,56 @@
   pickle->WriteString16(data.name());
   pickle->WriteString16(data.value());
   pickle->WriteString(FormControlTypeToString(data.form_control_type()));
-  pickle->WriteString(data.autocomplete_attribute);
+  pickle->WriteString(data.autocomplete_attribute());
   pickle->WriteUInt64(data.max_length());
   pickle->WriteBool(data.is_autofilled());
 }
 
 void WriteSection3(const FormFieldData& data, base::Pickle* pickle) {
-  pickle->WriteBool(IsChecked(data.check_status));
-  pickle->WriteBool(IsCheckable(data.check_status));
+  pickle->WriteBool(IsChecked(data.check_status()));
+  pickle->WriteBool(IsCheckable(data.check_status()));
 }
 
 void WriteSection4(const FormFieldData& data, base::Pickle* pickle) {
-  pickle->WriteInt(static_cast<int>(data.check_status));
+  pickle->WriteInt(static_cast<int>(data.check_status()));
 }
 
 void WriteSection5(const FormFieldData& data, base::Pickle* pickle) {
-  pickle->WriteBool(data.is_focusable);
-  pickle->WriteBool(data.should_autocomplete);
+  pickle->WriteBool(data.is_focusable());
+  pickle->WriteBool(data.should_autocomplete());
 }
 
 void WriteSection2(const FormFieldData& data, base::Pickle* pickle) {
-  pickle->WriteInt(data.text_direction);
-  pickle->WriteInt(static_cast<int>(data.options.size()));
-  for (const auto& option : data.options)
+  pickle->WriteInt(data.text_direction());
+  pickle->WriteInt(static_cast<int>(data.options().size()));
+  for (const auto& option : data.options()) {
     pickle->WriteString16(option.value);
-  pickle->WriteInt(static_cast<int>(data.options.size()));
-  for (const auto& option : data.options)
+  }
+  pickle->WriteInt(static_cast<int>(data.options().size()));
+  for (const auto& option : data.options()) {
     pickle->WriteString16(option.content);
+  }
 }
 
 void WriteVersion9Specific(const FormFieldData& data, base::Pickle* pickle) {
-  pickle->WriteInt(data.text_direction);
-  pickle->WriteInt(static_cast<int>(data.options.size()));
-  for (const SelectOption& option : data.options) {
+  pickle->WriteInt(data.text_direction());
+  pickle->WriteInt(static_cast<int>(data.options().size()));
+  for (const SelectOption& option : data.options()) {
     pickle->WriteString16(option.value);
     pickle->WriteString16(option.content);
   }
 }
 
 void WriteVersion2Specific(const FormFieldData& data, base::Pickle* pickle) {
-  pickle->WriteInt(static_cast<int>(data.role));
+  pickle->WriteInt(static_cast<int>(data.role()));
 }
 
 void WriteVersion3Specific(const FormFieldData& data, base::Pickle* pickle) {
-  pickle->WriteString16(data.placeholder);
+  pickle->WriteString16(data.placeholder());
 }
 
 void WriteVersion5Specific(const FormFieldData& data, base::Pickle* pickle) {
-  pickle->WriteString16(data.css_classes);
+  pickle->WriteString16(data.css_classes());
 }
 
 void WriteVersion6Specific(const FormFieldData& data, base::Pickle* pickle) {
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc b/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
index 4d34465cc..6d2490f 100644
--- a/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
+++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
@@ -207,7 +207,7 @@
     if (!data.ReadSelectedText(&selected_text)) {
       return false;
     }
-    out->selected_text = std::move(selected_text);
+    out->set_selected_text(std::move(selected_text));
   }
 
   {
@@ -222,7 +222,7 @@
     if (!data.ReadAutocompleteAttribute(&autocomplete_attribute)) {
       return false;
     }
-    out->autocomplete_attribute = std::move(autocomplete_attribute);
+    out->set_autocomplete_attribute(std::move(autocomplete_attribute));
   }
   {
     std::optional<autofill::AutocompleteParsingResult> parsed_autocomplete;
@@ -237,7 +237,7 @@
     if (!data.ReadPlaceholder(&placeholder)) {
       return false;
     }
-    out->placeholder = std::move(placeholder);
+    out->set_placeholder(std::move(placeholder));
   }
 
   {
@@ -245,7 +245,7 @@
     if (!data.ReadCssClasses(&css_classes)) {
       return false;
     }
-    out->css_classes = std::move(css_classes);
+    out->set_css_classes(std::move(css_classes));
   }
 
   {
@@ -253,7 +253,7 @@
     if (!data.ReadAriaLabel(&aria_label)) {
       return false;
     }
-    out->aria_label = std::move(aria_label);
+    out->set_aria_label(std::move(aria_label));
   }
 
   {
@@ -261,7 +261,7 @@
     if (!data.ReadAriaDescription(&aria_description)) {
       return false;
     }
-    out->aria_description = std::move(aria_description);
+    out->set_aria_description(std::move(aria_description));
   }
 
   {
@@ -287,12 +287,12 @@
     if (!data.ReadHostFormId(&host_form_id)) {
       return false;
     }
-    out->host_form_id = std::move(host_form_id);
+    out->set_host_form_id(std::move(host_form_id));
   }
 
-  out->form_control_ax_id = data.form_control_ax_id();
+  out->set_form_control_ax_id(data.form_control_ax_id());
   out->set_max_length(data.max_length());
-  out->is_user_edited = data.is_user_edited();
+  out->set_is_user_edited(data.is_user_edited());
   out->set_is_autofilled(data.is_autofilled());
 
   {
@@ -300,19 +300,19 @@
     if (!data.ReadCheckStatus(&check_status)) {
       return false;
     }
-    out->check_status = std::move(check_status);
+    out->set_check_status(std::move(check_status));
   }
 
-  out->is_focusable = data.is_focusable();
-  out->is_visible = data.is_visible();
-  out->should_autocomplete = data.should_autocomplete();
+  out->set_is_focusable(data.is_focusable());
+  out->set_is_visible(data.is_visible());
+  out->set_should_autocomplete(data.should_autocomplete());
 
   {
     autofill::FormFieldData::RoleAttribute role;
     if (!data.ReadRole(&role)) {
       return false;
     }
-    out->role = std::move(role);
+    out->set_role(std::move(role));
   }
 
   {
@@ -320,17 +320,17 @@
     if (!data.ReadTextDirection(&text_direction)) {
       return false;
     }
-    out->text_direction = std::move(text_direction);
+    out->set_text_direction(std::move(text_direction));
   }
 
-  out->is_enabled = data.is_enabled();
-  out->is_readonly = data.is_readonly();
+  out->set_is_enabled(data.is_enabled());
+  out->set_is_readonly(data.is_readonly());
   {
     std::u16string user_input;
     if (!data.ReadUserInput(&user_input)) {
       return false;
     }
-    out->user_input = std::move(user_input);
+    out->set_user_input(std::move(user_input));
   }
 
   {
@@ -338,7 +338,7 @@
     if (!data.ReadOptions(&options)) {
       return false;
     }
-    out->options = std::move(options);
+    out->set_options(std::move(options));
   }
 
   {
@@ -346,7 +346,7 @@
     if (!data.ReadLabelSource(&label_source)) {
       return false;
     }
-    out->label_source = std::move(label_source);
+    out->set_label_source(std::move(label_source));
   }
 
   {
@@ -354,7 +354,7 @@
     if (!data.ReadBounds(&bounds)) {
       return false;
     }
-    out->bounds = std::move(bounds);
+    out->set_bounds(std::move(bounds));
   }
 
   {
@@ -362,10 +362,10 @@
     if (!data.ReadDatalistOptions(&datalist_options)) {
       return false;
     }
-    out->datalist_options = std::move(datalist_options);
+    out->set_datalist_options(std::move(datalist_options));
   }
 
-  out->force_override = data.force_override();
+  out->set_force_override(data.force_override());
 
   return true;
 }
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits.h b/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
index 79c30ff..ff070c8 100644
--- a/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
+++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
@@ -211,7 +211,7 @@
   }
 
   static const std::u16string& selected_text(const autofill::FormFieldData& r) {
-    return r.selected_text;
+    return r.selected_text();
   }
 
   static autofill::mojom::FormControlType form_control_type(
@@ -221,7 +221,7 @@
 
   static const std::string& autocomplete_attribute(
       const autofill::FormFieldData& r) {
-    return r.autocomplete_attribute;
+    return r.autocomplete_attribute();
   }
 
   static const std::optional<autofill::AutocompleteParsingResult>
@@ -230,20 +230,20 @@
   }
 
   static const std::u16string& placeholder(const autofill::FormFieldData& r) {
-    return r.placeholder;
+    return r.placeholder();
   }
 
   static const std::u16string& css_classes(const autofill::FormFieldData& r) {
-    return r.css_classes;
+    return r.css_classes();
   }
 
   static const std::u16string& aria_label(const autofill::FormFieldData& r) {
-    return r.aria_label;
+    return r.aria_label();
   }
 
   static const std::u16string& aria_description(
       const autofill::FormFieldData& r) {
-    return r.aria_description;
+    return r.aria_description();
   }
 
   static autofill::FieldRendererId renderer_id(
@@ -253,7 +253,7 @@
 
   static autofill::FormRendererId host_form_id(
       const autofill::FormFieldData& r) {
-    return r.host_form_id;
+    return r.host_form_id();
   }
 
   static uint32_t properties_mask(const autofill::FormFieldData& r) {
@@ -261,7 +261,7 @@
   }
 
   static int32_t form_control_ax_id(const autofill::FormFieldData& r) {
-    return r.form_control_ax_id;
+    return r.form_control_ax_id();
   }
 
   static uint64_t max_length(const autofill::FormFieldData& r) {
@@ -269,7 +269,7 @@
   }
 
   static bool is_user_edited(const autofill::FormFieldData& r) {
-    return r.is_user_edited;
+    return r.is_user_edited();
   }
 
   static bool is_autofilled(const autofill::FormFieldData& r) {
@@ -282,67 +282,67 @@
 
   static autofill::FormFieldData::CheckStatus check_status(
       const autofill::FormFieldData& r) {
-    return r.check_status;
+    return r.check_status();
   }
 
   static bool is_focusable(const autofill::FormFieldData& r) {
-    return r.is_focusable;
+    return r.is_focusable();
   }
 
   static bool is_visible(const autofill::FormFieldData& r) {
-    return r.is_visible;
+    return r.is_visible();
   }
 
   static bool should_autocomplete(const autofill::FormFieldData& r) {
-    return r.should_autocomplete;
+    return r.should_autocomplete();
   }
 
   static autofill::FormFieldData::RoleAttribute role(
       const autofill::FormFieldData& r) {
-    return r.role;
+    return r.role();
   }
 
   static base::i18n::TextDirection text_direction(
       const autofill::FormFieldData& r) {
-    return r.text_direction;
+    return r.text_direction();
   }
 
   static bool is_enabled(const autofill::FormFieldData& r) {
-    return r.is_enabled;
+    return r.is_enabled();
   }
 
   static bool is_readonly(const autofill::FormFieldData& r) {
-    return r.is_readonly;
+    return r.is_readonly();
   }
 
   static const std::u16string& user_input(const autofill::FormFieldData& r) {
-    return r.user_input;
+    return r.user_input();
   }
 
   static const std::vector<autofill::SelectOption>& options(
       const autofill::FormFieldData& r) {
-    return r.options;
+    return r.options();
   }
 
   static autofill::FormFieldData::LabelSource label_source(
       const autofill::FormFieldData& r) {
-    return r.label_source;
+    return r.label_source();
   }
 
   static gfx::RectF bounds(const autofill::FormFieldData& r) {
-    return r.bounds;
+    return r.bounds();
   }
 
   static const std::vector<autofill::SelectOption>& datalist_options(
       const autofill::FormFieldData& r) {
-    return r.datalist_options;
+    return r.datalist_options();
   }
 
   static bool Read(autofill::mojom::FormFieldDataDataView data,
                    autofill::FormFieldData* out);
 
   static bool force_override(const autofill::FormFieldData& r) {
-    return r.force_override;
+    return r.force_override();
   }
 };
 
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc b/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc
index 3173eef..6a06b5ef 100644
--- a/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc
+++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc
@@ -215,11 +215,11 @@
 void ExpectFormFieldData(const FormFieldData& expected,
                          base::OnceClosure closure,
                          const FormFieldData& passed) {
-  EXPECT_TRUE(passed.host_frame.is_empty());
+  EXPECT_TRUE(passed.host_frame().is_empty());
   EXPECT_TRUE(FormFieldData::DeepEqual(test::WithoutUnserializedData(expected),
                                        passed));
   EXPECT_EQ(expected.value(), passed.value());
-  EXPECT_EQ(expected.user_input, passed.user_input);
+  EXPECT_EQ(expected.user_input(), passed.user_input());
   std::move(closure).Run();
 }
 
@@ -319,7 +319,7 @@
   // Randomizing the LocalFrameToken requires an AutofillTestEnvironment, which
   // doesn't exist yet because SectionTestCases() is called by
   // INSTANTIATE_TEST_SUITE_P().
-  field.host_frame = test::MakeLocalFrameToken(test::RandomizeFrame(false));
+  field.set_host_frame(test::MakeLocalFrameToken(test::RandomizeFrame(false)));
   field.set_renderer_id(FieldRendererId(123));
   s = Section::FromFieldIdentifier(field, frame_token_ids);
   test_cases.push_back(s);
@@ -335,38 +335,38 @@
   FormFieldData input = test::CreateTestSelectField(
       "TestLabel", "TestName", "TestValue", kOptions, kOptions);
   // Set other attributes to check if they are passed correctly.
-  input.host_frame = test::MakeLocalFrameToken();
+  input.set_host_frame(test::MakeLocalFrameToken());
   input.set_name(u"name");
   input.set_id_attribute(u"id");
   input.set_name_attribute(u"name");
   input.set_value(u"value");
   input.set_form_control_type(FormControlType::kInputText);
-  input.autocomplete_attribute = "on";
+  input.set_autocomplete_attribute("on");
   input.set_parsed_autocomplete(
       AutocompleteParsingResult{.section = "autocomplete_section",
                                 .mode = HtmlFieldMode::kShipping,
                                 .field_type = HtmlFieldType::kAddressLine1});
-  input.placeholder = u"placeholder";
-  input.css_classes = u"class1";
-  input.aria_label = u"aria label";
-  input.aria_description = u"aria description";
+  input.set_placeholder(u"placeholder");
+  input.set_css_classes(u"class1");
+  input.set_aria_label(u"aria label");
+  input.set_aria_description(u"aria description");
   input.set_renderer_id(FieldRendererId(1234));
-  input.host_form_id = FormRendererId(123);
+  input.set_host_form_id(FormRendererId(123));
   input.set_max_length(12345);
   input.set_is_autofilled(true);
-  input.is_user_edited = true;
-  input.check_status = FormFieldData::CheckStatus::kChecked;
-  input.should_autocomplete = true;
-  input.role = FormFieldData::RoleAttribute::kPresentation;
-  input.text_direction = base::i18n::RIGHT_TO_LEFT;
+  input.set_is_user_edited(true);
+  input.set_check_status(FormFieldData::CheckStatus::kChecked);
+  input.set_should_autocomplete(true);
+  input.set_role(FormFieldData::RoleAttribute::kPresentation);
+  input.set_text_direction(base::i18n::RIGHT_TO_LEFT);
   input.set_properties_mask(FieldPropertiesFlags::kHadFocus);
-  input.user_input = u"TestTypedValue";
-  input.bounds = gfx::RectF(1, 2, 10, 100);
+  input.set_user_input(u"TestTypedValue");
+  input.set_bounds(gfx::RectF(1, 2, 10, 100));
   base::flat_map<LocalFrameToken, size_t> frame_token_ids;
   input.set_section(Section::FromAutocomplete(
       {.section = "autocomplete_section", .mode = HtmlFieldMode::kShipping}));
 
-  EXPECT_FALSE(input.host_frame.is_empty());
+  EXPECT_FALSE(input.host_frame().is_empty());
   base::RunLoop loop;
   mojo::Remote<mojom::TypeTraitsTest> remote(GetTypeTraitsTestRemote());
   remote->PassFormFieldData(
@@ -379,28 +379,28 @@
   FormFieldData input = test::CreateTestDatalistField(
       "DatalistLabel", "DatalistName", "DatalistValue", kOptions, kOptions);
   // Set other attributes to check if they are passed correctly.
-  input.host_frame = test::MakeLocalFrameToken();
+  input.set_host_frame(test::MakeLocalFrameToken());
   input.set_renderer_id(FieldRendererId(1234));
   input.set_id_attribute(u"id");
   input.set_name_attribute(u"name");
-  input.autocomplete_attribute = "on";
+  input.set_autocomplete_attribute("on");
   input.set_parsed_autocomplete(std::nullopt);
-  input.placeholder = u"placeholder";
-  input.css_classes = u"class1";
-  input.aria_label = u"aria label";
-  input.aria_description = u"aria description";
+  input.set_placeholder(u"placeholder");
+  input.set_css_classes(u"class1");
+  input.set_aria_label(u"aria label");
+  input.set_aria_description(u"aria description");
   input.set_max_length(12345);
   input.set_is_autofilled(true);
-  input.is_user_edited = true;
-  input.check_status = FormFieldData::CheckStatus::kChecked;
-  input.should_autocomplete = true;
-  input.role = FormFieldData::RoleAttribute::kPresentation;
-  input.text_direction = base::i18n::RIGHT_TO_LEFT;
+  input.set_is_user_edited(true);
+  input.set_check_status(FormFieldData::CheckStatus::kChecked);
+  input.set_should_autocomplete(true);
+  input.set_role(FormFieldData::RoleAttribute::kPresentation);
+  input.set_text_direction(base::i18n::RIGHT_TO_LEFT);
   input.set_properties_mask(FieldPropertiesFlags::kHadFocus);
-  input.user_input = u"TestTypedValue";
-  input.bounds = gfx::RectF(1, 2, 10, 100);
+  input.set_user_input(u"TestTypedValue");
+  input.set_bounds(gfx::RectF(1, 2, 10, 100));
 
-  EXPECT_FALSE(input.host_frame.is_empty());
+  EXPECT_FALSE(input.host_frame().is_empty());
   base::RunLoop loop;
   mojo::Remote<mojom::TypeTraitsTest> remote(GetTypeTraitsTestRemote());
   remote->PassFormFieldData(
diff --git a/components/autofill/core/common/save_password_progress_logger.cc b/components/autofill/core/common/save_password_progress_logger.cc
index f79f0fa..e0119e2 100644
--- a/components/autofill/core/common/save_password_progress_logger.cc
+++ b/components/autofill/core/common/save_password_progress_logger.cc
@@ -122,12 +122,13 @@
 // static
 std::string SavePasswordProgressLogger::GetFormFieldDataLogString(
     const FormFieldData& field) {
-  const char* const is_visible = field.is_focusable ? "visible" : "invisible";
+  const char* const is_visible = field.is_focusable() ? "visible" : "invisible";
   const char* const is_empty = field.value().empty() ? "empty" : "non-empty";
   std::string autocomplete =
-      field.autocomplete_attribute.empty()
+      field.autocomplete_attribute().empty()
           ? std::string()
-          : (", autocomplete=" + ScrubElementID(field.autocomplete_attribute));
+          : (", autocomplete=" +
+             ScrubElementID(field.autocomplete_attribute()));
   return base::StringPrintf(
       "%s: signature=%s, type=%s, renderer_id=%s, %s, %s%s",
       ScrubElementID(field.name()).c_str(),
diff --git a/components/autofill/core/common/signatures.cc b/components/autofill/core/common/signatures.cc
index 2b3e7c0e..393e761 100644
--- a/components/autofill/core/common/signatures.cc
+++ b/components/autofill/core/common/signatures.cc
@@ -93,7 +93,7 @@
   std::string form_signature_field_names;
 
   for (const FormFieldData& field : form_data.fields) {
-    if (!IsCheckable(field.check_status)) {
+    if (!IsCheckable(field.check_status())) {
       // Add all supported form fields (including with empty names) to the
       // signature.  This is a requirement for Autofill servers.
       base::StrAppend(&form_signature_field_names,
@@ -121,7 +121,7 @@
 
   std::string form_signature_field_types;
   for (const FormFieldData& field : form_data.fields) {
-    if (!IsCheckable(field.check_status)) {
+    if (!IsCheckable(field.check_status())) {
       // Add all supported form fields' form control types to the signature.
       // We use the string representation of the FormControlType because
       // changing the signature algorithm is non-trivial. If and when the
diff --git a/components/autofill/ios/browser/autofill_across_iframes_unittest.mm b/components/autofill/ios/browser/autofill_across_iframes_unittest.mm
index 62c0b53..cf1e4570 100644
--- a/components/autofill/ios/browser/autofill_across_iframes_unittest.mm
+++ b/components/autofill/ios/browser/autofill_across_iframes_unittest.mm
@@ -260,10 +260,10 @@
 
   EXPECT_EQ(form.fields.size(), 2u);
   for (const FormFieldData& field : form.fields) {
-    EXPECT_EQ(field.host_frame, form.host_frame);
-    EXPECT_EQ(field.host_form_id, form.renderer_id);
-    EXPECT_EQ(field.origin, url::Origin::Create(form.url));
-    EXPECT_EQ(field.host_form_signature, form_signature);
+    EXPECT_EQ(field.host_frame(), form.host_frame);
+    EXPECT_EQ(field.host_form_id(), form.renderer_id);
+    EXPECT_EQ(field.origin(), url::Origin::Create(form.url));
+    EXPECT_EQ(field.host_form_signature(), form_signature);
   }
 }
 
diff --git a/components/autofill/ios/browser/autofill_agent.mm b/components/autofill/ios/browser/autofill_agent.mm
index 9b4456b..1af6db5 100644
--- a/components/autofill/ios/browser/autofill_agent.mm
+++ b/components/autofill/ios/browser/autofill_agent.mm
@@ -102,7 +102,7 @@
                   FieldRendererId fieldIdentifier) {
   for (const auto& currentField : form.fields) {
     if (currentField.renderer_id() == fieldIdentifier &&
-        currentField.is_focusable) {
+        currentField.is_focusable()) {
       *field = currentField;
       break;
     }
diff --git a/components/autofill/ios/browser/autofill_util.mm b/components/autofill/ios/browser/autofill_util.mm
index 03e28fec..ac6e86cd 100644
--- a/components/autofill/ios/browser/autofill_util.mm
+++ b/components/autofill/ios/browser/autofill_util.mm
@@ -251,9 +251,9 @@
       // Some data is extracted at the form level, but also appears at the
       // field level. Reuse the extracted values.
       if (include_frame_metadata) {
-        field_data.host_frame = form_data->host_frame;
-        field_data.host_form_id = form_data->renderer_id;
-        field_data.origin = frame_origin_object;
+        field_data.set_host_frame(form_data->host_frame);
+        field_data.set_host_form_id(form_data->renderer_id);
+        field_data.set_origin(frame_origin_object);
       }
       form_data->fields.push_back(std::move(field_data));
     } else {
@@ -264,7 +264,7 @@
   if (include_frame_metadata) {
     FormSignature form_signature = CalculateFormSignature(*form_data);
     for (FormFieldData& field : form_data->fields) {
-      field.host_form_signature = form_signature;
+      field.set_host_form_signature(form_signature);
     }
   }
   return true;
@@ -309,40 +309,40 @@
   }
   field_data->set_is_autofilled(
       field.FindBool("is_autofilled").value_or(field_data->is_autofilled()));
-  field_data->is_user_edited =
-      field.FindBool("is_user_edited").value_or(field_data->is_user_edited);
+  field_data->set_is_user_edited(
+      field.FindBool("is_user_edited").value_or(field_data->is_user_edited()));
 
   if (const std::string* autocomplete_attribute =
           field.FindString("autocomplete_attribute")) {
-    field_data->autocomplete_attribute = *autocomplete_attribute;
+    field_data->set_autocomplete_attribute(*autocomplete_attribute);
   }
   if (std::optional<int> max_length = field.FindInt("max_length")) {
     field_data->set_max_length(*max_length);
   }
   field_data->set_parsed_autocomplete(
-      ParseAutocompleteAttribute(field_data->autocomplete_attribute));
+      ParseAutocompleteAttribute(field_data->autocomplete_attribute()));
 
   // TODO(crbug.com/427614): Extract |is_checked|.
   bool is_checkable = field.FindBool("is_checkable").value_or(false);
   autofill::SetCheckStatus(field_data, is_checkable, false);
 
-  field_data->is_focusable =
-      field.FindBool("is_focusable").value_or(field_data->is_focusable);
-  field_data->should_autocomplete =
+  field_data->set_is_focusable(
+      field.FindBool("is_focusable").value_or(field_data->is_focusable()));
+  field_data->set_should_autocomplete(
       field.FindBool("should_autocomplete")
-          .value_or(field_data->should_autocomplete);
+          .value_or(field_data->should_autocomplete()));
 
   if (const std::string* placeholder_attribute =
           field.FindString("placeholder_attribute")) {
-    field_data->placeholder = base::UTF8ToUTF16(*placeholder_attribute);
+    field_data->set_placeholder(base::UTF8ToUTF16(*placeholder_attribute));
   }
 
   if (const std::string* aria_label = field.FindString("aria_label")) {
-    field_data->aria_label = base::UTF8ToUTF16(*aria_label);
+    field_data->set_aria_label(base::UTF8ToUTF16(*aria_label));
   }
   if (const std::string* aria_description =
           field.FindString("aria_description")) {
-    field_data->aria_description = base::UTF8ToUTF16(*aria_description);
+    field_data->set_aria_description(base::UTF8ToUTF16(*aria_description));
   }
 
   // RoleAttribute::kOther is the default value. The only other value as of this
@@ -350,7 +350,7 @@
   std::optional<int> role = field.FindInt("role");
   if (role &&
       *role == static_cast<int>(FormFieldData::RoleAttribute::kPresentation)) {
-    field_data->role = FormFieldData::RoleAttribute::kPresentation;
+    field_data->set_role(FormFieldData::RoleAttribute::kPresentation);
   }
 
   // TODO(crbug.com/427614): Extract |text_direction|.
@@ -362,24 +362,26 @@
     if (option_values->size() != option_contents->size()) {
       return false;
     }
+    std::vector<SelectOption> options;
     auto value_it = option_values->begin();
     auto content_it = option_contents->begin();
     while (value_it != option_values->end() &&
            content_it != option_contents->end()) {
       if (value_it->is_string() && content_it->is_string()) {
-        field_data->options.push_back(
+        options.push_back(
             {.value = base::UTF8ToUTF16(value_it->GetString()),
              .content = base::UTF8ToUTF16(content_it->GetString())});
       }
       ++value_it;
       ++content_it;
     }
+    field_data->set_options(std::move(options));
   }
 
   // Fill user input and properties mask.
   if (field_data_manager.HasFieldData(field_data->renderer_id())) {
-    field_data->user_input =
-        field_data_manager.GetUserInput(field_data->renderer_id());
+    field_data->set_user_input(
+        field_data_manager.GetUserInput(field_data->renderer_id()));
     field_data->set_properties_mask(
         field_data_manager.GetFieldPropertiesMask(field_data->renderer_id()));
   }
diff --git a/components/autofill/ios/browser/autofill_util_unittests.mm b/components/autofill/ios/browser/autofill_util_unittests.mm
index 2b2d8b5..a51a903b 100644
--- a/components/autofill/ios/browser/autofill_util_unittests.mm
+++ b/components/autofill/ios/browser/autofill_util_unittests.mm
@@ -81,7 +81,7 @@
   autofill::FormFieldData field_data;
   autofill::ExtractFormFieldData(field, *field_data_manager, &field_data);
 
-  EXPECT_EQ(u"my@mail", field_data.user_input);
+  EXPECT_EQ(u"my@mail", field_data.user_input());
   EXPECT_EQ(autofill::FieldPropertiesFlags::kUserTyped,
             field_data.properties_mask());
 }
diff --git a/components/bookmarks/browser/base_bookmark_model_observer.cc b/components/bookmarks/browser/base_bookmark_model_observer.cc
index 5787535..7146f06 100644
--- a/components/bookmarks/browser/base_bookmark_model_observer.cc
+++ b/components/bookmarks/browser/base_bookmark_model_observer.cc
@@ -49,7 +49,7 @@
 
 void BaseBookmarkModelObserver::BookmarkNodeFaviconChanged(
     const BookmarkNode* node) {
-  BookmarkModelChanged();
+  // Report no change, as observers typically don't care as much about favicons.
 }
 
 void BaseBookmarkModelObserver::BookmarkNodeChildrenReordered(
diff --git a/components/browser_ui/strings/android/browser_ui_strings.grd b/components/browser_ui/strings/android/browser_ui_strings.grd
index 282e9ac..55f9a26 100644
--- a/components/browser_ui/strings/android/browser_ui_strings.grd
+++ b/components/browser_ui/strings/android/browser_ui_strings.grd
@@ -457,8 +457,8 @@
       <message name="IDS_PAGE_INFO_FORGET_SITE_TITLE" desc="Label used at top of dialog which clears stored information displayed in page info (ie permissions, cookies, eventually history).">
         Forget this site?
       </message>
-      <message name="IDS_PAGE_INFO_FORGET_SITE_MESSAGE" desc="Message used in dialogwhich clears stored information displayed in page info.">
-        Are you sure you want to reset permissions, and clear cookies and site data?
+      <message name="IDS_PAGE_INFO_FORGET_SITE_MESSAGE" desc="Message used in dialog which deletes stored information displayed in page info.">
+        Are you sure you want to reset permissions, and delete cookies and site data?
       </message>
       <message name="IDS_PAGE_INFO_FORGET_SITE_CONFIRMATION_BUTTON" desc="Confirmation button in dialog which clears stored information displayed in page info.">
         Forget
diff --git a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_FORGET_SITE_MESSAGE.png.sha1 b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_FORGET_SITE_MESSAGE.png.sha1
index 079ff63..e41b15ab 100644
--- a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_FORGET_SITE_MESSAGE.png.sha1
+++ b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_FORGET_SITE_MESSAGE.png.sha1
@@ -1 +1 @@
-baf91ad9988c2742181e2c3e09a60f9be9713ac4
\ No newline at end of file
+909e34d3f3404a768f9c74373b7e0ef3bfe0a756
\ No newline at end of file
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb
index 8262681..0fe9afff 100644
--- a/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb
+++ b/components/browser_ui/strings/android/translations/browser_ui_strings_ms.xtb
@@ -134,6 +134,7 @@
 <translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> data disimpan</translation>
 <translation id="321187648315454507">Untuk membolehkan <ph name="APP_NAME" /> menghantar pemberitahuan kepada anda, hidupkan juga pemberitahuan dalam <ph name="BEGIN_LINK" />Tetapan Android<ph name="END_LINK" />.</translation>
 <translation id="3227137524299004712">Mikrofon</translation>
+<translation id="3232293466644486101">Padamkan data semakan imbas…</translation>
 <translation id="3242646949159196181">Apabila dihidupkan, laman dapat memainkan bunyi. Apabila dimatikan, laman tidak dapat memainkan bunyi.</translation>
 <translation id="3277252321222022663">Benarkan tapak mengakses penderia (disyorkan)</translation>
 <translation id="3285500645985761267">Benarkan laman berkaitan melihat aktiviti anda dalam kumpulan</translation>
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json
index bd9ba79..120d2193 100644
--- a/components/certificate_transparency/data/log_list.json
+++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@
 {
-  "version": "33.51",
-  "log_list_timestamp": "2024-04-21T12:55:58Z",
+  "version": "33.52",
+  "log_list_timestamp": "2024-04-22T12:55:04Z",
   "operators": [
     {
       "name": "Google",
diff --git a/components/compose/core/browser/compose_manager_impl.cc b/components/compose/core/browser/compose_manager_impl.cc
index af59435..ba40b03 100644
--- a/components/compose/core/browser/compose_manager_impl.cc
+++ b/components/compose/core/browser/compose_manager_impl.cc
@@ -100,8 +100,8 @@
   }
 
   if (base::FeatureList::IsEnabled(compose::features::kComposeTextSelection) &&
-      IsWordCountWithinBounds(base::UTF16ToUTF8(form_field_data->selected_text),
-                              0, 1)) {
+      IsWordCountWithinBounds(
+          base::UTF16ToUTF8(form_field_data->selected_text()), 0, 1)) {
     // Select all words. Consecutive calls using the same message pipe
     // should complete in the same order it's received.
     // Therefore, we can safely assume that the text selection will complete
diff --git a/components/content_settings/core/browser/cookie_settings_unittest.cc b/components/content_settings/core/browser/cookie_settings_unittest.cc
index 67340c4..b55f355 100644
--- a/components/content_settings/core/browser/cookie_settings_unittest.cc
+++ b/components/content_settings/core/browser/cookie_settings_unittest.cc
@@ -119,7 +119,7 @@
       scoped_observation_{this};
 };
 
-class CookieSettingsTestBase {
+class CookieSettingsTestBase : public testing::Test {
  public:
   CookieSettingsTestBase()
       : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
@@ -151,14 +151,14 @@
         kAllHttpsSitesPattern(ContentSettingsPattern::FromString("https://*")) {
   }
 
-  ~CookieSettingsTestBase() {
+  ~CookieSettingsTestBase() override {
     cookie_settings_->ShutdownOnUIThread();
     cookie_settings_incognito_->ShutdownOnUIThread();
     settings_map_->ShutdownOnUIThread();
     tracking_protection_settings_->Shutdown();
   }
 
-  void SetUp() {
+  void SetUp() override {
     ContentSettingsRegistry::GetInstance()->ResetForTest();
     CookieSettings::RegisterProfilePrefs(prefs_.registry());
     HostContentSettingsMap::RegisterProfilePrefs(prefs_.registry());
@@ -191,6 +191,13 @@
     task_environment_.FastForwardBy(delta);
   }
 
+  bool ShouldDeleteCookieOnExit(const std::string& domain, bool is_https) {
+    return cookie_settings_->ShouldDeleteCookieOnExit(
+        cookie_settings_->GetCookieSettings(), domain,
+        is_https ? net::CookieSourceScheme::kSecure
+                 : net::CookieSourceScheme::kNonSecure);
+  }
+
  protected:
   // There must be a valid SingleThreadTaskRunner::CurrentDefaultHandle in
   // HostContentSettingsMap's scope.
@@ -232,13 +239,47 @@
   ContentSettingsPattern kAllHttpsSitesPattern;
 };
 
-class CookieSettingsTest
+// Default test class to be used by most tests. If you want to add a new
+// parameter, consider whether all test cases actually require this parameter
+// or whether it is sufficient to add a new subclass of CookieSettingsTestBase.
+class CookieSettingsTest : public CookieSettingsTestBase,
+                           public testing::WithParamInterface<
+                               /*kHostIndexedMetadataGrantsEnabled*/ bool> {
+ public:
+  CookieSettingsTest() {
+    std::vector<base::test::FeatureRefAndParams> enabled_features;
+    std::vector<base::test::FeatureRef> disabled_features;
+
+    enabled_features.push_back(
+        {content_settings::features::kUserBypassUI, {{"expiration", "0d"}}});
+
+    if (IsIndexedContentSettingsEnabled()) {
+      enabled_features.push_back({features::kHostIndexedMetadataGrants, {}});
+      enabled_features.push_back(
+          {features::kIndexedHostContentSettingsMap, {}});
+    } else {
+      disabled_features.push_back(features::kHostIndexedMetadataGrants);
+      disabled_features.push_back(features::kIndexedHostContentSettingsMap);
+    }
+
+    feature_list_.InitWithFeaturesAndParameters(enabled_features,
+                                                disabled_features);
+  }
+
+ private:
+  bool IsIndexedContentSettingsEnabled() const { return GetParam(); }
+};
+
+// Parameterized class that tests combinations of StorageAccess grants and 3pcd
+// grants. Tests that don't need the whole range of combinations should create
+// their own parameterized subclasses.
+class CookieSettingsTestP
     : public CookieSettingsTestBase,
-      public testing::TestWithParam<
+      public testing::WithParamInterface<
           std::tuple</*kGrantSource*/ GrantSource,
                      /*kHostIndexedMetadataGrantsEnabled*/ bool>> {
  public:
-  CookieSettingsTest() {
+  CookieSettingsTestP() {
     std::vector<base::test::FeatureRefAndParams> enabled_features;
     std::vector<base::test::FeatureRef> disabled_features;
 
@@ -273,8 +314,6 @@
                                                 disabled_features);
   }
 
-  void SetUp() override { CookieSettingsTestBase::SetUp(); }
-
   bool IsStorageAccessGrantEligible() const {
     return std::get<TestVariables::kGrantSource>(GetParam()) ==
            GrantSource::kStorageAccessGrantsEligible;
@@ -381,14 +420,6 @@
     }
     return net::cookie_util::StorageAccessResult::ACCESS_BLOCKED;
   }
-
- protected:
-  bool ShouldDeleteCookieOnExit(const std::string& domain, bool is_https) {
-    return cookie_settings_->ShouldDeleteCookieOnExit(
-        cookie_settings_->GetCookieSettings(), domain,
-        is_https ? net::CookieSourceScheme::kSecure
-                 : net::CookieSourceScheme::kNonSecure);
-  }
 };
 
 TEST_P(CookieSettingsTest, UserBypassPermanentExceptions) {
@@ -634,35 +665,35 @@
   cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
   EXPECT_FALSE(cookie_settings_->IsFullCookieAccessAllowed(
       kHttpSite, kChromeSiteForCookies, /*top_frame_origin=*/std::nullopt,
-      GetCookieSettingOverrides()));
+      net::CookieSettingOverrides()));
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kHttpsSite, kChromeSiteForCookies, /*top_frame_origin=*/std::nullopt,
-      GetCookieSettingOverrides()));
+      net::CookieSettingOverrides()));
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kChromeURL, kHttpSiteForCookies, /*top_frame_origin=*/std::nullopt,
-      GetCookieSettingOverrides()));
+      net::CookieSettingOverrides()));
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kExtensionURL, kExtensionSiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
 #else
   EXPECT_FALSE(cookie_settings_->IsFullCookieAccessAllowed(
       kExtensionURL, kExtensionSiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
 #endif
   EXPECT_FALSE(cookie_settings_->IsFullCookieAccessAllowed(
       kExtensionURL, kHttpSiteForCookies, /*top_frame_origin=*/std::nullopt,
-      GetCookieSettingOverrides()));
+      net::CookieSettingOverrides()));
 }
 
 TEST_P(CookieSettingsTest, CookiesBlockSingle) {
   cookie_settings_->SetCookieSetting(kBlockedSite, CONTENT_SETTING_BLOCK);
   EXPECT_FALSE(cookie_settings_->IsFullCookieAccessAllowed(
       kBlockedSite, kBlockedSiteForCookies, /*top_frame_origin=*/std::nullopt,
-      GetCookieSettingOverrides()));
+      net::CookieSettingOverrides()));
 }
 
-TEST_P(CookieSettingsTest, CookiesBlockThirdParty) {
+TEST_P(CookieSettingsTestP, CookiesBlockThirdParty) {
   prefs_.SetInteger(prefs::kCookieControlsMode,
                     static_cast<int>(CookieControlsMode::kBlockThirdParty));
   // Cookie is allowed only when block is overridden.
@@ -695,12 +726,12 @@
 TEST_P(CookieSettingsTest, CookiesControlsDefault) {
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kBlockedSite, kFirstPartySiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
   EXPECT_NE(
       kSupports3pcBlocking,
       cookie_settings_incognito_->IsFullCookieAccessAllowed(
           kBlockedSite, kFirstPartySiteForCookies,
-          /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+          /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
 }
 
 TEST_P(CookieSettingsTest, CookiesControlsDisabled) {
@@ -708,23 +739,23 @@
                     static_cast<int>(CookieControlsMode::kOff));
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kBlockedSite, kFirstPartySiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
   EXPECT_TRUE(cookie_settings_incognito_->IsFullCookieAccessAllowed(
       kBlockedSite, kFirstPartySiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
 }
 
 TEST_P(CookieSettingsTest, CookiesControlsEnabledForIncognito) {
-  auto cookie_setting_overrides = GetCookieSettingOverrides();
   prefs_.SetInteger(prefs::kCookieControlsMode,
                     static_cast<int>(CookieControlsMode::kIncognitoOnly));
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kBlockedSite, kFirstPartySiteForCookies,
-      /*top_frame_origin=*/std::nullopt, cookie_setting_overrides));
-  EXPECT_NE(kSupports3pcBlocking,
-            cookie_settings_incognito_->IsFullCookieAccessAllowed(
-                kBlockedSite, kFirstPartySiteForCookies,
-                /*top_frame_origin=*/std::nullopt, cookie_setting_overrides));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
+  EXPECT_NE(
+      kSupports3pcBlocking,
+      cookie_settings_incognito_->IsFullCookieAccessAllowed(
+          kBlockedSite, kFirstPartySiteForCookies,
+          /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
 }
 
 TEST_P(CookieSettingsTest, TestThirdPartyCookiePhaseout) {
@@ -737,8 +768,6 @@
       {});
   ASSERT_TRUE(net::cookie_util::IsForceThirdPartyCookieBlockingEnabled());
 
-  auto cookie_setting_overrides = GetCookieSettingOverrides();
-
   // Build new CookieSettings since `cookie_settings_` was created before
   // ForceThirdPartyCookieBlocking was enabled.
   scoped_refptr<CookieSettings> cookie_settings = new CookieSettings(
@@ -749,36 +778,36 @@
   EXPECT_EQ(kSupports3pcBlocking,
             cookie_settings->ShouldBlockThirdPartyCookies());
 
-  EXPECT_NE(kSupports3pcBlocking,
-            cookie_settings->IsFullCookieAccessAllowed(
-                kBlockedSite, kFirstPartySiteForCookies,
-                /*top_frame_origin=*/std::nullopt, cookie_setting_overrides));
+  EXPECT_NE(kSupports3pcBlocking, cookie_settings->IsFullCookieAccessAllowed(
+                                      kBlockedSite, kFirstPartySiteForCookies,
+                                      /*top_frame_origin=*/std::nullopt,
+                                      net::CookieSettingOverrides()));
 
   // Test that ForceThirdPartyCookieBlocking overrides preference changes.
   prefs_.SetInteger(prefs::kCookieControlsMode,
                     static_cast<int>(CookieControlsMode::kOff));
-  EXPECT_NE(kSupports3pcBlocking,
-            cookie_settings->IsFullCookieAccessAllowed(
-                kBlockedSite, kFirstPartySiteForCookies,
-                /*top_frame_origin=*/std::nullopt, cookie_setting_overrides));
+  EXPECT_NE(kSupports3pcBlocking, cookie_settings->IsFullCookieAccessAllowed(
+                                      kBlockedSite, kFirstPartySiteForCookies,
+                                      /*top_frame_origin=*/std::nullopt,
+                                      net::CookieSettingOverrides()));
 
   // Test that ForceThirdPartyCookieBlocking can be overridden by site-specific
   // content settings.
   cookie_settings->SetCookieSetting(kBlockedSite, CONTENT_SETTING_ALLOW);
   EXPECT_TRUE(cookie_settings->IsFullCookieAccessAllowed(
       kBlockedSite, kFirstPartySiteForCookies,
-      /*top_frame_origin=*/std::nullopt, cookie_setting_overrides));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
 
   // Requests from DevTools panels added by extensions should get cookies.
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kHttpsSite, kDevToolsSiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
 }
 
 TEST_P(CookieSettingsTest, CookiesAllowThirdParty) {
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kBlockedSite, kFirstPartySiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
   EXPECT_FALSE(cookie_settings_->IsCookieSessionOnly(kBlockedSite));
 }
 
@@ -786,10 +815,10 @@
   cookie_settings_->SetCookieSetting(kBlockedSite, CONTENT_SETTING_BLOCK);
   EXPECT_FALSE(cookie_settings_->IsFullCookieAccessAllowed(
       kBlockedSite, kFirstPartySiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kAllowedSite, kFirstPartySiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
 }
 
 TEST_P(CookieSettingsTest, CookiesExplicitSessionOnly) {
@@ -797,14 +826,14 @@
                                      CONTENT_SETTING_SESSION_ONLY);
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kBlockedSite, kFirstPartySiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
   EXPECT_TRUE(cookie_settings_->IsCookieSessionOnly(kBlockedSite));
 
   prefs_.SetInteger(prefs::kCookieControlsMode,
                     static_cast<int>(CookieControlsMode::kBlockThirdParty));
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kBlockedSite, kFirstPartySiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
   EXPECT_TRUE(cookie_settings_->IsCookieSessionOnly(kBlockedSite));
 }
 
@@ -1125,17 +1154,17 @@
                     static_cast<int>(CookieControlsMode::kBlockThirdParty));
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kAllowedSite, kFirstPartySiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
   EXPECT_FALSE(cookie_settings_->IsCookieSessionOnly(kAllowedSite));
 
   // Extensions should always be allowed to use cookies.
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kAllowedSite, kExtensionSiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
 }
 
 TEST_P(CookieSettingsTest, CookiesThirdPartyBlockedAllSitesAllowed) {
-  auto cookie_setting_overrides = GetCookieSettingOverrides();
+  net::CookieSettingOverrides cookie_setting_overrides;
 
   cookie_settings_->SetCookieSetting(kAllowedSite, CONTENT_SETTING_ALLOW);
   prefs_.SetInteger(prefs::kCookieControlsMode,
@@ -1181,10 +1210,10 @@
 
   EXPECT_FALSE(cookie_settings_->IsFullCookieAccessAllowed(
       kFirstPartySite, kFirstPartySiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
   EXPECT_FALSE(cookie_settings_->IsFullCookieAccessAllowed(
       kAllowedSite, kFirstPartySiteForCookies,
-      /*top_frame_origin*/ std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin*/ std::nullopt, net::CookieSettingOverrides()));
 }
 
 TEST_P(CookieSettingsTest, CookiesBlockEverythingExceptAllowed) {
@@ -1192,13 +1221,13 @@
   cookie_settings_->SetCookieSetting(kAllowedSite, CONTENT_SETTING_ALLOW);
   EXPECT_FALSE(cookie_settings_->IsFullCookieAccessAllowed(
       kFirstPartySite, kFirstPartySiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kAllowedSite, kFirstPartySiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kAllowedSite, kAllowedSiteForCookies, /*top_frame_origin=*/std::nullopt,
-      GetCookieSettingOverrides()));
+      net::CookieSettingOverrides()));
   EXPECT_FALSE(cookie_settings_->IsCookieSessionOnly(kAllowedSite));
 }
 
@@ -1214,7 +1243,7 @@
   histogram_tester.ExpectTotalCount(kAllowedRequestsHistogram, 0);
 
   EXPECT_EQ(cookie_settings_->GetCookieSetting(
-                url, top_level_url, GetCookieSettingOverrides(), nullptr),
+                url, top_level_url, net::CookieSettingOverrides(), nullptr),
             CONTENT_SETTING_ALLOW);
   histogram_tester.ExpectTotalCount(kAllowedRequestsHistogram, 1);
   histogram_tester.ExpectBucketCount(
@@ -1223,10 +1252,7 @@
       1);
 }
 
-// The behaviour of the Storage Access API should be gated behind
-// |kStorageAccessAPI|. The setting also affects which buckets are used by
-// metrics.
-TEST_P(CookieSettingsTest, GetCookieSettingSAA) {
+TEST_P(CookieSettingsTestP, GetCookieSettingSAA) {
   const GURL top_level_url = GURL(kFirstPartySite);
   const GURL url = GURL(kAllowedSite);
   const GURL third_url = GURL(kBlockedSite);
@@ -1266,7 +1292,7 @@
 }
 
 // Test that http exceptions also affect websocket requests.
-TEST_P(CookieSettingsTest, GetCookieSettingSAAWebsocket) {
+TEST_P(CookieSettingsTestP, GetCookieSettingSAAWebsocket) {
   const GURL top_level_url = GURL(kFirstPartySite);
   const GURL url = GURL(kHttpsSite);
 
@@ -1299,7 +1325,7 @@
             CONTENT_SETTING_BLOCK);
 }
 
-TEST_P(CookieSettingsTest, GetCookieSettingSAAViaFedCM) {
+TEST_P(CookieSettingsTestP, GetCookieSettingSAAViaFedCM) {
   const GURL top_level_url = GURL(kFirstPartySite);
   const GURL url = GURL(kAllowedSite);
   const GURL third_url = GURL(kBlockedSite);
@@ -1348,7 +1374,7 @@
 
 // A top-level storage access grant should behave similarly to standard SAA
 // grants.
-TEST_P(CookieSettingsTest, GetCookieSettingTopLevelStorageAccess) {
+TEST_P(CookieSettingsTestP, GetCookieSettingTopLevelStorageAccess) {
   const GURL top_level_url(kFirstPartySite);
   const GURL url(kAllowedSite);
   const GURL third_url(kBlockedSite);
@@ -1389,7 +1415,7 @@
 
 // Subdomains of the granted resource url should not gain access if a valid
 // grant exists; the grant should also not apply on different schemes.
-TEST_P(CookieSettingsTest, GetCookieSettingSAAResourceWildcards) {
+TEST_P(CookieSettingsTestP, GetCookieSettingSAAResourceWildcards) {
   const GURL top_level_url = GURL(kFirstPartySite);
   const GURL url = GURL(kHttpsSite);
 
@@ -1416,7 +1442,7 @@
 
 // Subdomains of the granted top level url should not grant access if a valid
 // grant exists; the grant should also not apply on different schemes.
-TEST_P(CookieSettingsTest, GetCookieSettingSAATopLevelWildcards) {
+TEST_P(CookieSettingsTestP, GetCookieSettingSAATopLevelWildcards) {
   const GURL top_level_url = GURL(kHttpsSite);
   const GURL url = GURL(kFirstPartySite);
 
@@ -1442,7 +1468,7 @@
 
 // Explicit settings should be respected regardless of whether Storage Access
 // API is enabled and/or has grants.
-TEST_P(CookieSettingsTest, GetCookieSettingRespectsExplicitSettings) {
+TEST_P(CookieSettingsTestP, GetCookieSettingRespectsExplicitSettings) {
   const GURL top_level_url = GURL(kFirstPartySite);
   const GURL url = GURL(kAllowedSite);
 
@@ -1459,7 +1485,7 @@
 }
 
 // Once a grant expires access should no longer be given.
-TEST_P(CookieSettingsTest, GetCookieSettingSAAExpiredGrant) {
+TEST_P(CookieSettingsTestP, GetCookieSettingSAAExpiredGrant) {
   const GURL top_level_url = GURL(kFirstPartySite);
   const GURL url = GURL(kAllowedSite);
 
@@ -1490,7 +1516,7 @@
             CONTENT_SETTING_BLOCK);
 }
 
-TEST_P(CookieSettingsTest, GetCookieSetting3pcdTrial) {
+TEST_P(CookieSettingsTestP, GetCookieSetting3pcdTrial) {
   const GURL top_level_url(kFirstPartySite);
   const GURL url(kAllowedSite);
   const GURL third_url(kBlockedSite);
@@ -1535,7 +1561,7 @@
             CONTENT_SETTING_BLOCK);
 }
 
-TEST_P(CookieSettingsTest, GetCookieSetting3pcdMetadataGrants) {
+TEST_P(CookieSettingsTestP, GetCookieSetting3pcdMetadataGrants) {
   const GURL top_level_url(kFirstPartySite);
   const GURL url(kAllowedSite);
   const GURL third_url(kBlockedSite);
@@ -1591,7 +1617,7 @@
       cookie_settings_->IsAllowedByTpcdMetadataGrant(top_level_url, third_url));
 }
 
-TEST_P(CookieSettingsTest, GetCookieSetting3pcdHeuristicsGrants) {
+TEST_P(CookieSettingsTestP, GetCookieSetting3pcdHeuristicsGrants) {
   const GURL first_party_url(kFirstPartySite);
   const GURL third_party_url(kAllowedSite);
   const base::TimeDelta expiration = base::Seconds(5);
@@ -1652,45 +1678,45 @@
   prefs_.SetBoolean(prefs::kTrackingProtection3pcdEnabled, true);
 
   // Expect that cookies are blocked before setting the temporary grant.
-  EXPECT_EQ(
-      cookie_settings_->GetCookieSetting(third_party_url, first_party_url,
-                                         GetCookieSettingOverrides(), nullptr),
-      CONTENT_SETTING_BLOCK);
+  EXPECT_EQ(cookie_settings_->GetCookieSetting(third_party_url, first_party_url,
+                                               net::CookieSettingOverrides(),
+                                               nullptr),
+            CONTENT_SETTING_BLOCK);
 
   // Create a grant and verify that cookies are now allowed.
   cookie_settings_->SetTemporaryCookieGrantForHeuristic(
       third_party_url, first_party_url, expiration_short);
-  EXPECT_EQ(
-      cookie_settings_->GetCookieSetting(third_party_url, first_party_url,
-                                         GetCookieSettingOverrides(), nullptr),
-      CONTENT_SETTING_ALLOW);
+  EXPECT_EQ(cookie_settings_->GetCookieSetting(third_party_url, first_party_url,
+                                               net::CookieSettingOverrides(),
+                                               nullptr),
+            CONTENT_SETTING_ALLOW);
 
   // Create a longer grant and verify that this extends the TTL of the first
   // grant.
   cookie_settings_->SetTemporaryCookieGrantForHeuristic(
       third_party_url, first_party_url, expiration_long);
   FastForwardTime(expiration_short + base::Seconds(1));
-  EXPECT_EQ(
-      cookie_settings_->GetCookieSetting(third_party_url, first_party_url,
-                                         GetCookieSettingOverrides(), nullptr),
-      CONTENT_SETTING_ALLOW);
+  EXPECT_EQ(cookie_settings_->GetCookieSetting(third_party_url, first_party_url,
+                                               net::CookieSettingOverrides(),
+                                               nullptr),
+            CONTENT_SETTING_ALLOW);
 
   // Create a shorter grant and verify that this does NOT shorten the TTL of the
   // longer grant.
   cookie_settings_->SetTemporaryCookieGrantForHeuristic(
       third_party_url, first_party_url, expiration_short);
   FastForwardTime(expiration_short + base::Seconds(1));
-  EXPECT_EQ(
-      cookie_settings_->GetCookieSetting(third_party_url, first_party_url,
-                                         GetCookieSettingOverrides(), nullptr),
-      CONTENT_SETTING_ALLOW);
+  EXPECT_EQ(cookie_settings_->GetCookieSetting(third_party_url, first_party_url,
+                                               net::CookieSettingOverrides(),
+                                               nullptr),
+            CONTENT_SETTING_ALLOW);
 
   // Expect that cookies are blocked again after the longer grant expires.
   FastForwardTime(expiration_long + base::Seconds(1));
-  EXPECT_EQ(
-      cookie_settings_->GetCookieSetting(third_party_url, first_party_url,
-                                         GetCookieSettingOverrides(), nullptr),
-      CONTENT_SETTING_BLOCK);
+  EXPECT_EQ(cookie_settings_->GetCookieSetting(third_party_url, first_party_url,
+                                               net::CookieSettingOverrides(),
+                                               nullptr),
+            CONTENT_SETTING_BLOCK);
 }
 
 TEST_P(CookieSettingsTest, SetTemporaryCookieGrantForHeuristicSchemeless) {
@@ -1704,20 +1730,20 @@
   prefs_.SetBoolean(prefs::kTrackingProtection3pcdEnabled, true);
 
   // Expect that cookies are blocked before setting the temporary grant.
-  EXPECT_EQ(
-      cookie_settings_->GetCookieSetting(third_party_url, first_party_https_url,
-                                         GetCookieSettingOverrides(), nullptr),
-      CONTENT_SETTING_BLOCK);
+  EXPECT_EQ(cookie_settings_->GetCookieSetting(
+                third_party_url, first_party_https_url,
+                net::CookieSettingOverrides(), nullptr),
+            CONTENT_SETTING_BLOCK);
 
   // Set a (schemeful) cookie grant on the HTTP URL.
   cookie_settings_->SetTemporaryCookieGrantForHeuristic(
       third_party_url, first_party_http_url, expiration);
 
   // This grant should not affect the HTTPS URL.
-  EXPECT_EQ(
-      cookie_settings_->GetCookieSetting(third_party_url, first_party_https_url,
-                                         GetCookieSettingOverrides(), nullptr),
-      CONTENT_SETTING_BLOCK);
+  EXPECT_EQ(cookie_settings_->GetCookieSetting(
+                third_party_url, first_party_https_url,
+                net::CookieSettingOverrides(), nullptr),
+            CONTENT_SETTING_BLOCK);
 
   // Set a schemeless cookie grant on the HTTP URL.
   cookie_settings_->SetTemporaryCookieGrantForHeuristic(
@@ -1725,17 +1751,17 @@
       /*use_schemeless_patterns=*/true);
 
   // This grant should enable cookie access on the HTTPS first-party URL.
-  EXPECT_EQ(
-      cookie_settings_->GetCookieSetting(third_party_url, first_party_https_url,
-                                         GetCookieSettingOverrides(), nullptr),
-      CONTENT_SETTING_ALLOW);
+  EXPECT_EQ(cookie_settings_->GetCookieSetting(
+                third_party_url, first_party_https_url,
+                net::CookieSettingOverrides(), nullptr),
+            CONTENT_SETTING_ALLOW);
 
   // Expect that cookies are blocked again after the grant expires.
   FastForwardTime(expiration + base::Seconds(1));
-  EXPECT_EQ(
-      cookie_settings_->GetCookieSetting(third_party_url, first_party_https_url,
-                                         GetCookieSettingOverrides(), nullptr),
-      CONTENT_SETTING_BLOCK);
+  EXPECT_EQ(cookie_settings_->GetCookieSetting(
+                third_party_url, first_party_https_url,
+                net::CookieSettingOverrides(), nullptr),
+            CONTENT_SETTING_BLOCK);
 }
 #endif
 
@@ -1745,7 +1771,7 @@
   // Regular cookie settings also apply to extensions.
   EXPECT_FALSE(cookie_settings_->IsFullCookieAccessAllowed(
       kBlockedSite, kExtensionSiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
 }
 
 TEST_P(CookieSettingsTest, ExtensionsOwnCookies) {
@@ -1755,13 +1781,13 @@
   // Extensions can always use cookies (and site data) in their own origin.
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kExtensionURL, kExtensionSiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
 #else
   // Except if extensions are disabled. Then the extension-specific checks do
   // not exist and the default setting is to block.
   EXPECT_FALSE(cookie_settings_->IsFullCookieAccessAllowed(
       kExtensionURL, kExtensionSiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
 #endif
 }
 
@@ -1773,12 +1799,12 @@
   // rules (as the first party is always the extension's security origin).
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kBlockedSite, kExtensionSiteForCookies,
-      /*top_frame_origin=*/std::nullopt, GetCookieSettingOverrides()));
+      /*top_frame_origin=*/std::nullopt, net::CookieSettingOverrides()));
 }
 
 TEST_P(CookieSettingsTest, ThirdPartyException) {
   GURL first_party_url = kFirstPartySiteForCookies.RepresentativeUrl();
-  auto cookie_setting_overrides = GetCookieSettingOverrides();
+  net::CookieSettingOverrides cookie_setting_overrides;
 
   EXPECT_TRUE(
       cookie_settings_->IsThirdPartyAccessAllowed(kFirstPartySite, nullptr));
@@ -1839,7 +1865,7 @@
       cookie_settings_->IsThirdPartyAccessAllowed(kFirstPartySite, &info));
   EXPECT_TRUE(cookie_settings_->IsFullCookieAccessAllowed(
       kHttpsSite, kFirstPartySiteForCookies, /*top_frame_origin=*/std::nullopt,
-      GetCookieSettingOverrides()));
+      net::CookieSettingOverrides()));
   EXPECT_EQ(info.source, SettingSource::SETTING_SOURCE_USER);
 
   prefs_.SetManagedPref(prefs::kManagedDefaultCookiesSetting,
@@ -1848,7 +1874,7 @@
       cookie_settings_->IsThirdPartyAccessAllowed(kFirstPartySite, &info));
   EXPECT_FALSE(cookie_settings_->IsFullCookieAccessAllowed(
       kHttpsSite, kFirstPartySiteForCookies, /*top_frame_origin=*/std::nullopt,
-      GetCookieSettingOverrides()));
+      net::CookieSettingOverrides()));
   EXPECT_EQ(info.source, SettingSource::SETTING_SOURCE_POLICY);
 }
 
@@ -1954,11 +1980,17 @@
   }
 }
 
+INSTANTIATE_TEST_SUITE_P(
+    /* no prefix */,
+    CookieSettingsTest,
+    testing::Bool()  // HostIndexedMetadataGrantsEnabled
+);
+
 // NOTE: These tests will fail if their FINAL name is of length greater than 256
 // characters. Thus, try to avoid (unnecessary) generalized parameterization
 // when possible.
 std::string CustomTestName(
-    const testing::TestParamInfo<CookieSettingsTest::ParamType>& info) {
+    const testing::TestParamInfo<CookieSettingsTestP::ParamType>& info) {
   std::stringstream custom_test_name;
   // clang-format off
   custom_test_name
@@ -1973,7 +2005,7 @@
 
 INSTANTIATE_TEST_SUITE_P(
     /* no prefix */,
-    CookieSettingsTest,
+    CookieSettingsTestP,
     testing::Combine(
 #if BUILDFLAG(IS_IOS)
         testing::Values(GrantSource::kNoneGranted),
@@ -1987,22 +2019,15 @@
 INSTANTIATE_TEST_SUITE_P(
     /* no prefix */,
     CookieSettingsTestUserBypass,
-    testing::Combine(
-#if BUILDFLAG(IS_IOS)
-        testing::Values(GrantSource::kNoneGranted),
-#else
-        testing::Range(GrantSource::kNoneGranted,
-                       GrantSource::kGrantSourceCount),
-#endif
-        testing::Bool()),
-    CustomTestName);
+    testing::Bool()  // HostIndexedMetadataGrantsEnabled
+);
 
 #if !BUILDFLAG(IS_IOS)
 class CookieSettingsTopLevelTpcdTrialTest
     : public CookieSettingsTestBase,
       public testing::
-          TestWithParam</*net::features::kTopLevelTpcdTrialSettings:*/
-                        bool> {
+          WithParamInterface</*net::features::kTopLevelTpcdTrialSettings:*/
+                             bool> {
  public:
   CookieSettingsTopLevelTpcdTrialTest() {
     std::vector<base::test::FeatureRef> enabled_features;
@@ -2017,8 +2042,6 @@
     feature_list_.InitWithFeatures(enabled_features, disabled_features);
   }
 
-  void SetUp() override { CookieSettingsTestBase::SetUp(); }
-
   bool IsTopLevel3pcdTrialEligible() const { return GetParam(); }
 
   net::CookieSettingOverrides GetCookieSettingOverrides() const {
diff --git a/components/cronet/android/cronet_combined_impl_native_proguard_golden.cfg b/components/cronet/android/cronet_combined_impl_native_proguard_golden.cfg
index b5d8bc3..a305b190 100644
--- a/components/cronet/android/cronet_combined_impl_native_proguard_golden.cfg
+++ b/components/cronet/android/cronet_combined_impl_native_proguard_golden.cfg
@@ -115,12 +115,20 @@
 }
 
 # Mark fields with this to help R8 figure out that they cannot be null.
--assumenosideeffects class ** {
+# Use assumevalues in addition to assumenosideeffects block because Google3 proguard cannot parse
+# assumenosideeffects blocks which overwrite return value.
+-assumevalues class ** {
   @org.chromium.build.annotations.AssumeNonNull *** *(...) return _NONNULL_;
 }
 -assumenosideeffects class ** {
+  @org.chromium.build.annotations.AssumeNonNull *** *(...);
+}
+-assumevalues class ** {
   @org.chromium.build.annotations.AssumeNonNull *** * return _NONNULL_;
 }
+-assumenosideeffects class ** {
+  @org.chromium.build.annotations.AssumeNonNull *** *;
+}
 # -------- Config Path: components/cronet/android/cronet_impl_common_proguard.cfg --------
 # Proguard config for apps that depend on cronet_impl_common_java.jar.
 
diff --git a/components/enterprise/client_certificates/core/features.cc b/components/enterprise/client_certificates/core/features.cc
index 28f221d..e8406e9 100644
--- a/components/enterprise/client_certificates/core/features.cc
+++ b/components/enterprise/client_certificates/core/features.cc
@@ -8,7 +8,7 @@
 
 BASE_FEATURE(kManagedClientCertificateForUserEnabled,
              "ManagedClientCertificateForUserEnabled",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 bool IsManagedClientCertificateForUserEnabled() {
   return base::FeatureList::IsEnabled(kManagedClientCertificateForUserEnabled);
diff --git a/components/invalidation/impl/fcm_invalidation_listener.cc b/components/invalidation/impl/fcm_invalidation_listener.cc
index 1fccd25..4f714cd 100644
--- a/components/invalidation/impl/fcm_invalidation_listener.cc
+++ b/components/invalidation/impl/fcm_invalidation_listener.cc
@@ -179,20 +179,6 @@
   }
 }
 
-void FCMInvalidationListener::EmitStateChangeForTest(InvalidatorState state) {
-  delegate_->OnInvalidatorStateChange(state);
-}
-
-void FCMInvalidationListener::EmitSavedInvalidationForTest(
-    const Invalidation& invalidation) {
-  EmitSavedInvalidation(invalidation);
-}
-
-void FCMInvalidationListener::EmitSuccessfullySubscribedForTest(
-    const Topic& topic) {
-  delegate_->OnSuccessfullySubscribed(topic);
-}
-
 void FCMInvalidationListener::Stop() {
   delegate_ = nullptr;
 
diff --git a/components/invalidation/impl/fcm_invalidation_listener.h b/components/invalidation/impl/fcm_invalidation_listener.h
index 8a19436..d12ad7bc 100644
--- a/components/invalidation/impl/fcm_invalidation_listener.h
+++ b/components/invalidation/impl/fcm_invalidation_listener.h
@@ -84,10 +84,6 @@
       PerUserTopicSubscriptionManager::RequestType request_type,
       Status code) override;
 
-  void EmitStateChangeForTest(InvalidatorState state);
-  void EmitSavedInvalidationForTest(const Invalidation& invalidation);
-  void EmitSuccessfullySubscribedForTest(const Topic& topic);
-
  private:
   // Callbacks for the |network_channel_|.
   void InvalidationReceived(const std::string& payload,
diff --git a/components/invalidation/impl/fcm_invalidation_service_unittest.cc b/components/invalidation/impl/fcm_invalidation_service_unittest.cc
index 50804c50..0134ce6 100644
--- a/components/invalidation/impl/fcm_invalidation_service_unittest.cc
+++ b/components/invalidation/impl/fcm_invalidation_service_unittest.cc
@@ -198,17 +198,17 @@
   }
 
   void TriggerOnInvalidatorStateChange(InvalidatorState state) {
-    listener_->EmitStateChangeForTest(state);
+    invalidation_service_->OnInvalidatorStateChange(state);
   }
 
   template <class... TopicType>
   void TriggerSuccessfullySubscribed(TopicType... topics) {
-    (listener_->EmitSuccessfullySubscribedForTest(topics), ...);
+    (invalidation_service_->OnSuccessfullySubscribed(topics), ...);
   }
 
   template <class... Inv>
   void TriggerOnIncomingInvalidation(Inv... inv) {
-    (listener_->EmitSavedInvalidationForTest(inv), ...);
+    (invalidation_service_->OnInvalidate(inv), ...);
   }
 
   base::test::TaskEnvironment task_environment_;
diff --git a/components/omnibox/resources/omnibox_pedal_synonyms.grd b/components/omnibox/resources/omnibox_pedal_synonyms.grd
index e006325..2d363bc 100644
--- a/components/omnibox/resources/omnibox_pedal_synonyms.grd
+++ b/components/omnibox/resources/omnibox_pedal_synonyms.grd
@@ -179,9 +179,9 @@
         inside, within, for, how, the, an, do, in, my, on, to, a, i
       </message>
 
-      <!-- Pedal #1: CLEAR_BROWSING_DATA -->
-      <message name="IDS_OMNIBOX_PEDAL_SYNONYMS_CLEAR_BROWSING_DATA_ONE_REQUIRED_CLEAR_BROWSER_CACHE" is_accessibility_with_no_ui="true" desc="Whole phrases for the CLEAR_BROWSING_DATA Pedal's solitary triggering group. Context: The user is typing into the search bar to find a way to 'Clear browsing data' but the user is not sure how to describe this action. The input text is scanned for any phrases in this comma-separated list to determine whether the action button should appear. Do not translate the list 1:1 phrase for phrase. List several (~3-15) queries that users typing in the target language might search to perform this Pedal's action. Delimit each separate query phrase with a comma, including variations for the gender, plurals, etc. For other instructions, please see doc: https://docs.google.com/document/d/1cggNrwZvEbt9Hv_zMryByvgR8Vr4yal_V8Rxg1AOugw/edit">
-        clear browser cache, clear history, delete cookies, erase browsing history
+      <!-- Pedal #1: DELETE_BROWSING_DATA -->
+      <message name="IDS_OMNIBOX_PEDAL_SYNONYMS_CLEAR_BROWSING_DATA_ONE_REQUIRED_CLEAR_BROWSER_CACHE" is_accessibility_with_no_ui="true" desc="Whole phrases for the CLEAR_BROWSING_DATA Pedal's solitary triggering group. Context: The user is typing into the search bar to find a way to 'Delete browsing data' but the user is not sure how to describe this action. The input text is scanned for any phrases in this comma-separated list to determine whether the action button should appear. Do not translate the list 1:1 phrase for phrase. List several (~3-15) queries that users typing in the target language might search to perform this Pedal's action. Delimit each separate query phrase with a comma, including variations for the gender, plurals, etc. For other instructions, please see doc: https://docs.google.com/document/d/1cggNrwZvEbt9Hv_zMryByvgR8Vr4yal_V8Rxg1AOugw/edit">
+        delete browser cache, delete history, delete cookies, erase browsing history
       </message>
       <message name="IDS_OMNIBOX_PEDAL_SYNONYMS_CLEAR_BROWSING_DATA_ONE_OPTIONAL_GOOGLE_CHROME" translateable="false" is_accessibility_with_no_ui="true" desc="Synonyms for the CLEAR_BROWSING_DATA Pedal's 'google chrome' group. To trigger, exactly ONE of this group is OPTIONAL. Context: The user is typing into the omnibox to find a way to 'Clear browsing data' but the user is not sure how to describe this action. The input text is scanned for any words included in this synonym group to determine whether this concept is present in the query. Note: This string is not translated; it's used for triggering in English only.">
         google chrome, browsing, browser, chrome
diff --git a/components/os_crypt/async/browser/os_crypt_async.cc b/components/os_crypt/async/browser/os_crypt_async.cc
index b097287..a8dec03 100644
--- a/components/os_crypt/async/browser/os_crypt_async.cc
+++ b/components/os_crypt/async/browser/os_crypt_async.cc
@@ -97,7 +97,7 @@
     }
   } else {
     // TODO(crbug.com/40241934): Return errors back via a callback.
-    LOG(WARNING) << "Provider " << tag << " failed to return a key.";
+    DVLOG(1) << "Provider " << tag << " failed to return a key.";
   }
 
   if (++current == providers_.end()) {
diff --git a/components/page_info/android/BUILD.gn b/components/page_info/android/BUILD.gn
index 1e5045d..ddc1903 100644
--- a/components/page_info/android/BUILD.gn
+++ b/components/page_info/android/BUILD.gn
@@ -43,6 +43,7 @@
     "java/res/layout/page_info_row.xml",
     "java/res/layout/page_info_summary.xml",
     "java/res/layout/page_info_title.xml",
+    "java/res/layout/tracking_protection_status.xml",
     "java/res/values-night/dimens.xml",
     "java/res/values/dimens.xml",
     "java/res/values/ids.xml",
@@ -87,6 +88,7 @@
     "java/src/org/chromium/components/page_info/PageInfoView.java",
     "java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java",
     "java/src/org/chromium/components/page_info/SystemSettingsActivityRequiredListener.java",
+    "java/src/org/chromium/components/page_info/TrackingProtectionStatusPreference.java",
   ]
 
   deps = [
diff --git a/components/page_info/android/java/res/layout/tracking_protection_status.xml b/components/page_info/android/java/res/layout/tracking_protection_status.xml
new file mode 100644
index 0000000..688789c
--- /dev/null
+++ b/components/page_info/android/java/res/layout/tracking_protection_status.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2024 The Chromium Authors
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+    <!-- Cookies section. -->
+    <org.chromium.components.browser_ui.widget.text.TextViewWithCompoundDrawables
+            android:id="@+id/cookie_status"
+            style="@style/TextAppearance.TextMedium.Secondary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="12dp"
+            android:drawablePadding="8dp"
+            app:drawableWidth="20dp"
+            app:drawableHeight="20dp"/>
+    <!-- IP protection section. -->
+    <org.chromium.components.browser_ui.widget.text.TextViewWithCompoundDrawables
+            android:id="@+id/ip_status"
+            style="@style/TextAppearance.TextMedium.Secondary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="12dp"
+            android:layout_marginTop="12dp"
+            android:layout_marginBottom="12dp"
+            android:drawablePadding="8dp"
+            app:drawableWidth="20dp"
+            app:drawableHeight="20dp"/>
+    <!-- Fingerprinting -->
+    <org.chromium.components.browser_ui.widget.text.TextViewWithCompoundDrawables
+            android:id="@+id/fingerprint_status"
+            style="@style/TextAppearance.TextMedium.Secondary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="12dp"
+            android:drawablePadding="8dp"
+            app:drawableWidth="20dp"
+            app:drawableHeight="20dp"/>
+</LinearLayout>
diff --git a/components/page_info/android/java/res/values/dimens.xml b/components/page_info/android/java/res/values/dimens.xml
index 12ed76c..4b63d5e 100644
--- a/components/page_info/android/java/res/values/dimens.xml
+++ b/components/page_info/android/java/res/values/dimens.xml
@@ -15,4 +15,4 @@
 
     <!-- Page Info Background Elevation -->
     <dimen name="page_info_bg_elev">@dimen/default_elevation_0</dimen>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/components/page_info/android/java/res/xml/page_info_tracking_protection_launch_preference.xml b/components/page_info/android/java/res/xml/page_info_tracking_protection_launch_preference.xml
index 6634a455..475aa81 100644
--- a/components/page_info/android/java/res/xml/page_info_tracking_protection_launch_preference.xml
+++ b/components/page_info/android/java/res/xml/page_info_tracking_protection_launch_preference.xml
@@ -29,4 +29,7 @@
         android:persistent="false"
         app:allowDividerAbove="false" />
 
+    <org.chromium.components.page_info.TrackingProtectionStatusPreference
+        android:key="tp_status" />
+
 </PreferenceScreen>
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoTrackingProtectionSettings.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoTrackingProtectionSettings.java
index bcd1cdc..5d1b093 100644
--- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoTrackingProtectionSettings.java
+++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoTrackingProtectionSettings.java
@@ -34,6 +34,7 @@
 public class PageInfoTrackingProtectionSettings extends BaseSiteSettingsFragment {
     private static final String COOKIE_SUMMARY_PREFERENCE = "cookie_summary";
     private static final String TP_SWITCH_PREFERENCE = "tp_switch";
+    private static final String TP_STATUS_PREFERENCE = "tp_status";
     private static final String STORAGE_IN_USE_PREFERENCE = "storage_in_use";
     private static final String FPS_IN_USE_PREFERENCE = "fps_in_use";
     private static final String TPC_TITLE = "tpc_title";
@@ -45,6 +46,7 @@
     private ChromeImageViewPreference mFPSInUse;
     private TextMessagePreference mThirdPartyCookiesTitle;
     private Preference mThirdPartyCookiesSummary;
+    private TrackingProtectionStatusPreference mTpStatus;
     private Runnable mOnClearCallback;
     private Runnable mOnCookieSettingsLinkClicked;
     private Callback<Activity> mOnFeedbackClicked;
@@ -98,6 +100,7 @@
         mCookieSwitch = findPreference(TP_SWITCH_PREFERENCE);
         if (mShowLaunchUI) mCookieSwitch.setUseSummaryAsTitle(false);
 
+        mTpStatus = findPreference(TP_STATUS_PREFERENCE);
         mStorageInUse = findPreference(STORAGE_IN_USE_PREFERENCE);
         mFPSInUse = findPreference(FPS_IN_USE_PREFERENCE);
         mFPSInUse.setVisible(false);
@@ -147,6 +150,7 @@
         mCookieSwitch.setOnPreferenceChangeListener(
                 (preference, newValue) -> {
                     boolean boolValue = (Boolean) newValue;
+                    if (mShowLaunchUI) mTpStatus.setTrackingProtectionStatus(boolValue);
                     // Invert since the switch is inverted.
                     boolValue = !boolValue;
                     params.onThirdPartyCookieToggleChanged.onResult(boolValue);
@@ -242,6 +246,7 @@
                                     : R.drawable.ic_visibility_black));
         }
         mCookieSwitch.setChecked(!protectionsOn);
+        if (mShowLaunchUI) mTpStatus.setTrackingProtectionStatus(protectionsOn);
         mCookieSwitch.setEnabled(!isEnforced);
         mCookieSwitch.setManagedPreferenceDelegate(
                 new ForwardingManagedPreferenceDelegate(
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/TrackingProtectionStatusPreference.java b/components/page_info/android/java/src/org/chromium/components/page_info/TrackingProtectionStatusPreference.java
new file mode 100644
index 0000000..d1ed6cd
--- /dev/null
+++ b/components/page_info/android/java/src/org/chromium/components/page_info/TrackingProtectionStatusPreference.java
@@ -0,0 +1,76 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.page_info;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+import androidx.appcompat.content.res.AppCompatResources;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+public class TrackingProtectionStatusPreference extends Preference {
+    private TextView mCookieStatus;
+    private TextView mIpStatus;
+    private TextView mFingerprintStatus;
+
+    private boolean mStatus;
+
+    /** Creates a new object and sets the widget layout. */
+    public TrackingProtectionStatusPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mStatus = true;
+        setLayoutResource(R.layout.tracking_protection_status);
+    }
+
+    /** Gets triggered when the view elements are created. */
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        mCookieStatus = (TextView) holder.findViewById(R.id.cookie_status);
+        mIpStatus = (TextView) holder.findViewById(R.id.ip_status);
+        mFingerprintStatus = (TextView) holder.findViewById(R.id.fingerprint_status);
+        setTrackingProtectionStatus(mStatus);
+    }
+
+    public void setTrackingProtectionStatus(boolean enabled) {
+        mStatus = enabled;
+        if (mCookieStatus == null) return;
+
+        // TODO(b/330745124): Use the actual icons.
+        Drawable cookieIcon =
+                AppCompatResources.getDrawable(
+                        getContext(),
+                        enabled ? R.drawable.ic_eye_crossed : R.drawable.ic_cookie_24dp);
+        Drawable ipIcon =
+                AppCompatResources.getDrawable(
+                        getContext(),
+                        enabled ? R.drawable.ic_eye_crossed : R.drawable.ic_cookie_24dp);
+        Drawable fingerprintIcon =
+                AppCompatResources.getDrawable(
+                        getContext(),
+                        enabled ? R.drawable.ic_eye_crossed : R.drawable.ic_cookie_24dp);
+
+        // TODO(b/330745124): Use the actual strings.
+        mCookieStatus.setText(
+                enabled
+                        ? R.string.page_info_tracking_protection_site_info_button_label_limited
+                        : R.string.page_info_tracking_protection_site_info_button_label_allowed);
+        mCookieStatus.setCompoundDrawablesRelativeWithIntrinsicBounds(cookieIcon, null, null, null);
+        mIpStatus.setText(
+                enabled
+                        ? R.string.page_info_tracking_protection_site_info_button_label_limited
+                        : R.string.page_info_tracking_protection_site_info_button_label_allowed);
+        mIpStatus.setCompoundDrawablesRelativeWithIntrinsicBounds(ipIcon, null, null, null);
+        mFingerprintStatus.setText(
+                enabled
+                        ? R.string.page_info_tracking_protection_site_info_button_label_limited
+                        : R.string.page_info_tracking_protection_site_info_button_label_allowed);
+        mFingerprintStatus.setCompoundDrawablesRelativeWithIntrinsicBounds(
+                fingerprintIcon, null, null, null);
+    }
+}
diff --git a/components/page_info_strings.grdp b/components/page_info_strings.grdp
index 40cb4fb..1d90789d 100644
--- a/components/page_info_strings.grdp
+++ b/components/page_info_strings.grdp
@@ -742,13 +742,13 @@
   <message name="IDS_PAGE_INFO_TRACKING_PROTECTION_SITE_INFO_BUTTON_NAME" desc="A button in the Page Info bubble (which shows when you click the lock icon) that expands to another bubble detailing the user's Tracking protection settings.">
     Tracking Protection
   </message>
-  <message name="IDS_PAGE_INFO_TRACKING_PROTECTION_SITE_INFO_BUTTON_LABEL_ALLOWED" desc="The label for the Tracking Protection button in the Page Info bubble (which shows when you click the site info icon) detailing that third party cookies are allowed.">
+  <message name="IDS_PAGE_INFO_TRACKING_PROTECTION_SITE_INFO_BUTTON_LABEL_ALLOWED" desc="The label for the Tracking Protection button in the Page Info bubble (which shows when you click the site info icon) detailing that third party cookies are allowed." formatter_data="android_java">
     Third-party cookies allowed
   </message>
   <message name="IDS_PAGE_INFO_TRACKING_PROTECTION_SITE_INFO_BUTTON_LABEL_BLOCKED" desc="The label for the Tracking Protection button in the Page Info bubble (which shows when you click the site info icon) detailing that third party cookies are blocked.">
     Third-party cookies blocked
   </message>
-  <message name="IDS_PAGE_INFO_TRACKING_PROTECTION_SITE_INFO_BUTTON_LABEL_LIMITED" desc="The label for the Tracking Protection button in the Page Info bubble (which shows when you click the site info icon) detailing that third party cookies are limited.">
+  <message name="IDS_PAGE_INFO_TRACKING_PROTECTION_SITE_INFO_BUTTON_LABEL_LIMITED" desc="The label for the Tracking Protection button in the Page Info bubble (which shows when you click the site info icon) detailing that third party cookies are limited." formatter_data="android_java">
     Third-party cookies limited
   </message>
   <message name="IDS_PAGE_INFO_SUB_PAGE_VIEW_TRACKING_PROTECTION_HEADER" desc="The header label of Tracking Protection subview page.">
diff --git a/components/password_manager/core/browser/affiliation/passkey_affiliation_source_adapter_unittest.cc b/components/password_manager/core/browser/affiliation/passkey_affiliation_source_adapter_unittest.cc
index 532cd59..74e08d81 100644
--- a/components/password_manager/core/browser/affiliation/passkey_affiliation_source_adapter_unittest.cc
+++ b/components/password_manager/core/browser/affiliation/passkey_affiliation_source_adapter_unittest.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <utility>
 
+#include "base/location.h"
 #include "base/rand_util.h"
 #include "base/test/mock_callback.h"
 #include "base/test/task_environment.h"
@@ -143,7 +144,7 @@
   EXPECT_CALL(*mock_source_observer(),
               OnFacetsRemoved(ElementsAre(
                   FacetURI::FromCanonicalSpec(kTestWebFacetURIAlpha1))));
-  test_passkey_model()->DeletePasskey(passkey.credential_id());
+  test_passkey_model()->DeletePasskey(passkey.credential_id(), FROM_HERE);
   RunUntilIdle();
 }
 
diff --git a/components/password_manager/core/browser/browser_save_password_progress_logger_unittest.cc b/components/password_manager/core/browser/browser_save_password_progress_logger_unittest.cc
index 6470bc77..14765e5 100644
--- a/components/password_manager/core/browser/browser_save_password_progress_logger_unittest.cc
+++ b/components/password_manager/core/browser/browser_save_password_progress_logger_unittest.cc
@@ -62,18 +62,18 @@
     autofill::FormFieldData field;
     field.set_name(u"password");
     field.set_form_control_type(autofill::FormControlType::kInputPassword);
-    field.is_focusable = true;
-    field.autocomplete_attribute = "new-password";
+    field.set_is_focusable(true);
+    field.set_autocomplete_attribute("new-password");
     field.set_renderer_id(autofill::FieldRendererId(10));
     form_.fields.push_back(field);
 
     // Add a text field.
     field.set_name(u"email");
     field.set_form_control_type(autofill::FormControlType::kInputText);
-    field.is_focusable = false;
+    field.set_is_focusable(false);
     field.set_renderer_id(autofill::FieldRendererId(42));
     field.set_value(u"a@example.com");
-    field.autocomplete_attribute = {};
+    field.set_autocomplete_attribute({});
     form_.fields.push_back(field);
   }
 
diff --git a/components/password_manager/core/browser/form_parsing/form_data_parser.cc b/components/password_manager/core/browser/form_parsing/form_data_parser.cc
index 8f60ead..ffeb7f2 100644
--- a/components/password_manager/core/browser/form_parsing/form_data_parser.cc
+++ b/components/password_manager/core/browser/form_parsing/form_data_parser.cc
@@ -183,7 +183,7 @@
 
 // Returns |user_input| if it is not empty, |value| otherwise.
 const std::u16string& GetFieldValue(const FormFieldData& field) {
-  return field.user_input.empty() ? field.value() : field.user_input;
+  return field.user_input().empty() ? field.value() : field.user_input();
 }
 
 // A helper struct that is used to capture significant fields to be used for
@@ -606,7 +606,7 @@
   // only temporarily, that makes it still interesting for saving. The fact
   // that a user typed or Chrome filled into that field in the past is an
   // indicator that the readonly was only temporary.
-  if (field.field->is_readonly &&
+  if (field.field->is_readonly() &&
       !(field.field->properties_mask() & (FieldPropertiesFlags::kUserTyped |
                                           FieldPropertiesFlags::kAutofilled))) {
     ++*ignored_readonly;
@@ -748,7 +748,7 @@
       continue;
     if (!username)
       username = it->field;
-    if (!focusable_username && it->field->is_focusable) {
+    if (!focusable_username && it->field->is_focusable()) {
       focusable_username = it->field;
     }
     if (stored_usernames.contains(base::i18n::ToLower(it->field->value()))) {
@@ -949,7 +949,7 @@
     }
 
     const AutocompleteParsing autocomplete_parsing =
-        ParseAutocomplete(field.autocomplete_attribute);
+        ParseAutocomplete(field.autocomplete_attribute());
 
     ProcessedField processed_field = {
         .field = &field,
@@ -960,7 +960,7 @@
 
     if (field.properties_mask() & FieldPropertiesFlags::kUserTyped) {
       processed_field.interactability = Interactability::kCertain;
-    } else if (field.is_focusable) {
+    } else if (field.is_focusable()) {
       processed_field.interactability = Interactability::kPossible;
     }
 
diff --git a/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc
index a5daaab..767c43a 100644
--- a/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc
+++ b/components/password_manager/core/browser/form_parsing/form_data_parser_unittest.cc
@@ -188,8 +188,9 @@
 
   EXPECT_EQ(element_name, field_it->name());
 
-  std::u16string expected_value =
-      field_it->user_input.empty() ? field_it->value() : field_it->user_input;
+  std::u16string expected_value = field_it->user_input().empty()
+                                      ? field_it->value()
+                                      : field_it->user_input();
 
   if (element_value)
     EXPECT_EQ(expected_value, *element_value);
@@ -305,9 +306,9 @@
       }
       field.set_name_attribute(field.name());
       field.set_form_control_type(field_description.form_control_type);
-      field.is_focusable = field_description.is_focusable;
-      field.is_enabled = field_description.is_enabled;
-      field.is_readonly = field_description.is_readonly;
+      field.set_is_focusable(field_description.is_focusable);
+      field.set_is_enabled(field_description.is_enabled);
+      field.set_is_readonly(field_description.is_readonly);
       field.set_properties_mask(field_description.properties_mask);
       if (field_description.value == kNonimportantValue) {
         field.set_value(StampUniqueSuffix(u"value"));
@@ -315,9 +316,10 @@
         field.set_value(field_description.value);
       }
       if (field_description.autocomplete_attribute)
-        field.autocomplete_attribute = field_description.autocomplete_attribute;
+        field.set_autocomplete_attribute(
+            field_description.autocomplete_attribute);
       if (!field_description.user_input.empty())
-        field.user_input = field_description.user_input;
+        field.set_user_input(field_description.user_input);
       form_data.fields.push_back(field);
       if (field_description.role == ElementRole::NONE) {
         UpdateResultWithIdByRole(fill_result, renderer_id,
diff --git a/components/password_manager/core/browser/form_parsing/fuzzer/form_data_proto_producer.cc b/components/password_manager/core/browser/form_parsing/fuzzer/form_data_proto_producer.cc
index b9554b1f..12eae1eb 100644
--- a/components/password_manager/core/browser/form_parsing/fuzzer/form_data_proto_producer.cc
+++ b/components/password_manager/core/browser/form_parsing/fuzzer/form_data_proto_producer.cc
@@ -45,12 +45,12 @@
     const ::form_data_fuzzer::FormField& form_data_proto = form_proto.fields(i);
     result.fields[i].set_id_attribute(UTF8ToUTF16(form_data_proto.id()));
     result.fields[i].set_name_attribute(UTF8ToUTF16(form_data_proto.name()));
-    result.fields[i].is_focusable = form_data_proto.is_focusable();
+    result.fields[i].set_is_focusable(form_data_proto.is_focusable());
     result.fields[i].set_form_control_type(
         static_cast<autofill::FormControlType>(
             form_data_proto.form_control_type()));
-    result.fields[i].autocomplete_attribute =
-        form_data_proto.autocomplete_attribute();
+    result.fields[i].set_autocomplete_attribute(
+        form_data_proto.autocomplete_attribute());
     result.fields[i].set_label(UTF8ToUTF16(form_data_proto.label()));
     result.fields[i].set_name(UTF8ToUTF16(form_data_proto.name()));
     result.fields[i].set_value(UTF8ToUTF16(form_data_proto.value()));
diff --git a/components/password_manager/core/browser/form_saver_impl.cc b/components/password_manager/core/browser/form_saver_impl.cc
index 60f6e3b1..419112b 100644
--- a/components/password_manager/core/browser/form_saver_impl.cc
+++ b/components/password_manager/core/browser/form_saver_impl.cc
@@ -31,10 +31,10 @@
   for (FormFieldData& field : form->fields) {
     field.set_label({});
     field.set_value({});
-    field.autocomplete_attribute = {};
-    field.options.clear();
-    field.placeholder = {};
-    field.css_classes = {};
+    field.set_autocomplete_attribute({});
+    field.set_options({});
+    field.set_placeholder({});
+    field.set_css_classes({});
     field.set_id_attribute({});
     field.set_name_attribute({});
   }
diff --git a/components/password_manager/core/browser/form_saver_impl_unittest.cc b/components/password_manager/core/browser/form_saver_impl_unittest.cc
index 6280452c..239885a4 100644
--- a/components/password_manager/core/browser/form_saver_impl_unittest.cc
+++ b/components/password_manager/core/browser/form_saver_impl_unittest.cc
@@ -291,10 +291,10 @@
   field.set_form_control_type(autofill::FormControlType::kInputPassword);
   field.set_value(u"value");
   field.set_label(u"label");
-  field.placeholder = u"placeholder";
+  field.set_placeholder(u"placeholder");
   field.set_id_attribute(u"id");
   field.set_name_attribute(field.name());
-  field.css_classes = u"css_classes";
+  field.set_css_classes(u"css_classes");
   pending.form_data.fields.push_back(field);
 
   PasswordForm saved;
@@ -320,10 +320,10 @@
             saved_field.form_control_type());
   EXPECT_TRUE(saved_field.value().empty());
   EXPECT_TRUE(saved_field.label().empty());
-  EXPECT_TRUE(saved_field.placeholder.empty());
+  EXPECT_TRUE(saved_field.placeholder().empty());
   EXPECT_TRUE(saved_field.id_attribute().empty());
   EXPECT_TRUE(saved_field.name_attribute().empty());
-  EXPECT_TRUE(saved_field.css_classes.empty());
+  EXPECT_TRUE(saved_field.css_classes().empty());
 }
 
 INSTANTIATE_TEST_SUITE_P(All,
diff --git a/components/password_manager/core/browser/password_credential_filler_impl_unittest.cc b/components/password_manager/core/browser/password_credential_filler_impl_unittest.cc
index 936f32af..1243ff9 100644
--- a/components/password_manager/core/browser/password_credential_filler_impl_unittest.cc
+++ b/components/password_manager/core/browser/password_credential_filler_impl_unittest.cc
@@ -54,9 +54,9 @@
       focusability_vector, std::back_inserter(form.fields),
       [](FormFieldFocusabilityType type) {
         autofill::FormFieldData field;
-        field.is_focusable =
+        field.set_is_focusable(
             (type == FormFieldFocusabilityType::kFocusableInput ||
-             type == FormFieldFocusabilityType::kFocusableCheckbox);
+             type == FormFieldFocusabilityType::kFocusableCheckbox));
         field.set_form_control_type(
             (type == FormFieldFocusabilityType::kFocusableCheckbox)
                 ? autofill::FormControlType::kInputCheckbox
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index ec18a0d..84fda9e 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -727,7 +727,7 @@
     FieldRendererId field_id = field.renderer_id();
     if (!field_data_manager.HasFieldData(field_id))
       continue;
-    field.user_input = field_data_manager.GetUserInput(field_id);
+    field.set_user_input(field_data_manager.GetUserInput(field_id));
     field.set_properties_mask(
         field_data_manager.GetFieldPropertiesMask(field_id));
     data_found = true;
@@ -1661,7 +1661,8 @@
       differences_bitmask |= PasswordFormMetricsRecorder::kFormControlTypes;
     }
 
-    if (lhs_field.autocomplete_attribute != rhs_field.autocomplete_attribute) {
+    if (lhs_field.autocomplete_attribute() !=
+        rhs_field.autocomplete_attribute()) {
       differences_bitmask |=
           PasswordFormMetricsRecorder::kAutocompleteAttributes;
     }
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index a7b6ce0..bb7c0b3 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -727,7 +727,7 @@
 // the form was misclassified.
 TEST_P(PasswordFormManagerTest, AutofillSignUpForm) {
   // Make |observed_form_| to be sign-up form.
-  observed_form_.fields.back().autocomplete_attribute = "new-password";
+  observed_form_.fields.back().set_autocomplete_attribute("new-password");
 
   PasswordFormFillData fill_data;
   EXPECT_CALL(driver_, SetPasswordFillData).WillOnce(SaveArg<0>(&fill_data));
@@ -756,7 +756,7 @@
 // fields are marked with autocomplete attribute.
 TEST_P(PasswordFormManagerTest, GenerationOnNewAndConfirmPasswordFields) {
   // Make |observed_form_| to be sign-up form.
-  observed_form_.fields.back().autocomplete_attribute = "new-password";
+  observed_form_.fields.back().set_autocomplete_attribute("new-password");
   const autofill::FieldRendererId new_password_render_id =
       observed_form_.fields.back().renderer_id();
   // Add a confirmation field.
@@ -765,7 +765,7 @@
       new_password_render_id.value() + 1);
   field.set_renderer_id(confirm_password_render_id);
   field.set_form_control_type(autofill::FormControlType::kInputPassword);
-  field.autocomplete_attribute = "new-password";
+  field.set_autocomplete_attribute("new-password");
   observed_form_.fields.push_back(field);
 
   PasswordFormGenerationData generation_data;
@@ -1549,8 +1549,8 @@
   // Emulate submitting form that updates the password for a known username.
   submitted_form_.fields[kUsernameFieldIndex].set_value(
       saved_match_.username_value);
-  submitted_form_.fields[kPasswordFieldIndex].autocomplete_attribute =
-      "new-password";
+  submitted_form_.fields[kPasswordFieldIndex].set_autocomplete_attribute(
+      "new-password");
   submitted_form_.fields[kPasswordFieldIndex].set_value(
       u"new_password_field_value");
   form_manager_->ProvisionallySave(submitted_form_, &driver_,
@@ -2072,7 +2072,8 @@
   base::HistogramTester histogram_tester;
 
   FormData form = observed_form_;
-  form.fields[kUsernameFieldIndex].autocomplete_attribute += "...";
+  form.fields[kUsernameFieldIndex].set_autocomplete_attribute(
+      form.fields[kUsernameFieldIndex].autocomplete_attribute() + "...");
   EXPECT_TRUE(HasObservedFormChanged(form, *form_manager_));
   form_manager_.reset();
 
@@ -2116,7 +2117,7 @@
   base::HistogramTester histogram_tester;
 
   FormData form = observed_form_;
-  form.fields[kUsernameFieldIndex].css_classes = u"class1";
+  form.fields[kUsernameFieldIndex].set_css_classes(u"class1");
   EXPECT_FALSE(HasObservedFormChanged(form, *form_manager_));
   form_manager_.reset();
 
@@ -2290,8 +2291,8 @@
   // Simulate that the user fills the saved username manually.
   non_password_form_.fields[kUsernameFieldIndex].set_value(
       saved_match_.username_value);
-  non_password_form_.fields[kUsernameFieldIndex].autocomplete_attribute =
-      "username";
+  non_password_form_.fields[kUsernameFieldIndex].set_autocomplete_attribute(
+      "username");
   non_password_form_.fields[kUsernameFieldIndex].set_properties_mask(
       FieldPropertiesFlags::kAutofilledOnUserTrigger);
 
@@ -2571,12 +2572,12 @@
   form_manager_->ProvisionallySaveFieldDataManagerInfo(
       *field_data_manager, &driver_, possible_usernames);
 
-  EXPECT_EQ(form_manager_->observed_form()->fields[1].user_input,
+  EXPECT_EQ(form_manager_->observed_form()->fields[1].user_input(),
             u"typed_username");
   EXPECT_EQ(form_manager_->observed_form()->fields[1].properties_mask(),
             FieldPropertiesFlags::kUserTyped);
 
-  EXPECT_EQ(form_manager_->observed_form()->fields[2].user_input,
+  EXPECT_EQ(form_manager_->observed_form()->fields[2].user_input(),
             u"autofilled_pw");
   EXPECT_EQ(form_manager_->observed_form()->fields[2].properties_mask(),
             FieldPropertiesFlags::kAutofilledOnUserTrigger);
@@ -2746,7 +2747,7 @@
 
   FormData submitted_form = observed_form_only_password_fields_;
   // Imitate sign-up flow: the only filled password field is a new password.
-  submitted_form.fields[0].autocomplete_attribute = "new-password";
+  submitted_form.fields[0].set_autocomplete_attribute("new-password");
   submitted_form.fields[0].set_value(u"strongpassword");
 
   ASSERT_TRUE(form_manager_->ProvisionallySave(submitted_form, &driver_,
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.cc b/components/password_manager/core/browser/password_form_metrics_recorder.cc
index c8f90d3f..14f986f5 100644
--- a/components/password_manager/core/browser/password_form_metrics_recorder.cc
+++ b/components/password_manager/core/browser/password_form_metrics_recorder.cc
@@ -121,7 +121,7 @@
 
   for (const FormFieldData& field : submitted_form.fields) {
     const std::u16string& value =
-        field.user_input.empty() ? field.value() : field.user_input;
+        field.user_input().empty() ? field.value() : field.user_input();
 
     bool user_typed =
         field.properties_mask() & FieldPropertiesFlags::kUserTyped;
@@ -197,7 +197,7 @@
       password_bubble_experiment::GetSmartBubbleDismissalThreshold();
   for (const FormFieldData& field : submitted_form.fields) {
     const std::u16string& value =
-        field.user_input.empty() ? field.value() : field.user_input;
+        field.user_input().empty() ? field.value() : field.user_input();
     for (const InteractionsStats& stat : interactions_stats) {
       if (stat.username_value == value &&
           stat.dismissal_count >= show_threshold)
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc b/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc
index e8b9876..ff9f5d0 100644
--- a/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc
+++ b/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc
@@ -600,7 +600,7 @@
   for (const auto& field : fields) {
     FormFieldData form_field;
     form_field.set_value(ASCIIToUTF16(field.value));
-    form_field.user_input = ASCIIToUTF16(field.user_input);
+    form_field.set_user_input(ASCIIToUTF16(field.user_input));
 
     if (field.user_typed)
       form_field.set_properties_mask(form_field.properties_mask() |
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc
index 35a3b28..1568975f 100644
--- a/components/password_manager/core/browser/password_manager.cc
+++ b/components/password_manager/core/browser/password_manager.cc
@@ -227,8 +227,9 @@
     if (submitted_form.password_element_renderer_id == field.renderer_id() ||
         submitted_form.new_password_element_renderer_id ==
             field.renderer_id()) {
-      if (field.is_focusable)
+      if (field.is_focusable()) {
         return false;
+      }
     }
   }
   return true;
@@ -959,11 +960,11 @@
 
   bool is_likely_otp = password_manager::util::IsLikelyOtp(
       field.name_attribute(), field.id_attribute(),
-      field.autocomplete_attribute);
+      field.autocomplete_attribute());
 
   OnUserModifiedNonPasswordField(
       driver, field_id, field_value,
-      base::Contains(field.autocomplete_attribute,
+      base::Contains(field.autocomplete_attribute(),
                      password_manager::constants::kAutocompleteUsername),
       is_likely_otp);
 }
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc
index 6a1ca93..138e0973 100644
--- a/components/password_manager/core/browser/password_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -318,10 +318,10 @@
   for (FormFieldData& field : form->fields) {
     field.set_label({});
     field.set_value({});
-    field.autocomplete_attribute = {};
-    field.options.clear();
-    field.placeholder = {};
-    field.css_classes = {};
+    field.set_autocomplete_attribute({});
+    field.set_options({});
+    field.set_placeholder({});
+    field.set_css_classes({});
     field.set_id_attribute({});
     field.set_name_attribute({});
   }
@@ -557,7 +557,7 @@
 
   FormData MakeGAIAChangePasswordFormData() {
     FormData form_data(MakeSimpleFormData());
-    form_data.fields[1].autocomplete_attribute = "new-password";
+    form_data.fields[1].set_autocomplete_attribute("new-password");
     form_data.url = GURL("https://accounts.google.com");
     form_data.action = GURL("http://www.google.com/a/Login");
     form_data.name = u"the-form-name";
@@ -569,14 +569,14 @@
     PasswordForm form = MakeSimpleForm();
     form.new_password_element.swap(form.password_element);
     form.new_password_value.swap(form.password_value);
-    form.form_data.fields[1].autocomplete_attribute = "new-password";
+    form.form_data.fields[1].set_autocomplete_attribute("new-password");
     return form;
   }
 
   // Create a sign-up FormData that has username and new password fields.
   FormData MakeSignUpFormData() {
     FormData form_data = MakeSimpleFormData();
-    form_data.fields[1].autocomplete_attribute = "new-password";
+    form_data.fields[1].set_autocomplete_attribute("new-password");
     return form_data;
   }
 
@@ -754,7 +754,7 @@
     field.set_value(form.username_value);
     field.set_form_control_type(autofill::FormControlType::kInputText);
     field.set_renderer_id(FieldRendererId(2));
-    field.autocomplete_attribute = "cc-name";
+    field.set_autocomplete_attribute("cc-name");
     form.form_data.fields.push_back(field);
 
     field.set_name(form.password_element);
@@ -762,7 +762,7 @@
     field.set_value(form.password_value);
     field.set_form_control_type(autofill::FormControlType::kInputPassword);
     field.set_renderer_id(FieldRendererId(3));
-    field.autocomplete_attribute = "cc-number";
+    field.set_autocomplete_attribute("cc-number");
     form.form_data.fields.push_back(field);
 
     return form;
@@ -1049,7 +1049,7 @@
   ON_CALL(client_, IsSavingAndFillingEnabled(_)).WillByDefault(Return(true));
 
   FormData form_data = MakeSingleUsernameFormData();
-  form_data.fields[0].autocomplete_attribute = "username";
+  form_data.fields[0].set_autocomplete_attribute("username");
   FieldRendererId username_renderer_id = form_data.fields[0].renderer_id();
 
   ON_CALL(driver_, GetLastCommittedURL).WillByDefault(ReturnRef(form_data.url));
@@ -3292,7 +3292,7 @@
 
   form_data.fields[0].set_value(u"username");
   form_data.fields[1].set_value(u"password");
-  form_data.fields[1].is_focusable = false;
+  form_data.fields[1].set_is_focusable(false);
 
   EXPECT_CALL(client_, PromptUserToSaveOrUpdatePassword).Times(0);
   manager()->OnDynamicFormSubmission(&driver_, form_data.submission_event);
@@ -3386,7 +3386,7 @@
   EXPECT_CALL(client_, IsSavingAndFillingEnabled(form_data.url))
       .WillRepeatedly(Return(true));
   // Make the form to be credit card form.
-  form_data.fields[1].autocomplete_attribute = "cc-csc";
+  form_data.fields[1].set_autocomplete_attribute("cc-csc");
 
   manager()->OnPasswordFormsParsed(&driver_, {form_data});
 
@@ -3418,7 +3418,7 @@
 
   // Simulate that the form is incorrectly marked as sign-up, which means it can
   // not be filled without server predictions.
-  form.form_data.fields[1].autocomplete_attribute = "new-password";
+  form.form_data.fields[1].set_autocomplete_attribute("new-password");
 
   manager()->OnPasswordFormsParsed(&driver_, {form.form_data});
   task_environment_.RunUntilIdle();
@@ -3462,7 +3462,7 @@
   store_->AddLogin(form);
 
   // The renderer would detect the autocomplete attribute below.
-  form.form_data.fields[0].autocomplete_attribute = "username";
+  form.form_data.fields[0].set_autocomplete_attribute("username");
 
   // No fill call is sent to the renderer during prediction processing.
   EXPECT_CALL(driver_, SetPasswordFillData).Times(0);
@@ -3548,7 +3548,7 @@
 
   // Simulate that the form is incorrectly marked as sign-up, which means it can
   // not be filled without server predictions.
-  form2.form_data.fields[1].autocomplete_attribute = "new-password";
+  form2.form_data.fields[1].set_autocomplete_attribute("new-password");
   manager()->OnPasswordFormsParsed(&driver_,
                                    {form1.form_data, form2.form_data});
   task_environment_.RunUntilIdle();
@@ -5078,7 +5078,7 @@
       autofill::FormControlType::kInputPassword);
   new_password_field.set_renderer_id(FieldRendererId(3));
   new_password_field.set_name(u"newpass");
-  new_password_field.autocomplete_attribute = "new-password";
+  new_password_field.set_autocomplete_attribute("new-password");
   form_data.fields.push_back(new_password_field);
 
   FormFieldData confirm_password_field;
@@ -5166,7 +5166,7 @@
       autofill::FormControlType::kInputPassword);
   new_password_field.set_renderer_id(FieldRendererId(3));
   new_password_field.set_name(kEmptyName);
-  new_password_field.autocomplete_attribute = "new-password";
+  new_password_field.set_autocomplete_attribute("new-password");
   form_data.fields.push_back(new_password_field);
 
   manager()->OnPasswordFormsParsed(&driver_, {form_data});
@@ -5210,7 +5210,7 @@
         autofill::FormControlType::kInputPassword);
     new_password_field.set_renderer_id(FieldRendererId(2));
     new_password_field.set_name(u"newpass");
-    new_password_field.autocomplete_attribute = "new-password";
+    new_password_field.set_autocomplete_attribute("new-password");
     form_data.fields.push_back(new_password_field);
 
     FormFieldData confirm_password_field;
@@ -5275,7 +5275,7 @@
         autofill::FormControlType::kInputPassword);
     new_password_field.set_renderer_id(FieldRendererId(2));
     new_password_field.set_name(kEmptyName);
-    new_password_field.autocomplete_attribute = "new-password";
+    new_password_field.set_autocomplete_attribute("new-password");
     form_data.fields.push_back(new_password_field);
 
     manager()->OnPasswordFormsParsed(&driver_, {form_data});
@@ -5516,7 +5516,7 @@
 
   // User sees a single username field. The password field is hidden.
   PasswordForm username_form = MakeSimpleForm();
-  username_form.form_data.fields[1].is_focusable = false;
+  username_form.form_data.fields[1].set_is_focusable(false);
   std::vector<FormData> observed = {username_form.form_data};
   EXPECT_CALL(*weak_factory, TryCreateLeakCheck).Times(0);
   manager()->OnPasswordFormsParsed(&driver_, observed);
@@ -5528,7 +5528,7 @@
 
   // User sees a single password field. The username field is hidden.
   PasswordForm password_form = MakeSimpleForm();
-  password_form.form_data.fields[0].is_focusable = false;
+  password_form.form_data.fields[0].set_is_focusable(false);
   observed = {password_form.form_data};
   manager()->OnPasswordFormsParsed(&driver_, observed);
   manager()->OnPasswordFormsRendered(&driver_, observed);
@@ -5769,8 +5769,8 @@
       break;
     case PredictionSource::AUTOCOMPLETE:
       one_time_code_form.form_data.fields[otp_form_has_username]
-          .autocomplete_attribute =
-          base::UTF16ToUTF8(test_form_password_element_);
+          .set_autocomplete_attribute(
+              base::UTF16ToUTF8(test_form_password_element_));
       break;
     case PredictionSource::SERVER:
       manager()->ProcessAutofillPredictions(
diff --git a/components/password_manager/core/browser/password_save_manager_impl_unittest.cc b/components/password_manager/core/browser/password_save_manager_impl_unittest.cc
index a74251d..89ac88f 100644
--- a/components/password_manager/core/browser/password_save_manager_impl_unittest.cc
+++ b/components/password_manager/core/browser/password_save_manager_impl_unittest.cc
@@ -622,7 +622,7 @@
   // There is an anonymous password field and set it as the new password field.
   anonymous_signup.fields[2].set_name({});
   anonymous_signup.fields[2].set_value(u"a password");
-  anonymous_signup.fields[2].autocomplete_attribute = "new-password";
+  anonymous_signup.fields[2].set_autocomplete_attribute("new-password");
 
   password_save_manager_impl()->CreatePendingCredentials(
       Parse(anonymous_signup), &observed_form_, anonymous_signup,
diff --git a/components/password_manager/core/browser/ui/saved_passwords_presenter.cc b/components/password_manager/core/browser/ui/saved_passwords_presenter.cc
index 4294535..cb42dc76 100644
--- a/components/password_manager/core/browser/ui/saved_passwords_presenter.cc
+++ b/components/password_manager/core/browser/ui/saved_passwords_presenter.cc
@@ -18,6 +18,7 @@
 #include "base/containers/fixed_flat_set.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
+#include "base/location.h"
 #include "base/notreached.h"
 #include "base/observer_list.h"
 #include "base/ranges/algorithm.h"
@@ -148,7 +149,7 @@
     CHECK(passkey_store_);
     std::string credential_id(credential.passkey_credential_id.begin(),
                               credential.passkey_credential_id.end());
-    if (!passkey_store_->DeletePasskey(std::move(credential_id))) {
+    if (!passkey_store_->DeletePasskey(std::move(credential_id), FROM_HERE)) {
       return false;
     }
     return true;
diff --git a/components/password_manager/core/common/password_manager_util.cc b/components/password_manager/core/common/password_manager_util.cc
index cc616b42..c28897f9 100644
--- a/components/password_manager/core/common/password_manager_util.cc
+++ b/components/password_manager/core/common/password_manager_util.cc
@@ -23,10 +23,10 @@
   return base::ranges::any_of(
       form.fields, [](const autofill::FormFieldData& field) {
         return field.IsPasswordInputElement() ||
-               field.autocomplete_attribute.find(
+               field.autocomplete_attribute().find(
                    password_manager::constants::kAutocompleteUsername) !=
                    std::string::npos ||
-               field.autocomplete_attribute.find(
+               field.autocomplete_attribute().find(
                    password_manager::constants::kAutocompleteWebAuthn) !=
                    std::string::npos;
       });
diff --git a/components/password_manager/core/common/password_manager_util_unittest.cc b/components/password_manager/core/common/password_manager_util_unittest.cc
index 71c26999..fc7d0da 100644
--- a/components/password_manager/core/common/password_manager_util_unittest.cc
+++ b/components/password_manager/core/common/password_manager_util_unittest.cc
@@ -24,7 +24,7 @@
   // /common.
   FormFieldData field;
   field.set_form_control_type(form_control_type);
-  field.autocomplete_attribute = std::move(autocomplete_attribute);
+  field.set_autocomplete_attribute(std::move(autocomplete_attribute));
 
   return field;
 }
diff --git a/components/plus_addresses/plus_address_http_client.h b/components/plus_addresses/plus_address_http_client.h
index 6611fe96..18ea62d 100644
--- a/components/plus_addresses/plus_address_http_client.h
+++ b/components/plus_addresses/plus_address_http_client.h
@@ -24,18 +24,24 @@
   // `on_completed` when the request is completed. If `refresh` is true, then
   // the server receives a flag that indicates that the address should be a new
   // one and not one that the user has previously seen.
+  // On success, the facet of the returned `PlusProfile` is set to the `origin`
+  // by the server.
   virtual void ReservePlusAddress(const url::Origin& origin,
                                   bool refresh,
                                   PlusAddressRequestCallback on_completed) = 0;
 
   // Initiates a request to confirm `plus_address` for use on `origin` and runs
   // `on_completed` when the request is completed.
+  // On success, the facet of the returned `PlusProfile` is set to the `origin`
+  // by the server.
   virtual void ConfirmPlusAddress(const url::Origin& origin,
                                   const std::string& plus_address,
                                   PlusAddressRequestCallback on_completed) = 0;
 
   // Initiates a request to get all plus addresses from the remote enterprise-
   // specified server and runs `on_completed` when the request is completed.
+  // On success, the facets of the returned `PlusProfile` are set to eTLD+1s.
+  // TODO(b/322147254): Remove once sync support is launched.
   virtual void GetAllPlusAddresses(
       PlusAddressMapRequestCallback on_completed) = 0;
 
diff --git a/components/plus_addresses/plus_address_service.cc b/components/plus_addresses/plus_address_service.cc
index b44b053..3e455c0 100644
--- a/components/plus_addresses/plus_address_service.cc
+++ b/components/plus_addresses/plus_address_service.cc
@@ -122,10 +122,10 @@
 std::optional<PlusProfile> PlusAddressService::GetPlusProfile(
     const url::Origin& origin) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  std::string etld_plus_one = GetEtldPlusOne(origin);
+  const std::string facet = IsSyncingPlusAddresses() ? origin.GetURL().spec()
+                                                     : GetEtldPlusOne(origin);
   // `facet` is used as the comparator, so the other fields don't matter.
-  auto it =
-      plus_profiles_.find(PlusProfile("", /*facet=*/etld_plus_one, "", false));
+  auto it = plus_profiles_.find(PlusProfile("", facet, "", false));
   if (it == plus_profiles_.end()) {
     return std::nullopt;
   }
@@ -135,9 +135,14 @@
 void PlusAddressService::SavePlusProfile(url::Origin origin,
                                          const PlusProfile& profile) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  const PlusProfile profile_to_save(profile.profile_id, GetEtldPlusOne(origin),
-                                    profile.plus_address,
-                                    /*is_confirmed=*/true);
+  CHECK(profile.is_confirmed);
+  // TODO(b/322147254): Once sync support is launched, and the client has thus
+  // migrated from eTLD+1 to origin, remove `profile_to_save` and simply store
+  // `profile`.
+  PlusProfile profile_to_save = profile;
+  if (!IsSyncingPlusAddresses()) {
+    profile_to_save.facet = GetEtldPlusOne(origin);
+  }
   // New plus addresses are requested directly from the PlusAddress backend. If
   // `IsSyncingPlusAddresses()`, these addresses become later available through
   // sync. Until the address shows up in sync, it should still be available
@@ -150,7 +155,8 @@
   plus_profiles_.insert(profile_to_save);
   plus_addresses_.insert(profile_to_save.plus_address);
   for (Observer& o : observers_) {
-    o.OnPlusAddressesChanged();
+    o.OnPlusAddressesChanged({PlusAddressDataChange(
+        PlusAddressDataChange::Type::kAdd, profile_to_save)});
   }
 }
 
@@ -346,30 +352,40 @@
         PlusProfile(/*profile_id=*/"", facet, address, /*is_confirmed=*/true));
     plus_addresses_.insert(address);
   }
-  for (Observer& o : observers_) {
-    o.OnPlusAddressesChanged();
-  }
 }
 
 void PlusAddressService::OnWebDataChangedBySync(
-    const PlusAddressDataChange& change) {
+    const std::vector<PlusAddressDataChange>& changes) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  switch (change.type()) {
-    case PlusAddressDataChange::Type::kAdd: {
-      plus_profiles_.insert(change.profile());
-      plus_addresses_.insert(change.profile().plus_address);
-      break;
-    }
-    case PlusAddressDataChange::Type::kRemove: {
-      plus_profiles_.erase(change.profile());
-      plus_addresses_.erase(change.profile().plus_address);
-      break;
+  std::vector<PlusAddressDataChange> applied_changes;
+  for (const PlusAddressDataChange& change : changes) {
+    const PlusProfile& profile = change.profile();
+    switch (change.type()) {
+      // Sync updates affect the local cache only if they introduce changes
+      // (e.g., an added plus address that wasn't previously confirmed via
+      // ConfirmPlusAddress).
+      case PlusAddressDataChange::Type::kAdd: {
+        const auto [it, inserted] = plus_profiles_.insert(profile);
+        if (inserted) {
+          plus_addresses_.insert(profile.plus_address);
+          applied_changes.emplace_back(PlusAddressDataChange::Type::kAdd,
+                                       profile);
+        }
+        break;
+      }
+      case PlusAddressDataChange::Type::kRemove: {
+        if (plus_profiles_.erase(profile)) {
+          plus_addresses_.erase(profile.plus_address);
+          applied_changes.emplace_back(PlusAddressDataChange::Type::kRemove,
+                                       profile);
+        }
+        break;
+      }
     }
   }
 
   for (Observer& o : observers_) {
-    o.OnPlusAddressesChanged();
+    o.OnPlusAddressesChanged(applied_changes);
   }
 }
 
@@ -385,14 +401,19 @@
 void PlusAddressService::ReplacePlusProfiles(
     const std::vector<PlusProfile>& profiles) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  plus_profiles_.clear();
-  plus_addresses_.clear();
+  CHECK(plus_profiles_.empty());
+  CHECK(plus_addresses_.empty());
+  std::vector<PlusAddressDataChange> applied_changes;
+  applied_changes.reserve(profiles.size());
   for (const PlusProfile& plus_profile : profiles) {
     plus_profiles_.insert(plus_profile);
     plus_addresses_.insert(plus_profile.plus_address);
+    applied_changes.emplace_back(PlusAddressDataChange::Type::kAdd,
+                                 plus_profile);
   }
+
   for (Observer& o : observers_) {
-    o.OnPlusAddressesChanged();
+    o.OnPlusAddressesChanged(applied_changes);
   }
 }
 
@@ -445,9 +466,6 @@
   plus_addresses_.clear();
   polling_timer_.Stop();
   plus_address_http_client_->Reset();
-  for (Observer& o : observers_) {
-    o.OnPlusAddressesChanged();
-  }
 }
 
 std::set<std::string> PlusAddressService::GetAndParseExcludedSites() {
diff --git a/components/plus_addresses/plus_address_service.h b/components/plus_addresses/plus_address_service.h
index d8eebbe..4956dee 100644
--- a/components/plus_addresses/plus_address_service.h
+++ b/components/plus_addresses/plus_address_service.h
@@ -48,9 +48,14 @@
  public:
   class Observer : public base::CheckedObserver {
    public:
-    // Called whenever the set of `PlusProfile`s returned by `GetPlusProfiles()`
-    // changes, e.g. because a new plus addresses arrived via Sync.
-    virtual void OnPlusAddressesChanged() = 0;
+    // Called whenever the set of plus addresses cached in the service
+    // gets modified (e.g. `SavePlusProfile` calls, sync updates, etc).
+    // `changes` represents a sequence of addition or removal operations
+    // triggered on the local cache. Notably, update operations are emulated as
+    // a remove operation of the old value followed by an addition of the
+    // updated value.
+    virtual void OnPlusAddressesChanged(
+        const std::vector<PlusAddressDataChange>& changes) = 0;
   };
 
   // The number of `HTTP_FORBIDDEN` responses that the user may receive before
@@ -79,7 +84,8 @@
   void RecordAutofillSuggestionEvent(SuggestionEvent suggestion_event) override;
 
   // PlusAddressWebDataService::Observer:
-  void OnWebDataChangedBySync(const PlusAddressDataChange& change) override;
+  void OnWebDataChangedBySync(
+      const std::vector<PlusAddressDataChange>& changes) override;
 
   // WebDataServiceConsumer:
   void OnWebDataServiceRequestDone(
@@ -111,6 +117,7 @@
 
   // Saves a plus profile for the given origin, which is converted to its eTLD+1
   // form prior to persistence.
+  // TODO(b/322147254): Remove `origin` parameter when sync support is launched.
   void SavePlusProfile(url::Origin origin, const PlusProfile& profile);
 
   // Asks the PlusAddressHttpClient to reserve a plus address for use on
diff --git a/components/plus_addresses/plus_address_service_unittest.cc b/components/plus_addresses/plus_address_service_unittest.cc
index 31712f9..0c9b4d8 100644
--- a/components/plus_addresses/plus_address_service_unittest.cc
+++ b/components/plus_addresses/plus_address_service_unittest.cc
@@ -80,6 +80,16 @@
 
 namespace plus_addresses {
 
+class MockPlusAddressServiceObserver : public PlusAddressService::Observer {
+ public:
+  MockPlusAddressServiceObserver() = default;
+  ~MockPlusAddressServiceObserver() override = default;
+  MOCK_METHOD(void,
+              OnPlusAddressesChanged,
+              (const std::vector<PlusAddressDataChange>&),
+              (override));
+};
+
 class PlusAddressServiceTest : public ::testing::Test {
  public:
   PlusAddressServiceTest()
@@ -126,7 +136,6 @@
   network::TestURLLoaderFactory test_url_loader_factory_;
   scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
   data_decoder::test::InProcessDataDecoder decoder_;
-
   std::optional<PlusAddressService> service_;
 };
 
@@ -309,6 +318,11 @@
 
 TEST_F(PlusAddressServiceRequestsTest, ConfirmPlusAddress_Successful) {
   const PlusProfile& profile = test::CreatePlusProfile();
+  MockPlusAddressServiceObserver mock_service_observer;
+  service().AddObserver(&mock_service_observer);
+  EXPECT_CALL(mock_service_observer,
+              OnPlusAddressesChanged(testing::ElementsAre(PlusAddressDataChange(
+                  PlusAddressDataChange::Type::kAdd, profile))));
   base::test::TestFuture<const PlusProfileOrError&> future;
   service().ConfirmPlusAddress(OriginFromFacet(profile.facet),
                                profile.plus_address, future.GetCallback());
@@ -772,17 +786,30 @@
   // `service()` has no way of knowing about this data.
   table().AddOrUpdatePlusProfile(profile1);
   table().AddOrUpdatePlusProfile(profile2);
-  EXPECT_THAT(service().GetPlusProfiles(), testing::IsEmpty());
+
+  service().SavePlusProfile(url::Origin::Create(GURL("https://foo.com")),
+                            profile1);
+  EXPECT_THAT(service().GetPlusProfiles(), testing::ElementsAre(profile1));
+
+  MockPlusAddressServiceObserver observer;
+  service().AddObserver(&observer);
+  // Simulate incoming changes from sync. Note that `profile1` already exists in
+  // the service and therefore should not be included as part of the updates
+  // sent to the `observer`.
+  EXPECT_CALL(observer,
+              OnPlusAddressesChanged(testing::ElementsAre(PlusAddressDataChange(
+                  PlusAddressDataChange::Type::kAdd, profile2))));
   service().OnWebDataChangedBySync(
-      PlusAddressDataChange(PlusAddressDataChange::Type::kAdd, profile1));
-  service().OnWebDataChangedBySync(
-      PlusAddressDataChange(PlusAddressDataChange::Type::kAdd, profile2));
+      {PlusAddressDataChange(PlusAddressDataChange::Type::kAdd, profile1),
+       PlusAddressDataChange(PlusAddressDataChange::Type::kAdd, profile2)});
   EXPECT_THAT(service().GetPlusProfiles(),
               testing::UnorderedElementsAre(profile1, profile2));
 
   table().RemovePlusProfile(profile1.profile_id);
-  service().OnWebDataChangedBySync(
-      PlusAddressDataChange(PlusAddressDataChange::Type::kRemove, profile1));
+  std::vector<PlusAddressDataChange> remove_changes = {
+      PlusAddressDataChange(PlusAddressDataChange::Type::kRemove, profile1)};
+  EXPECT_CALL(observer, OnPlusAddressesChanged(remove_changes));
+  service().OnWebDataChangedBySync(remove_changes);
   EXPECT_THAT(service().GetPlusProfiles(),
               testing::UnorderedElementsAre(profile2));
 }
diff --git a/components/plus_addresses/plus_address_types.h b/components/plus_addresses/plus_address_types.h
index e8be4767..9bb0e75f 100644
--- a/components/plus_addresses/plus_address_types.h
+++ b/components/plus_addresses/plus_address_types.h
@@ -29,6 +29,8 @@
   friend bool operator==(const PlusProfile&, const PlusProfile&) = default;
 
   std::string profile_id;
+  // TODO(b/322147254): Make this an `affiliations::FacetURI` when sync support
+  // is launched. Right now, this represents an eTLD+1.
   std::string facet;
   std::string plus_address;
   bool is_confirmed;
diff --git a/components/plus_addresses/webdata/plus_address_webdata_service.cc b/components/plus_addresses/webdata/plus_address_webdata_service.cc
index 57100f964..92512cd 100644
--- a/components/plus_addresses/webdata/plus_address_webdata_service.cc
+++ b/components/plus_addresses/webdata/plus_address_webdata_service.cc
@@ -141,9 +141,7 @@
     std::vector<PlusAddressDataChange> changes) {
   CHECK(ui_task_runner_->RunsTasksInCurrentSequence());
   for (Observer& o : observers_) {
-    for (const PlusAddressDataChange& change : changes) {
-      o.OnWebDataChangedBySync(change);
-    }
+    o.OnWebDataChangedBySync(changes);
   }
 }
 
diff --git a/components/plus_addresses/webdata/plus_address_webdata_service.h b/components/plus_addresses/webdata/plus_address_webdata_service.h
index a1025e42..115a487 100644
--- a/components/plus_addresses/webdata/plus_address_webdata_service.h
+++ b/components/plus_addresses/webdata/plus_address_webdata_service.h
@@ -49,7 +49,7 @@
     // operations are emulated as a remove operation of the old value followed
     // by an addition of the updated value.
     virtual void OnWebDataChangedBySync(
-        const PlusAddressDataChange& change) = 0;
+        const std::vector<PlusAddressDataChange>& changes) = 0;
   };
 
   PlusAddressWebDataService(
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/ApplicationBoundEncryptionEnabled.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/ApplicationBoundEncryptionEnabled.yaml
index 4449c7a4..5467440 100644
--- a/components/policy/resources/templates/policy_definitions/Miscellaneous/ApplicationBoundEncryptionEnabled.yaml
+++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/ApplicationBoundEncryptionEnabled.yaml
@@ -11,9 +11,9 @@
   dynamic_refresh: false
   per_profile: false
 items:
-- caption: Disable Application Bound Encryption
-  value: true
 - caption: Enable Application Bound Encryption
+  value: true
+- caption: Disable Application Bound Encryption
   value: false
 owners:
 - wfh@chromium.org
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/ProvisionManagedClientCertificateForUser.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/ProvisionManagedClientCertificateForUser.yaml
index 754f631b..daf19251 100644
--- a/components/policy/resources/templates/policy_definitions/Miscellaneous/ProvisionManagedClientCertificateForUser.yaml
+++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/ProvisionManagedClientCertificateForUser.yaml
@@ -7,9 +7,9 @@
 
   Setting this policy to <ph name="PROVISION_MANAGED_CLIENT_CERTIFICATE_FOR_USER_DISABLED">Disabled</ph> (value 0) will prevent the browser from requesting the client certificate. If a profile's managed client certificate had already been provisioned, due to this policy being enabled before, it will not be deleted, but it won't be available for mTLS connections and won't be renewed when it expires.
 
-future_on:
-- chrome.win
-- chrome.mac
+supported_on:
+- chrome.win:126-
+- chrome.mac:126-
 features:
   dynamic_refresh: true
   per_profile: true
diff --git a/components/privacy_sandbox/privacy_sandbox_settings.h b/components/privacy_sandbox/privacy_sandbox_settings.h
index f30c11c..c7c4501d 100644
--- a/components/privacy_sandbox/privacy_sandbox_settings.h
+++ b/components/privacy_sandbox/privacy_sandbox_settings.h
@@ -87,6 +87,10 @@
     // the standard set of Privacy Sandbox APIs.
     virtual bool IsSubjectToM1NoticeRestricted() const = 0;
 
+    // Whether the Privacy Sandbox is partially enabled based on
+    // restrictions.
+    virtual bool IsRestrictedNoticeEnabled() const = 0;
+
     // Whether the profile is eligible for 3PCD experiment. The eligibility
     // applies for both mode A and mode B experiments.
     virtual bool IsCookieDeprecationExperimentEligible() const = 0;
@@ -314,7 +318,8 @@
   virtual bool IsSubjectToM1NoticeRestricted() const = 0;
 
   // Returns whether the Privacy Sandbox is partially enabled based on
-  // restrictions.
+  // restrictions. Forwards to the delegate. Virtual for
+  // mocking in tests.
   virtual bool IsRestrictedNoticeEnabled() const = 0;
 
   // Called when there's a broad cookies clearing action. For example, this
diff --git a/components/privacy_sandbox/privacy_sandbox_settings_impl.cc b/components/privacy_sandbox/privacy_sandbox_settings_impl.cc
index 2b16fd7b..2e41bcac 100644
--- a/components/privacy_sandbox/privacy_sandbox_settings_impl.cc
+++ b/components/privacy_sandbox/privacy_sandbox_settings_impl.cc
@@ -769,7 +769,7 @@
 }
 
 bool PrivacySandboxSettingsImpl::IsRestrictedNoticeEnabled() const {
-  return privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.Get();
+  return delegate_->IsRestrictedNoticeEnabled();
 }
 
 void PrivacySandboxSettingsImpl::OnCookiesCleared() {
diff --git a/components/privacy_sandbox/privacy_sandbox_settings_impl_unittest.cc b/components/privacy_sandbox/privacy_sandbox_settings_impl_unittest.cc
index 7635526..c8633e7 100644
--- a/components/privacy_sandbox/privacy_sandbox_settings_impl_unittest.cc
+++ b/components/privacy_sandbox/privacy_sandbox_settings_impl_unittest.cc
@@ -1448,16 +1448,14 @@
 class PrivacySandboxSettingsM1RestrictedNotice
     : public PrivacySandboxSettingsM1Test {
   void InitializeFeaturesBeforeStart() override {
-    feature_list_.InitAndEnableFeatureWithParameters(
-        privacy_sandbox::kPrivacySandboxSettings4,
-        {{"notice-required", "true"},
-         {privacy_sandbox::kPrivacySandboxSettings4RestrictedNotice.name,
-          "true"}});
+    // Do not set default handlers so each call must be mocked.
   }
 };
 
 TEST_F(PrivacySandboxSettingsM1RestrictedNotice,
        AllApisAreOffExceptMeasurementForRestrictedAccounts) {
+  ON_CALL(*mock_delegate(), IsRestrictedNoticeEnabled())
+      .WillByDefault(testing::Return(true));
   RunTestCase(
       TestState{{MultipleStateKeys{kM1TopicsEnabledUserPrefValue,
                                    kM1FledgeEnabledUserPrefValue,
diff --git a/components/privacy_sandbox/privacy_sandbox_test_util.h b/components/privacy_sandbox/privacy_sandbox_test_util.h
index 9beba00d..511e0094 100644
--- a/components/privacy_sandbox/privacy_sandbox_test_util.h
+++ b/components/privacy_sandbox/privacy_sandbox_test_util.h
@@ -123,6 +123,7 @@
   MOCK_METHOD(bool, IsIncognitoProfile, (), (const, override));
   MOCK_METHOD(bool, HasAppropriateTopicsConsent, (), (const, override));
   MOCK_METHOD(bool, IsSubjectToM1NoticeRestricted, (), (const, override));
+  MOCK_METHOD(bool, IsRestrictedNoticeEnabled, (), (const, override));
   MOCK_METHOD(bool,
               IsCookieDeprecationExperimentEligible,
               (),
diff --git a/components/signin/internal/identity_manager/primary_account_manager.cc b/components/signin/internal/identity_manager/primary_account_manager.cc
index 769523a..3812a928 100644
--- a/components/signin/internal/identity_manager/primary_account_manager.cc
+++ b/components/signin/internal/identity_manager/primary_account_manager.cc
@@ -38,6 +38,15 @@
              base::FEATURE_ENABLED_BY_DEFAULT);
 namespace {
 
+// Registers that the sign in occurred with an explicit user action.
+// Affected by all signin sources except when signing in to Chrome caused by a
+// web sign in or by an unknown source.
+// Note: This value is potentially set before the
+// `switches::kExplicitBrowserSigninUIOnDesktop` is enabled. It is currently not
+// expected to be used and is logged for potential usages in the future.
+const char kExplicitBrowserSigninWithoutFeatureEnabled[] =
+    "signin.explicit_browser_signin";
+
 enum class InitializePrefState {
   kWithPrimaryAccountId_NotConsentedForSync = 0,
   kWithPrimaryAccountId_ConsentedForSync = 1,
@@ -205,6 +214,13 @@
       account_tracker_service_(account_tracker_service) {
   DCHECK(client_);
   DCHECK(account_tracker_service_);
+
+  // Clear the pref it is was set and the feature is now off.
+  if (!switches::IsExplicitBrowserSigninUIOnDesktopEnabled(
+          switches::ExplicitBrowserSigninPhase::kExperimental)) {
+    ScopedPrefCommit(client_->GetPrefs(), /*commit_on_destroy=*/false)
+        .ClearPref(prefs::kExplicitBrowserSignin);
+  }
 }
 
 PrimaryAccountManager::~PrimaryAccountManager() {
@@ -229,6 +245,8 @@
   registry->RegisterListPref(prefs::kReverseAutologinRejectedEmailList);
   registry->RegisterBooleanPref(prefs::kSigninAllowed, true);
   registry->RegisterBooleanPref(prefs::kSignedInWithCredentialProvider, false);
+  registry->RegisterBooleanPref(kExplicitBrowserSigninWithoutFeatureEnabled,
+                                false);
   registry->RegisterBooleanPref(prefs::kExplicitBrowserSignin, false);
 }
 
@@ -692,7 +710,11 @@
     case PrimaryAccountChangeEvent::Type::kNone:
       return;
     case PrimaryAccountChangeEvent::Type::kCleared:
-      scoped_pref_commit.ClearPref(prefs::kExplicitBrowserSignin);
+      scoped_pref_commit.ClearPref(kExplicitBrowserSigninWithoutFeatureEnabled);
+      if (switches::IsExplicitBrowserSigninUIOnDesktopEnabled(
+              switches::ExplicitBrowserSigninPhase::kExperimental)) {
+        scoped_pref_commit.ClearPref(prefs::kExplicitBrowserSignin);
+      }
       return;
     case PrimaryAccountChangeEvent::Type::kSet:
       CHECK(event_details.GetAccessPoint().has_value());
@@ -702,11 +724,21 @@
       if (access_point == signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN ||
           access_point ==
               signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN) {
-        scoped_pref_commit.ClearPref(prefs::kExplicitBrowserSignin);
+        scoped_pref_commit.ClearPref(
+            kExplicitBrowserSigninWithoutFeatureEnabled);
+        if (switches::IsExplicitBrowserSigninUIOnDesktopEnabled(
+                switches::ExplicitBrowserSigninPhase::kExperimental)) {
+          scoped_pref_commit.ClearPref(prefs::kExplicitBrowserSignin);
+        }
       } else {
         // All others access points are explicit sign ins except the Web
         // Signin event.
-        scoped_pref_commit.SetBoolean(prefs::kExplicitBrowserSignin, true);
+        scoped_pref_commit.SetBoolean(
+            kExplicitBrowserSigninWithoutFeatureEnabled, true);
+        if (switches::IsExplicitBrowserSigninUIOnDesktopEnabled(
+                switches::ExplicitBrowserSigninPhase::kExperimental)) {
+          scoped_pref_commit.SetBoolean(prefs::kExplicitBrowserSignin, true);
+        }
       }
   }
 }
diff --git a/components/signin/internal/identity_manager/primary_account_manager_unittest.cc b/components/signin/internal/identity_manager/primary_account_manager_unittest.cc
index c127034..b5009a5 100644
--- a/components/signin/internal/identity_manager/primary_account_manager_unittest.cc
+++ b/components/signin/internal/identity_manager/primary_account_manager_unittest.cc
@@ -44,6 +44,13 @@
 using testing::ElementsAreArray;
 
 namespace {
+
+// Equivalent to the content of `kExplicitBrowserSigninWithoutFeatureEnabled`
+// defined in primary_account_manager.cc that is internal. Recreating it here
+// for testing purposes.
+const char kExplicitBrowserSigninWithoutFeatureEnabledForTesting[] =
+    "signin.explicit_browser_signin";
+
 struct ExpectedAccessPoints {
   std::optional<AccessPoint> sign_in = std::nullopt;
   std::optional<AccessPoint> sync_opt_in = std::nullopt;
@@ -847,11 +854,16 @@
 }
 
 TEST_F(PrimaryAccountManagerTest, ExplicitSigninPref) {
+  base::test::ScopedFeatureList feature{
+      switches::kExplicitBrowserSigninUIOnDesktop};
+
   CreatePrimaryAccountManager();
   CoreAccountId account_id =
       AddToAccountTracker("account_id", "user@gmail.com");
 
   ASSERT_FALSE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+  ASSERT_FALSE(prefs()->GetBoolean(
+      kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
 
   // Simulate an explicit signin through the Chrome Signin Intercept bubble.
   manager_->SetPrimaryAccountInfo(
@@ -860,21 +872,30 @@
       signin_metrics::AccessPoint::ACCESS_POINT_CHROME_SIGNIN_INTERCEPT_BUBBLE);
 
   EXPECT_TRUE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+  EXPECT_TRUE(prefs()->GetBoolean(
+      kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
 
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
   // Clearing signin.
   manager_->ClearPrimaryAccount(signin_metrics::ProfileSignout::kTest);
 
   EXPECT_FALSE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+  EXPECT_FALSE(prefs()->GetBoolean(
+      kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
 #endif
 }
 
 TEST_F(PrimaryAccountManagerTest, ImplicitSigninDoesNotSetExplicitSigninPref) {
+  base::test::ScopedFeatureList feature{
+      switches::kExplicitBrowserSigninUIOnDesktop};
+
   CreatePrimaryAccountManager();
   CoreAccountId account_id =
       AddToAccountTracker("account_id", "user@gmail.com");
 
   ASSERT_FALSE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+  ASSERT_FALSE(prefs()->GetBoolean(
+      kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
 
   // Simulate an implicit signin through a web signin event.
   manager_->SetPrimaryAccountInfo(
@@ -883,14 +904,21 @@
       signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN);
 
   EXPECT_FALSE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+  EXPECT_FALSE(prefs()->GetBoolean(
+      kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
 }
 
 TEST_F(PrimaryAccountManagerTest, ExplicitSigninFollowedByUnknownSignin) {
+  base::test::ScopedFeatureList feature{
+      switches::kExplicitBrowserSigninUIOnDesktop};
+
   CreatePrimaryAccountManager();
   CoreAccountId account_id =
       AddToAccountTracker("account_id", "user@gmail.com");
 
   ASSERT_FALSE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+  ASSERT_FALSE(prefs()->GetBoolean(
+      kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
 
   // Simulate an explicit signin through the Chrome Signin Intercept bubble.
   manager_->SetPrimaryAccountInfo(
@@ -899,6 +927,8 @@
       signin_metrics::AccessPoint::ACCESS_POINT_CHROME_SIGNIN_INTERCEPT_BUBBLE);
 
   EXPECT_TRUE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+  EXPECT_TRUE(prefs()->GetBoolean(
+      kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
 
   // Creating a second account.
   CoreAccountId account_id2 =
@@ -912,6 +942,8 @@
 
   // The explicit sign in pref should be cleared.
   EXPECT_FALSE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+  EXPECT_FALSE(prefs()->GetBoolean(
+      kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
 }
 
 TEST_F(PrimaryAccountManagerTest, ExplicitSigninFollowedByWebSignin) {
@@ -926,6 +958,8 @@
       AddToAccountTracker("account_id", "user@gmail.com");
 
   ASSERT_FALSE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+  ASSERT_FALSE(prefs()->GetBoolean(
+      kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
 
   // Simulate an explicit signin through the Chrome Signin Intercept bubble.
   manager_->SetPrimaryAccountInfo(
@@ -934,6 +968,8 @@
       signin_metrics::AccessPoint::ACCESS_POINT_CHROME_SIGNIN_INTERCEPT_BUBBLE);
 
   EXPECT_TRUE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+  EXPECT_TRUE(prefs()->GetBoolean(
+      kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
 
   // Creating a second account.
   CoreAccountId account_id2 =
@@ -948,4 +984,82 @@
 
   // The explicit sign in pref should be reset.
   EXPECT_FALSE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+  EXPECT_FALSE(prefs()->GetBoolean(
+      kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
+}
+
+TEST_F(
+    PrimaryAccountManagerTest,
+    ExplicitBrowserSigninDoesNotSetPrefWithExplicitBrowserSigninFeatureDisabled) {
+  base::test::ScopedFeatureList feature;
+  feature.InitAndDisableFeature(switches::kExplicitBrowserSigninUIOnDesktop);
+
+  CreatePrimaryAccountManager();
+  CoreAccountId account_id =
+      AddToAccountTracker("account_id", "user@gmail.com");
+
+  ASSERT_FALSE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+  ASSERT_FALSE(prefs()->GetBoolean(
+      kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
+
+  // Simulate an explicit signin through the Chrome Signin Intercept bubble.
+  manager_->SetPrimaryAccountInfo(
+      account_tracker()->GetAccountInfo(account_id),
+      signin::ConsentLevel::kSignin,
+      signin_metrics::AccessPoint::ACCESS_POINT_CHROME_SIGNIN_INTERCEPT_BUBBLE);
+
+  // Explicit pref is not set.
+  EXPECT_FALSE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+  // Internal version of the pref is set though.
+  EXPECT_TRUE(prefs()->GetBoolean(
+      kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
+}
+
+TEST_F(PrimaryAccountManagerTest,
+       RollingBackUsersOfExplicitBrowserSigninPrefCheck) {
+  ASSERT_FALSE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+  ASSERT_FALSE(prefs()->GetBoolean(
+      kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
+
+  // Explicit sign in with `switches::kExplicitBrowserSigninUIOnDesktop` on.
+  {
+    base::test::ScopedFeatureList feature{
+        switches::kExplicitBrowserSigninUIOnDesktop};
+
+    CreatePrimaryAccountManager();
+    CoreAccountId account_id =
+        AddToAccountTracker("account_id", "user@gmail.com");
+
+    // Simulate an explicit signin through the Chrome Signin Intercept bubble.
+    manager_->SetPrimaryAccountInfo(
+        account_tracker()->GetAccountInfo(account_id),
+        signin::ConsentLevel::kSignin,
+        signin_metrics::AccessPoint::
+            ACCESS_POINT_CHROME_SIGNIN_INTERCEPT_BUBBLE);
+
+    // The explicit sign in pref should be reset.
+    EXPECT_TRUE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+    EXPECT_TRUE(prefs()->GetBoolean(
+        kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
+  }
+
+  // Simulate a restart by shutting down the manager and creating a new one with
+  // `switches::kExplicitBrowserSigninUIOnDesktop` off.
+  ShutDownManager();
+  {
+    ASSERT_TRUE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+    ASSERT_TRUE(prefs()->GetBoolean(
+        kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
+
+    base::test::ScopedFeatureList feature;
+    feature.InitAndDisableFeature(switches::kExplicitBrowserSigninUIOnDesktop);
+
+    CreatePrimaryAccountManager();
+
+    // Explicit pref is cleared.
+    EXPECT_FALSE(prefs()->GetBoolean(prefs::kExplicitBrowserSignin));
+    // Internal version of the pref is still set though.
+    EXPECT_TRUE(prefs()->GetBoolean(
+        kExplicitBrowserSigninWithoutFeatureEnabledForTesting));
+  }
 }
diff --git a/components/signin/public/base/signin_pref_names.cc b/components/signin/public/base/signin_pref_names.cc
index 916d974..6425cd6 100644
--- a/components/signin/public/base/signin_pref_names.cc
+++ b/components/signin/public/base/signin_pref_names.cc
@@ -146,7 +146,10 @@
 // Registers that the sign in occurred with an explicit user action.
 // Affected by all signin sources except when signing in to Chrome caused by a
 // web sign in or by an unknown source.
-const char kExplicitBrowserSignin[] = "signin.explicit_browser_signin";
+// Note: this pref is only recorded when the
+// `switches::kExplicitBrowserSigninUIOnDesktop` is enabled.
+const char kExplicitBrowserSignin[] =
+    "signin.signin_with_explicit_browser_signin_on";
 
 // Boolean indicating whether the Device Bound Session Credentials should be
 // enabled. Takes precedence over the "EnableBoundSessionCredentials" feature
diff --git a/components/strings/components_strings_ar.xtb b/components/strings/components_strings_ar.xtb
index 260e7ee8..805110e 100644
--- a/components/strings/components_strings_ar.xtb
+++ b/components/strings/components_strings_ar.xtb
@@ -380,6 +380,7 @@
 <translation id="168693727862418163">تعذّر التحقُّق من قيمة السياسة هذه وفقًا لمخططها وسيتم تجاهلها.</translation>
 <translation id="168841957122794586">تحتوي شهادة الخادم على مفتاح ترميز ضعيف.</translation>
 <translation id="1689333818294560261">اللقب</translation>
+<translation id="1691425742011409472">قفل المؤشر</translation>
 <translation id="1692622044604477956">قوائم أفلام ومواعيد العروض في السينما</translation>
 <translation id="1697430960030447570">‏<ph name="BEGIN_BOLD" />كيف يمكنك إدارة بياناتك:<ph name="END_BOLD" /> يحذف Chrome تلقائيًا المواضيع التي يمر أكثر من 4 أسابيع على إضافتها إلى قائمة مواضيع الإعلانات. ومع استمرارك في التصفّح، قد يظهر موضوع في القائمة مجددًا. يمكنك أيضًا حظر المواضيع التي لا تريد أن يشاركها Chrome مع المواقع الإلكترونية، وإيقاف ميزة "مواضيع الإعلانات" متى شئت من خلال إعدادات Chrome.</translation>
 <translation id="1697532407822776718">أنت الآن على أتم استعداد.</translation>
@@ -729,6 +730,7 @@
 <translation id="2337852623177822836">يتم التحكّم في الإعداد من قبل المشرف</translation>
 <translation id="2340263603246777781">يريد <ph name="ORIGIN" /> الاقتران</translation>
 <translation id="2346319942568447007">الصورة التي نسختها</translation>
+<translation id="2349056830177284083">قفل لوحة المفاتيح</translation>
 <translation id="2349957959687031096">زر فتح علامة تبويب في وضع التصفّح المتخفي: انقر على هذا الزر للتصفّح بخصوصية تامة.</translation>
 <translation id="2350796302381711542">هل تريد السماح لـ <ph name="HANDLER_HOSTNAME" /> بفتح كل روابط <ph name="PROTOCOL" /> بدلاً من <ph name="REPLACED_HANDLER_TITLE" />؟</translation>
 <translation id="2353297238722298836">تم السماح باستخدام الكاميرا والميكروفون</translation>
@@ -946,6 +948,7 @@
 <translation id="2784474685437057136">B5 Extra</translation>
 <translation id="2784949926578158345">تمت إعادة ضبط الاتصال.</translation>
 <translation id="2786008859124691917">دراجات وإكسسوارات</translation>
+<translation id="2791955793407772554">قفل المؤشر</translation>
 <translation id="2792012897584536778">أعدّ مشرفو هذا الجهاز شهادات الأمان التي قد تسمح لهم بالاطّلاع على محتوى المواقع الإلكترونية التي تزورها.</translation>
 <translation id="2794233252405721443">تم حظر الموقع</translation>
 <translation id="2794629552137076216">زجاج (سطحي)</translation>
@@ -1105,6 +1108,7 @@
 <translation id="3121994479408824897">الانتقال إلى <ph name="DOMAIN" /></translation>
 <translation id="3126023634486644099">تصنيفات (دائمة)</translation>
 <translation id="3133565499688974786">تم ضبط <ph name="SEARCH_ENGINE_NAME" /> على أنّه محرك البحث التلقائي.</translation>
+<translation id="3137283076021007034">‏‫‎<ph name="KEYWORD" />: البحث في "<ph name="KEYWORD_SHORT_NAME" />"</translation>
 <translation id="3140646734028448730">خدمات أنشطة تجارية</translation>
 <translation id="3141093262818886744">الفتح على أي حال</translation>
 <translation id="3141641372357166056">لم يتم اتخاذ قرار بشأن الموافقة.</translation>
@@ -1429,11 +1433,13 @@
 <translation id="3711895659073496551">تعليق</translation>
 <translation id="3712006010833051684">ظرف رقم 10</translation>
 <translation id="3712624925041724820">التراخيص مستنفذة</translation>
+<translation id="3713277100229669269">يمكنك الآن الاطّلاع على مزايا البطاقة قبل الدفع</translation>
 <translation id="371420189621607696">ألعاب فيديو تنافسية</translation>
 <translation id="3714633008798122362">تقويم الويب</translation>
 <translation id="3714780639079136834">‏تشغيل بيانات شبكة الجوّال أو Wi-Fi</translation>
 <translation id="3715016660240337709">{0,plural, =1{تم حظر تحميل الملف}zero{تم حظر تحميل <ph name="FILE_COUNT" /> ملف}two{تم حظر تحميل ملفَين (<ph name="FILE_COUNT" />)}few{تم حظر تحميل <ph name="FILE_COUNT" /> ملفات}many{تم حظر تحميل <ph name="FILE_COUNT" /> ملفًا}other{تم حظر تحميل <ph name="FILE_COUNT" /> ملف}}</translation>
 <translation id="3715597595485130451">‏الاتصال بـ Wi-Fi</translation>
+<translation id="3716622997181469465">قفل لوحة المفاتيح</translation>
 <translation id="3717027428350673159"><ph name="BEGIN_LINK" />التحقق من إعداد الخادم الوكيل والجدار الناري ونظام أسماء النطاقات<ph name="END_LINK" /></translation>
 <translation id="3723663469265383848">أثناء إجراء التحديث، لن تتمكّن من استخدام الجهاز لمدة تصل إلى 10 دقائق.</translation>
 <translation id="372429172604983730">تتضمن التطبيقات التي يمكن أن تسبب ذلك الخطأ برنامج مكافحة الفيروسات والجدار الناري وبرنامج تصفية الويب أو برنامج الخادم الوكيل.</translation>
@@ -3527,6 +3533,7 @@
 <translation id="7751019142333897329"><ph name="FIRST_STRING" /> <ph name="SECOND_STRING" /></translation>
 <translation id="7751971323486164747">‏تخصيص أحجام الخطوط وأنماطها في Chrome</translation>
 <translation id="7752995774971033316">غير مُدار</translation>
+<translation id="7753769899818674547">‏‫‎<ph name="KEYWORD" />: بدء الدردشة مع "<ph name="KEYWORD_SHORT_NAME" />"</translation>
 <translation id="7754587126786572336">‏سيتم إغلاق علامات تبويب Chrome وتطبيقاته عند بدء التحديث</translation>
 <translation id="7755287808199759310">قد يلغي والداك الحظر لك</translation>
 <translation id="7755624218968747854">اللفافة الأساسية</translation>
diff --git a/components/strings/components_strings_id.xtb b/components/strings/components_strings_id.xtb
index 852794d..684a9a98 100644
--- a/components/strings/components_strings_id.xtb
+++ b/components/strings/components_strings_id.xtb
@@ -2108,6 +2108,7 @@
 <translation id="5040262127954254034">Privasi</translation>
 <translation id="5043480802608081735">Link yang Anda Salin</translation>
 <translation id="5045550434625856497">Sandi salah</translation>
+<translation id="5048293684454354469">Topik iklan hanyalah salah satu dari banyak hal yang dapat digunakan situs untuk mempersonalisasi iklan. Bahkan tanpa topik iklan, situs tetap dapat menampilkan iklan kepada Anda, tetapi iklan tersebut mungkin kurang dipersonalisasi. Pelajari lebih lanjut cara <ph name="BEGIN_LINK" />mengelola privasi iklan<ph name="LINK_END" />.</translation>
 <translation id="5052517576853118371">Topik aktif</translation>
 <translation id="5056425809654826431">{NUM_FILES,plural, =1{Untuk mengirim file ini menggunakan Berbagi Langsung, kosongkan ruang penyimpanan (<ph name="DISK_SPACE_SIZE" />) di perangkat Anda}other{Untuk mengirim file ini menggunakan Berbagi Langsung, kosongkan ruang penyimpanan (<ph name="DISK_SPACE_SIZE" />) di perangkat Anda}}</translation>
 <translation id="505757197798929356">Berikan alasan membuka (wajib)</translation>
@@ -2326,6 +2327,7 @@
     <ph name="LINE_BREAK" />
     Coba hubungi administrator sistem Anda.</translation>
 <translation id="549333378215107354">Ukuran 3</translation>
+<translation id="5496804587179176046">Simpan kode keamanan, tidak ada kode keamanan yang disimpan saat ini</translation>
 <translation id="550365051221576010">Isi semua</translation>
 <translation id="5508443345185481044">Kamera &amp; Perekam Video</translation>
 <translation id="5509762909502811065">B0</translation>
diff --git a/components/strings/components_strings_ka.xtb b/components/strings/components_strings_ka.xtb
index 8f3c523..75b7db3 100644
--- a/components/strings/components_strings_ka.xtb
+++ b/components/strings/components_strings_ka.xtb
@@ -935,6 +935,7 @@
 <translation id="2759825833388495838">შეავსეთ თქვენი პაროლი <ph name="APP_NAME" />-ში</translation>
 <translation id="2764001903315068341">კომიქსები</translation>
 <translation id="2765217105034171413">პატარა</translation>
+<translation id="2768397283109119044">თქვენ ცადეთ <ph name="DOMAIN" />-ზე შეღწევა, მაგრამ სერვერზე წარმოდგენილია ამ სახელზე გაცემული არასწორი სერტიფიკატი. სახელი არის კერძო IP მისამართი ან შიდა სერვერის სახელი.</translation>
 <translation id="2770159525358613612">ცადეთ თქვენი ფაილების ხელახლა ატვირთვა</translation>
 <translation id="277133753123645258">გაგზავნის მეთოდი</translation>
 <translation id="2773388851563527404">Chrome უზღუდავს საიტების უმეტესობას მესამე მხარის ქუქი-ჩანაწერების გამოყენებას. ამის მიუხედავად, მესამე მხარის ქუქი-ჩანაწერები დაშვებულია ამ საიტზე, რადგან ის მათი მეშვეობით უზრუნველყოფს ძირითად სერვისებს. <ph name="LINK" /> თუ გსურთ, ეწვიეთ პარამეტრებს.</translation>
@@ -1716,6 +1717,7 @@
 <translation id="4265872034478892965">დაშვებულია თქვენი ადმინისტრატორის მიერ</translation>
 <translation id="4269029136757623689">ვენტილატორები</translation>
 <translation id="4269264543938335308">საცურაო ტანსაცმელი</translation>
+<translation id="4269599248168651462">სერვერის სერტიფიკატი გაცემულია სახელზე, რომელიც არ არის უნიკალური.</translation>
 <translation id="4270541775497538019">სტეკერი 6</translation>
 <translation id="4275830172053184480">გადატვირთეთ თქვენი მოწყობილობა</translation>
 <translation id="4276974990916607331">არა, გმადლობთ</translation>
@@ -3194,6 +3196,7 @@
 <translation id="7163295244162773898">{0,plural, =1{გსურთ კონფიდენციალური ფაილის კოპირება?}other{გსურთ კონფიდენციალური ფაილების კოპირება?}}</translation>
 <translation id="7168625890036931112">„<ph name="DATA_CONTROLS_RESTRICTION" />“ არ არის მხარდაჭერილი შეზღუდვა ამ პლატფორმაზე</translation>
 <translation id="717330890047184534">GAIA ID:</translation>
+<translation id="7173338713290252554">ფასის ისტორია ვებში</translation>
 <translation id="7174545416324379297">გაერთიანებული</translation>
 <translation id="7175097078723125014">არჩეული იყო მისამართის რედაქტირების ვარიანტი</translation>
 <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> და <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> სხვა}other{<ph name="SHIPPING_OPTION_PREVIEW" /> და <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> სხვა}}</translation>
@@ -4118,6 +4121,7 @@
 <translation id="8919740778133505789">სპორტული მანქანები</translation>
 <translation id="8919895429178014996">ყველა ერთეულის დამალვა</translation>
 <translation id="8922013791253848639">ამ საიტზე რეკლამის ყოველთვის დაშვება</translation>
+<translation id="8924109546403192898">Chrome-ის მიერ უსაფრთხოებასთან დაკავშირებული მოვლენების ალმით მონიშვნის შემთხვევაში, მოვლენების შესაბამისი მონაცემები გაეგზავნება თქვენს ადმინისტრატორს. აღნიშნული შეიძლება მოიცავდეს თქვენ მიერ Chrome-ში მონახულებული გვერდების URL-ებს, ფაილების სახელებს ან მეტამონაცემებს, ასევე, მომხმარებლის სახელს, რომელსაც ვებზე დაფუძნებულ აპლიკაციებში, თქვენს მოწყობილობაში და Chrome-ში შესასვლელად იყენებთ და იმ გვერდების URL-ებს, რომლებიდანაც მონაცემები დააკოპირეთ.</translation>
 <translation id="892588693504540538">ზედა მარჯვენა ნაწილის გახვრეტა</translation>
 <translation id="8926389886865778422">აღარ მკითხო</translation>
 <translation id="8932102934695377596">თქვენი საათი უკანაა</translation>
diff --git a/components/strings/components_strings_lo.xtb b/components/strings/components_strings_lo.xtb
index 9301589..ebe8227 100644
--- a/components/strings/components_strings_lo.xtb
+++ b/components/strings/components_strings_lo.xtb
@@ -935,6 +935,7 @@
 <translation id="2759825833388495838">ຕື່ມລະຫັດຂອງທ່ານໃສ່ <ph name="APP_NAME" /></translation>
 <translation id="2764001903315068341">ກາຕູນ</translation>
 <translation id="2765217105034171413">ນ້ອຍ</translation>
+<translation id="2768397283109119044">ທ່ານພະຍາຍາມເຂົ້າເຖິງ <ph name="DOMAIN" />, ແຕ່ເຊີບເວີໄດ້ນຳສະເໜີໃບຮັບຮອງທີ່ບໍ່ຖືກຕ້ອງທີ່ອອກໃຫ້ກັບຊື່ນັ້ນ. ຊື່ເປັນທີ່ຢູ່ IP ທີ່ສະຫງວນໄວ້ ຫຼື ຊື່ໂຮສພາຍໃນ.</translation>
 <translation id="2770159525358613612">ລອງອັບໂຫຼດໄຟລ໌ຂອງທ່ານອີກຄັ້ງ</translation>
 <translation id="277133753123645258">ວິທີການຈັດສົ່ງ</translation>
 <translation id="2773388851563527404">Chrome ຈໍາກັດເວັບໄຊສ່ວນໃຫຍ່ຈາກການໃຊ້ຄຸກກີ້ພາກສ່ວນທີສາມໄວ້. ແຕ່ຄຸກກີ້ພາກສ່ວນທີສາມຖືກອະນຸຍາດໃຫ້ຢູ່ເວັບໄຊນີ້ເພາະວ່າຕ້ອງອາໄສພວກມັນເພື່ອໃຫ້ບໍລິການພື້ນຖານ. ເຂົ້າເບິ່ງການຕັ້ງຄ່າເພື່ອ <ph name="LINK" />.</translation>
@@ -1716,6 +1717,7 @@
 <translation id="4265872034478892965">ອະນຸຍາດໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ</translation>
 <translation id="4269029136757623689">ພັດລົມໃນຄົວເຮືອນ</translation>
 <translation id="4269264543938335308">ຊຸດລອຍນ້ຳ</translation>
+<translation id="4269599248168651462">ໃບຮັບຮອງເຊີບເວີຖືກອອກໃຫ້ຊື່ທີ່ບໍ່ຊ້ຳກັນ.</translation>
 <translation id="4270541775497538019">ສະແຕັກເກີ້ 6</translation>
 <translation id="4275830172053184480">ເລີ່ມຕົ້ນອຸປະກອນຂອງທ່ານໃໝ່</translation>
 <translation id="4276974990916607331">ບໍ່, ຂອບໃຈ</translation>
@@ -3194,6 +3196,7 @@
 <translation id="7163295244162773898">{0,plural, =1{ສຳເນົາໄຟລ໌ຄວາມລັບບໍ?}other{ສຳເນົາໄຟລ໌ຄວາມລັບບໍ?}}</translation>
 <translation id="7168625890036931112">"<ph name="DATA_CONTROLS_RESTRICTION" />" ບໍ່ແມ່ນການຈຳກັດທີ່ຮອງຮັບຢູ່ແພລດຟອມນີ້</translation>
 <translation id="717330890047184534">Gaia ID:</translation>
+<translation id="7173338713290252554">ປະ​ຫວັດ​ລາຄາທົ່ວເວັບ</translation>
 <translation id="7174545416324379297">ຮວມເຂົ້າກັນແລ້ວ</translation>
 <translation id="7175097078723125014">ເລືອກຕົວເລືອກແກ້ໄຂທີ່ຢູ່ແລ້ວ</translation>
 <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> ແລະ ອີກ <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ທີ່ຢູ່}other{<ph name="SHIPPING_OPTION_PREVIEW" /> ແລະ ອີກ <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ທີ່ຢູ່}}</translation>
@@ -4118,6 +4121,7 @@
 <translation id="8919740778133505789">ລົດສະປອດ</translation>
 <translation id="8919895429178014996">ເຊື່ອງລາຍການທັງໝົດ</translation>
 <translation id="8922013791253848639">ອະນຸຍາດໂຄສະນາໃນເວັບໄຊນີ້ທຸກເທື່ອ</translation>
+<translation id="8924109546403192898">ເມື່ອມີການໝາຍທຸງເຫດການຄວາມປອດໄພໂດຍ Chrome, ຂໍ້ມູນກ່ຽວຂ້ອງທີ່ກ່ຽວກັບເຫດການນັ້ນຈະຖືກສົ່ງໃຫ້ຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ. ນີ້ສາມາດຮວມມີ URL ຂອງໜ້າທີ່ທ່ານເຂົ້າເບິ່ງໃນ Chrome, URL ຂອງໜ້າທີ່ທ່ານສຳເນົາຂໍ້ມູນຈາກ, ຊື່ໄຟລ໌ ຫຼື ເມຕາເດຕາ, ໂປຣແກຣມທ່ອງເວັບ ຫຼື ແຖບຂັດຂ້ອງ ແລະ ຊື່ຜູ້ໃຊ້ທີ່ທ່ານໃຊ້ເພື່ອເຂົ້າສູ່ລະບົບແອັບພລິເຄຊັນຢູ່ເວັບ, ອຸປະກອນຂອງທ່ານ ແລະ Chrome.</translation>
 <translation id="892588693504540538">ເຈາະຮູເທິງສຸດເບື້ອງຊ້າຍ</translation>
 <translation id="8926389886865778422">ຢ່າຖາມອີກ</translation>
 <translation id="8932102934695377596">ໂມງ​ຂອງ​ທ່ານ​ຊ້າ</translation>
diff --git a/components/strings/components_strings_ms.xtb b/components/strings/components_strings_ms.xtb
index f964923..af87467 100644
--- a/components/strings/components_strings_ms.xtb
+++ b/components/strings/components_strings_ms.xtb
@@ -162,6 +162,7 @@
 <translation id="1282358575813748144">Bot &amp; Kapal Air</translation>
 <translation id="1283977499362032052">Resume &amp; Portfolio</translation>
 <translation id="1285320974508926690">Jangan sekali-kali menterjemahkan tapak ini</translation>
+<translation id="1291249564161469503">Kunci papan kekunci anda</translation>
 <translation id="1292571435393770077">Dulang 16</translation>
 <translation id="1292701964462482250">"Perisian pada komputer anda menghalang Chrome daripada menyambung ke web dengan selamat" (komputer Windows sahaja)</translation>
 <translation id="1293797321964802402">Sampul 9 x 11 inci</translation>
@@ -572,6 +573,7 @@
 <translation id="2046951263634619614">Penjual Buku</translation>
 <translation id="2048261947532620704">Menterjemah halaman</translation>
 <translation id="2053111141626950936">Halaman dalam <ph name="LANGUAGE" /> tidak akan diterjemah.</translation>
+<translation id="2056492565825767809">Kunci penuding tetikus anda</translation>
 <translation id="2056658168519009885">Laman boleh meminta maklumat daripada Chrome untuk membantu laman memeribadikan iklan yang anda lihat.</translation>
 <translation id="2059166748188874810">Perbandaran</translation>
 <translation id="2059202684901022309">22 x 34 in</translation>
@@ -1069,6 +1071,7 @@
 <translation id="3052964831964880138"><ph name="PRICE_DROP" /> penurunan harga pada <ph name="PRODUCT_NAME" /></translation>
 <translation id="3054512251683174387">Chrome memadamkan laman yang disimpan melebihi 4 minggu secara automatik. Semasa anda terus menyemak imbas, topik mungkin dipaparkan semula dalam senarai. Anda juga boleh menyekat topik yang tidak mahu dikongsi oleh Chrome dengan laman. Ketahui lebih lanjut tentang pengurusan privasi iklan anda dalam Chrome.</translation>
 <translation id="3061707000357573562">Perkhidmatan Tampung</translation>
+<translation id="3062655045399308513">Padamkan Data Semakan Imbas...</translation>
 <translation id="306573536155379004">Permainan dimulakan.</translation>
 <translation id="3067505415088964188">Harga rendah</translation>
 <translation id="3076865167425975822">Sistem Pengendalian</translation>
@@ -2026,6 +2029,7 @@
 <translation id="4885256590493466218">Buat bayaran menggunakan <ph name="CARD_DETAIL" /> semasa daftar keluar</translation>
 <translation id="4887406273302438710">Lindungi kata laluan dengan Windows Hello</translation>
 <translation id="4890070067176768718">Pentadbir anda telah membenarkan <ph name="PERMISSION" /> pada <ph name="ORIGIN" /></translation>
+<translation id="4891425819480327855"><ph name="CLEAR_BROWSING_DATA_FOCUSED_FRIENDLY_MATCH_TEXT" />, tekan Tab, kemudian Enter untuk memadamkan sejarah penyemakan imbas, kuki, cache dan pelbagai lagi dalam tetapan Chrome</translation>
 <translation id="4892518386797173871">Belakang</translation>
 <translation id="4895019427244614047">Padamkan alamat</translation>
 <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation>
@@ -2593,6 +2597,7 @@
 <translation id="6014851866995737824">Diabaikan kerana tiada senarai "dayakan" atau "lumpuhkan".</translation>
 <translation id="6015796118275082299">Tahun</translation>
 <translation id="6017514345406065928">Hijau</translation>
+<translation id="6018650639991193045">Padamkan sejarah penyemakan imbas, kuki, cache dan pelbagai lagi dalam tetapan Chrome</translation>
 <translation id="6025416945513303461"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /> (disegerakkan)</translation>
 <translation id="6028591542479806248">Urus peranti mudah alih dan pemberitahuan e-mel</translation>
 <translation id="6028833024483927901">Masakan Taraf Dunia</translation>
@@ -2766,6 +2771,7 @@
 <translation id="634500758737709758">Arah</translation>
 <translation id="6348220984832452017">Variasi Aktif</translation>
 <translation id="6349101878882523185">Pasang <ph name="APP_NAME" /></translation>
+<translation id="6351658970066645919">Padamkan Data Semakan Imbas</translation>
 <translation id="6353505687280762741">{COUNT,plural, =0{Tiada}=1{1 kata laluan (untuk <ph name="DOMAIN_LIST" />, disegerakkan)}=2{2 kata laluan (untuk <ph name="DOMAIN_LIST" />, disegerakkan)}other{# kata laluan (untuk <ph name="DOMAIN_LIST" />, disegerakkan)}}</translation>
 <translation id="6355392890578844978">Penyemak imbas ini tidak diurus oleh syarikat atau organisasi lain. Aktiviti pada peranti ini mungkin diurus di luar Chromium. <ph name="BEGIN_LINK" />Ketahui lebih lanjut<ph name="END_LINK" /></translation>
 <translation id="6358088212770985041">edit kaedah pembayaran</translation>
@@ -3493,6 +3499,7 @@
 <translation id="7682287625158474539">Penghantaran</translation>
 <translation id="7682451652090915298">Ragbi</translation>
 <translation id="7684683146428206649">Logam</translation>
+<translation id="7684817988830401358">Padamkan butang data semakan imbas, aktifkan butang untuk memadamkan sejarah penyemakan imbas, kuki, cache dan pelbagai lagi dalam tetapan Chrome anda</translation>
 <translation id="7684928361160505327">{0,plural, =1{<ph name="FILE_NAME" /> disekat disebabkan oleh dasar}other{<ph name="FILE_COUNT" /> fail disekat disebabkan oleh dasar}}</translation>
 <translation id="7687186412095877299">Mengisi borang pembayaran dengan kaedah pembayaran yang disimpan</translation>
 <translation id="7687305263118037187">Cuba semula tamat masa</translation>
@@ -3605,6 +3612,7 @@
 <translation id="7935318582918952113">DOM Distiller</translation>
 <translation id="7937163678541954811">CVC kad ini akan disulitkan dan disimpan pada peranti anda untuk semak keluar yang lebih pantas</translation>
 <translation id="7937554595067888181">Tamat tempoh pada <ph name="EXPIRATION_DATE_ABBR" /></translation>
+<translation id="7938490694919717008">Paparkan ganjaran dan manfaat yang tersedia untuk kad anda semasa menyemak keluar <ph name="CARD_BENEFIT_HELP_LINK_BEGIN" />Ketahui tentang manfaat kad<ph name="CARD_BENEFIT_HELP_LINK_END" /></translation>
 <translation id="7938958445268990899">Sijil pelayan masih belum sah.</translation>
 <translation id="7941628148012649605">Sampul Chou 4</translation>
 <translation id="794169214536209644">Kandi &amp; Gula-gula</translation>
@@ -3994,6 +4002,7 @@
 <translation id="8662463432865928030">Hartanah Komersial</translation>
 <translation id="8663226718884576429">Ringkasan Pesanan, <ph name="TOTAL_LABEL" />, Butiran Lanjut</translation>
 <translation id="8663909737634214500">Cakera Optik</translation>
+<translation id="8664326323360157684">Padamkan data semakan imbas...</translation>
 <translation id="8671519637524426245">Nilai <ph name="SECURE_DNS_SALT" /> tidak memenuhi keperluan saiz.</translation>
 <translation id="867224526087042813">Tandatangan</translation>
 <translation id="8672535691554698269">Rangkaian Komputer</translation>
@@ -4291,6 +4300,7 @@
 <translation id="949314938206378263">Anda meminta untuk melawat laman ini. Ibu bapa anda boleh membalas dalam Family Link.</translation>
 <translation id="950736567201356821">Tiga tebukan atas</translation>
 <translation id="961663415146723894">Ikatan bawah</translation>
+<translation id="961856697154696964">Padamkan data semakan imbas</translation>
 <translation id="961930410699694996">Lokasi dibenarkan pada masa ini</translation>
 <translation id="962484866189421427">Kandungan ini mungkin cuba memasang apl mengelirukan yang berpura-pura menjadi sesuatu yang lain atau mengumpulkan data yang mungkin digunakan untuk menjejak anda. <ph name="BEGIN_LINK" />Tunjukkan juga <ph name="END_LINK" /></translation>
 <translation id="963734905955638680">Berdasarkan undang-undang di rantau anda, Chromium meminta anda memilih enjin carian lalai anda. Enjin carian ini popular di rantau anda dan ditunjukkan dalam tertib rawak.</translation>
diff --git a/components/strings/components_strings_ne.xtb b/components/strings/components_strings_ne.xtb
index 62b06845..bff9135e 100644
--- a/components/strings/components_strings_ne.xtb
+++ b/components/strings/components_strings_ne.xtb
@@ -3233,7 +3233,7 @@
 <translation id="7236417832106250253"><ph name="PROGRESS_PERCENT" />% पूरा भयो | <ph name="ESTIMATED_REMAINING_TIME" /></translation>
 <translation id="7237166092326447040">उपहार र विशेष समारोहका सामग्रीहरू</translation>
 <translation id="7237454422623102448">सिस्टम सेटिङ</translation>
-<translation id="7237492777898608035">यो साइटका हकमा यो सन्देश फेरि नदेखाइयोस्</translation>
+<translation id="7237492777898608035">यो साइटका हकमा यो सन्देश फेरि नदेखाउनुहोस्</translation>
 <translation id="7240120331469437312">प्रमाणपत्र विषय वैकल्पिक नाम</translation>
 <translation id="7241863998525879494">अपेक्षा गर्न सकिने कुराहरू</translation>
 <translation id="7243010569062352439"><ph name="PASSWORDS" />; <ph name="SIGNIN_DATA" /></translation>
diff --git a/components/strings/components_strings_ru.xtb b/components/strings/components_strings_ru.xtb
index d9a476ad..6bafda4 100644
--- a/components/strings/components_strings_ru.xtb
+++ b/components/strings/components_strings_ru.xtb
@@ -1995,7 +1995,7 @@
 <translation id="4832961164064927107">Барбекю и гриль</translation>
 <translation id="4834250788637067901">Способы оплаты, адреса и специальные предложения из Google Pay</translation>
 <translation id="4840250757394056958">Посмотреть историю Chrome</translation>
-<translation id="484462545196658690">Выбрать автоматически</translation>
+<translation id="484462545196658690">Авто</translation>
 <translation id="484671803914931257">Получите скидку в магазине "<ph name="MERCHANT_NAME" />" и у других продавцов</translation>
 <translation id="484988093836683706">Использовать разблокировку устройства</translation>
 <translation id="4850886885716139402">Посмотреть</translation>
diff --git a/components/sync/base/features.cc b/components/sync/base/features.cc
index 6668d8c..2601845 100644
--- a/components/sync/base/features.cc
+++ b/components/sync/base/features.cc
@@ -209,12 +209,6 @@
              base::FEATURE_DISABLED_BY_DEFAULT);
 
 #if BUILDFLAG(IS_ANDROID)
-BASE_FEATURE(kSyncShowIdentityErrorsForSignedInUsers,
-             "SyncShowIdentityErrorsForSignedInUsers",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-#endif  // BUILDFLAG(IS_ANDROID)
-
-#if BUILDFLAG(IS_ANDROID)
 BASE_FEATURE(kWebApkBackupAndRestoreBackend,
              "WebApkBackupAndRestoreBackend",
              base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/components/sync/base/features.h b/components/sync/base/features.h
index cdb7203..fd3990e 100644
--- a/components/sync/base/features.h
+++ b/components/sync/base/features.h
@@ -194,11 +194,6 @@
 BASE_DECLARE_FEATURE(kSyncSchedulerUseWallClockTimer);
 
 #if BUILDFLAG(IS_ANDROID)
-// If enabled, shows identity errors for signed-in non-syncing users.
-BASE_DECLARE_FEATURE(kSyncShowIdentityErrorsForSignedInUsers);
-#endif  // BUILDFLAG(IS_ANDROID)
-
-#if BUILDFLAG(IS_ANDROID)
 // If enabled, WebAPK data will be synced for Backup&Restore purposes.
 BASE_DECLARE_FEATURE(kWebApkBackupAndRestoreBackend);
 #endif  // BUILDFLAG(IS_ANDROID)
diff --git a/components/sync/service/sync_service_impl_unittest.cc b/components/sync/service/sync_service_impl_unittest.cc
index 24e1697..128a01b0 100644
--- a/components/sync/service/sync_service_impl_unittest.cc
+++ b/components/sync/service/sync_service_impl_unittest.cc
@@ -687,7 +687,9 @@
 
   // Sign-in.
   SignInWithoutSyncConsent();
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
   ASSERT_TRUE(prefs()->GetBoolean(::prefs::kExplicitBrowserSignin));
+#endif
 
   // Registering CONTACT_INFO which includes addresses.
   InitializeService({{CONTACT_INFO, true}});
diff --git a/components/user_manager/user_manager_base.cc b/components/user_manager/user_manager_base.cc
index 7981173..cd7198a 100644
--- a/components/user_manager/user_manager_base.cc
+++ b/components/user_manager/user_manager_base.cc
@@ -39,6 +39,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
 #include "components/user_manager/known_user.h"
+#include "components/user_manager/multi_user/multi_user_sign_in_policy.h"
 #include "components/user_manager/user_directory_integrity_manager.h"
 #include "components/user_manager/user_manager_pref_names.h"
 #include "components/user_manager/user_names.h"
@@ -140,6 +141,33 @@
   return users_;
 }
 
+UserList UserManagerBase::GetUsersAllowedForMultiProfile() const {
+  // Supervised users are not allowed to use multi-profiles.
+  if (logged_in_users_.size() == 1 &&
+      primary_user_->GetType() != UserType::kRegular) {
+    return {};
+  }
+
+  // No user is allowed if the primary user policy forbids it.
+  if (GetMultiUserSignInPolicy(primary_user_) ==
+      MultiUserSignInPolicy::kNotAllowed) {
+    return {};
+  }
+
+  user_manager::UserList result;
+  for (user_manager::User* user : GetUsers()) {
+    if (user->GetType() == UserType::kRegular && !user->is_logged_in()) {
+      // Users with a policy that prevents them being added to a session will be
+      // shown in login UI but will be grayed out.
+      // Same applies to owner account (see http://crbug.com/385034).
+      result.push_back(user);
+    }
+  }
+
+  // Extract out users that are allowed on login screen.
+  return FindLoginAllowedUsersFrom(result);
+}
+
 UserList UserManagerBase::FindLoginAllowedUsersFrom(
     const UserList& users) const {
   bool show_users_on_signin;
diff --git a/components/user_manager/user_manager_base.h b/components/user_manager/user_manager_base.h
index c2f063f..cfffa38 100644
--- a/components/user_manager/user_manager_base.h
+++ b/components/user_manager/user_manager_base.h
@@ -105,6 +105,7 @@
   // UserManager implementation:
   void Shutdown() override;
   const UserList& GetUsers() const override;
+  UserList GetUsersAllowedForMultiProfile() const override;
   UserList FindLoginAllowedUsersFrom(const UserList& users) const final;
   const UserList& GetLoggedInUsers() const override;
   const UserList& GetLRULoggedInUsers() const override;
diff --git a/components/variations/service/limited_entropy_randomization.cc b/components/variations/service/limited_entropy_randomization.cc
index 5101821f..34c94a5 100644
--- a/components/variations/service/limited_entropy_randomization.cc
+++ b/components/variations/service/limited_entropy_randomization.cc
@@ -32,7 +32,8 @@
 
 // Converts a probability value (represented by numerator/denominator) to an
 // entropy value. Callers should ensure that both arguments are strictly
-// positive and that `numerator` <= `denominator`.
+// positive and that `numerator` <= `denominator`. This always returns a
+// non-negative number.
 double ConvertToBitsOfEntropy(uint64_t numerator, uint64_t denominator) {
   CHECK_GT(numerator, 0u);
   CHECK_LE(numerator, denominator);
@@ -117,6 +118,7 @@
         ConvertToBitsOfEntropy(num_slots_in_member, limited_layer.num_slots());
   }
 
+  bool includes_entropy_used_by_study = false;
   for (const Study& study : seed.study()) {
     if (study.has_layer() && study.layer().layer_id() == limited_layer.id()) {
       auto layer_member_id = study.layer().layer_member_id();
@@ -129,11 +131,24 @@
       if (entropy != entropy_used.end()) {
         // TODO(b/319681288): Consider mutual exclusivity among studies
         // referencing the same layer member from the study's filter values.
-        entropy->second += GetEntropyUsedByStudy(study);
+        double entropy_used_by_study = GetEntropyUsedByStudy(study);
+        if (entropy_used_by_study > 0) {
+          entropy->second += entropy_used_by_study;
+          includes_entropy_used_by_study = true;
+        }
       }
     }
   }
 
+  // The entropy used is zero when none of the studies constrained to the
+  // limited layer use any entropy. The results stored in `entropy_used` is
+  // not applicable here because they include entropy used from layer members.
+  // Those entropy usage only applies when studies that use entropy are
+  // constrained to these layer members.
+  if (!includes_entropy_used_by_study) {
+    return 0.0;
+  }
+
   double max_entropy_used = 0.0;
   for (const auto& entry : entropy_used) {
     // All layer members are included in the entropy calculation, including
diff --git a/components/variations/service/limited_entropy_randomization_unittest.cc b/components/variations/service/limited_entropy_randomization_unittest.cc
index e0fae3d..9d5e10b0 100644
--- a/components/variations/service/limited_entropy_randomization_unittest.cc
+++ b/components/variations/service/limited_entropy_randomization_unittest.cc
@@ -289,6 +289,24 @@
   auto test_layer =
       CreateLayer(kTestLayerId, /*num_slots=*/100, Layer::LIMITED,
                   {CreateLayerMember(kTestLayerMemberId, {{0, 49}})});
+  auto test_study_1 = CreateTestStudy(
+      CreateExperimentsWithTwoBitsOfEntropy(),
+      CreateLayerMemberReference(kTestLayerId, kTestLayerMemberId));
+  auto test_study_2 = CreateTestStudy(
+      {CreateExperiment(50)},
+      CreateLayerMemberReference(kTestLayerId, kTestLayerMemberId));
+  auto test_seed = CreateTestSeed({test_layer}, {test_study_1, test_study_2});
+
+  // Expecting 3 bits of total usage with 2 bits from `test_study_1`, 0 bit from
+  // `test_study_2`, and 1 bit from the layer member.
+  EXPECT_EQ(3, GetEntropyUsedByLimitedLayerForTesting(test_layer, test_seed));
+}
+
+TEST_F(LimitedEntropyRandomizationTest,
+       TestEntropyUsedByLimitedLayer_StudiesOfDifferentEntropyInLayerMember) {
+  auto test_layer =
+      CreateLayer(kTestLayerId, /*num_slots=*/100, Layer::LIMITED,
+                  {CreateLayerMember(kTestLayerMemberId, {{0, 49}})});
   auto test_seed = CreateTestSeed(
       {test_layer}, {CreateTestStudy(CreateExperimentsWithTwoBitsOfEntropy(),
                                      CreateLayerMemberReference(
@@ -368,8 +386,8 @@
   int default_layer_id = kTestLayerId + 1;
   auto test_limited_layer =
       CreateLayer(limited_layer_id, /*num_slots=*/100, Layer::LIMITED,
-                  {CreateLayerMember(kTestLayerMemberId, {{0, 49}}),
-                   CreateLayerMember(kTestLayerMemberId, {{50, 74}}),
+                  {CreateLayerMember(kTestLayerMemberId + 2, {{0, 49}}),
+                   CreateLayerMember(kTestLayerMemberId + 1, {{50, 74}}),
                    CreateLayerMember(kTestLayerMemberId, {{75, 99}})});
   auto test_default_layer =
       CreateLayer(default_layer_id, /*num_slots=*/100, Layer::DEFAULT,
@@ -383,9 +401,31 @@
            CreateExperimentsWithTwoBitsOfEntropy(),
            CreateLayerMemberReference(default_layer_id, kTestLayerMemberId))});
 
-  // 2 bits from the layer member, although it's unused.
+  // Entropy used is zero since the layer members in the limited layer is
+  // unused (the studies in `test_seed` is not constrained to a limited layer).
   EXPECT_EQ(
-      2, GetEntropyUsedByLimitedLayerForTesting(test_limited_layer, test_seed));
+      0, GetEntropyUsedByLimitedLayerForTesting(test_limited_layer, test_seed));
+}
+
+TEST_F(
+    LimitedEntropyRandomizationTest,
+    TestEntropyUsedByLimitedLayer_NoReferencingStudiesWithGoogleExperimentID) {
+  auto test_limited_layer =
+      CreateLayer(kTestLayerId, /*num_slots=*/100, Layer::LIMITED,
+                  {CreateLayerMember(kTestLayerMemberId + 2, {{0, 49}}),
+                   CreateLayerMember(kTestLayerMemberId + 1, {{50, 74}}),
+                   CreateLayerMember(kTestLayerMemberId, {{75, 99}})});
+  auto test_seed = CreateTestSeed(
+      {test_limited_layer},
+      {CreateTestStudy(
+          {CreateExperiment(1), CreateExperiment(1)},
+          CreateLayerMemberReference(kTestLayerId, kTestLayerMemberId))});
+
+  // Without Google experiment IDs, a study that is constrained to a limited
+  // layer does not use entropy. Entropy usage is zero if none of the studies in
+  // any layer members use entropy.
+  EXPECT_EQ(
+      0, GetEntropyUsedByLimitedLayerForTesting(test_limited_layer, test_seed));
 }
 
 TEST_F(LimitedEntropyRandomizationTest,
diff --git a/components/visited_url_ranking/DEPS b/components/visited_url_ranking/DEPS
index ffe5cc77..0f87da3 100644
--- a/components/visited_url_ranking/DEPS
+++ b/components/visited_url_ranking/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
+  "+components/keyed_service/core",
   "+components/sync_device_info",
 ]
diff --git a/components/visited_url_ranking/public/BUILD.gn b/components/visited_url_ranking/public/BUILD.gn
index 05bcaa43..c35219c5 100644
--- a/components/visited_url_ranking/public/BUILD.gn
+++ b/components/visited_url_ranking/public/BUILD.gn
@@ -4,12 +4,16 @@
 
 source_set("public") {
   sources = [
+    "fetch_options.cc",
+    "fetch_options.h",
     "url_visit.cc",
     "url_visit.h",
+    "visited_url_ranking_service.h",
   ]
 
   deps = [
     "//base",
+    "//components/keyed_service/core",
     "//components/sync_device_info",
     "//url",
   ]
diff --git a/components/visited_url_ranking/public/fetch_options.cc b/components/visited_url_ranking/public/fetch_options.cc
new file mode 100644
index 0000000..4e426f4
--- /dev/null
+++ b/components/visited_url_ranking/public/fetch_options.cc
@@ -0,0 +1,38 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/visited_url_ranking/public/fetch_options.h"
+
+#include <map>
+
+#include "base/check.h"
+#include "base/containers/enum_set.h"
+
+namespace visited_url_ranking {
+
+FetchOptions::FetchOptions(std::map<Fetcher, FetchSources> fetcher_sources_arg,
+                           base::Time begin_time_arg)
+    : fetcher_sources(std::move(fetcher_sources_arg)),
+      begin_time(begin_time_arg) {
+  DCHECK(!fetcher_sources.empty());
+  DCHECK(!begin_time.is_null());
+}
+
+FetchOptions::~FetchOptions() = default;
+
+FetchOptions::FetchOptions(FetchOptions&& other) = default;
+
+FetchOptions& FetchOptions::operator=(FetchOptions&& other) = default;
+
+// static
+FetchOptions FetchOptions::CreateDefaultFetchOptionsForTabResumption() {
+  return FetchOptions(
+      {
+          {Fetcher::kHistory, FetchOptions::kOriginSources},
+          {Fetcher::kSession, FetchOptions::kOriginSources},
+      },
+      base::Time::Now() - base::Days(1));
+}
+
+}  // namespace visited_url_ranking
diff --git a/components/visited_url_ranking/public/fetch_options.h b/components/visited_url_ranking/public/fetch_options.h
new file mode 100644
index 0000000..f8135d2
--- /dev/null
+++ b/components/visited_url_ranking/public/fetch_options.h
@@ -0,0 +1,55 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VISITED_URL_RANKING_PUBLIC_FETCH_OPTIONS_H_
+#define COMPONENTS_VISITED_URL_RANKING_PUBLIC_FETCH_OPTIONS_H_
+
+#include <map>
+
+#include "base/containers/enum_set.h"
+#include "base/time/time.h"
+#include "components/visited_url_ranking/public/url_visit.h"
+
+namespace visited_url_ranking {
+
+// The currently supported URL visit data fetchers that may participate in a
+// fetch request.
+enum class Fetcher {
+  kTabModel = 0,
+  kSession = 1,
+  kHistory = 2,
+};
+
+// The options that may be specified when fetching URL visit data.
+struct FetchOptions {
+  using Source = URLVisit::Source;
+  using FetchSources =
+      base::EnumSet<Source, Source::kNotApplicable, Source::kRemote>;
+  FetchOptions(std::map<Fetcher, FetchSources> fetcher_sources,
+               base::Time begin_time);
+  FetchOptions(const FetchOptions&) = delete;
+  FetchOptions(FetchOptions&& other);
+  FetchOptions& operator=(FetchOptions&& other);
+  ~FetchOptions();
+
+  // The set of sources that correspond to an origin.
+  static constexpr FetchSources kOriginSources = {Source::kLocal,
+                                                  Source::kRemote};
+
+  // Returns the default fetch options for tab resumption use cases.
+  static FetchOptions CreateDefaultFetchOptionsForTabResumption();
+
+  // The set of data fetchers that should participate in the data fetching and
+  // computation of URLVisit data, including their data source characteristics.
+  std::map<Fetcher, FetchSources> fetcher_sources;
+
+  // The earliest visit associated time to consider when fetching data. Each
+  // fetcher may leverage this time differently depending on the timestamps that
+  // are supported by their associated sources.
+  base::Time begin_time;
+};
+
+}  // namespace visited_url_ranking
+
+#endif  // COMPONENTS_VISITED_URL_RANKING_PUBLIC_FETCH_OPTIONS_H_
diff --git a/components/visited_url_ranking/public/url_visit.h b/components/visited_url_ranking/public/url_visit.h
index 60723ec..f441623 100644
--- a/components/visited_url_ranking/public/url_visit.h
+++ b/components/visited_url_ranking/public/url_visit.h
@@ -14,14 +14,15 @@
 
 namespace visited_url_ranking {
 
-// Whether the visit was sourced from local or remote data.
-enum class Source { kLocal, kRemote };
-
 /**
  * A wrapper data type that encompasses URL visit related data from various
  * sources.
  */
 struct URLVisit {
+  // If applicable, whether the visit data was sourced from a specific origin
+  // (local or remote).
+  enum class Source { kNotApplicable = 0, kLocal = 1, kRemote = 2 };
+
   URLVisit();
   URLVisit(const URLVisit&) = delete;
   URLVisit(URLVisit&& other);
diff --git a/components/visited_url_ranking/public/visited_url_ranking_service.h b/components/visited_url_ranking/public/visited_url_ranking_service.h
new file mode 100644
index 0000000..dbffab51
--- /dev/null
+++ b/components/visited_url_ranking/public/visited_url_ranking_service.h
@@ -0,0 +1,72 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VISITED_URL_RANKING_PUBLIC_VISITED_URL_RANKING_SERVICE_H_
+#define COMPONENTS_VISITED_URL_RANKING_PUBLIC_VISITED_URL_RANKING_SERVICE_H_
+
+#include <string>
+#include <vector>
+
+#include "base/functional/callback_forward.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "components/visited_url_ranking/public/fetch_options.h"
+#include "components/visited_url_ranking/public/url_visit.h"
+
+namespace visited_url_ranking {
+
+const char kTabResumptionRankerKey[] = "tab_resumption_ranker";
+
+// Settings leveraged for ranking `URLVisit` objects.
+struct Config {
+  // A value that identifies the type of model to run.
+  std::string key;
+};
+
+enum class ResultStatus { kError = 0, kSuccess = 1 };
+
+// Provides APIs suitable for combining URL Visit data across various data
+// sources and their subsequent ranking via a model.
+// Example usage:
+//   auto on_rank_callback = base::BindOnce([](ResultStatus status,
+//       std::vector<URLVisit> visits) {
+//     if(status == ResultStatus::kSuccess) {
+//       // Client logic placeholder.
+//     }
+//   });
+//   auto on_fetch_callback = base::BindOnce([](OnceCallback on_rank_callback,
+//       ResultStatus status, std::vector<URLVisit> visits) {
+//     if(status == ResultStatus::kSuccess) {
+//       // Client logic placeholder (e.g. filtering, caching, etc.).
+//       Config config = {.key = kTabResumptionRankerKey};
+//       GetService()->RankVisits(config, std::move(visits),
+//           std::move(on_rank_callback));
+//     }
+//   }, std::move(on_rank_callback));
+//   GetService()->Fetch(CreateTabResumptionDefaultFetchOptions(),
+//     std::move(on_fetch_callback))
+//
+class VisitedURLRankingService : public KeyedService {
+ public:
+  VisitedURLRankingService();
+  ~VisitedURLRankingService() override = default;
+
+  // Computes `URLVisit` objects based on a series of `options` from one or more
+  // data providers and triggers the `callback` with such data.
+  using GetURLVisitsCallback =
+      base::OnceCallback<void(ResultStatus, std::vector<URLVisit>)>;
+  virtual void FetchURLVisits(const FetchOptions& options,
+                              GetURLVisitsCallback callback) = 0;
+
+  using RankVisitsCallback =
+      base::OnceCallback<void(ResultStatus, std::vector<URLVisit>)>;
+  // Ranks a collection of `URLVisit` objects based on a client specified
+  // strategy.
+  virtual void RankVisits(const Config& config,
+                          std::vector<URLVisit> visits,
+                          RankVisitsCallback callback) = 0;
+};
+
+}  // namespace visited_url_ranking
+
+#endif  // COMPONENTS_VISITED_URL_RANKING_PUBLIC_VISITED_URL_RANKING_SERVICE_H_
diff --git a/components/viz/common/resources/shared_bitmap.cc b/components/viz/common/resources/shared_bitmap.cc
index b0554311..5f854ff 100644
--- a/components/viz/common/resources/shared_bitmap.cc
+++ b/components/viz/common/resources/shared_bitmap.cc
@@ -19,7 +19,7 @@
 
 // static
 SharedBitmapId SharedBitmap::GenerateId() {
-  return gpu::Mailbox::GenerateLegacyMailboxForSharedBitmap();
+  return gpu::Mailbox::GenerateLegacySharedBitmapMailbox();
 }
 
 }  // namespace viz
diff --git a/components/viz/service/display_embedder/output_presenter.cc b/components/viz/service/display_embedder/output_presenter.cc
index 2ed1445..e99825fd5 100644
--- a/components/viz/service/display_embedder/output_presenter.cc
+++ b/components/viz/service/display_embedder/output_presenter.cc
@@ -154,10 +154,4 @@
   deps_->GetSharedImageManager()->SetPurgeable(mailbox_, false);
 }
 
-std::unique_ptr<OutputPresenter::Image> OutputPresenter::AllocateSingleImage(
-    gfx::ColorSpace color_space,
-    gfx::Size image_size) {
-  return nullptr;
-}
-
 }  // namespace viz
diff --git a/components/viz/service/display_embedder/output_presenter.h b/components/viz/service/display_embedder/output_presenter.h
index 472e666..da0121b 100644
--- a/components/viz/service/display_embedder/output_presenter.h
+++ b/components/viz/service/display_embedder/output_presenter.h
@@ -111,11 +111,6 @@
       gfx::ColorSpace color_space,
       gfx::Size image_size,
       size_t num_images) = 0;
-  // This function exists because the Fuchsia call to 'AllocateImages' does not
-  // support single image allocation.
-  virtual std::unique_ptr<Image> AllocateSingleImage(
-      gfx::ColorSpace color_space,
-      gfx::Size image_size);
   virtual void Present(SwapCompletionCallback completion_callback,
                        BufferPresentedCallback presentation_callback,
                        gfx::FrameData data) = 0;
diff --git a/components/viz/service/display_embedder/output_presenter_gl.cc b/components/viz/service/display_embedder/output_presenter_gl.cc
index 3e80ecf1..b018f28 100644
--- a/components/viz/service/display_embedder/output_presenter_gl.cc
+++ b/components/viz/service/display_embedder/output_presenter_gl.cc
@@ -115,23 +115,15 @@
 
 }  // namespace
 
-// static
-const uint32_t OutputPresenterGL::kDefaultSharedImageUsage =
-    gpu::SHARED_IMAGE_USAGE_SCANOUT | gpu::SHARED_IMAGE_USAGE_DISPLAY_READ |
-    gpu::SHARED_IMAGE_USAGE_DISPLAY_WRITE |
-    gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT;
-
 OutputPresenterGL::OutputPresenterGL(
     scoped_refptr<gl::Presenter> presenter,
     SkiaOutputSurfaceDependency* deps,
     gpu::SharedImageFactory* factory,
-    gpu::SharedImageRepresentationFactory* representation_factory,
-    uint32_t shared_image_usage)
+    gpu::SharedImageRepresentationFactory* representation_factory)
     : presenter_(presenter),
       dependency_(deps),
       shared_image_factory_(factory),
-      shared_image_representation_factory_(representation_factory),
-      shared_image_usage_(shared_image_usage) {}
+      shared_image_representation_factory_(representation_factory) {}
 
 OutputPresenterGL::~OutputPresenterGL() = default;
 
@@ -203,13 +195,17 @@
 OutputPresenterGL::AllocateImages(gfx::ColorSpace color_space,
                                   gfx::Size image_size,
                                   size_t num_images) {
+  const uint32_t usage = gpu::SHARED_IMAGE_USAGE_SCANOUT |
+                         gpu::SHARED_IMAGE_USAGE_DISPLAY_READ |
+                         gpu::SHARED_IMAGE_USAGE_DISPLAY_WRITE |
+                         gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT;
+
   std::vector<std::unique_ptr<Image>> images;
   for (size_t i = 0; i < num_images; ++i) {
     auto image = std::make_unique<PresenterImageGL>(
         shared_image_factory_, shared_image_representation_factory_,
         dependency_);
-    if (!image->Initialize(image_size, color_space, image_format_,
-                           shared_image_usage_)) {
+    if (!image->Initialize(image_size, color_space, image_format_, usage)) {
       DLOG(ERROR) << "Failed to initialize image.";
       return {};
     }
@@ -219,19 +215,6 @@
   return images;
 }
 
-std::unique_ptr<OutputPresenter::Image> OutputPresenterGL::AllocateSingleImage(
-    gfx::ColorSpace color_space,
-    gfx::Size image_size) {
-  auto image = std::make_unique<PresenterImageGL>(
-      shared_image_factory_, shared_image_representation_factory_, dependency_);
-  if (!image->Initialize(image_size, color_space, image_format_,
-                         shared_image_usage_)) {
-    DLOG(ERROR) << "Failed to initialize image.";
-    return nullptr;
-  }
-  return image;
-}
-
 void OutputPresenterGL::Present(SwapCompletionCallback completion_callback,
                                 BufferPresentedCallback presentation_callback,
                                 gfx::FrameData data) {
diff --git a/components/viz/service/display_embedder/output_presenter_gl.h b/components/viz/service/display_embedder/output_presenter_gl.h
index 0bf1e74..f881a8a 100644
--- a/components/viz/service/display_embedder/output_presenter_gl.h
+++ b/components/viz/service/display_embedder/output_presenter_gl.h
@@ -24,14 +24,11 @@
 
 class VIZ_SERVICE_EXPORT OutputPresenterGL : public OutputPresenter {
  public:
-  static const uint32_t kDefaultSharedImageUsage;
-
   OutputPresenterGL(
       scoped_refptr<gl::Presenter> presenter,
       SkiaOutputSurfaceDependency* deps,
       gpu::SharedImageFactory* factory,
-      gpu::SharedImageRepresentationFactory* representation_factory,
-      uint32_t shared_image_usage = kDefaultSharedImageUsage);
+      gpu::SharedImageRepresentationFactory* representation_factory);
   ~OutputPresenterGL() override;
 
   // OutputPresenter implementation:
@@ -45,8 +42,6 @@
       gfx::ColorSpace color_space,
       gfx::Size image_size,
       size_t num_images) final;
-  std::unique_ptr<Image> AllocateSingleImage(gfx::ColorSpace color_space,
-                                             gfx::Size image_size) final;
   void Present(SwapCompletionCallback completion_callback,
                BufferPresentedCallback presentation_callback,
                gfx::FrameData data) final;
@@ -75,7 +70,6 @@
   const raw_ptr<gpu::SharedImageFactory> shared_image_factory_;
   const raw_ptr<gpu::SharedImageRepresentationFactory>
       shared_image_representation_factory_;
-  uint32_t shared_image_usage_;
 
 #if BUILDFLAG(IS_APPLE)
   gfx::CALayerResult ca_layer_error_code_ = gfx::kCALayerSuccess;
diff --git a/components/web_package/BUILD.gn b/components/web_package/BUILD.gn
index 75a9c4f..00ece33 100644
--- a/components/web_package/BUILD.gn
+++ b/components/web_package/BUILD.gn
@@ -8,6 +8,7 @@
   sources = [
     "input_reader.cc",
     "input_reader.h",
+    "signed_web_bundles/constants.h",
     "signed_web_bundles/integrity_block_parser.cc",
     "signed_web_bundles/integrity_block_parser.h",
     "signed_web_bundles/signed_web_bundle_id.cc",
diff --git a/components/web_package/signed_web_bundles/constants.h b/components/web_package/signed_web_bundles/constants.h
new file mode 100644
index 0000000..1d28db0
--- /dev/null
+++ b/components/web_package/signed_web_bundles/constants.h
@@ -0,0 +1,18 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_WEB_PACKAGE_SIGNED_WEB_BUNDLES_CONSTANTS_H_
+#define COMPONENTS_WEB_PACKAGE_SIGNED_WEB_BUNDLES_CONSTANTS_H_
+
+#include <string_view>
+
+namespace web_package {
+
+// CBOR attribute name for Ed25519 public keys.
+inline constexpr std::string_view kEd25519PublicKeyAttributeName =
+    "ed25519PublicKey";
+
+}  // namespace web_package
+
+#endif  // COMPONENTS_WEB_PACKAGE_SIGNED_WEB_BUNDLES_CONSTANTS_H_
diff --git a/components/web_package/signed_web_bundles/integrity_block_parser.cc b/components/web_package/signed_web_bundles/integrity_block_parser.cc
index c2845148..64dfaf8 100644
--- a/components/web_package/signed_web_bundles/integrity_block_parser.cc
+++ b/components/web_package/signed_web_bundles/integrity_block_parser.cc
@@ -14,6 +14,7 @@
 #include "base/types/expected_macros.h"
 #include "components/web_package/input_reader.h"
 #include "components/web_package/mojom/web_bundle_parser.mojom.h"
+#include "components/web_package/signed_web_bundles/constants.h"
 #include "components/web_package/signed_web_bundles/ed25519_public_key.h"
 #include "components/web_package/signed_web_bundles/ed25519_signature.h"
 #include "components/web_package/web_bundle_parser.h"
@@ -23,17 +24,19 @@
 
 namespace {
 
+using SignatureType = mojom::SignatureInfo::Tag;
+
 constexpr auto kPublicKeyAttributeNameToSignatureType =
-    base::MakeFixedFlatMap<std::string_view, mojom::SignatureInfo::Tag>({
+    base::MakeFixedFlatMap<std::string_view, SignatureType>({
         // clang-format off
-        {"ed25519PublicKey", mojom::SignatureInfo::Tag::kEd25519},
+        {kEd25519PublicKeyAttributeName, SignatureType::kEd25519},
         // clang-format on
     });
 
-mojom::SignatureInfo::Tag GetSignatureType(std::string_view attribute_name) {
+SignatureType GetSignatureType(std::string_view attribute_name) {
   auto* signature_type =
       base::FindOrNull(kPublicKeyAttributeNameToSignatureType, attribute_name);
-  return signature_type ? *signature_type : mojom::SignatureInfo::Tag::kUnknown;
+  return signature_type ? *signature_type : SignatureType::kUnknown;
 }
 
 }  // namespace
@@ -295,13 +298,11 @@
   offset_in_stream += input.CurrentOffset();
 
   switch (GetSignatureType(*attribute_name)) {
-    case mojom::SignatureInfo::Tag::kEd25519: {
+    case SignatureType::kEd25519: {
       signature_stack_entry->signature_info =
           mojom::SignatureInfo::NewEd25519(mojom::SignatureInfoEd25519::New());
-
-      break;
-    }
-    case mojom::SignatureInfo::Tag::kUnknown: {
+    } break;
+    case SignatureType::kUnknown: {
       // Unknown signature cipher type.
       if (signature_stack_.size() == 0) {
         RunErrorCallback("Unknown cipher type of the first signature.");
@@ -310,9 +311,7 @@
 
       signature_stack_entry->signature_info =
           mojom::SignatureInfo::NewUnknown(mojom::SignatureInfoUnknown::New());
-
-      break;
-    }
+    } break;
   }
   data_source_->get()->Read(
       offset_in_stream, *public_key_value_size,
@@ -335,14 +334,13 @@
 
   auto& signature_info = signature_stack_entry->signature_info;
   switch (signature_info->which()) {
-    case mojom::SignatureInfo::Tag::kEd25519: {
+    case SignatureType::kEd25519: {
       ASSIGN_OR_RETURN(
           signature_stack_entry->signature_info->get_ed25519()->public_key,
           Ed25519PublicKey::Create(*public_key_bytes),
           [&](std::string error) { RunErrorCallback(std::move(error)); });
-      break;
-    }
-    case mojom::SignatureInfo::Tag::kUnknown:
+    } break;
+    case SignatureType::kUnknown:
       break;
   }
 
@@ -382,7 +380,7 @@
 
   auto& signature_info = signature_stack_entry->signature_info;
   switch (signature_info->which()) {
-    case mojom::SignatureInfo::Tag::kEd25519: {
+    case SignatureType::kEd25519: {
       if (*signature_length != ED25519_SIGNATURE_LEN) {
         RunErrorCallback(base::StringPrintf(
             "The signature does not have the correct length, "
@@ -391,7 +389,7 @@
         return;
       }
     } break;
-    case mojom::SignatureInfo::Tag::kUnknown:
+    case SignatureType::kUnknown:
       break;
   }
 
@@ -420,13 +418,13 @@
 
   auto& signature_info = signature_stack_entry->signature_info;
   switch (signature_info->which()) {
-    case mojom::SignatureInfo::Tag::kEd25519: {
+    case SignatureType::kEd25519: {
       ASSIGN_OR_RETURN(
           signature_stack_entry->signature_info->get_ed25519()->signature,
           Ed25519Signature::Create(*signature_bytes),
           [&](std::string error) { RunErrorCallback(std::move(error)); });
     } break;
-    case mojom::SignatureInfo::Tag::kUnknown:
+    case SignatureType::kUnknown:
       break;
   }
 
diff --git a/components/web_package/signed_web_bundles/signed_web_bundle_signature_stack_entry.cc b/components/web_package/signed_web_bundles/signed_web_bundle_signature_stack_entry.cc
index e4c6cfd..593f5d45 100644
--- a/components/web_package/signed_web_bundles/signed_web_bundle_signature_stack_entry.cc
+++ b/components/web_package/signed_web_bundles/signed_web_bundle_signature_stack_entry.cc
@@ -4,9 +4,6 @@
 
 #include "components/web_package/signed_web_bundles/signed_web_bundle_signature_stack_entry.h"
 
-#include "components/web_package/mojom/web_bundle_parser.mojom.h"
-#include "components/web_package/signed_web_bundles/ed25519_public_key.h"
-
 namespace web_package {
 
 SignedWebBundleSignatureStackEntry::SignedWebBundleSignatureStackEntry(
diff --git a/components/web_package/signed_web_bundles/signed_web_bundle_signature_verifier_unittest.cc b/components/web_package/signed_web_bundles/signed_web_bundle_signature_verifier_unittest.cc
index 5a3de86..f3f9e65 100644
--- a/components/web_package/signed_web_bundles/signed_web_bundle_signature_verifier_unittest.cc
+++ b/components/web_package/signed_web_bundles/signed_web_bundle_signature_verifier_unittest.cc
@@ -11,10 +11,13 @@
 
 #include "base/base_paths.h"
 #include "base/containers/extend.h"
+#include "base/containers/map_util.h"
+#include "base/containers/to_vector.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
+#include "base/functional/overloaded.h"
 #include "base/path_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
@@ -24,6 +27,7 @@
 #include "base/test/test_future.h"
 #include "components/cbor/values.h"
 #include "components/web_package/mojom/web_bundle_parser.mojom.h"
+#include "components/web_package/signed_web_bundles/constants.h"
 #include "components/web_package/signed_web_bundles/ed25519_public_key.h"
 #include "components/web_package/signed_web_bundles/signed_web_bundle_integrity_block.h"
 #include "components/web_package/test_support/signed_web_bundles/web_bundle_signer.h"
@@ -87,26 +91,35 @@
     0xc5, 0xcf, 0x04, 0x15, 0xdb, 0x63, 0x59, 0xb2, 0xff, 0xee, 0x13, 0x93,
     0x2c, 0x99, 0x68, 0x0d};
 
+using PublicKey = absl::variant<Ed25519PublicKey>;
+
+mojom::SignatureInfoPtr CreateSignatureInfo(
+    const Ed25519PublicKey& public_key,
+    base::span<const uint8_t> signature) {
+  auto ed25519_signature_info = mojom::SignatureInfoEd25519::New();
+  ed25519_signature_info->public_key = public_key;
+  ed25519_signature_info->signature =
+      *web_package::Ed25519Signature::Create(signature);
+  return mojom::SignatureInfo::NewEd25519(std::move(ed25519_signature_info));
+}
+
 mojom::BundleIntegrityBlockSignatureStackEntryPtr MakeSignatureStackEntry(
-    base::span<const uint8_t> public_key,
+    const PublicKey& public_key,
     base::span<const uint8_t> signature,
     base::span<const uint8_t> complete_entry_cbor,
     base::span<const uint8_t> attributes_cbor) {
   auto raw_signature_stack_entry =
       mojom::BundleIntegrityBlockSignatureStackEntry::New();
 
-  auto ed25519_signature_info = mojom::SignatureInfoEd25519::New();
-  ed25519_signature_info->public_key =
-      *web_package::Ed25519PublicKey::Create(public_key);
-  ed25519_signature_info->signature =
-      *web_package::Ed25519Signature::Create(signature);
-
   raw_signature_stack_entry->complete_entry_cbor = std::vector(
       std::begin(complete_entry_cbor), std::end(complete_entry_cbor));
   raw_signature_stack_entry->attributes_cbor =
       std::vector(std::begin(attributes_cbor), std::end(attributes_cbor));
   raw_signature_stack_entry->signature_info =
-      mojom::SignatureInfo::NewEd25519(std::move(ed25519_signature_info));
+      absl::visit(base::Overloaded{[&](const auto& public_key) {
+                    return CreateSignatureInfo(public_key, signature);
+                  }},
+                  public_key);
   return raw_signature_stack_entry;
 }
 
@@ -143,9 +156,9 @@
 
   std::vector<mojom::BundleIntegrityBlockSignatureStackEntryPtr>
       raw_signature_stack;
-  raw_signature_stack.push_back(
-      MakeSignatureStackEntry(kEd25519PublicKey, kEd25519Signature,
-                              kCompleteEntryCbor, kAttributesCbor));
+  raw_signature_stack.push_back(MakeSignatureStackEntry(
+      Ed25519PublicKey::Create(base::span(kEd25519PublicKey)),
+      kEd25519Signature, kCompleteEntryCbor, kAttributesCbor));
 
   auto raw_integrity_block = mojom::BundleIntegrityBlock::New();
   raw_integrity_block->size = 135;
@@ -250,21 +263,36 @@
   }
 
   base::expected<SignedWebBundleIntegrityBlock, std::string>
-  CreateParsedIntegrityBlock(const cbor::Value& integrity_block,
-                             size_t integrity_block_size) {
+  CreateParsedIntegrityBlock(
+      const cbor::Value& integrity_block,
+      size_t integrity_block_size,
+      const std::vector<WebBundleSigner::KeyPair>& key_pairs) {
     std::vector<mojom::BundleIntegrityBlockSignatureStackEntryPtr>
         raw_signature_stack;
-    for (const auto& signature_stack_entry :
-         integrity_block.GetArray()[2].GetArray()) {
+    const auto& signature_stack = integrity_block.GetArray()[2].GetArray();
+    for (size_t idx = 0; idx < signature_stack.size(); idx++) {
+      const auto& signature_stack_entry = signature_stack[idx];
+      const auto& key_pair = key_pairs[idx];
+
       auto complete_entry_cbor = *cbor::Writer::Write(signature_stack_entry);
       const auto& attributes = signature_stack_entry.GetArray()[0];
       auto attributes_cbor = *cbor::Writer::Write(attributes);
-      const auto& public_key = attributes.GetMap()
-                                   .at(cbor::Value("ed25519PublicKey"))
-                                   .GetBytestring();
+
       const auto& signature =
           signature_stack_entry.GetArray()[1].GetBytestring();
 
+      auto public_key = absl::visit(
+          base::Overloaded{[&](const WebBundleSigner::Ed25519KeyPair& key_pair)
+                               -> PublicKey {
+            auto ed25519_public_key = *Ed25519PublicKey::Create(
+                base::FindOrNull(attributes.GetMap(),
+                                 cbor::Value(kEd25519PublicKeyAttributeName))
+                    ->GetBytestring());
+            EXPECT_EQ(ed25519_public_key, key_pair.public_key);
+            return ed25519_public_key;
+          }},
+          key_pair);
+
       raw_signature_stack.push_back(MakeSignatureStackEntry(
           public_key, signature, complete_entry_cbor, attributes_cbor));
     }
@@ -283,14 +311,15 @@
 };
 
 TEST_P(SignedWebBundleSignatureVerifierTest, VerifySignatures) {
+  const auto& key_pairs = std::get<0>(GetParam());
   auto [signed_web_bundle, integrity_block, integrity_block_size] =
-      CreateSignedWebBundle(std::get<0>(GetParam()));
+      CreateSignedWebBundle(key_pairs);
   base::FilePath signed_web_bundle_path =
       WriteSignedWebBundleToDisk(signed_web_bundle);
   auto file = MakeWebBundleFile(signed_web_bundle_path);
-  ASSERT_OK_AND_ASSIGN(
-      auto parsed_integrity_block,
-      CreateParsedIntegrityBlock(integrity_block, integrity_block_size));
+  ASSERT_OK_AND_ASSIGN(auto parsed_integrity_block,
+                       CreateParsedIntegrityBlock(
+                           integrity_block, integrity_block_size, key_pairs));
 
   base::test::TestFuture<std::optional<SignedWebBundleSignatureVerifier::Error>>
       future;
diff --git a/components/web_package/test_support/signed_web_bundles/web_bundle_signer.cc b/components/web_package/test_support/signed_web_bundles/web_bundle_signer.cc
index da957b0..cb6d16b 100644
--- a/components/web_package/test_support/signed_web_bundles/web_bundle_signer.cc
+++ b/components/web_package/test_support/signed_web_bundles/web_bundle_signer.cc
@@ -9,6 +9,7 @@
 #include "base/functional/overloaded.h"
 #include "components/cbor/values.h"
 #include "components/cbor/writer.h"
+#include "components/web_package/signed_web_bundles/constants.h"
 #include "components/web_package/signed_web_bundles/ed25519_public_key.h"
 #include "components/web_package/signed_web_bundles/signed_web_bundle_utils.h"
 #include "crypto/secure_hash.h"
@@ -25,10 +26,16 @@
 using IntegritySignatureErrorsForTesting =
     WebBundleSigner::IntegritySignatureErrorsForTesting;
 
+using PublicKey = absl::variant<Ed25519PublicKey>;
+
 cbor::Value CreateSignatureStackEntryAttributes(
-    const Ed25519PublicKey& public_key,
+    const PublicKey& public_key,
     IntegritySignatureErrorsForTesting errors_for_testing = {}) {
-  std::vector<uint8_t> public_key_bytes = base::ToVector(public_key.bytes());
+  std::vector<uint8_t> public_key_bytes =
+      absl::visit(base::Overloaded{[](const auto& public_key) {
+                    return base::ToVector(public_key.bytes());
+                  }},
+                  public_key);
   if (errors_for_testing.Has(
           IntegritySignatureErrorForTesting::kInvalidPublicKeyLength)) {
     public_key_bytes.push_back(42);
@@ -49,8 +56,11 @@
       attributes[cbor::Value("ed25519")] = cbor::Value(public_key_bytes);
 
     } else {
-      attributes[cbor::Value("ed25519PublicKey")] =
-          cbor::Value(public_key_bytes);
+      attributes[cbor::Value(
+          absl::visit(base::Overloaded{[](const Ed25519PublicKey&) {
+                        return kEd25519PublicKeyAttributeName;
+                      }},
+                      public_key))] = cbor::Value(public_key_bytes);
     }
   }
 
@@ -63,7 +73,7 @@
 }
 
 cbor::Value CreateSignatureStackEntry(
-    const Ed25519PublicKey& public_key,
+    const PublicKey& public_key,
     std::vector<uint8_t> signature,
     IntegritySignatureErrorsForTesting errors_for_testing = {}) {
   if (errors_for_testing.Has(
diff --git a/components/webauthn/core/browser/passkey_model.h b/components/webauthn/core/browser/passkey_model.h
index df084ab..133128ee 100644
--- a/components/webauthn/core/browser/passkey_model.h
+++ b/components/webauthn/core/browser/passkey_model.h
@@ -17,6 +17,10 @@
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/webauthn/core/browser/passkey_model_change.h"
 
+namespace base {
+class Location;
+}
+
 namespace sync_pb {
 class WebauthnCredentialSpecifics;
 }
@@ -99,9 +103,11 @@
 
   // Deletes the passkey with the given `credential_id`. If the passkey is the
   // head of the shadow chain, then all passkeys for the same (user id, rp id)
-  // are deleted as well.
-  // Returns true if a passkey was found and deleted, false otherwise.
-  virtual bool DeletePasskey(const std::string& credential_id) = 0;
+  // are deleted as well. `location` is used for logging purposes and
+  // investigations. Returns true if a passkey was found and deleted, false
+  // otherwise.
+  virtual bool DeletePasskey(const std::string& credential_id,
+                             const base::Location& location) = 0;
 
   // Updates attributes of the passkey with the given `credential_id`. Returns
   // true if the credential was found and updated, false otherwise.
diff --git a/components/webauthn/core/browser/passkey_sync_bridge.cc b/components/webauthn/core/browser/passkey_sync_bridge.cc
index f007713..be2dba94 100644
--- a/components/webauthn/core/browser/passkey_sync_bridge.cc
+++ b/components/webauthn/core/browser/passkey_sync_bridge.cc
@@ -20,6 +20,7 @@
 #include "base/ranges/algorithm.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/trace_event/trace_event.h"
+#include "components/sync/base/deletion_origin.h"
 #include "components/sync/base/features.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/model/client_tag_based_model_type_processor.h"
@@ -315,7 +316,8 @@
   return passkey_model_utils::FilterShadowedCredentials(passkeys);
 }
 
-bool PasskeySyncBridge::DeletePasskey(const std::string& credential_id) {
+bool PasskeySyncBridge::DeletePasskey(const std::string& credential_id,
+                                      const base::Location& location) {
   // Find the credential with the given |credential_id|.
   const auto passkey_it =
       base::ranges::find_if(data_, [&credential_id](const auto& passkey) {
@@ -357,7 +359,9 @@
     changes.emplace_back(PasskeyModelChange::ChangeType::REMOVE,
                          data_.at(sync_id));
     data_.erase(sync_id);
-    change_processor()->Delete(sync_id, write_batch->GetMetadataChangeList());
+    change_processor()->Delete(sync_id,
+                               syncer::DeletionOrigin::FromLocation(location),
+                               write_batch->GetMetadataChangeList());
     write_batch->DeleteData(sync_id);
   }
   store_->CommitWriteBatch(
diff --git a/components/webauthn/core/browser/passkey_sync_bridge.h b/components/webauthn/core/browser/passkey_sync_bridge.h
index ab93c49..7feb537 100644
--- a/components/webauthn/core/browser/passkey_sync_bridge.h
+++ b/components/webauthn/core/browser/passkey_sync_bridge.h
@@ -64,7 +64,8 @@
       const std::string& credential_id) const override;
   std::vector<sync_pb::WebauthnCredentialSpecifics>
   GetPasskeysForRelyingPartyId(const std::string& rp_id) const override;
-  bool DeletePasskey(const std::string& credential_id) override;
+  bool DeletePasskey(const std::string& credential_id,
+                     const base::Location& location) override;
   bool UpdatePasskey(const std::string& credential_id,
                      PasskeyUpdate change) override;
   sync_pb::WebauthnCredentialSpecifics CreatePasskey(
diff --git a/components/webauthn/core/browser/test_passkey_model.cc b/components/webauthn/core/browser/test_passkey_model.cc
index 0577a87..38127ef 100644
--- a/components/webauthn/core/browser/test_passkey_model.cc
+++ b/components/webauthn/core/browser/test_passkey_model.cc
@@ -119,7 +119,8 @@
   return credentials_.back().credential_id();
 }
 
-bool TestPasskeyModel::DeletePasskey(const std::string& credential_id) {
+bool TestPasskeyModel::DeletePasskey(const std::string& credential_id,
+                                     const base::Location& location) {
   // Don't implement the shadow chain deletion logic. Instead, remove the
   // credential with the matching id.
   const auto credential_it =
diff --git a/components/webauthn/core/browser/test_passkey_model.h b/components/webauthn/core/browser/test_passkey_model.h
index 43617bd..773581f8 100644
--- a/components/webauthn/core/browser/test_passkey_model.h
+++ b/components/webauthn/core/browser/test_passkey_model.h
@@ -32,7 +32,8 @@
       const std::string& credential_id) const override;
   std::vector<sync_pb::WebauthnCredentialSpecifics>
   GetPasskeysForRelyingPartyId(const std::string& rp_id) const override;
-  bool DeletePasskey(const std::string& credential_id) override;
+  bool DeletePasskey(const std::string& credential_id,
+                     const base::Location& location) override;
   bool UpdatePasskey(const std::string& credential_id,
                      PasskeyUpdate change) override;
   sync_pb::WebauthnCredentialSpecifics CreatePasskey(
diff --git a/components/webrtc/fake_ssl_client_socket.h b/components/webrtc/fake_ssl_client_socket.h
index 15330e7..9a7abc8 100644
--- a/components/webrtc/fake_ssl_client_socket.h
+++ b/components/webrtc/fake_ssl_client_socket.h
@@ -111,8 +111,8 @@
   // The callback passed to Connect().
   net::CompletionOnceCallback user_connect_callback_;
 
-  scoped_refptr<net::DrainableIOBuffer> write_buf_;
-  scoped_refptr<net::DrainableIOBuffer> read_buf_;
+  ::scoped_refptr<net::DrainableIOBuffer> write_buf_;
+  ::scoped_refptr<net::DrainableIOBuffer> read_buf_;
 };
 
 }  // namespace webrtc
diff --git a/components/zucchini/fuzzers/imposed_ensemble_matcher_fuzzer.cc b/components/zucchini/fuzzers/imposed_ensemble_matcher_fuzzer.cc
index 062138fa..4436f230 100644
--- a/components/zucchini/fuzzers/imposed_ensemble_matcher_fuzzer.cc
+++ b/components/zucchini/fuzzers/imposed_ensemble_matcher_fuzzer.cc
@@ -7,6 +7,7 @@
 #include <iostream>
 #include <memory>
 
+#include "base/containers/heap_array.h"
 #include "base/environment.h"
 #include "base/logging.h"
 #include "components/zucchini/buffer_sink.h"
@@ -62,7 +63,7 @@
 
   // Write to buffer to avoid IO.
   size_t patch_size = patch_writer.SerializedSize();
-  std::unique_ptr<uint8_t[]> patch_data(new uint8_t[patch_size]);
-  zucchini::BufferSink patch(patch_data.get(), patch_size);
+  auto patch_data = base::HeapArray<uint8_t>::Uninit(patch_size);
+  zucchini::BufferSink patch(patch_data.data(), patch_data.size());
   patch_writer.SerializeInto(patch);
 }
diff --git a/components/zucchini/fuzzers/raw_gen_fuzzer.cc b/components/zucchini/fuzzers/raw_gen_fuzzer.cc
index 212cc88a..285a255 100644
--- a/components/zucchini/fuzzers/raw_gen_fuzzer.cc
+++ b/components/zucchini/fuzzers/raw_gen_fuzzer.cc
@@ -7,6 +7,7 @@
 #include <iostream>
 #include <memory>
 
+#include "base/containers/heap_array.h"
 #include "base/environment.h"
 #include "base/logging.h"
 #include "components/zucchini/buffer_sink.h"
@@ -66,7 +67,7 @@
   CHECK_LE(patch_size, kMaxImageSize * 2);
 
   // Write to buffer to avoid IO.
-  std::unique_ptr<uint8_t[]> patch_data(new uint8_t[patch_size]);
-  zucchini::BufferSink patch(patch_data.get(), patch_size);
+  auto patch_data = base::HeapArray<uint8_t>::Uninit(patch_size);
+  zucchini::BufferSink patch(patch_data.data(), patch_data.size());
   patch_writer.SerializeInto(patch);
 }
diff --git a/components/zucchini/fuzzers/ztf_gen_fuzzer.cc b/components/zucchini/fuzzers/ztf_gen_fuzzer.cc
index 2bef726..9fff3136 100644
--- a/components/zucchini/fuzzers/ztf_gen_fuzzer.cc
+++ b/components/zucchini/fuzzers/ztf_gen_fuzzer.cc
@@ -7,6 +7,7 @@
 #include <iostream>
 #include <memory>
 
+#include "base/containers/heap_array.h"
 #include "base/environment.h"
 #include "base/logging.h"
 #include "components/zucchini/buffer_sink.h"
@@ -62,7 +63,7 @@
 
   // Write to buffer to avoid IO.
   size_t patch_size = patch_writer.SerializedSize();
-  std::unique_ptr<uint8_t[]> patch_data(new uint8_t[patch_size]);
-  zucchini::BufferSink patch(patch_data.get(), patch_size);
+  auto patch_data = base::HeapArray<uint8_t>::Uninit(patch_size);
+  zucchini::BufferSink patch(patch_data.data(), patch_data.size());
   patch_writer.SerializeInto(patch);
 }
diff --git a/content/app_shim_remote_cocoa/web_contents_view_cocoa.mm b/content/app_shim_remote_cocoa/web_contents_view_cocoa.mm
index ce06582..8f4b9ae 100644
--- a/content/app_shim_remote_cocoa/web_contents_view_cocoa.mm
+++ b/content/app_shim_remote_cocoa/web_contents_view_cocoa.mm
@@ -125,7 +125,7 @@
 
   gfx::Rect _windowControlsOverlayRect;
 
-  // TODO(https://crbug.com/883031): Remove this when kMacWebContentsOcclusion
+  // TODO(crbug.com/40593221): Remove this when kMacWebContentsOcclusion
   // is enabled by default.
   BOOL _inFullScreenTransition;
   BOOL _willSetWebContentsOccludedAfterDelay;
diff --git a/content/browser/accessibility/accessibility_auralinux_browsertest.cc b/content/browser/accessibility/accessibility_auralinux_browsertest.cc
index e6c2344b..5b00af40 100644
--- a/content/browser/accessibility/accessibility_auralinux_browsertest.cc
+++ b/content/browser/accessibility/accessibility_auralinux_browsertest.cc
@@ -1674,7 +1674,7 @@
   g_object_unref(contenteditable);
 }
 
-// TODO(crbug.com/981913): This flakes on linux.
+// TODO(crbug.com/41469621): This flakes on linux.
 IN_PROC_BROWSER_TEST_F(
     AccessibilityAuraLinuxBrowserTest,
     DISABLED_TestSetCaretSetsSequentialFocusNavigationStartingPoint) {
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index a1c7db9..21579ab 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -1712,7 +1712,7 @@
 
 BrowserAccessibility* BrowserAccessibilityManager::CachingAsyncHitTest(
     const gfx::Point& physical_pixel_point) const {
-  // TODO(crbug.com/1061323): By starting the hit test on the root frame,
+  // TODO(crbug.com/40679532): By starting the hit test on the root frame,
   // it allows for the possibility that we don't return a descendant as the
   // hit test result, but AXPlatformNodeDelegate says that it's only supposed
   // to return a descendant, so this isn't correctly fulfilling the contract.
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
index 96201e12..c847b789 100644
--- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -391,7 +391,7 @@
 }
 
 // TODO(crbug.com/835455): Fails on Windows.
-// TODO(crbug.com/945193): Flaky on Mac.
+// TODO(crbug.com/41448628): Flaky on Mac.
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
 #define MAYBE_AccessibilityEventsAriaComboBoxDelayAddList \
   DISABLED_AccessibilityEventsAriaComboBoxDelayAddList
@@ -916,7 +916,7 @@
 
 // TODO(crbug.com/1327652): disabled on UIA
 IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTestExceptUIA,
-                       // TODO(crbug.com/1446550): Re-enable this test
+                       // TODO(crbug.com/40913066): Re-enable this test
                        DISABLED_AccessibilityEventsMenuListNext) {
   RunEventTest(FILE_PATH_LITERAL("menulist-next.html"));
 }
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index 3f8a07f9..cfad47f 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -2268,7 +2268,7 @@
   RunHtmlTest(FILE_PATH_LITERAL("iframe-with-region-role.html"));
 }
 
-// TODO(crbug.com/1475950): Fix and reenable the test.
+// TODO(crbug.com/40070579): Fix and reenable the test.
 IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, DISABLED_AccessibilityImg) {
   RunHtmlTest(FILE_PATH_LITERAL("img.html"));
 }
diff --git a/content/browser/accessibility/line_layout_browsertest.cc b/content/browser/accessibility/line_layout_browsertest.cc
index 259c550..74b663c21 100644
--- a/content/browser/accessibility/line_layout_browsertest.cc
+++ b/content/browser/accessibility/line_layout_browsertest.cc
@@ -109,7 +109,7 @@
 // immediately; we can wait for them but without the aforementioned fix the
 // updated tree isn't processed to create the Next/PreviousOnLine links.)
 #if !BUILDFLAG(IS_ANDROID)
-// TODO(crbug.com/1515673): Disabled on chromeos due to failing on
+// TODO(crbug.com/41488668): Disabled on chromeos due to failing on
 // linux-chromeos-dbg.
 #if BUILDFLAG(IS_CHROMEOS)
 #define MAYBE_NestedLayoutNGInlineFormattingContext \
diff --git a/content/browser/accessibility/web_contents_accessibility.h b/content/browser/accessibility/web_contents_accessibility.h
index c027b0a..acc8bdf 100644
--- a/content/browser/accessibility/web_contents_accessibility.h
+++ b/content/browser/accessibility/web_contents_accessibility.h
@@ -13,7 +13,7 @@
 
 // Class that bridges BrowserAccessibilityManager and platform-dependent
 // handler.
-// TODO(crbug.com/727210): Expand this class to work on all the platforms.
+// TODO(crbug.com/40522979): Expand this class to work on all the platforms.
 class CONTENT_EXPORT WebContentsAccessibility {
  public:
   WebContentsAccessibility() {}
diff --git a/content/browser/audio/audio_service.cc b/content/browser/audio/audio_service.cc
index 94679d2..ae32b0ce 100644
--- a/content/browser/audio/audio_service.cc
+++ b/content/browser/audio/audio_service.cc
@@ -94,7 +94,7 @@
   }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH) && defined(USE_CRAS)
 
-  // TODO(https://crbug.com/853254): Remove
+  // TODO(crbug.com/40580951): Remove
   // BrowserMainLoop::GetAudioManager().
   audio::Service::GetInProcessTaskRunner()->PostTask(
       FROM_HERE,
diff --git a/content/browser/back_forward_cache_features_browsertest.cc b/content/browser/back_forward_cache_features_browsertest.cc
index a7152ff..9da1b02 100644
--- a/content/browser/back_forward_cache_features_browsertest.cc
+++ b/content/browser/back_forward_cache_features_browsertest.cc
@@ -4778,7 +4778,7 @@
                     {}, {}, {}, FROM_HERE);
 }
 
-// TODO(https://crbug.com/1495476): Reenable. This is flaky because we block on
+// TODO(crbug.com/40937711): Reenable. This is flaky because we block on
 // the permission request, not on API usage.
 IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, DISABLED_WebMidiNotCached) {
   ASSERT_TRUE(embedded_test_server()->Start());
@@ -5204,7 +5204,7 @@
     // The MediaSessionEnterPictureInPicture feature depends on the
     // BackForwardCacheMediaSessionService feature, so we need to also disable
     // it here.
-    // TODO(https://crbug.com/1510995): Remove these tests since the
+    // TODO(crbug.com/41483582): Remove these tests since the
     // BackForwardCacheMediaSessionService feature has been launched.
     DisableFeature(blink::features::kMediaSessionEnterPictureInPicture);
 
diff --git a/content/browser/back_forward_cache_internal_browsertest.cc b/content/browser/back_forward_cache_internal_browsertest.cc
index 73d92e4..33b0f84 100644
--- a/content/browser/back_forward_cache_internal_browsertest.cc
+++ b/content/browser/back_forward_cache_internal_browsertest.cc
@@ -1091,7 +1091,7 @@
 // updated during the "freeze" event in a way that would have prevented the
 // document from entering the BackForwardCache in the first place.
 //
-// TODO(https://crbug.com/996267): The document should be evicted.
+// TODO(crbug.com/41477477): The document should be evicted.
 //
 // ┌───────┐                     ┌────────┐
 // │browser│                     │renderer│
diff --git a/content/browser/background_fetch/background_fetch.proto b/content/browser/background_fetch/background_fetch.proto
index 5cd08f7..9baf94a 100644
--- a/content/browser/background_fetch/background_fetch.proto
+++ b/content/browser/background_fetch/background_fetch.proto
@@ -45,7 +45,7 @@
   optional BackgroundFetchFailureReason failure_reason = 8;
 }
 
-// TODO(crbug.com/1381377): Move ImageResource to generic place.
+// TODO(crbug.com/40245169): Move ImageResource to generic place.
 // Currently also being used within chrome/browser/web_applications
 // https://w3c.github.io/manifest/#dom-imageresource
 //
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 2746f7b..57afaab 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -1337,7 +1337,7 @@
   bool always_uses_gpu = true;
   bool established_gpu_channel = false;
 #if BUILDFLAG(IS_ANDROID)
-  // TODO(crbug.com/439322): This should be set to |true|.
+  // TODO(crbug.com/40396955): This should be set to |true|.
   established_gpu_channel = false;
   always_uses_gpu = ShouldStartGpuProcessOnBrowserStartup();
   BrowserGpuChannelHostFactory::Initialize(established_gpu_channel);
diff --git a/content/browser/browsing_data/clear_site_data_handler.cc b/content/browser/browsing_data/clear_site_data_handler.cc
index 16273d2f..cc4cbe3 100644
--- a/content/browser/browsing_data/clear_site_data_handler.cc
+++ b/content/browser/browsing_data/clear_site_data_handler.cc
@@ -183,7 +183,7 @@
   bool deferred = Run();
 
   // If the redirect is deferred, wait until it is resumed.
-  // TODO(crbug.com/876931): Delay output until next frame for navigations.
+  // TODO(crbug.com/41409604): Delay output until next frame for navigations.
   if (!deferred) {
     OutputConsoleMessages();
     RunCallbackNotDeferred();
@@ -381,7 +381,7 @@
     base::OnceClosure callback) {
   DCHECK(!clearing_started.is_null());
 
-  // TODO(crbug.com/876931): Delay output until next frame for navigations.
+  // TODO(crbug.com/41409604): Delay output until next frame for navigations.
   delegate->OutputMessages(web_contents);
 
   std::move(callback).Run();
diff --git a/content/browser/browsing_data/clear_site_data_handler_unittest.cc b/content/browser/browsing_data/clear_site_data_handler_unittest.cc
index f1de489a..30a3cc1 100644
--- a/content/browser/browsing_data/clear_site_data_handler_unittest.cc
+++ b/content/browser/browsing_data/clear_site_data_handler_unittest.cc
@@ -527,7 +527,7 @@
        "No recognized types specified.\n"},
   };
 
-  // TODO(crbug.com/876931): Delay output until next frame for navigations.
+  // TODO(crbug.com/41409604): Delay output until next frame for navigations.
   bool kHandlerTypeIsNavigation[] = {false};
 
   for (bool navigation : kHandlerTypeIsNavigation) {
diff --git a/content/browser/child_process_host_impl.cc b/content/browser/child_process_host_impl.cc
index e5717d0..5006539 100644
--- a/content/browser/child_process_host_impl.cc
+++ b/content/browser/child_process_host_impl.cc
@@ -389,7 +389,7 @@
   // really no need to get this information from the child process when we
   // already have it.
   //
-  // TODO(crbug.com/616980): Remove the peer_pid argument altogether from
+  // TODO(crbug.com/41256971): Remove the peer_pid argument altogether from
   // IPC::Listener::OnChannelConnected.
   const base::Process& peer_process = GetPeerProcess();
   base::ProcessId pid =
diff --git a/content/browser/client_hints/client_hints.cc b/content/browser/client_hints/client_hints.cc
index b6e63391..284acf8 100644
--- a/content/browser/client_hints/client_hints.cc
+++ b/content/browser/client_hints/client_hints.cc
@@ -643,7 +643,7 @@
 // The permissions policy the browser side has for the frame was set in stone
 // before HTML parsing began, so any updates must be sent via
 // `container_policy`.
-// TODO(crbug.com/1278127): Replace w/ generic HTML policy modification.
+// TODO(crbug.com/40208054): Replace w/ generic HTML policy modification.
 void UpdateIFramePermissionsPolicyWithDelegationSupportForClientHints(
     ClientHintsExtendedData& data,
     const blink::ParsedPermissionsPolicy& container_policy) {
diff --git a/content/browser/code_cache/generated_code_cache.cc b/content/browser/code_cache/generated_code_cache.cc
index 47f39d6..8fc176cf 100644
--- a/content/browser/code_cache/generated_code_cache.cc
+++ b/content/browser/code_cache/generated_code_cache.cc
@@ -116,7 +116,7 @@
   if (net::HttpCache::IsSplitCacheEnabled() &&
       base::FeatureList::IsEnabled(
           net::features::kSplitCodeCacheByNetworkIsolationKey)) {
-    // TODO(https://crbug.com/1346188):  Transient NIKs return nullopt when
+    // TODO(crbug.com/40232395):  Transient NIKs return nullopt when
     // their ToCacheKeyString() method is invoked, as they generally shouldn't
     // be written to disk. This code is currently reached for transient NIKs,
     // which needs to be fixed.
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
index cdda11f..be977ca 100644
--- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
+++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -880,7 +880,7 @@
 // TODO(crbug.com/40157725) Android has a problem with changing scale.
 // TODO(crbug.com/1147911) Android Lollipop has a problem with capturing
 // screenshot.
-// TODO(crbug.com/1156767) Flaky on linux-lacros-tester-rel
+// TODO(crbug.com/40736077) Flaky on linux-lacros-tester-rel
 // TODO(crbug.com/1286261): Failing on MacOS.
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH) || \
     BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_MAC)
@@ -1098,7 +1098,7 @@
 }
 
 IN_PROC_BROWSER_TEST_F(CaptureScreenshotTest,
-// TODO(crbug.com/1381597): Fix this failing test
+// TODO(crbug.com/40876878): Fix this failing test
 #if BUILDFLAG(IS_ANDROID)
                        DISABLED_TransparentScreenshotsBeyondViewport) {
 #else
diff --git a/content/browser/do_not_track_browsertest.cc b/content/browser/do_not_track_browsertest.cc
index ffd3247..37d58e3a 100644
--- a/content/browser/do_not_track_browsertest.cc
+++ b/content/browser/do_not_track_browsertest.cc
@@ -52,9 +52,9 @@
  protected:
   void SetUpOnMainThread() override {
 #if BUILDFLAG(IS_ANDROID)
-    // TODO(crbug.com/864403): It seems that we call unsupported Android APIs on
-    // KitKat when we set a ContentBrowserClient. Don't call such APIs and make
-    // this test available on KitKat.
+    // TODO(crbug.com/40585282): It seems that we call unsupported Android APIs
+    // on KitKat when we set a ContentBrowserClient. Don't call such APIs and
+    // make this test available on KitKat.
     int32_t major_version = 0, minor_version = 0, bugfix_version = 0;
     base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version,
                                                  &bugfix_version);
diff --git a/content/browser/download/mhtml_generation_browsertest.cc b/content/browser/download/mhtml_generation_browsertest.cc
index 0e8c413..6eb1272 100644
--- a/content/browser/download/mhtml_generation_browsertest.cc
+++ b/content/browser/download/mhtml_generation_browsertest.cc
@@ -565,7 +565,7 @@
 
 // Regression test for the crash/race from https://crbug.com/612098.
 //
-// TODO(crbug.com/959435): Flaky on Android.
+// TODO(crbug.com/41456635): Flaky on Android.
 #if BUILDFLAG(IS_ANDROID)
 #define MAYBE_GenerateMHTMLAndCloseConnection \
   DISABLED_GenerateMHTMLAndCloseConnection
@@ -594,7 +594,7 @@
   EXPECT_EQ(ReadFileSizeFromDisk(path), file_size());
 }
 
-// TODO(crbug.com/672313): Flaky on Windows.
+// TODO(crbug.com/41290169): Flaky on Windows.
 #if BUILDFLAG(IS_WIN)
 #define MAYBE_InvalidPath DISABLED_InvalidPath
 #else
diff --git a/content/browser/file_system_access/file_system_access_file_modification_host_impl_browsertest.cc b/content/browser/file_system_access/file_system_access_file_modification_host_impl_browsertest.cc
index d371423..a11b643f 100644
--- a/content/browser/file_system_access/file_system_access_file_modification_host_impl_browsertest.cc
+++ b/content/browser/file_system_access/file_system_access_file_modification_host_impl_browsertest.cc
@@ -214,7 +214,7 @@
 }
 
 // TODO(crbug.com/1304977): Failing on Mac, Linux, and ChromeOS builders.
-// TODO(crbug.com/1459385): Re-enable this test
+// TODO(crbug.com/40274291): Re-enable this test
 IN_PROC_BROWSER_TEST_F(FileSystemAccessFileModificationHostImplBrowserTest,
                        DISABLED_QuotaUsageShrinks) {
   const GURL& test_url =
diff --git a/content/browser/find_request_manager_browsertest.cc b/content/browser/find_request_manager_browsertest.cc
index 4a06d531..688323a 100644
--- a/content/browser/find_request_manager_browsertest.cc
+++ b/content/browser/find_request_manager_browsertest.cc
@@ -386,8 +386,8 @@
 }
 
 // TODO(crbug.com/615291): This test frequently fails on Android.
-// TODO(crbug.com/674742): This test is flaky on Win
-// TODO(crbug.com/850286): Flaky on CrOS MSan
+// TODO(crbug.com/41291496): This test is flaky on Win
+// TODO(crbug.com/41393143): Flaky on CrOS MSan
 // Tests sending a large number of find requests subsequently.
 IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, DISABLED_RapidFire) {
   LoadAndWait("/find_in_page.html");
@@ -676,8 +676,8 @@
 }
 
 // TODO(crbug.com/615291): These tests frequently fail on Android.
-// TODO(crbug.com/779912): Flaky timeout on Win7 (dbg).
-// TODO(crbug.com/875306): Flaky on Win10.
+// TODO(crbug.com/41352658): Flaky timeout on Win7 (dbg).
+// TODO(crbug.com/41408666): Flaky on Win10.
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN)
 #define MAYBE_FindInPage_Issue627799 DISABLED_FindInPage_Issue627799
 #else
diff --git a/content/browser/loader/keep_alive_url_loader.cc b/content/browser/loader/keep_alive_url_loader.cc
index b48a18bd..27e10ca 100644
--- a/content/browser/loader/keep_alive_url_loader.cc
+++ b/content/browser/loader/keep_alive_url_loader.cc
@@ -95,7 +95,7 @@
 // Checks if `url` is allowed by the set of Content-Security-Policy `policies`.
 // Violation will not be reported back to renderer, as this function must be
 // called after renderer is gone.
-// TODO(crbug.com/1431165): Isolated world's CSP is not handled.
+// TODO(crbug.com/40263403): Isolated world's CSP is not handled.
 bool IsRedirectAllowedByCSP(
     const std::vector<network::mojom::ContentSecurityPolicyPtr>& policies,
     const GURL& url,
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index b245f69..10b5d89 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -412,7 +412,7 @@
     return;
   }
 
-  // TODO(https://crbug.com/1362779) Remove this instrumentation once fixed.
+  // TODO(crbug.com/40864513) Remove this instrumentation once fixed.
   auto to_string = [](const auto& policies) {
     std::string out;
     for (const auto& csp : policies) {
diff --git a/content/browser/loader/url_loader_factory_utils.cc b/content/browser/loader/url_loader_factory_utils.cc
index 157fd8f2..1ad1227e 100644
--- a/content/browser/loader/url_loader_factory_utils.cc
+++ b/content/browser/loader/url_loader_factory_utils.cc
@@ -183,7 +183,7 @@
 
     // The following cases are not reached just because `devtools_params` is
     // always `std::nullopt` for the current `Create*` callers.
-    // TODO(crbug.com/1506871): Return proper values once non-nullopt
+    // TODO(crbug.com/40947547): Return proper values once non-nullopt
     // `devtools_params` is given.
     case ContentBrowserClient::URLLoaderFactoryType::kPrefetch:
     case ContentBrowserClient::URLLoaderFactoryType::kDevTools:
diff --git a/content/browser/loader/url_loader_factory_utils.h b/content/browser/loader/url_loader_factory_utils.h
index 59fc4985..d63c2ba6 100644
--- a/content/browser/loader/url_loader_factory_utils.h
+++ b/content/browser/loader/url_loader_factory_utils.h
@@ -33,7 +33,7 @@
 // behavior.
 // This method must be called either on the UI thread or before threads start.
 // This callback is run on the UI thread.
-// TODO(crbug.com/1506871): Document when the interception occurs.
+// TODO(crbug.com/40947547): Document when the interception occurs.
 CONTENT_EXPORT void SetInterceptorForTesting(const Interceptor& interceptor);
 
 // A parameter object for `ContentBrowserClient::WillCreateURLLoaderFactory()`.
diff --git a/content/browser/media/capture/frame_sink_video_capture_device.cc b/content/browser/media/capture/frame_sink_video_capture_device.cc
index 4441f15..7a6f7fb4 100644
--- a/content/browser/media/capture/frame_sink_video_capture_device.cc
+++ b/content/browser/media/capture/frame_sink_video_capture_device.cc
@@ -174,7 +174,7 @@
 bool FrameSinkVideoCaptureDevice::CanSupportNV12Format() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  // TODO(crbug.com/1518528): Determine if we actually need to know the format
+  // TODO(crbug.com/41491504): Determine if we actually need to know the format
   // client-side (which is what this method is used for) beyond sending it over
   // to the service side. If not, compute this information service-side. If yes,
   // port all of the below code to be a check on SharedImageCapabilities once
diff --git a/content/browser/media/captured_surface_controller.h b/content/browser/media/captured_surface_controller.h
index 2db7be4..dd112a0 100644
--- a/content/browser/media/captured_surface_controller.h
+++ b/content/browser/media/captured_surface_controller.h
@@ -128,7 +128,7 @@
   // In the unlikely-yet-possible case that SendWheel() or SetZoomLevel()
   // are called while the task to resolve is pending, those calls will
   // fail gracefully. Subsequent calls are valid and can succeed.
-  // TODO(crbug.com/1520375): Add UMA to measure how often this happens
+  // TODO(crbug.com/41493349): Add UMA to measure how often this happens
   // and determine whether it's worth the effort to fix.
   std::optional<base::WeakPtr<WebContents>> captured_wc_;
 
diff --git a/content/browser/media/media_browsertest.cc b/content/browser/media/media_browsertest.cc
index a69f04c9..66804f6b 100644
--- a/content/browser/media/media_browsertest.cc
+++ b/content/browser/media/media_browsertest.cc
@@ -380,7 +380,7 @@
 
 // Android can't reliably load lots of videos on a page.
 // See http://crbug.com/749265
-// TODO(crbug.com/1222852): Flaky on Mac.
+// TODO(crbug.com/40774322): Flaky on Mac.
 #if BUILDFLAG(IS_MAC)
 #define MAYBE_LoadManyVideos DISABLED_LoadManyVideos
 #else
diff --git a/content/browser/media/session/audio_focus_delegate_android_browsertest.cc b/content/browser/media/session/audio_focus_delegate_android_browsertest.cc
index b0606b3..d80059b 100644
--- a/content/browser/media/session/audio_focus_delegate_android_browsertest.cc
+++ b/content/browser/media/session/audio_focus_delegate_android_browsertest.cc
@@ -23,7 +23,7 @@
 // is the only way found to actually reproduce the crash so as a result, the
 // test will only run on builds without DCHECK's.
 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
-// TODO(crbug.com/602787) The test is flaky, disabling it everywhere.
+// TODO(crbug.com/40464766) The test is flaky, disabling it everywhere.
 #define MAYBE_OnAudioFocusChangeAfterDtorCrash \
   DISABLED_OnAudioFocusChangeAfterDtorCrash
 #else
diff --git a/content/browser/navigation_transitions/back_forward_transition_animator.cc b/content/browser/navigation_transitions/back_forward_transition_animator.cc
index 1b42d20..2fb79e77 100644
--- a/content/browser/navigation_transitions/back_forward_transition_animator.cc
+++ b/content/browser/navigation_transitions/back_forward_transition_animator.cc
@@ -571,7 +571,7 @@
   // 204/205/Download, or the ongoing navigation is cancelled. We need
   // to animate the old page back.
   //
-  // TODO(https://crbug.com/1509886): We might need a better UX than
+  // TODO(crbug.com/41482488): We might need a better UX than
   // just display the cancel animation.
   AdvanceAndProcessState(State::kDisplayingCancelAnimation);
 }
diff --git a/content/browser/notifications/blink_notification_service_impl.cc b/content/browser/notifications/blink_notification_service_impl.cc
index 688c95e..08aedfc9 100644
--- a/content/browser/notifications/blink_notification_service_impl.cc
+++ b/content/browser/notifications/blink_notification_service_impl.cc
@@ -316,7 +316,7 @@
   database_data.notification_data = platform_notification_data;
   database_data.notification_resources = notification_resources;
 
-  // TODO(https://crbug.com/870258): Validate resources are not too big (either
+  // TODO(crbug.com/41405589): Validate resources are not too big (either
   // here or in the mojo struct traits).
 
   notification_context_->WriteNotificationData(
diff --git a/content/browser/push_messaging/push_messaging_router.h b/content/browser/push_messaging/push_messaging_router.h
index 5415fe75..35ec9224 100644
--- a/content/browser/push_messaging/push_messaging_router.h
+++ b/content/browser/push_messaging/push_messaging_router.h
@@ -46,7 +46,7 @@
                              std::optional<std::string> payload,
                              PushEventCallback deliver_message_callback);
 
-  // TODO(https://crbug.com/753163): Add the ability to trigger a push
+  // TODO(crbug.com/41338108): Add the ability to trigger a push
   // subscription change event in DevTools
   // Fires a pushsubscriptionchangeevent with the arguments |new_subscription|
   // and |old_subscription| to service workers.
diff --git a/content/browser/renderer_host/back_forward_cache_impl.h b/content/browser/renderer_host/back_forward_cache_impl.h
index b618d29a..bd6be0e 100644
--- a/content/browser/renderer_host/back_forward_cache_impl.h
+++ b/content/browser/renderer_host/back_forward_cache_impl.h
@@ -761,7 +761,7 @@
   // from all the reachable cross-origin iframes. We decrement this count
   // every time we call this function, and report only when |index| is 0 so
   // that reporting happens only for randomly picked one of such iframes.
-  // TODO(crbug.com/1518408): Add "masked" when UA internal reasons such as
+  // TODO(crbug.com/41491384): Add "masked" when UA internal reasons such as
   // memory pressure and browsing instance not swapped are blocking as well.
   blink::mojom::BackForwardCacheNotRestoredReasonsPtr
   GetWebExposedNotRestoredReasonsInternal(int& index);
diff --git a/content/browser/renderer_host/cookie_utils.cc b/content/browser/renderer_host/cookie_utils.cc
index 8cc93e5..da31492 100644
--- a/content/browser/renderer_host/cookie_utils.cc
+++ b/content/browser/renderer_host/cookie_utils.cc
@@ -72,29 +72,13 @@
   }
 }
 
+// Relies on checks in RecordPartitionedCookiesUKMs to confirm that that the
+// cookie name is not "receive-cookie-deprecation", that cookie is first party
+// partitioned and the RenderFrameHost is not prerendering.
 void RecordFirstPartyPartitionedCookieCrossSiteContextUKM(
     RenderFrameHostImpl* render_frame_host_impl,
-    const net::CanonicalCookie& cookie) {
-  // Our data collection policy disallows collecting UKMs while prerendering.
-  // See //content/browser/preloading/prerender/README.md and ask the team to
-  // explore options to record data for prerendering pages if we need to
-  // support the case.
-  if (render_frame_host_impl->IsInLifecycleState(
-          RenderFrameHost::LifecycleState::kPrerendering)) {
-    return;
-  }
-
-  if (!cookie.IsFirstPartyPartitioned()) {
-    return;
-  }
-
-  // Cookies_FirstPartyPartitionedInCrossSiteContextV3 measures cookies
-  // without the name of 'receive-cookie-deprecation'. Return here to ensure
-  // that the metric does not include those cookies.
-  if (cookie.Name() == "receive-cookie-deprecation") {
-    return;
-  }
-
+    const net::CanonicalCookie& cookie,
+    const ukm::SourceId& source_id) {
   // Same-site embed with cross-site ancestors (ABA embeds) have a null site
   // for cookies since it is a cross-site context. If the result of
   // ComputeSiteForCookies is first-party that means we are not in an ABA
@@ -104,29 +88,49 @@
           GURL(base::StrCat({url::kHttpsScheme, url::kStandardSchemeSeparator,
                              cookie.DomainWithoutDot()})));
 
-  ukm::builders::Cookies_FirstPartyPartitionedInCrossSiteContextV3(
-      render_frame_host_impl->GetPageUkmSourceId())
+  ukm::builders::Cookies_FirstPartyPartitionedInCrossSiteContextV3(source_id)
       .SetCookiePresent(has_cross_site_ancestor)
       .Record(ukm::UkmRecorder::Get());
 }
 
-void RecordPartitionedCookieUseUKM(RenderFrameHost* rfh,
-                                   bool partitioned_cookies_exist) {
+// Relies on checks in RecordPartitionedCookiesUKMs to confirm that that the
+// cookie is partitioned, the cookie name is not
+// "receive-cookie-deprecation" and the RenderFrameHost is not prerendering.
+void RecordPartitionedCookieUseV2UKM(RenderFrameHost* rfh,
+                                     const net::CanonicalCookie& cookie,
+                                     const ukm::SourceId& source_id) {
+  ukm::builders::PartitionedCookiePresentV2(source_id)
+      .SetPartitionedCookiePresentV2(true)
+      .Record(ukm::UkmRecorder::Get());
+}
+
+void RecordPartitionedCookiesUKMs(RenderFrameHostImpl* render_frame_host_impl,
+                                  const net::CanonicalCookie& cookie) {
   // Our data collection policy disallows collecting UKMs while prerendering.
   // See //content/browser/preloading/prerender/README.md and ask the team to
   // explore options to record data for prerendering pages if we need to
   // support the case.
-  if (rfh->IsInLifecycleState(RenderFrameHost::LifecycleState::kPrerendering)) {
+  if (render_frame_host_impl->IsInLifecycleState(
+          RenderFrameHost::LifecycleState::kPrerendering)) {
     return;
   }
-  if (!partitioned_cookies_exist) {
-    return;
-  }
-  ukm::SourceId source_id = rfh->GetPageUkmSourceId();
 
-  ukm::builders::PartitionedCookiePresent(source_id)
-      .SetPartitionedCookiePresent(partitioned_cookies_exist)
-      .Record(ukm::UkmRecorder::Get());
+  // Cookies_FirstPartyPartitionedInCrossSiteContextV3 and
+  // PartitionedCookiePresentV2 both measure cookies
+  // without the name of 'receive-cookie-deprecation'. Return here to ensure
+  // that the metrics do not include those cookies.
+  if (cookie.Name() == "receive-cookie-deprecation") {
+    return;
+  }
+
+  ukm::SourceId source_id = render_frame_host_impl->GetPageUkmSourceId();
+
+  if (cookie.IsFirstPartyPartitioned()) {
+    RecordFirstPartyPartitionedCookieCrossSiteContextUKM(render_frame_host_impl,
+                                                         cookie, source_id);
+  }
+
+  RecordPartitionedCookieUseV2UKM(render_frame_host_impl, cookie, source_id);
 }
 
 void RecordRedirectContextDowngradeUKM(RenderFrameHost* rfh,
@@ -309,11 +313,9 @@
          // usage of the Partitioned attribute.
          !cookie->cookie_or_line->get_cookie().PartitionKey()->nonce());
 
-    RecordPartitionedCookieUseUKM(rfh, partitioned_cookies_exist);
 
     if (partitioned_cookies_exist) {
-      RecordFirstPartyPartitionedCookieCrossSiteContextUKM(
-          rfh, cookie->cookie_or_line->get_cookie());
+      RecordPartitionedCookiesUKMs(rfh, cookie->cookie_or_line->get_cookie());
     }
 
     breaking_context_downgrade =
diff --git a/content/browser/renderer_host/input/input_event_browsertest.cc b/content/browser/renderer_host/input/input_event_browsertest.cc
index ce805355..8ccd8417e 100644
--- a/content/browser/renderer_host/input/input_event_browsertest.cc
+++ b/content/browser/renderer_host/input/input_event_browsertest.cc
@@ -253,7 +253,7 @@
   EXPECT_NEAR(event_time_ms, monotonic_time, 1);
 }
 
-// TODO(crbug.com/1516021): Flaky on LaCros.
+// TODO(crbug.com/41489011): Flaky on LaCros.
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 #define MAYBE_TouchStartEventTimeStamp DISABLED_TouchStartEventTimeStamp
 #else
diff --git a/content/browser/renderer_host/input/touch_action_browsertest.cc b/content/browser/renderer_host/input/touch_action_browsertest.cc
index b84776b..eed7f89 100644
--- a/content/browser/renderer_host/input/touch_action_browsertest.cc
+++ b/content/browser/renderer_host/input/touch_action_browsertest.cc
@@ -676,7 +676,7 @@
                                     kShortJankTime);
 }
 
-// TODO(crbug.com/899005): Make this test work on Android.
+// TODO(crbug.com/41422733): Make this test work on Android.
 #if BUILDFLAG(IS_ANDROID)
 #define MAYBE_TwoFingerPanYDisallowed DISABLED_TwoFingerPanYDisallowed
 #else
diff --git a/content/browser/renderer_host/isolated_web_app_throttle.cc b/content/browser/renderer_host/isolated_web_app_throttle.cc
index d4266933..2c9e211 100644
--- a/content/browser/renderer_host/isolated_web_app_throttle.cc
+++ b/content/browser/renderer_host/isolated_web_app_throttle.cc
@@ -157,7 +157,7 @@
 #if BUILDFLAG(IS_CHROMEOS)
   // The default browser can't be changed in ChromeOS, so just open the URL
   // directly.
-  // TODO(crbug.com/1310207): Should we set the referrer?
+  // TODO(crbug.com/40830234): Should we set the referrer?
   OpenURLParams params(url, Referrer(),
                        WindowOpenDisposition::NEW_FOREGROUND_TAB, transition,
                        /*is_renderer_initiated=*/false);
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc
index 317c118..e2ce9de 100644
--- a/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -382,7 +382,7 @@
 // will be captured. Otherwise, the capturer ends up capturing
 // their own tab.
 //
-// TODO(crbug.com/1512911): Refactor this function.
+// TODO(crbug.com/41485487): Refactor this function.
 MediaStreamDevices DisplayMediaDevicesFromFakeDeviceConfig(
     blink::mojom::MediaStreamType media_type,
     bool request_audio,
diff --git a/content/browser/renderer_host/media/media_stream_manager_unittest.cc b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
index 0e11a72..c28efaf 100644
--- a/content/browser/renderer_host/media/media_stream_manager_unittest.cc
+++ b/content/browser/renderer_host/media/media_stream_manager_unittest.cc
@@ -2007,7 +2007,7 @@
 // This test is currently disabled because the code that ensures that Captured
 // Surface Control APIs are disallowed for self-capture has not yet been
 // authored.
-// TODO(crbug.com/1511754): Enable this test.
+// TODO(crbug.com/41484336): Enable this test.
 TEST_P(MediaStreamManagerCapturedSurfaceControlActionTest,
        DISABLED_FailsIfSelfCapture) {
   SCOPED_TRACE("FailsIfSelfCapture");
diff --git a/content/browser/renderer_host/navigation_controller_impl.cc b/content/browser/renderer_host/navigation_controller_impl.cc
index 4564602..3d61ec9 100644
--- a/content/browser/renderer_host/navigation_controller_impl.cc
+++ b/content/browser/renderer_host/navigation_controller_impl.cc
@@ -4130,7 +4130,7 @@
   // back/forward/reload navigation that does a form resubmission.
   scoped_refptr<network::ResourceRequestBody> request_body;
   std::string post_content_type;
-  // TODO(https://crbug.com/931209) Store |is_form_submission| in the history
+  // TODO(crbug.com/41440869) Store |is_form_submission| in the history
   // entry. This way, it could be directly retrieved here. Right now, it is only
   // partially recovered when request.method == "POST" and request.body exists.
   bool is_form_submission = false;
diff --git a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
index 590aae9..79441c5 100644
--- a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
+++ b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
@@ -3634,7 +3634,7 @@
 
 // Verify that navigations to the same WebUI URL are correctly classified as
 // EXISTING_ENTRY (it becomes a reload).
-// TODO(crbug.com/1516015): Flaky on Linux.
+// TODO(crbug.com/41489005): Flaky on Linux.
 #if BUILDFLAG(IS_LINUX)
 #define MAYBE_NavigationTypeClassification_ExistingEntrySameURL_WebUI \
   DISABLED_NavigationTypeClassification_ExistingEntrySameURL_WebUI
@@ -17323,7 +17323,7 @@
   EXPECT_TRUE(ExecJs(shell(), "history.back(); history.back();"));
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
 
-  // TODO(https://crbug.com/869710): This should be url2.
+  // TODO(crbug.com/41405295): This should be url2.
   EXPECT_EQ(url1, shell()->web_contents()->GetLastCommittedURL());
 }
 
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
index d20a6a1..93e1517 100644
--- a/content/browser/renderer_host/navigation_request.cc
+++ b/content/browser/renderer_host/navigation_request.cc
@@ -3571,7 +3571,7 @@
   // opt-out, which would trigger a normal global walk and record that the
   // origin has already been implicitly isolated in some BrowsingInstances.
 
-  // TODO(crbug.com/1442972): investigate using one of NavigationRequest's
+  // TODO(crbug.com/40910871): investigate using one of NavigationRequest's
   // Get*Origin*() functions to compute this, instead of assuming we can just
   // convert directly from GetURL().
   url::Origin origin = url::Origin::Create(GetURL());
diff --git a/content/browser/renderer_host/page_lifecycle_state_manager_browsertest.cc b/content/browser/renderer_host/page_lifecycle_state_manager_browsertest.cc
index d7b5493..c5786488 100644
--- a/content/browser/renderer_host/page_lifecycle_state_manager_browsertest.cc
+++ b/content/browser/renderer_host/page_lifecycle_state_manager_browsertest.cc
@@ -143,7 +143,7 @@
             EvalJs(rfh, "window.performanceObserverEntries"));
 }
 
-// TODO(crbug.com/1241814): Test is flaky on Win and Lacros
+// TODO(crbug.com/40786254): Test is flaky on Win and Lacros
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_LACROS)
 #define MAYBE_CrossProcessIframeHiddenAnFrozen \
   DISABLED_CrossProcessIframeHiddenAnFrozen
diff --git a/content/browser/renderer_host/panel_rotation_browsertest.cc b/content/browser/renderer_host/panel_rotation_browsertest.cc
index 1a0196a..227d527 100644
--- a/content/browser/renderer_host/panel_rotation_browsertest.cc
+++ b/content/browser/renderer_host/panel_rotation_browsertest.cc
@@ -12,7 +12,7 @@
 
 namespace content {
 
-// TODO(https://crbug.com/998131): Add test coverage across all platforms.
+// TODO(crbug.com/41478398): Add test coverage across all platforms.
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 class PanelRotationBrowserTest : public ContentBrowserTest {
  protected:
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 109d53c..659bccc 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -3992,7 +3992,7 @@
     return;
   }
 
-  // TODO(crbug.com/1145708). The interface exposed to tests should
+  // TODO(crbug.com/40155982). The interface exposed to tests should
   // match the mojo interface.
   OnCreateChildFrame(new_routing_id, std::move(frame_remote),
                      std::move(browser_interface_broker_receiver),
@@ -4926,7 +4926,7 @@
 }
 
 bool RenderFrameHostImpl::IsFrozen() {
-  // TODO(crbug.com/1081920): Account for non-bfcache freezing here as well.
+  // TODO(crbug.com/40691610): Account for non-bfcache freezing here as well.
   return lifecycle_state() == LifecycleStateImpl::kInBackForwardCache;
 }
 
@@ -7327,7 +7327,7 @@
           GetProcess(), bad_message::RFH_INACTIVE_CHECK_FROM_SPECULATIVE_RFH);
       return false;
     case LifecycleStateImpl::kPendingCommit:
-      // TODO(https://crbug.com/1191469): Understand the expected behaviour to
+      // TODO(crbug.com/40174540): Understand the expected behaviour to
       // disallow activation for kPendingCommit RenderFrameHosts and update
       // accordingly.
       bad_message::ReceivedBadMessage(
@@ -7372,7 +7372,7 @@
           "Source location must not be provided in this condition.");
     }
   }
-  // TODO(crbug.com/1513120): Use `source` to report the source location of
+  // TODO(crbug.com/41485693): Use `source` to report the source location of
   // JavaScript execution.
   EvictFromBackForwardCacheWithReason(
       RendererEvictionReasonToNotRestoredReason(reason));
@@ -15840,7 +15840,7 @@
       "navigation",
       perfetto::StaticString{LifecycleStateImplToString(new_state)},
       perfetto::Track::FromPointer(this));
-// TODO(crbug.com/1256898): Consider associating expectations with each
+// TODO(crbug.com/40200417): Consider associating expectations with each
 // transitions.
 #if DCHECK_IS_ON()
   static const base::NoDestructor<base::StateTransitions<LifecycleStateImpl>>
@@ -15884,7 +15884,7 @@
                           /*new_state=*/new_state);
 #endif  // DCHECK_IS_ON()
 
-  // TODO(crbug.com/1256896): Use switch-case to make this more readable.
+  // TODO(crbug.com/40200416): Use switch-case to make this more readable.
   // If the RenderFrameHost is restored from BackForwardCache or is part of a
   // prerender activation, update states of all the children to kActive.
   if (new_state == LifecycleStateImpl::kActive) {
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h
index 008bd9c..2400d8d5 100644
--- a/content/browser/renderer_host/render_frame_host_impl.h
+++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -2877,7 +2877,7 @@
   // details, see the definition of `FrameTreeNode::is_initial_empty_document_`.
   // This is implemented in the .cc file to avoid a circular dependency on
   // frame_tree_node.h.
-  // TODO(https://crbug.com/1517371): Remove this function. Callers within RFHI
+  // TODO(crbug.com/41490349): Remove this function. Callers within RFHI
   // should migrate to another way of getting this information such as having a
   // caller pass it or through `owner_`.
   bool is_initial_empty_document() const;
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 39ad2280..765f7fa 100644
--- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -5235,7 +5235,7 @@
       3, injector.GetObjectHost().GetMockObject()->get_num_elements_received());
 }
 
-// TODO(crbug.com/1459205): This test is flaky.
+// TODO(crbug.com/40274210): This test is flaky.
 IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
                        DISABLED_RemoteObjectInvokeMethodReturningObject) {
   GURL url(embedded_test_server()->GetURL("/empty.html"));
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc
index ba7ecb7a..85efdc6 100644
--- a/content/browser/renderer_host/render_frame_host_manager.cc
+++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -5004,7 +5004,7 @@
 
   // Note that we don't know yet what the next state will be, so it is
   // temporarily marked with SetHasPendingLifecycleStateUpdate().
-  // TODO(https://crbug.com/1182237): Determine the next state earlier and
+  // TODO(crbug.com/40170710): Determine the next state earlier and
   // remove SetHasPendingLifecycleStateUpdate().
   if (old_render_frame_host && !old_render_frame_host->IsPendingDeletion()) {
     // After the old RenderFrameHost is no longer the current one, set the value
diff --git a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
index c4fcd76b..0257524 100644
--- a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
@@ -1576,7 +1576,7 @@
 // Ensures that a pending navigation's URL  is no longer visible after the
 // speculative RFH is discarded due to a concurrent renderer-initiated
 // navigation.  See https://crbug.com/760342.
-// TODO(https://crbug.com/945194): Disabled due to flaky timeouts.
+// TODO(crbug.com/41448629): Disabled due to flaky timeouts.
 IN_PROC_BROWSER_TEST_P(
     RenderFrameHostManagerTest,
     DISABLED_ResetVisibleURLOnCrossProcessNavigationInterrupted) {
diff --git a/content/browser/renderer_host/render_widget_host_browsertest.cc b/content/browser/renderer_host/render_widget_host_browsertest.cc
index 31e5ddc..17169a37 100644
--- a/content/browser/renderer_host/render_widget_host_browsertest.cc
+++ b/content/browser/renderer_host/render_widget_host_browsertest.cc
@@ -794,7 +794,7 @@
   FrameTreeNode* root = contents->GetPrimaryFrameTree().root();
   RenderFrameHostImpl* root_frame_host = root->current_frame_host();
 
-  // TODO(crbug.com/1181150): Crash when we attempt to use a mock prompt here.
+  // TODO(crbug.com/40750695): Crash when we attempt to use a mock prompt here.
   // After the ticket is fixed, remove the shortcut of getting bounds and use
   // the `MockPermissionPromptFactory` instead.
   // Create a popup widget and wait for the RenderWidgetHost to be shown.
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc
index f7c65b95..7268485b 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router.cc
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -478,7 +478,7 @@
     // the OOPIF renderer. Instead of using the coordinate transformation in the
     // browser process process, use the cached coordinates that were determined
     // by the renderer process on the previous MouseDown.
-    // TODO(crbug.com/989109): Currently there is a mismatch between the
+    // TODO(crbug.com/41473630): Currently there is a mismatch between the
     // coordinate transforms from browser process and renderer process. We need
     // to fix it so that we don't need to cache the transform from MouseDown.
     if (event.GetType() == blink::WebInputEvent::Type::kMouseUp &&
@@ -636,11 +636,11 @@
     auto hit_test_result =
         FindViewAtLocation(root_view, mouse_event.PositionInWidget(),
                            viz::EventSource::MOUSE, &transformed_point);
-    // TODO(crbug.com/893101): This is skipped if the HitTestResult is requiring
-    // an asynchronous hit test to the renderer process, because it might mean
-    // sending extra MouseMoves to renderers that don't need the event updates
-    // which is a worse outcome than the cursor being delayed in updating.
-    // An asynchronous hit test can be added here to fix the problem.
+    // TODO(crbug.com/41419447): This is skipped if the HitTestResult is
+    // requiring an asynchronous hit test to the renderer process, because it
+    // might mean sending extra MouseMoves to renderers that don't need the
+    // event updates which is a worse outcome than the cursor being delayed in
+    // updating. An asynchronous hit test can be added here to fix the problem.
     if (hit_test_result.view != target && !hit_test_result.should_query_view) {
       SendMouseEnterOrLeaveEvents(
           mouse_event, hit_test_result.view, root_view,
@@ -914,7 +914,7 @@
     } else {
       // GetTransformToViewCoordSpace() fails when viz_hit_test is off but
       // TransformRootPointToViewCoordSpace() still works at this case.
-      // TODO(crbug.com/917015) remove the extra code when viz_hit_test is
+      // TODO(crbug.com/41432837) remove the extra code when viz_hit_test is
       // always on.
       gfx::PointF point_in_target =
           touch_target_->TransformRootPointToViewCoordSpace(
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index a52e22d..f599a4af 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -1588,7 +1588,7 @@
 
 bool RenderWidgetHostViewAura::SetEditableSelectionRange(
     const gfx::Range& range) {
-  // TODO(crbug.com/915630): Write an unit test for this method.
+  // TODO(crbug.com/41432062): Write an unit test for this method.
   auto* input_handler = GetFrameWidgetInputHandlerForFocusedWidget();
   if (!input_handler)
     return false;
@@ -2004,7 +2004,7 @@
   if (!window_->GetRootWindow())
     return;
 
-  // TODO(crbug.com/1446142): Add unittest for lacros.
+  // TODO(crbug.com/40268472): Add unittest for lacros.
   if (needs_to_update_display_metrics_ ||
       old_device_scale_factor != new_device_scale_factor) {
     ProcessDisplayMetricsChanged();
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index d3d2495..30b2d07 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -987,8 +987,8 @@
 
   float device_scale_factor = original_view->GetDeviceScaleFactor();
   DCHECK_GT(device_scale_factor, 0.0f);
-  // TODO(crbug.com/966995): Optimize so that |point_in_pixels| doesn't need to
-  // be in the coordinate space of the root surface in HitTestQuery.
+  // TODO(crbug.com/41460959): Optimize so that |point_in_pixels| doesn't need
+  // to be in the coordinate space of the root surface in HitTestQuery.
   gfx::Transform transform_root_to_original;
   query->GetTransformToTarget(original_view->GetFrameSinkId(),
                               &transform_root_to_original);
diff --git a/content/browser/renderer_host/render_widget_host_view_event_handler.cc b/content/browser/renderer_host/render_widget_host_view_event_handler.cc
index dcad4f3..17e9abc2 100644
--- a/content/browser/renderer_host/render_widget_host_view_event_handler.cc
+++ b/content/browser/renderer_host/render_widget_host_view_event_handler.cc
@@ -836,7 +836,8 @@
       // the center of the screen leading to the lock operation not working
       // correctly. Workaround is to treat a mouse move or drag event off by
       // atmost 2 px from the center as a move to center event.
-      // TODO(crbug.com/991236): figure out a way to avoid the conversion error.
+      // TODO(crbug.com/41474713): figure out a way to avoid the conversion
+      // error.
       return ((std::abs(event.PositionInScreen().x() -
                         synthetic_move_position_->x()) <= 2) &&
               (std::abs(event.PositionInScreen().y() -
diff --git a/content/browser/sandbox_ipc_linux.cc b/content/browser/sandbox_ipc_linux.cc
index d4050a08..b9ed8db8 100644
--- a/content/browser/sandbox_ipc_linux.cc
+++ b/content/browser/sandbox_ipc_linux.cc
@@ -134,7 +134,7 @@
   uint32_t size;
   if (!iter.ReadUInt32(&size))
     return;
-  // TODO(crbug.com/982879): executable shared memory should be removed when
+  // TODO(crbug.com/41470149): executable shared memory should be removed when
   // NaCl is unshipped.
   bool executable;
   if (!iter.ReadBool(&executable))
diff --git a/content/browser/service_worker/service_worker_new_script_loader.cc b/content/browser/service_worker/service_worker_new_script_loader.cc
index 5c6d3df..9e1de32 100644
--- a/content/browser/service_worker/service_worker_new_script_loader.cc
+++ b/content/browser/service_worker/service_worker_new_script_loader.cc
@@ -314,7 +314,7 @@
                  request_url_)) {
       version_->set_policy_container_host(
           base::MakeRefCounted<PolicyContainerHost>(
-              // TODO(crbug.com/1352929): Add DCHECK to parsed_headers
+              // TODO(crbug.com/40235036): Add DCHECK to parsed_headers
               response_head->parsed_headers
                   // This does not parse the referrer policy, which will be
                   // updated in ServiceWorkerGlobalScope::Initialize
diff --git a/content/browser/shape_detection/shape_detection_browsertest.cc b/content/browser/shape_detection/shape_detection_browsertest.cc
index 5cc9c121..58132ef 100644
--- a/content/browser/shape_detection/shape_detection_browsertest.cc
+++ b/content/browser/shape_detection/shape_detection_browsertest.cc
@@ -99,7 +99,7 @@
   }
 };
 
-// TODO(https://crbug.com/659138): Enable the test on other platforms.
+// TODO(crbug.com/41282827): Enable the test on other platforms.
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
 #define MAYBE_DetectShapesInImage DetectShapesInImage
 #else
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index 69769f36..91dd13b 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -5115,7 +5115,7 @@
 
     // X-Frame-Options and CSP frame-ancestors behave differently. XFO commits
     // an error page, while CSP commits a "data:," URL.
-    // TODO(https://crbug.com/870815): Use an error page for both.
+    // TODO(crbug.com/41405925): Use an error page for both.
     EXPECT_FALSE(load_observer.last_navigation_succeeded());
     EXPECT_EQ(net::ERR_BLOCKED_BY_RESPONSE,
               load_observer.last_net_error_code());
@@ -10613,7 +10613,8 @@
 // Create an out-of-process iframe that causes itself to be detached during
 // its layout/animate phase. See https://crbug.com/802932.
 //
-// TODO(809580): Disabled on Android, Mac, and ChromeOS due to flakiness.
+// TODO(crbug.com/40561636): Disabled on Android, Mac, and ChromeOS due to
+// flakiness.
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_OOPIFDetachDuringAnimation DISABLED_OOPIFDetachDuringAnimation
 #else
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc
index d20021b..ebe6a74 100644
--- a/content/browser/site_per_process_hit_test_browsertest.cc
+++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -3050,7 +3050,7 @@
 
 // Verify that an event is properly retargeted to the main frame when an
 // asynchronous hit test to the child frame times out.
-// TODO(crbug.com/1272137) Flaky on all platforms
+// TODO(crbug.com/40806028) Flaky on all platforms
 IN_PROC_BROWSER_TEST_F(SitePerProcessHitTestBrowserTest,
                        DISABLED_AsynchronousHitTestChildTimeout) {
   GURL main_url(embedded_test_server()->GetURL(
diff --git a/content/browser/site_per_process_layout_browsertest.cc b/content/browser/site_per_process_layout_browsertest.cc
index b36396e..5104330 100644
--- a/content/browser/site_per_process_layout_browsertest.cc
+++ b/content/browser/site_per_process_layout_browsertest.cc
@@ -806,7 +806,7 @@
   EXPECT_NEAR(expected.y(), viewport_offset.y(), tolerance);
 }
 
-// TODO(crbug.com/1168036): Flaky test.
+// TODO(crbug.com/40743132): Flaky test.
 IN_PROC_BROWSER_TEST_P(
     SitePerProcessBrowserTest,
     DISABLED_NestedIframeTransformedIntoViewViewportIntersection) {
@@ -858,7 +858,7 @@
 
 // Verify that OOPIF select element popup menu coordinates account for scroll
 // offset in containers embedding frame.
-// TODO(crbug.com/859552): Reenable this.
+// TODO(crbug.com/40583339): Reenable this.
 IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                        DISABLED_PopupMenuInTallIframeTest) {
   GURL main_url(embedded_test_server()->GetURL(
@@ -2131,7 +2131,7 @@
 
 // Test that the compositing scale factor for an out-of-process iframe are set
 // and updated correctly, including accounting for all intermediate transforms.
-// TODO(crbug.com/1164391): Flaky test.
+// TODO(crbug.com/40163506): Flaky test.
 IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTest,
                        DISABLED_CompositingScaleFactorInNestedFrameTest) {
   GURL main_url(embedded_test_server()->GetURL(
diff --git a/content/browser/site_per_process_sad_frame_browsertest.cc b/content/browser/site_per_process_sad_frame_browsertest.cc
index 2f368d8..a1856e2 100644
--- a/content/browser/site_per_process_sad_frame_browsertest.cc
+++ b/content/browser/site_per_process_sad_frame_browsertest.cc
@@ -69,7 +69,7 @@
 };
 
 // This test is flaky on all platforms.
-// TODO(crbug.com/1179074): Deflake it and enable this test back.
+// TODO(crbug.com/40749527): Deflake it and enable this test back.
 IN_PROC_BROWSER_TEST_P(
     SitePerProcessBrowserTestWithoutSadFrameTabReload,
     DISABLED_ChildFrameCrashMetrics_KilledWhileHiddenThenShown) {
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index 816127a..c5e8185 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -2846,7 +2846,7 @@
     // is specified. Therefore we ignore clearing session storage in this case.
     // TODO(lazyboy): Fix.
     if (storage_key_origin_empty) {
-      // TODO(crbug.com/960325): Sometimes SessionStorage fails to call its
+      // TODO(crbug.com/41457196): Sometimes SessionStorage fails to call its
       // callback. Figure out why.
       ClearSessionStorageOnUIThread(
           base::WrapRefCounted(dom_storage_context), storage_policy_ref,
diff --git a/content/browser/tracing/background_tracing_active_scenario.cc b/content/browser/tracing/background_tracing_active_scenario.cc
index ebaabd1..cbd6415 100644
--- a/content/browser/tracing/background_tracing_active_scenario.cc
+++ b/content/browser/tracing/background_tracing_active_scenario.cc
@@ -71,7 +71,7 @@
                  const BackgroundTracingConfigImpl* config)
       : parent_scenario_(parent_scenario) {
 #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
-    // TODO(crbug.com/941318): Re-enable startup tracing for Android once all
+    // TODO(crbug.com/41446559): Re-enable startup tracing for Android once all
     // Perfetto-related deadlocks are resolved and we also handle concurrent
     // system tracing for startup tracing.
     // TODO(khokhlov): Re-enable startup tracing in SDK build. Make sure that
diff --git a/content/browser/tracing/background_tracing_manager_browsertest.cc b/content/browser/tracing/background_tracing_manager_browsertest.cc
index 9b4197c..14d04d7 100644
--- a/content/browser/tracing/background_tracing_manager_browsertest.cc
+++ b/content/browser/tracing/background_tracing_manager_browsertest.cc
@@ -1251,7 +1251,7 @@
   background_tracing_helper.WaitForScenarioIdle();
 }
 
-// TODO(crbug.com/1227164): Test is flaky on Linux and Windows.
+// TODO(crbug.com/40776884): Test is flaky on Linux and Windows.
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
 #define MAYBE_CustomConfig DISABLED_CustomConfig
 #else
@@ -1314,7 +1314,7 @@
 
 // Test that the tracing sampler profiler running in background tracing mode,
 // produces stack frames in the expected JSON format.
-// TODO(https://crbug.com/1062581) Disabled for being flaky.
+// TODO(crbug.com/40680210) Disabled for being flaky.
 IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
                        DISABLED_EndToEndStackSampling) {
   // In the browser process, the tracing sampler profiler gets constructed by
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc
index d0abf014..7c47ed12 100644
--- a/content/browser/tracing/tracing_controller_impl.cc
+++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -384,7 +384,7 @@
       base::UnlocalizedTimeFormatWithPattern(TRACE_TIME_NOW(), "y-M-d H:m:s",
                                              icu::TimeZone::getGMT()));
 
-  // TODO(crbug.com/737049): The central controller doesn't know about
+  // TODO(crbug.com/40527661): The central controller doesn't know about
   // metadata filters, so we temporarily filter here as the controller is
   // what assembles the full trace data.
   base::trace_event::MetadataFilterPredicate metadata_filter;
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 5e6aaee..e445aff 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -8446,9 +8446,9 @@
   // loading. Notify the spare renderer manager about the page loading
   // completion. This is a no-op if a spare rendere already exists.
   //
-  // TODO(crbug.com/1517067): replace the implicit treatment of TimeDelta::Max()
-  // with an enum and optional TimeDelta if we decide to launch deferred spare
-  // renderer.
+  // TODO(crbug.com/41490050): replace the implicit treatment of
+  // TimeDelta::Max() with an enum and optional TimeDelta if we decide to launch
+  // deferred spare renderer.
   bool immediately_warmup_spare_renderer =
       GetContentClient()->browser()->GetSpareRendererDelayForSiteURL(
           GetURL()) == base::TimeDelta::Max();
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
index ba5eeb3..6f7a831 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -1671,7 +1671,7 @@
 void WebContentsViewAura::MaybeLetDelegateProcessDrop(
     OnPerformingDropContext drop_context) {
   // |delegate_| may be null in unit tests.
-  // TODO(crbug.com/1459352): Tests should use a delegate.
+  // TODO(crbug.com/40274271): Tests should use a delegate.
   if (delegate_) {
     auto* drop_data_ptr = drop_context.drop_data.get();
     delegate_->OnPerformingDrop(
diff --git a/content/browser/web_package/prefetched_signed_exchange_cache.cc b/content/browser/web_package/prefetched_signed_exchange_cache.cc
index b37f6fbd..dc5a6c7b 100644
--- a/content/browser/web_package/prefetched_signed_exchange_cache.cc
+++ b/content/browser/web_package/prefetched_signed_exchange_cache.cc
@@ -566,7 +566,7 @@
       ResponseHeadUpdateParams head_update_params;
       head_update_params.load_timing_info =
           this->exchange_->outer_response()->load_timing;
-      // TODO(crbug.com/1441384) test workerStart in SXG scenarios
+      // TODO(crbug.com/40266535) test workerStart in SXG scenarios
       std::move(callback).Run(NavigationLoaderInterceptor::Result(
           /*factory=*/nullptr, /*subresource_loader_params=*/{},
           std::move(head_update_params)));
diff --git a/content/browser/web_package/signed_exchange_loader.cc b/content/browser/web_package/signed_exchange_loader.cc
index 3712a43..fcda53c 100644
--- a/content/browser/web_package/signed_exchange_loader.cc
+++ b/content/browser/web_package/signed_exchange_loader.cc
@@ -290,7 +290,7 @@
       outer_response_head_->was_fetched_via_cache;
 
   // Currently we always assume that we have body.
-  // TODO(https://crbug.com/80374): Add error handling and bail out
+  // TODO(crbug.com/40558879): Add error handling and bail out
   // earlier if there's an error.
   mojo::ScopedDataPipeProducerHandle producer_handle;
   mojo::ScopedDataPipeConsumerHandle consumer_handle;
diff --git a/content/browser/web_package/signed_exchange_request_handler_browsertest.cc b/content/browser/web_package/signed_exchange_request_handler_browsertest.cc
index f9ede6d..3cecbfc 100644
--- a/content/browser/web_package/signed_exchange_request_handler_browsertest.cc
+++ b/content/browser/web_package/signed_exchange_request_handler_browsertest.cc
@@ -580,7 +580,7 @@
       UsePrefetch() ? 2 : 1);
 }
 
-// TODO(crbug.com/966820): Fails pretty often on Android.
+// TODO(crbug.com/41460883): Fails pretty often on Android.
 // TODO(crbug.com/40201215): Fails flakily on all platforms with Synchronous
 // HTML Parsing enabled.
 IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerBrowserTest,
@@ -925,7 +925,7 @@
   // This signed exchange should pass CertVerifier::Verify() and then fail at
   // SignedExchangeHandler::CheckOCSPStatus() because of the dummy OCSP
   // response.
-  // TODO(https://crbug.com/815024): Make this test pass the OCSP check. We'll
+  // TODO(crbug.com/40564303): Make this test pass the OCSP check. We'll
   // need to either generate an OCSP response on the fly, or override the OCSP
   // verification time.
   std::u16string title = u"Fallback URL response";
diff --git a/content/browser/webauth/authenticator_common_impl.cc b/content/browser/webauth/authenticator_common_impl.cc
index 93e8275..027b79b 100644
--- a/content/browser/webauth/authenticator_common_impl.cc
+++ b/content/browser/webauth/authenticator_common_impl.cc
@@ -1099,7 +1099,7 @@
     // These are magic values that a site can set to experiment with different
     // conditional UI behaviours.
     //
-    // TODO(crbug.com/1456525): remove this and everything else from
+    // TODO(crbug.com/40066138): remove this and everything else from
     // the CL that added it if this is unused by June 2024.
     switch (options->timeout->InMilliseconds()) {
       case 324441:
diff --git a/content/child/webthemeengine_impl_default_browsertest.cc b/content/child/webthemeengine_impl_default_browsertest.cc
index dcc47da..f95d5f7 100644
--- a/content/child/webthemeengine_impl_default_browsertest.cc
+++ b/content/child/webthemeengine_impl_default_browsertest.cc
@@ -24,7 +24,7 @@
   // The test non-deterministically fails on Windows-2008ServerR2 builders due
   // to a difference in the default theme. As a result, only run the test on
   // non-server versions.
-  // TODO(https://crbug.com/1385856): Remove this, and the windows_version.h
+  // TODO(crbug.com/40246975): Remove this, and the windows_version.h
   // include, if the failure turns out to be specific to Windows-2008ServerR2
   // and not any Windows server.
   if (base::win::OSInfo::GetInstance()->version_type() ==
diff --git a/content/common/background_fetch/background_fetch_types.cc b/content/common/background_fetch/background_fetch_types.cc
index 41d8b42..3fb78b6d 100644
--- a/content/common/background_fetch/background_fetch_types.cc
+++ b/content/common/background_fetch/background_fetch_types.cc
@@ -26,7 +26,7 @@
 // static
 blink::mojom::FetchAPIResponsePtr BackgroundFetchSettledFetch::CloneResponse(
     const blink::mojom::FetchAPIResponsePtr& response) {
-  // TODO(https://crbug.com/876546): Replace this method with response.Clone()
+  // TODO(crbug.com/41409379): Replace this method with response.Clone()
   // if the associated bug is fixed.
   if (response.is_null())
     return nullptr;
diff --git a/content/common/input/touch_action_filter.cc b/content/common/input/touch_action_filter.cc
index 07e2e75e..fbc993d 100644
--- a/content/common/input/touch_action_filter.cc
+++ b/content/common/input/touch_action_filter.cc
@@ -334,7 +334,7 @@
                (allowed_touch_action_.has_value()
                     ? cc::TouchActionToString(allowed_touch_action_.value())
                     : "n/a"));
-  // TODO(https://crbug.com/849819): add a DCHECK for
+  // TODO(crbug.com/40579429): add a DCHECK for
   // |has_touch_event_handler_|.
   // For multiple fingers, we take the intersection of the touch actions for
   // all fingers that have gone down during this action.  In the majority of
diff --git a/content/common/profiling_utils.cc b/content/common/profiling_utils.cc
index 5a6ab1c1..9ff52b4b 100644
--- a/content/common/profiling_utils.cc
+++ b/content/common/profiling_utils.cc
@@ -77,7 +77,7 @@
 
   // sajjadm@ and liaoyuke@ experimentally determined that a size 4 pool works
   // well for the coverage builder.
-  // TODO(https://crbug.com/1059335): Check if this is an appropriate value for
+  // TODO(crbug.com/40121559): Check if this is an appropriate value for
   // the PGO builds.
   int pool_index = base::RandInt(0, 3);
   std::string filename = base::StrCat(
diff --git a/content/public/browser/notification_types.h b/content/public/browser/notification_types.h
index 0bafc9c5..9338eca1 100644
--- a/content/public/browser/notification_types.h
+++ b/content/public/browser/notification_types.h
@@ -27,7 +27,7 @@
   //
   // DEPRECATED:
   // Use RenderWidgetHostObserver::RenderWidgetHostVisibilityChanged()
-  // TODO(https://crbug.com/1174771): Remove.
+  // TODO(crbug.com/40746966): Remove.
   NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
 };
 
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h
index 54d9a5a..f1f8b457 100644
--- a/content/public/browser/render_process_host.h
+++ b/content/public/browser/render_process_host.h
@@ -753,7 +753,7 @@
 
   // Return the spare RenderProcessHost, if it exists. There is at most one
   // globally-used spare RenderProcessHost at any time.
-  // TODO(crbug.com/1519190): remove the non-test method once the performance
+  // TODO(crbug.com/41492171): remove the non-test method once the performance
   // investigation is finished.
   static RenderProcessHost* GetSpareRenderProcessHost();
   static RenderProcessHost* GetSpareRenderProcessHostForTesting();
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index 811fde7..51919f7a6 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -843,7 +843,7 @@
   // Sets the visibility of the WebContents' view and notifies the WebContents
   // observers about Visibility change. Call UpdateWebContentsVisibility instead
   // of WasShown() if you are setting Visibility to VISIBLE for the first time.
-  // TODO(crbug.com/1444248): Make updating Visibility more robust.
+  // TODO(crbug.com/40911760): Make updating Visibility more robust.
   virtual void UpdateWebContentsVisibility(Visibility visibility) = 0;
 
   // This function checks *all* frames in this WebContents (not just the main
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 97299f0..f8185bd 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -1193,7 +1193,7 @@
              base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Apply text selection menu order correction logic for Android.
-// TODO(https://crbug.com/1506484) This is a kill switch landed in M122.
+// TODO(crbug.com/40947146) This is a kill switch landed in M122.
 // Please remove after M124.
 BASE_FEATURE(kSelectionMenuItemModification,
              "SelectionMenuItemModification",
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index a207a84..b9157706 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -891,7 +891,7 @@
 // Enables negotiation of encrypted header extensions from RFC 6904 for SRTP
 // in WebRTC.
 // See https://tools.ietf.org/html/rfc6904 for further information.
-// TODO(https://crbug.com/954201): Remove this.
+// TODO(crbug.com/40623740): Remove this.
 const char kEnableWebRtcSrtpEncryptedHeaders[] =
     "enable-webrtc-srtp-encrypted-headers";
 
diff --git a/content/public/common/zygote/sandbox_support_linux.h b/content/public/common/zygote/sandbox_support_linux.h
index 9e84459..d153d3b7 100644
--- a/content/public/common/zygote/sandbox_support_linux.h
+++ b/content/public/common/zygote/sandbox_support_linux.h
@@ -13,7 +13,7 @@
 
 namespace content {
 
-// TODO(crbug.com/982879): Remove this when NaCl is unshipped.
+// TODO(crbug.com/41470149): Remove this when NaCl is unshipped.
 class CONTENT_EXPORT SharedMemoryIPCSupport {
  private:
   friend class ::NaClListener;
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc
index 20b1520..a41ce47 100644
--- a/content/public/test/browser_test_base.cc
+++ b/content/public/test/browser_test_base.cc
@@ -846,7 +846,7 @@
   // ProxyRunTestOnMainThreadLoop() happens later as part of SetUp()).
   std::optional<base::test::ScopedRunLoopTimeout> scoped_run_timeout;
   if (!base::test::ScopedRunLoopTimeout::ExistsForCurrentThread()) {
-    // TODO(https://crbug.com/918724): determine whether the timeout can be
+    // TODO(crbug.com/40608077): determine whether the timeout can be
     // reduced from action_max_timeout() to action_timeout().
     scoped_run_timeout.emplace(FROM_HERE, TestTimeouts::action_max_timeout());
   }
diff --git a/content/public/test/fenced_frame_test_util.h b/content/public/test/fenced_frame_test_util.h
index e1f8e59b..8040f18 100644
--- a/content/public/test/fenced_frame_test_util.h
+++ b/content/public/test/fenced_frame_test_util.h
@@ -59,7 +59,7 @@
   // (which may be different from the one that navigation started in), and
   // `nullptr` otherwise. It takes an `expected_error_code` in case the
   // navigation to `url` fails, which can be detected on a per-error-code basis.
-  // TODO(crbug.com/1294189): Directly use TestFrameNavigationObserver instead
+  // TODO(crbug.com/40820418): Directly use TestFrameNavigationObserver instead
   // of relying on this method.
   RenderFrameHost* NavigateFrameInFencedFrameTree(
       RenderFrameHost* rfh,
diff --git a/content/public/test/test_navigation_observer.cc b/content/public/test/test_navigation_observer.cc
index 0d52cad2..2b8e3915 100644
--- a/content/public/test/test_navigation_observer.cc
+++ b/content/public/test/test_navigation_observer.cc
@@ -251,7 +251,7 @@
   WebContentsState* web_contents_state =
       GetWebContentsState(navigation_handle->GetWebContents());
 
-  // TODO(crbug.com/1233764): It is generally the case that we've received load
+  // TODO(crbug.com/40191691): It is generally the case that we've received load
   // started events by this point, but we don't send load events for prerendered
   // pages (by design). It's also the case that frame tree nodes don't report
   // load start if the tree is already loading. For all of prerendering,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 1f7ee84..867ff0f 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -6674,7 +6674,7 @@
     pip_mojom_opts->height = pip_options->height;
     // TODO(crbug.com/40911987): Remove this from mojom and the browser side.
     pip_mojom_opts->initial_aspect_ratio = 0.0;
-    // TODO(crbug.com/1410379): Remove this from mojom and the browser side.
+    // TODO(crbug.com/40889673): Remove this from mojom and the browser side.
     pip_mojom_opts->lock_aspect_ratio = false;
     pip_mojom_opts->disallow_return_to_opener =
         pip_options->disallow_return_to_opener;
diff --git a/content/shell/tools/breakpad_integration_test.py b/content/shell/tools/breakpad_integration_test.py
index c18c14a5..836d5dd 100755
--- a/content/shell/tools/breakpad_integration_test.py
+++ b/content/shell/tools/breakpad_integration_test.py
@@ -93,7 +93,7 @@
     time.sleep(5)
 
   if len(dumps) != 1:
-    # TODO(crbug.com/861730): Temporary code to debug unexpected crash dumps.
+    # TODO(crbug.com/41400491): Temporary code to debug unexpected crash dumps.
     minidump_stackwalk = os.path.join(options.build_dir, 'minidump_stackwalk')
     failure = 'Failed to run minidump_stackwalk.'
     for dump in dumps:
diff --git a/device/fido/cable/fido_ble_frames.h b/device/fido/cable/fido_ble_frames.h
index e4b3dc7..2474dcc1 100644
--- a/device/fido/cable/fido_ble_frames.h
+++ b/device/fido/cable/fido_ble_frames.h
@@ -27,7 +27,8 @@
 // The specification of what constitues a frame can be found here:
 // https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-bt-protocol-v1.2-ps-20170411.html#h2_framing
 //
-// TODO(crbug/763303): Consider refactoring U2fMessage to support BLE frames.
+// TODO(crbug.com/40539129): Consider refactoring U2fMessage to support BLE
+// frames.
 class COMPONENT_EXPORT(DEVICE_FIDO) FidoBleFrame {
  public:
   // The values which can be carried in the |data| section of a KEEPALIVE
diff --git a/docs/updating_clang.md b/docs/updating_clang.md
index 05737095..f4d1daa4 100644
--- a/docs/updating_clang.md
+++ b/docs/updating_clang.md
@@ -63,10 +63,24 @@
   compiler, a linker, sanitizer runtimes)
 - things needed for doing official builds
 
-If you want to add something to the clang package that doesn't (yet?) meet
-these criteria, you can make package.py upload it to a separate zip file
-and then download it on an opt-in basis by using update.py's --package option.
+# Adding a New Package
 
-If you're adding a new feature that you expect will meet the inclusion criteria
-eventually but doesn't yet, start by having your things in a separate zip
-and move it to the main zip once the criteria are met.
+If you want to make artifacts available that do not meet the criteria for
+being included in the "clang" package, you can make package.py upload it to
+a separate zip file and then download it on an opt-in basis by using
+update.py's --package option.  Here is [an example of adding a new package].
+
+To test changes to `package.py`, change `CLANG_SUB_REVISION` in `update.py` to
+a random number above 2000 and run the `*_upload_clang` trybots.
+
+Once the change to `package.py` is in, file a bug under `Tools > LLVM`
+requesting that a new package be created ([example bug]).
+
+Once it's been uploaded and rolled, you can download it via:
+
+```
+tools/clang/scripts/update.py --package your-package-name
+```
+
+[an example of adding a new package](https://chromium-review.googlesource.com/c/chromium/src/+/5463029)
+[example bug]: https://crbug.com/335730441
\ No newline at end of file
diff --git a/docs/webapps/isolated_web_apps.md b/docs/webapps/isolated_web_apps.md
index 1b6ee4d..9fc2fb8 100644
--- a/docs/webapps/isolated_web_apps.md
+++ b/docs/webapps/isolated_web_apps.md
@@ -41,7 +41,7 @@
 6. The validity of the Integrity Block is verified by
    `IsolatedWebAppValidator::ValidateIntegrityBlock`. This includes a check on
    whether the browser trusts the public key(s) used to sign the Web Bundle.
-   TODO(crbug.com/1365852): Not yet implemented.
+   TODO(crbug.com/40239530): Not yet implemented.
 7. If the Integrity Block is valid, then:
    - On non-ChromeOS: The signatures contained in the Isolated Web App are
      verified using `web_package::SignedWebBundleSignatureVerifier`.
diff --git a/extensions/browser/api/declarative_net_request/flat/extension_ruleset.fbs b/extensions/browser/api/declarative_net_request/flat/extension_ruleset.fbs
index c4d87e1..ab0fd07 100644
--- a/extensions/browser/api/declarative_net_request/flat/extension_ruleset.fbs
+++ b/extensions/browser/api/declarative_net_request/flat/extension_ruleset.fbs
@@ -93,7 +93,7 @@
 
   /// Headers to include/exclude. Note that `excluded_response_headers` will
   /// only match on header names.
-  /// TODO(crbug.com/1510018): Consider relocating these header conditions as
+  /// TODO(crbug.com/41482616): Consider relocating these header conditions as
   /// they apply to requests and what "embeds" the requests (such as the
   /// browser). One potentially suitable place would be a new table in the
   /// UrlPatternIndex for more complex conditions from requests and responses,
diff --git a/extensions/browser/api/file_handlers/app_file_handler_util.cc b/extensions/browser/api/file_handlers/app_file_handler_util.cc
index c3ff3ec..4293e5b6 100644
--- a/extensions/browser/api/file_handlers/app_file_handler_util.cc
+++ b/extensions/browser/api/file_handlers/app_file_handler_util.cc
@@ -411,7 +411,7 @@
 
 bool WebAppFileHandlerCanHandleEntry(const apps::FileHandler& handler,
                                      const EntryInfo& entry) {
-  // TODO(crbug.com/938103): At the moment, apps::FileHandler doesn't have an
+  // TODO(crbug.com/41444843): At the moment, apps::FileHandler doesn't have an
   // include_directories flag. It may be necessary to add one as this new
   // representation replaces apps::FileHandlerInfo.
   if (entry.is_directory)
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc
index f031257..0c0973f2 100644
--- a/extensions/browser/api/web_request/web_request_api.cc
+++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -281,7 +281,7 @@
       proxies_(std::make_unique<ProxySet>()),
       may_have_proxies_(MayHaveProxies()) {
   EventRouter* event_router = EventRouter::Get(browser_context_);
-  // TODO(crbug.com/433136): Once ExtensionWebRequestEventRouter is a per-
+  // TODO(crbug.com/40393861): Once ExtensionWebRequestEventRouter is a per-
   // BrowserContext instance, it can observe these events itself. That's a
   // bit tricky right now because the singleton instance would need to
   // observe the EventRouter for each BrowserContext that has webRequest
diff --git a/extensions/browser/api/web_request/web_request_resource_type.cc b/extensions/browser/api/web_request/web_request_resource_type.cc
index 5e2b532a7..401e69a 100644
--- a/extensions/browser/api/web_request/web_request_resource_type.cc
+++ b/extensions/browser/api/web_request/web_request_resource_type.cc
@@ -69,7 +69,7 @@
     case network::mojom::RequestDestination::kXslt:
       return WebRequestResourceType::STYLESHEET;
     case network::mojom::RequestDestination::kScript:
-    // TODO(crbug.com/1511722): Consider adding a new
+    // TODO(crbug.com/41484304): Consider adding a new
     // webRequest.ResourceType for JSON requests modules.
     case network::mojom::RequestDestination::kJson:
       return WebRequestResourceType::SCRIPT;
diff --git a/extensions/browser/events/event_ack_data.cc b/extensions/browser/events/event_ack_data.cc
index 75dfd18..9b559cd 100644
--- a/extensions/browser/events/event_ack_data.cc
+++ b/extensions/browser/events/event_ack_data.cc
@@ -220,7 +220,7 @@
     // torn down when EventRouter + BrowserContext are still alive and an
     // event happens to be acked here.
     case content::ServiceWorkerExternalRequestResult::kNullContext:
-      // TODO(crbug.com/1521084): Perform more graceful shutdown when
+      // TODO(crbug.com/41494056): Perform more graceful shutdown when
       // ServiceWorkerContextCore is torn down.
 
     // kBadRequestId can expectedly happen if a new instance of a worker starts
diff --git a/extensions/browser/extension_function.cc b/extensions/browser/extension_function.cc
index 329d1b8..ebdd086 100644
--- a/extensions/browser/extension_function.cc
+++ b/extensions/browser/extension_function.cc
@@ -459,14 +459,14 @@
 }
 
 bool ExtensionFunction::PreRunValidation(std::string* error) {
-  // TODO(crbug.com/625646) This is a partial fix to avoid crashes when certain
-  // extension functions run during shutdown. Browser or Notification creation
-  // for example create a ScopedKeepAlive, which hit a CHECK if the browser is
-  // shutting down. This fixes the current problem as the known issues happen
-  // through synchronous calls from Run(), but posted tasks will not be covered.
-  // A possible fix would involve refactoring ExtensionFunction: unrefcount
-  // here and use weakptrs for the tasks, then have it owned by something that
-  // will be destroyed naturally in the course of shut down.
+  // TODO(crbug.com/40475418) This is a partial fix to avoid crashes when
+  // certain extension functions run during shutdown. Browser or Notification
+  // creation for example create a ScopedKeepAlive, which hit a CHECK if the
+  // browser is shutting down. This fixes the current problem as the known
+  // issues happen through synchronous calls from Run(), but posted tasks will
+  // not be covered. A possible fix would involve refactoring ExtensionFunction:
+  // unrefcount here and use weakptrs for the tasks, then have it owned by
+  // something that will be destroyed naturally in the course of shut down.
   if (extensions::ExtensionsBrowserClient::Get()->IsShuttingDown()) {
     *error = "The browser is shutting down.";
     return false;
diff --git a/extensions/browser/script_injection_tracker.cc b/extensions/browser/script_injection_tracker.cc
index 1fd278f..0bcfb2e 100644
--- a/extensions/browser/script_injection_tracker.cc
+++ b/extensions/browser/script_injection_tracker.cc
@@ -685,7 +685,7 @@
   // Notify URLLoaderFactoryManager for both user and content scripts. This
   // needs to happen at ReadyToCommitNavigation time (i.e. before constructing a
   // URLLoaderFactory that will be sent to the Renderer in a Commit IPC).
-  // TODO(crbug.com/1495177): This should only use webview scripts, since it's
+  // TODO(crbug.com/40286422): This should only use webview scripts, since it's
   // not needed for all extensions.
   extensions_injecting_content_scripts.reserve(
       extensions_injecting_content_scripts.size() +
diff --git a/extensions/browser/service_worker/service_worker_task_queue.h b/extensions/browser/service_worker/service_worker_task_queue.h
index 20183487..a76eaaf 100644
--- a/extensions/browser/service_worker/service_worker_task_queue.h
+++ b/extensions/browser/service_worker/service_worker_task_queue.h
@@ -304,7 +304,7 @@
   // A map of Service Worker registrations if this instance is for an
   // off-the-record BrowserContext. These are stored in the ExtensionPrefs
   // for a regular profile.
-  // TODO(crbug.com/939664): Make this better by passing in something that
+  // TODO(crbug.com/40617251): Make this better by passing in something that
   // will manage storing and retrieving this data.
   base::flat_map<ExtensionId, base::Version> off_the_record_registrations_;
 
diff --git a/extensions/browser/user_script_loader.cc b/extensions/browser/user_script_loader.cc
index 305e03a..81a6fb14 100644
--- a/extensions/browser/user_script_loader.cc
+++ b/extensions/browser/user_script_loader.cc
@@ -522,7 +522,7 @@
         // For Controlled Frame embedders, |owner_host| will be a serialized
         // form of the embedder's origin, using scheme, host, port [if
         // applicable] tuple in origin form. No trailing slash.
-        // TODO(crbug.com/1517391): Use an actual Origin object in the
+        // TODO(crbug.com/41490369): Use an actual Origin object in the
         // Controlled Frame comparison rather than a serialized Origin.
         if (owner_host != host_id().id) {
           return SendUpdateResult::kNoActionTaken;
diff --git a/extensions/browser/zipfile_installer.cc b/extensions/browser/zipfile_installer.cc
index 263148e..f66a2e9 100644
--- a/extensions/browser/zipfile_installer.cc
+++ b/extensions/browser/zipfile_installer.cc
@@ -258,7 +258,7 @@
       },
       manifest_type == Manifest::TYPE_THEME);
 
-  // TODO(crbug.com/645263): This silently ignores blocked file types.
+  // TODO(crbug.com/41274425): This silently ignores blocked file types.
   //                         Add install warnings.
   unzip::UnzipWithFilter(
       unzip::LaunchUnzipper(), zip_file_, unzip_dir, filter,
diff --git a/extensions/renderer/api/automation/automation_internal_custom_bindings_unittests.cc b/extensions/renderer/api/automation/automation_internal_custom_bindings_unittests.cc
index b80cca8..afd9b518 100644
--- a/extensions/renderer/api/automation/automation_internal_custom_bindings_unittests.cc
+++ b/extensions/renderer/api/automation/automation_internal_custom_bindings_unittests.cc
@@ -38,7 +38,7 @@
     script_context->set_url(extension->url());
     bindings_system()->UpdateBindingsForContext(script_context);
 
-    // TODO(crbug/1487002) Add tests for service worker.
+    // TODO(crbug.com/40283128) Add tests for service worker.
     auto automation_internal_bindings =
         std::make_unique<AutomationInternalCustomBindings>(script_context,
                                                            bindings_system());
diff --git a/extensions/renderer/api_activity_logger.cc b/extensions/renderer/api_activity_logger.cc
index cbe366d..54728f60 100644
--- a/extensions/renderer/api_activity_logger.cc
+++ b/extensions/renderer/api_activity_logger.cc
@@ -162,7 +162,7 @@
     converter->SetFunctionAllowed(true);
     converter->SetStrategy(&strategy);
     for (size_t i = 0; i < arg_array->Length(); ++i) {
-      // TODO(crbug.com/913942): Possibly replace ToLocalChecked here with
+      // TODO(crbug.com/40605992): Possibly replace ToLocalChecked here with
       // actual error handling.
       std::unique_ptr<base::Value> converted_arg = converter->FromV8Value(
           arg_array->Get(context, i).ToLocalChecked(), context);
diff --git a/extensions/renderer/resources/set_icon.js b/extensions/renderer/resources/set_icon.js
index ae2b54e0..3b4f44d 100644
--- a/extensions/renderer/resources/set_icon.js
+++ b/extensions/renderer/resources/set_icon.js
@@ -180,7 +180,7 @@
   };
 }
 
-// TODO(crbug.com/462542): The setIcon export is only used by the declarative
+// TODO(crbug.com/41159896): The setIcon export is only used by the declarative
 // content custom bindings and it actually has some major problems with how it
 // uses it. When that is resolved we can likely remove this export.
 exports.$set('setIcon', setIcon);
diff --git a/fuchsia_web/webengine/browser/frame_impl.cc b/fuchsia_web/webengine/browser/frame_impl.cc
index 190aec1..040fcc6 100644
--- a/fuchsia_web/webengine/browser/frame_impl.cc
+++ b/fuchsia_web/webengine/browser/frame_impl.cc
@@ -123,8 +123,8 @@
 };
 
 bool FrameFocusRules::SupportsChildActivation(const aura::Window*) const {
-  // TODO(crbug.com/878439): Return a result based on window properties such as
-  // visibility.
+  // TODO(crbug.com/40591214): Return a result based on window properties such
+  // as visibility.
   return true;
 }
 
diff --git a/google_apis/gaia/gaia_auth_fetcher.h b/google_apis/gaia/gaia_auth_fetcher.h
index 6c8a6c3..d71aff63 100644
--- a/google_apis/gaia/gaia_auth_fetcher.h
+++ b/google_apis/gaia/gaia_auth_fetcher.h
@@ -201,7 +201,7 @@
   // Needed to use XmlHTTPRequest for Multilogin requeston iOS even after
   // iOS11 because WKWebView cannot read response body if content-disposition
   // header is set.
-  // TODO(https://crbug.com/889471) Remove this once requests are done using
+  // TODO(crbug.com/40595504) Remove this once requests are done using
   // NSUrlSession in iOS.
   bool IsMultiloginUrl(const GURL& url);
 
diff --git a/google_apis/gcm/base/socket_stream.cc b/google_apis/gcm/base/socket_stream.cc
index ca4e94e..2bae588 100644
--- a/google_apis/gcm/base/socket_stream.cc
+++ b/google_apis/gcm/base/socket_stream.cc
@@ -10,6 +10,7 @@
 
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
+#include "base/numerics/safe_conversions.h"
 #include "net/base/io_buffer.h"
 #include "net/socket/stream_socket.h"
 
@@ -108,7 +109,7 @@
     return net::OK;
   }
 
-  read_size_ = byte_limit;
+  read_size_ = base::checked_cast<size_t>(byte_limit);
   read_callback_ = std::move(callback);
   stream_watcher_.ArmOrNotify();
   last_error_ = net::ERR_IO_PENDING;
@@ -121,7 +122,7 @@
   DCHECK(read_callback_);
   DCHECK_NE(0u, read_size_);
 
-  uint32_t num_bytes = read_size_;
+  size_t num_bytes = read_size_;
   if (result == MOJO_RESULT_OK) {
     DVLOG(1) << "Refreshing input stream, limit of " << num_bytes << " bytes.";
     result = stream_->ReadData(read_buffer_->data(), &num_bytes,
@@ -154,7 +155,7 @@
     return;
 
   last_error_ = net::OK;
-  read_buffer_->DidConsume(num_bytes);
+  read_buffer_->DidConsume(base::checked_cast<uint32_t>(num_bytes));
   // TODO(zea): investigating crbug.com/409985
   CHECK_GT(UnreadByteCount(), 0);
 
@@ -288,7 +289,8 @@
   DCHECK(write_callback_);
   DCHECK(write_buffer_);
 
-  uint32_t num_bytes = write_buffer_->BytesRemaining();
+  size_t num_bytes =
+      base::checked_cast<size_t>(write_buffer_->BytesRemaining());
   DVLOG(1) << "Flushing " << num_bytes << " bytes into socket.";
   if (result == MOJO_RESULT_OK) {
     result = stream_->WriteData(write_buffer_->data(), &num_bytes,
@@ -312,7 +314,7 @@
 
   DCHECK_GE(num_bytes, 0u);
   last_error_ = net::OK;
-  write_buffer_->DidConsume(num_bytes);
+  write_buffer_->DidConsume(base::checked_cast<uint32_t>(num_bytes));
   if (write_buffer_->BytesRemaining() > 0) {
     DVLOG(1) << "Partial flush complete. Retrying.";
     // Only a partial write was completed. Flush again to finish the write.
diff --git a/google_apis/gcm/base/socket_stream.h b/google_apis/gcm/base/socket_stream.h
index 7b0ceda22..4eee29315 100644
--- a/google_apis/gcm/base/socket_stream.h
+++ b/google_apis/gcm/base/socket_stream.h
@@ -115,7 +115,7 @@
   // Internal net components.
   mojo::ScopedDataPipeConsumerHandle stream_;
   mojo::SimpleWatcher stream_watcher_;
-  uint32_t read_size_;
+  size_t read_size_;
   const scoped_refptr<net::IOBuffer> io_buffer_;
   base::OnceClosure read_callback_;
   // IOBuffer implementation that wraps the data within |io_buffer_| that hasn't
diff --git a/google_apis/gcm/base/socket_stream_unittest.cc b/google_apis/gcm/base/socket_stream_unittest.cc
index 8d3d5c2..e0ff449 100644
--- a/google_apis/gcm/base/socket_stream_unittest.cc
+++ b/google_apis/gcm/base/socket_stream_unittest.cc
@@ -428,7 +428,7 @@
 
   // Prepopulate |producer_handle| of |prefix_data|, now the pipe's capacity is
   // less than |kWriteDataSize|.
-  uint32_t num_bytes = prefix_data.size();
+  size_t num_bytes = prefix_data.size();
   MojoResult r = producer_handle->WriteData(prefix_data.data(), &num_bytes,
                                             MOJO_WRITE_DATA_FLAG_NONE);
   ASSERT_EQ(MOJO_RESULT_OK, r);
@@ -451,7 +451,7 @@
   std::string contents;
   // Read prefix.
   char buffer[kPrefixDataSize];
-  uint32_t read_size = sizeof(buffer);
+  size_t read_size = sizeof(buffer);
   ASSERT_EQ(MOJO_RESULT_OK, consumer_handle->ReadData(
                                 buffer, &read_size, MOJO_READ_DATA_FLAG_NONE));
   ASSERT_EQ(kPrefixDataSize, read_size);
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index cb7ef2ad..029a579 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -481,9 +481,9 @@
                          ->AllocateIDAtOrAbove(last_gpu_fence_id_ + 1);
   // Out of paranoia, don't allow IDs to wrap around to avoid potential
   // collisions on reuse. The space of 2^32 IDs is enough for over a year of
-  // allocating two per frame at 60fps. TODO(crbug.com/790550): Revisit if this
-  // is an issue, for example by deferring ID release if they would be reissued
-  // too soon.
+  // allocating two per frame at 60fps. TODO(crbug.com/40552536): Revisit if
+  // this is an issue, for example by deferring ID release if they would be
+  // reissued too soon.
   CHECK(client_id > last_gpu_fence_id_) << "ID wrap prevented";
   last_gpu_fence_id_ = client_id;
   helper_->CreateGpuFenceINTERNAL(client_id);
diff --git a/gpu/command_buffer/common/mailbox.cc b/gpu/command_buffer/common/mailbox.cc
index 91d36c91..27a945c 100644
--- a/gpu/command_buffer/common/mailbox.cc
+++ b/gpu/command_buffer/common/mailbox.cc
@@ -70,7 +70,7 @@
   return name[kSharedImageFlagIndex] & kSharedImageFlag;
 }
 
-Mailbox Mailbox::GenerateLegacyMailbox() {
+Mailbox Mailbox::GenerateLegacySharedBitmapMailbox() {
   return GenerateMailbox(false /* is_shared_image */);
 }
 
diff --git a/gpu/command_buffer/common/mailbox.h b/gpu/command_buffer/common/mailbox.h
index ebbaae0..5e6de03 100644
--- a/gpu/command_buffer/common/mailbox.h
+++ b/gpu/command_buffer/common/mailbox.h
@@ -17,20 +17,12 @@
 #define GL_MAILBOX_SIZE_CHROMIUM 16
 #endif
 
-namespace content {
-class PPB_Graphics3D_Impl;
-}
-
-namespace media {
-class GLES2DecoderHelperImpl;
+namespace viz {
+class SharedBitmap;
 }
 
 namespace gpu {
 
-namespace gles2 {
-class GLES2Implementation;
-}
-
 // Importance to use in tracing. Higher values get the memory cost attributed,
 // and equal values share the cost. We want the client to "win" over the
 // service, since the service is acting on its behalf.
@@ -68,12 +60,6 @@
   // system.
   static Mailbox GenerateForSharedImage();
 
-  // A temporary solution until when kSharedBitmapToSharedImage is enabled by
-  // default and the legacy ShareBitmap path is removed.
-  static Mailbox GenerateLegacyMailboxForSharedBitmap() {
-    return GenerateLegacyMailbox();
-  }
-
   // Verify that the mailbox was created through Mailbox::Generate. This only
   // works in Debug (always returns true in Release). This is not a secure
   // check, only to catch bugs where clients forgot to call Mailbox::Generate.
@@ -87,22 +73,19 @@
   Name name;
 
  private:
-  // Generate a unique unguessable mailbox name for use with the legacy mailbox
-  // system.
-  // NOTE: We are in the process of eliminating this method. DO NOT ADD ANY NEW
-  // USAGES - instead, reach out to shared-image-team@ with your use case. See
-  // crbug.com/1273084.
-  static Mailbox GenerateLegacyMailbox();
+  // A temporary solution until when kSharedBitmapToSharedImage is enabled by
+  // default and the legacy ShareBitmap path is removed.
+  static Mailbox GenerateLegacySharedBitmapMailbox();
 
-  friend class content::PPB_Graphics3D_Impl;
-  friend class gles2::GLES2Implementation;
-  friend class media::GLES2DecoderHelperImpl;
+  friend class viz::SharedBitmap;
 
  public:
   // Generate a legacy mailbox for usage in tests of production code that
   // still interacts with the legacy mailbox system.
+  // TODO(crbug.com/40057997): Remove all tests that use this functionality, as
+  // they are testing codepaths no longer used in production.
   static Mailbox GenerateLegacyMailboxForTesting() {
-    return GenerateLegacyMailbox();
+    return GenerateLegacySharedBitmapMailbox();
   }
 };
 
diff --git a/gpu/command_buffer/common/shared_image_usage.h b/gpu/command_buffer/common/shared_image_usage.h
index abaeb4c..23a93082 100644
--- a/gpu/command_buffer/common/shared_image_usage.h
+++ b/gpu/command_buffer/common/shared_image_usage.h
@@ -54,7 +54,7 @@
   SHARED_IMAGE_USAGE_RAW_DRAW = 1 << 14,
   // Image will be used in RasterInterface for DelegatedCompositing.
   // This is intended to avoid the overhead of a GPU fence per tile.
-  // TODO(crbug.com/1519911): In order to delegate buffers we need all buffer
+  // TODO(crbug.com/41492887): In order to delegate buffers we need all buffer
   // allocations to be set as SCANOUT. This will cause a fence per rastered
   // tiled. A new buffer concept that avoids scanout but allows delegation might
   // enable us to remove this usage.
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index a351ac1..2fa0edf 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -3836,7 +3836,7 @@
   if (((shader_spec == SH_WEBGL_SPEC || shader_spec == SH_WEBGL2_SPEC) &&
        features().enable_shader_name_hashing) ||
       force_shader_name_hashing_for_test) {
-    // TODO(https://crbug.com/902789): In theory, it should be OK to change this
+    // TODO(crbug.com/40601370): In theory, it should be OK to change this
     // hash. However, in practice, this seems to cause some tests to fail. See
     // https://crbug.com/963889.
     resources.HashFunction = +[](const char* data, size_t size) {
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
index cbbc051..0abcb578 100644
--- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
@@ -4,6 +4,7 @@
 
 #include "gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h"
 
+#include "base/feature_list.h"
 #include "base/logging.h"
 #include "components/viz/common/gpu/vulkan_context_provider.h"
 #include "components/viz/common/resources/shared_image_format_utils.h"
@@ -38,6 +39,10 @@
 
 namespace {
 
+BASE_FEATURE(kCorrectColorAttachmentUsageComputationInAngleVk,
+             "CorrectColorAttachmentUsageComputationInAngleVk",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
 gl::ScopedEGLImage CreateEGLImage(VkImage image,
                                   const VkImageCreateInfo* create_info,
                                   unsigned int internal_format) {
@@ -280,16 +285,28 @@
     const base::span<const uint8_t>& data) {
   auto* device_queue = context_state_->vk_context_provider()->GetDeviceQueue();
 
-  constexpr auto kUsageNeedsColorAttachment =
-      SHARED_IMAGE_USAGE_GLES2_READ | SHARED_IMAGE_USAGE_GLES2_WRITE |
-      SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT |
-      SHARED_IMAGE_USAGE_RASTER_READ | SHARED_IMAGE_USAGE_RASTER_WRITE |
-      SHARED_IMAGE_USAGE_OOP_RASTERIZATION | SHARED_IMAGE_USAGE_WEBGPU_READ |
-      SHARED_IMAGE_USAGE_WEBGPU_WRITE;
+  uint32_t usages_needing_color_attachment = 0;
+  // This killswitch guards the correction of the computation on using the color
+  // attachment, which conceptually is "can this backing be written".
+  // TODO(crbug.com/333014977): Remove this killswitch post safe rollout.
+  if (base::FeatureList::IsEnabled(
+          kCorrectColorAttachmentUsageComputationInAngleVk)) {
+    usages_needing_color_attachment = SHARED_IMAGE_USAGE_GLES2_WRITE |
+                                      SHARED_IMAGE_USAGE_RASTER_WRITE |
+                                      SHARED_IMAGE_USAGE_DISPLAY_WRITE;
+  } else {
+    usages_needing_color_attachment =
+        SHARED_IMAGE_USAGE_GLES2_READ | SHARED_IMAGE_USAGE_GLES2_WRITE |
+        SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT |
+        SHARED_IMAGE_USAGE_RASTER_READ | SHARED_IMAGE_USAGE_RASTER_WRITE |
+        SHARED_IMAGE_USAGE_OOP_RASTERIZATION | SHARED_IMAGE_USAGE_WEBGPU_READ |
+        SHARED_IMAGE_USAGE_WEBGPU_WRITE;
+  }
+
   VkImageUsageFlags vk_usage = VK_IMAGE_USAGE_SAMPLED_BIT |
                                VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
                                VK_IMAGE_USAGE_TRANSFER_DST_BIT;
-  if (usage() & kUsageNeedsColorAttachment) {
+  if (usage() & usages_needing_color_attachment) {
     vk_usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
                 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
     if (format().IsCompressed()) {
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.cc
index 04c07b5..9c2de46 100644
--- a/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.cc
@@ -7,7 +7,6 @@
 #include <list>
 #include <utility>
 
-#include "base/feature_list.h"
 #include "build/build_config.h"
 #include "gpu/command_buffer/common/mailbox.h"
 #include "gpu/command_buffer/common/shared_image_usage.h"
@@ -20,10 +19,6 @@
 namespace gpu {
 namespace {
 
-BASE_FEATURE(kCorrectFramebufferAttachmentComputationInGLTexture,
-             "CorrectFramebufferAttachmentComputationInGLTexture",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 constexpr uint32_t kWebGPUUsages =
     SHARED_IMAGE_USAGE_WEBGPU_READ | SHARED_IMAGE_USAGE_WEBGPU_WRITE |
     SHARED_IMAGE_USAGE_WEBGPU_SWAP_CHAIN_TEXTURE |
@@ -255,26 +250,13 @@
     base::span<const uint8_t> pixel_data) {
   DCHECK(CanCreateTexture(format, size, pixel_data, GL_TEXTURE_2D));
 
-  bool for_framebuffer_attachment = false;
-  // NOTE: We are in the process of computing writes to GL without using
-  // GLES2_FRAMEBUFFER_HINT as part of eliminating the latter. Here we make the
-  // change guarded by a killswitch.
-  // TODO(b/41491709): Remove this killswitch post safe rollout.
-  if (base::FeatureList::IsEnabled(
-          kCorrectFramebufferAttachmentComputationInGLTexture)) {
-    // GLTextureImageBackingFactory supports raster and display usage only for
-    // Ganesh-GL, meaning that raster/display write usage implies GL writes
-    // within Skia.
-    for_framebuffer_attachment = usage & (SHARED_IMAGE_USAGE_GLES2_WRITE |
-                                          SHARED_IMAGE_USAGE_RASTER_WRITE |
-                                          SHARED_IMAGE_USAGE_DISPLAY_WRITE);
-  } else {
-    for_framebuffer_attachment =
-        (usage &
-         (SHARED_IMAGE_USAGE_RASTER_READ | SHARED_IMAGE_USAGE_RASTER_WRITE |
-          SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT)) != 0;
-  }
-
+  // GLTextureImageBackingFactory supports raster and display usage only for
+  // Ganesh-GL, meaning that raster/display write usage implies GL writes
+  // within Skia.
+  const bool for_framebuffer_attachment =
+      usage &
+      (SHARED_IMAGE_USAGE_GLES2_WRITE | SHARED_IMAGE_USAGE_RASTER_WRITE |
+       SHARED_IMAGE_USAGE_DISPLAY_WRITE);
   const bool framebuffer_attachment_angle =
       for_framebuffer_attachment && texture_usage_angle_;
 
diff --git a/gpu/command_buffer/service/shared_image/ozone_image_backing.cc b/gpu/command_buffer/service/shared_image/ozone_image_backing.cc
index 66f127f..2b5fa2c 100644
--- a/gpu/command_buffer/service/shared_image/ozone_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/ozone_image_backing.cc
@@ -796,7 +796,7 @@
     // having the SI framework creating fences for each single message when
     // write access ends.
 
-    // TODO(crbug.com/1522940): Implement vk fence optimization in the case of
+    // TODO(crbug.com/41495896): Implement vk fence optimization in the case of
     // raster delegation.
     const bool skip_fence_in_delegation =
         (usage() & SHARED_IMAGE_USAGE_RASTER_DELEGATED_COMPOSITING) &&
diff --git a/gpu/command_buffer/tests/gl_map_buffer_range_unittest.cc b/gpu/command_buffer/tests/gl_map_buffer_range_unittest.cc
index bae4d3b7..4598e7c 100644
--- a/gpu/command_buffer/tests/gl_map_buffer_range_unittest.cc
+++ b/gpu/command_buffer/tests/gl_map_buffer_range_unittest.cc
@@ -370,7 +370,7 @@
   GLTestHelper::CheckGLError("no errors", __LINE__);
 }
 
-// TODO(crbug.com/1435122): Fix flakiness and re-enable the test.
+// TODO(crbug.com/40904610): Fix flakiness and re-enable the test.
 #if BUILDFLAG(IS_LINUX) && defined(ADDRESS_SANITIZER) && defined(LEAK_SANITIZER)
 #define MAYBE_TexImageAndSubImage3D DISABLED_TexImageAndSubImage3D
 #else
diff --git a/gpu/ipc/service/gpu_channel_manager_unittest.cc b/gpu/ipc/service/gpu_channel_manager_unittest.cc
index 577930f..acc3485a6 100644
--- a/gpu/ipc/service/gpu_channel_manager_unittest.cc
+++ b/gpu/ipc/service/gpu_channel_manager_unittest.cc
@@ -155,8 +155,8 @@
   base::test::TestTraceProcessor ttp;
   ttp.StartTrace("gpu");
 #else
-  // TODO(crbug.com/1006541): Remove trace_analyzer usage after migration to the
-  // SDK.
+  // TODO(crbug.com/42050015): Remove trace_analyzer usage after migration to
+  // the SDK.
   trace_analyzer::Start("gpu");
 #endif
 
diff --git a/headless/lib/switches.cc b/headless/lib/switches.cc
index 6b7500c..ba18029b 100644
--- a/headless/lib/switches.cc
+++ b/headless/lib/switches.cc
@@ -83,7 +83,7 @@
 // Specifies which encryption storage backend to use. Possible values are
 // kwallet, kwallet5, gnome-libsecret, basic. Any other value will lead to
 // Chrome detecting the best backend automatically.
-// TODO(crbug.com/571003): Once PasswordStore no longer uses KWallet for
+// TODO(crbug.com/40449930): Once PasswordStore no longer uses KWallet for
 // storing passwords, rename this flag to stop referencing passwords. Do not
 // rename it sooner, though; developers and testers might rely on it keeping
 // large amounts of testing passwords out of their KWallets.
diff --git a/headless/test/headless_compositor_browsertest.cc b/headless/test/headless_compositor_browsertest.cc
index 6b81ae49..683b3e30 100644
--- a/headless/test/headless_compositor_browsertest.cc
+++ b/headless/test/headless_compositor_browsertest.cc
@@ -72,7 +72,7 @@
 HEADLESS_COMPOSITOR_TEST(CompositorImageAnimation,
                          "emulation/compositor-image-animation-test.js")
 
-// Flaky on all platforms. TODO(crbug.com/986027): Re-enable.
+// Flaky on all platforms. TODO(crbug.com/41471823): Re-enable.
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
     BUILDFLAG(IS_FUCHSIA)
 #define MAYBE_CompositorCssAnimation DISABLED_CompositorCssAnimation
diff --git a/headless/test/headless_protocol_browsertest.cc b/headless/test/headless_protocol_browsertest.cc
index 4f52f253..4e800f1 100644
--- a/headless/test/headless_protocol_browsertest.cc
+++ b/headless/test/headless_protocol_browsertest.cc
@@ -232,7 +232,7 @@
 HEADLESS_PROTOCOL_TEST(VirtualTimeInterrupt,
                        "emulation/virtual-time-interrupt.js")
 
-// Flaky on Linux, Mac & Win. TODO(crbug.com/930717): Re-enable.
+// Flaky on Linux, Mac & Win. TODO(crbug.com/41440558): Re-enable.
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
     BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA)
 #define MAYBE_VirtualTimeCrossProcessNavigation \
diff --git a/headless/test/headless_web_contents_browsertest.cc b/headless/test/headless_web_contents_browsertest.cc
index 11e17f4..86a7c3cc6 100644
--- a/headless/test/headless_web_contents_browsertest.cc
+++ b/headless/test/headless_web_contents_browsertest.cc
@@ -604,7 +604,7 @@
   }
 };
 
-// TODO(crbug.com/1459385): Turning this off since it's flaking regularly.
+// TODO(crbug.com/40274291): Turning this off since it's flaking regularly.
 DISABLED_HEADLESS_DEVTOOLED_TEST_F(
     HeadlessWebContentsBeginFrameControlViewportTest);
 
diff --git a/infra/config/subprojects/chromium/ci/chromium.chromiumos.star b/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
index 06989cd..afa673d 100644
--- a/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
+++ b/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
@@ -1016,7 +1016,7 @@
             "release",
         ],
     ),
-    # TODO(https://crbug.com/1342761): enable sheriff rotation and tree_closing
+    # TODO(crbug.com/40231151): enable sheriff rotation and tree_closing
     # when the builder is stable.
     sheriff_rotations = args.ignore_default(None),
     tree_closing = False,
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
index b9fe0a41..5c37149 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
@@ -613,7 +613,7 @@
         "ci/Linux Chromium OS ASan LSan Tests (1)",
     ],
     gn_args = "ci/Linux Chromium OS ASan LSan Builder",
-    # TODO(crbug.com/1510339): Remove this when memory consumption during links
+    # TODO(crbug.com/41482936): Remove this when memory consumption during links
     # is reduced.
     cores = 16,
     ssd = True,
diff --git a/infra/config/targets/basic_suites.star b/infra/config/targets/basic_suites.star
index 88f741f..8649943 100644
--- a/infra/config/targets/basic_suites.star
+++ b/infra/config/targets/basic_suites.star
@@ -4124,7 +4124,7 @@
 targets.legacy_basic_suite(
     name = "linux_chromeos_oobe_specific_tests",
     tests = {
-        # TODO(crbug.com/1071693): Merge this suite back in to the main
+        # TODO(crbug.com/40126889): Merge this suite back in to the main
         # browser_tests when the tests no longer fail on MSAN.
         "oobe_only_browser_tests": targets.legacy_test_config(
             swarming = targets.swarming(
@@ -4140,7 +4140,7 @@
     tests = {
         # Chrome OS only.
         "ash_components_unittests": targets.legacy_test_config(),
-        # TODO(crbug.com/1351793) Enable on CQ when stable.
+        # TODO(crbug.com/40234627) Enable on CQ when stable.
         "ash_crosapi_tests": targets.legacy_test_config(
             ci_only = True,
         ),
diff --git a/infra/config/targets/mixins.star b/infra/config/targets/mixins.star
index 9cb43c4..68302f71 100644
--- a/infra/config/targets/mixins.star
+++ b/infra/config/targets/mixins.star
@@ -824,7 +824,7 @@
     ),
 )
 
-# TODO(crbug.com/1260217): Remove the xenial mixin once the MSAN bots have
+# TODO(crbug.com/40201775): Remove the xenial mixin once the MSAN bots have
 # migrated to focal.
 targets.mixin(
     name = "linux-xenial",
diff --git a/ios/chrome/app/application_delegate/app_state_observer.h b/ios/chrome/app/application_delegate/app_state_observer.h
index 794fee9..4955056 100644
--- a/ios/chrome/app/application_delegate/app_state_observer.h
+++ b/ios/chrome/app/application_delegate/app_state_observer.h
@@ -48,7 +48,7 @@
   // case the app will continue its transition to InitStageFinal and the UI is
   // initialized when the scene transitions to the foreground.
   InitStageNormalUI,
-  // TODO(crbug.com/1198246): Decouple FRE from Browser views to be able to go
+  // TODO(crbug.com/40760618): Decouple FRE from Browser views to be able to go
   // through this stage before InitStageNormalUI.
   // The app is considering presenting the FRE UI. Will remain in that state
   // when presenting the FRE.
diff --git a/ios/chrome/app/application_delegate/metrics_mediator.mm b/ios/chrome/app/application_delegate/metrics_mediator.mm
index e37c103..f280e76250 100644
--- a/ios/chrome/app/application_delegate/metrics_mediator.mm
+++ b/ios/chrome/app/application_delegate/metrics_mediator.mm
@@ -331,6 +331,8 @@
 // Returns a corresponding TabAgeGroup for provided `timeSinceCreation` time.
 + (TabsAgeGroup)tabsAgeGroupFromTimeSinceCreation:
     (base::TimeDelta)timeSinceCreation;
+// Logs the number of connected and disconnected scenes.
++ (void)recordConnectedAndDisconnectedSceneCount:(int)connectedScenes;
 @end
 
 @implementation MetricsMediator
@@ -507,6 +509,8 @@
     [self recordResumeLiveNTPTabCount:liveNTPTabCount];
   }
 
+  [self recordConnectedAndDisconnectedSceneCount:scenes.count];
+
   if (UIAccessibilityIsVoiceOverRunning()) {
     base::RecordAction(
         base::UserMetricsAction("MobileVoiceOverActiveOnLaunch"));
@@ -799,6 +803,14 @@
   }
 }
 
++ (void)recordConnectedAndDisconnectedSceneCount:(int)connectedScenes {
+  base::UmaHistogramCounts100("IOS.MultiWindow.ConnectedScenesCount",
+                              connectedScenes);
+  base::UmaHistogramCounts100(
+      "IOS.MultiWindow.DisconnectedScenesCount",
+      UIApplication.sharedApplication.openSessions.count - connectedScenes);
+}
+
 + (void)recordAndResetWarmStartCount {
   bool afterUpgrade =
       [PreviousSessionInfo sharedInstance].isFirstSessionAfterUpgrade;
diff --git a/ios/chrome/app/application_delegate/url_opener.mm b/ios/chrome/app/application_delegate/url_opener.mm
index 3144bcd..657baba 100644
--- a/ios/chrome/app/application_delegate/url_opener.mm
+++ b/ios/chrome/app/application_delegate/url_opener.mm
@@ -74,7 +74,7 @@
       // _startupParameters will not include the command from openURL.
       // Pass the startup parameters from here.
 
-      // TODO(crbug.com/1496951): Investigate why
+      // TODO(crbug.com/40938699): Investigate why
       // connectionInformation.startupParamters can be not nil and what to do in
       // that case.
       [connectionInformation setStartupParameters:params];
diff --git a/ios/chrome/app/main_application_delegate.mm b/ios/chrome/app/main_application_delegate.mm
index 20590d5ada..8023f175 100644
--- a/ios/chrome/app/main_application_delegate.mm
+++ b/ios/chrome/app/main_application_delegate.mm
@@ -270,7 +270,7 @@
   Browser* browser =
       _mainController.browserProviderInterface.mainBrowserProvider.browser;
   if (!browser) {
-    // TODO(crbug.com/1368617): We should store the completionHandler and wait
+    // TODO(crbug.com/40240359): We should store the completionHandler and wait
     // for mainBrowserProvider creation.
     completionHandler();
     return;
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm
index 4639918..07010b4 100644
--- a/ios/chrome/app/main_controller.mm
+++ b/ios/chrome/app/main_controller.mm
@@ -1436,7 +1436,7 @@
 }
 
 - (void)cleanupSnapshots {
-  // TODO(crbug.com/1116496): Browsers for disconnected scenes are not in the
+  // TODO(crbug.com/40144759): Browsers for disconnected scenes are not in the
   // BrowserList, so this may not reach all folders.
   std::vector<ChromeBrowserState*> loadedBrowserStates =
       GetApplicationContext()
diff --git a/ios/chrome/app/resources/inspect/inspect.html b/ios/chrome/app/resources/inspect/inspect.html
index 47f9e54..fe1898e6 100644
--- a/ios/chrome/app/resources/inspect/inspect.html
+++ b/ios/chrome/app/resources/inspect/inspect.html
@@ -3,7 +3,7 @@
 <head>
   <meta charset="utf-8"/>
 
-  <!-- TODO(crbug.com/487000): Remove this once injected by web. -->
+  <!-- TODO(crbug.com/41173939): Remove this once injected by web. -->
   <script src="chrome://resources/js/ios/web_ui.js"></script>
 
   <script src="chrome://resources/js/load_time_data_deprecated.js"></script>
diff --git a/ios/chrome/app/startup/setup_debugging.mm b/ios/chrome/app/startup/setup_debugging.mm
index b06f5896..61e85178 100644
--- a/ios/chrome/app/startup/setup_debugging.mm
+++ b/ios/chrome/app/startup/setup_debugging.mm
@@ -48,15 +48,15 @@
   // A set of image names that are exceptions to the 'missing image' check.
   NSMutableSet* exceptions = [NSMutableSet set];
 
-  // TODO(crbug.com/720337): Add missing image.
+  // TODO(crbug.com/41318097): Add missing image.
   [exceptions addObject:@"card_close_button_pressed_incognito"];
   // TODO(crbug.com/720355): Add missing image.
   [exceptions addObject:@"find_close_pressed_incognito"];
-  // TODO(crbug.com/720338): Add missing images.
+  // TODO(crbug.com/40519792): Add missing images.
   [exceptions addObject:@"glif-mic-to-dots-small_37"];
   [exceptions addObject:@"glif-mic-to-dots-large_37"];
   [exceptions addObject:@"glif-google-to-dots_28"];
-  // TODO(crbug.com/721338): Add missing image.
+  // TODO(crbug.com/41318906): Add missing image.
   [exceptions addObject:@"voice_icon_keyboard_accessory"];
 
   // The original implementation of [UIImage imageNamed:].
@@ -72,7 +72,7 @@
 
     if (![exceptions containsObject:imageName] &&
         ![imageName containsString:@".FAUXBUNDLEID."]) {
-// TODO(crbug.com/1325334): Temporarily turn off DCHECK while bootstrapping
+// TODO(crbug.com/40225445): Temporarily turn off DCHECK while bootstrapping
 // Catalyst. Log the error to the console instead.
 #if BUILDFLAG(IS_IOS_MACCATALYST)
       DLOG(ERROR) << "Missing image: " << base::SysNSStringToUTF8(imageName);
diff --git a/ios/chrome/app/strings/ios_chromium_strings.grd b/ios/chrome/app/strings/ios_chromium_strings.grd
index b178bf4..a1a0f33 100644
--- a/ios/chrome/app/strings/ios_chromium_strings.grd
+++ b/ios/chrome/app/strings/ios_chromium_strings.grd
@@ -574,7 +574,7 @@
       <message name="IDS_IOS_NEW_SYNC_ENCRYPTION_PASSPHRASE_INFO_UNO" desc="The information text for encrypting sync using a passphrase, shown on the passphrase screen [iOS only]">
         Payment methods and addresses won’t be encrypted. Browsing history from Chromium won’t sync.
 
-Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>clear the Chromium data in your account<ph name="END_LINK">END_LINK</ph>.
+Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>delete the Chromium data in your account<ph name="END_LINK">END_LINK</ph>.
       </message>
       <message name="IDS_IOS_NOTIFICATIONS_ALERT_MESSAGE" desc="Text for the Notifications UI Alert Prompt that redirects the user to the iOS notifications permission page">
         To receive notifications from Chromium, turn on notifications in your iOS Settings.
@@ -926,15 +926,10 @@
       <message name="IDS_IOS_SUGGESTED_STRONG_PASSWORD_HINT_DISPLAYING_EMAIL" desc="Text shown alongside a suggested password to tell user that generated passwords are recorded by chrome. [Length: unlimited] [iOS only]">
             You won't need to remember this password. It will be saved to Password Manager for <ph name="EMAIL">$1<ex>johndoe@gmail.com</ex></ph>
       </message>
-      <message name="IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT" desc="The information text on how to reset encryption passphrase for sync, shown on the sync encryption settings [Length: 300em] [iOS only]">
-        Passphrase encryption doesn’t include payment methods and addresses from Google Pay.
-
-To change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>clear the Chromium data in your account<ph name="END_LINK">END_LINK</ph>.
-      </message>
       <message name="IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT_UNO" desc="The information text on how to reset encryption passphrase for sync, shown on the sync encryption settings [Length: 300em] [iOS only]">
         Passphrase encryption doesn’t include payment methods and addresses.
 
-To change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>clear the Chromium data in your account<ph name="END_LINK">END_LINK</ph>.
+To change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>delete the Chromium data in your account<ph name="END_LINK">END_LINK</ph>.
       </message>
       <message name="IDS_IOS_SYNC_ENTER_PASSPHRASE_BODY_WITH_EMAIL" desc="Instructions for the dialog where the user enters the passphrase.">
         Signed in as <ph name="EMAIL">$1<ex>johndoe@gmail.com</ex></ph>.
@@ -950,7 +945,7 @@
         Keep using the Chromium data in your Google Account.
       </message>
       <message name="IDS_IOS_SYNC_PASSPHRASE_RECOVER" desc="Message about how to recover from a lost passphrase. [Length:100em, may be multiple lines] [iOS only]">
-        If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>clear the Chromium data in your account<ph name="END_LINK">END_LINK</ph>.
+        If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>delete the Chromium data in your account<ph name="END_LINK">END_LINK</ph>.
       </message>
       <message name="IDS_IOS_TAB_SWITCHER_NO_TABS_TO_SYNC_PROMO" desc="The title of the paragraph IDS_OPEN_TABS_NO_SESSION_INSTRUCTIONS_IOS. The paragraph explains that tabs opened on other devices where the user is signed in will appear here, in the Tab Switcher. [iOS only]">
         Use Chromium Everywhere
diff --git a/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_NEW_SYNC_ENCRYPTION_PASSPHRASE_INFO_UNO.png.sha1 b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_NEW_SYNC_ENCRYPTION_PASSPHRASE_INFO_UNO.png.sha1
index 4e5da1e..7d74492 100644
--- a/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_NEW_SYNC_ENCRYPTION_PASSPHRASE_INFO_UNO.png.sha1
+++ b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_NEW_SYNC_ENCRYPTION_PASSPHRASE_INFO_UNO.png.sha1
@@ -1 +1 @@
-49f9554797da82e27aeefcb1c180a97fddf9040c
\ No newline at end of file
+f88fae1ad03b0618261e5c8654293f102cf640d0
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT.png.sha1 b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT.png.sha1
deleted file mode 100644
index f2f93c85..0000000
--- a/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-9dae2cc420745ab4e7e0384c823600e648517642
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT_UNO.png.sha1 b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT_UNO.png.sha1
index 96e63b6..cac3ab07 100644
--- a/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT_UNO.png.sha1
+++ b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT_UNO.png.sha1
@@ -1 +1 @@
-219355ad46d9c6c477bc28e929311de7126aea20
\ No newline at end of file
+6accee5cb386d5fcd25ad1ee534ba61201e714a8
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_SYNC_PASSPHRASE_RECOVER.png.sha1 b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_SYNC_PASSPHRASE_RECOVER.png.sha1
index 7ee5cad68..1176b89 100644
--- a/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_SYNC_PASSPHRASE_RECOVER.png.sha1
+++ b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_SYNC_PASSPHRASE_RECOVER.png.sha1
@@ -1 +1 @@
-a9925ecedc214b2f00ba4294cdcbaade3e2931ff
\ No newline at end of file
+9b123012d2b93dbde7840354eb61e50ac1fbc87f
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_google_chrome_strings.grd b/ios/chrome/app/strings/ios_google_chrome_strings.grd
index 95d7841..9bb70a90 100644
--- a/ios/chrome/app/strings/ios_google_chrome_strings.grd
+++ b/ios/chrome/app/strings/ios_google_chrome_strings.grd
@@ -574,7 +574,7 @@
       <message name="IDS_IOS_NEW_SYNC_ENCRYPTION_PASSPHRASE_INFO_UNO" desc="The information text for encrypting sync using a passphrase, shown on the passphrase screen [iOS only]">
         Payment methods and addresses won’t be encrypted. Browsing history from Chrome won’t sync.
 
-Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>clear the Chrome data in your account<ph name="END_LINK">END_LINK</ph>.
+Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>delete the Chrome data in your account<ph name="END_LINK">END_LINK</ph>.
       </message>
       <message name="IDS_IOS_NOTIFICATIONS_ALERT_MESSAGE" desc="Text for the Notifications UI Alert Prompt that redirects the user to the iOS notifications permission page">
         To receive notifications from Chrome, turn on notifications in your iOS Settings.
@@ -935,7 +935,7 @@
       <message name="IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT_UNO" desc="The information text on how to reset encryption passphrase for sync, shown on the sync encryption settings [Length: 300em] [iOS only]">
         Passphrase encryption doesn’t include payment methods and addresses.
 
-To change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>clear the Chrome data in your account<ph name="END_LINK">END_LINK</ph>.
+To change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>delete the Chrome data in your account<ph name="END_LINK">END_LINK</ph>.
       </message>
       <message name="IDS_IOS_SYNC_ENTER_PASSPHRASE_BODY_WITH_EMAIL" desc="Instructions for the dialog where the user enters the passphrase.">
         Signed in as <ph name="EMAIL">$1<ex>johndoe@gmail.com</ex></ph>.
@@ -951,7 +951,7 @@
         Keep using the Chrome data in your Google Account.
       </message>
       <message name="IDS_IOS_SYNC_PASSPHRASE_RECOVER" desc="Message about how to recover from a lost passphrase. [Length:100em, may be multiple lines] [iOS only]">
-        If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>clear the Chrome data in your account<ph name="END_LINK">END_LINK</ph>.
+        If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK">BEGIN_LINK</ph>delete the Chrome data in your account<ph name="END_LINK">END_LINK</ph>.
       </message>
       <message name="IDS_IOS_TAB_SWITCHER_NO_TABS_TO_SYNC_PROMO" desc="The title of the paragraph IDS_OPEN_TABS_NO_SESSION_INSTRUCTIONS_IOS. The paragraph explains that tabs opened on other devices where the user is signed in will appear here, in the Tab Switcher. [iOS only]">
         Use Chrome Everywhere
diff --git a/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_NEW_SYNC_ENCRYPTION_PASSPHRASE_INFO_UNO.png.sha1 b/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_NEW_SYNC_ENCRYPTION_PASSPHRASE_INFO_UNO.png.sha1
index 4e5da1e..c087a0b 100644
--- a/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_NEW_SYNC_ENCRYPTION_PASSPHRASE_INFO_UNO.png.sha1
+++ b/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_NEW_SYNC_ENCRYPTION_PASSPHRASE_INFO_UNO.png.sha1
@@ -1 +1 @@
-49f9554797da82e27aeefcb1c180a97fddf9040c
\ No newline at end of file
+4d9985b53c6cbe681e5db0c1680869c74d2504af
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT_UNO.png.sha1 b/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT_UNO.png.sha1
index 96e63b6..14eb49bb 100644
--- a/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT_UNO.png.sha1
+++ b/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_SYNC_ENCRYPTION_PASSPHRASE_HINT_UNO.png.sha1
@@ -1 +1 @@
-219355ad46d9c6c477bc28e929311de7126aea20
\ No newline at end of file
+db58c7b0a7004803a57eecb6aa604a3d88e6f121
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_SYNC_PASSPHRASE_RECOVER.png.sha1 b/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_SYNC_PASSPHRASE_RECOVER.png.sha1
index 7ee5cad68..8ec59c63 100644
--- a/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_SYNC_PASSPHRASE_RECOVER.png.sha1
+++ b/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_SYNC_PASSPHRASE_RECOVER.png.sha1
@@ -1 +1 @@
-a9925ecedc214b2f00ba4294cdcbaade3e2931ff
\ No newline at end of file
+d0924eac74065f7fdac5eb27007f3a478c7f32d1
\ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index 0a36d0ab..3550035 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -4686,7 +4686,7 @@
       <message name="IDS_IOS_SIGNIN_SNACKBAR_UNDO" desc="This string is found on a button that signs the user out when the user taps it. It is on a confirmation message that users see when they sign in to Chrome with their Google Account. This text is a verb and is short for the longer phrase 'Undo my sign-in.' The tone should be informative. [Length: 15em] [iOS only]">
         Undo
       </message>
-      <message name="IDS_IOS_SIGNOUT_DIALOG_CLEAR_DATA_BUTTON" desc="This button signs the user out and clear all the data from the user device. The data remain in their Google account. Related to IDS_IOS_SIGNOUT_DIALOG_TITLE [iOS only].">
+      <message name="IDS_IOS_SIGNOUT_DIALOG_CLEAR_DATA_BUTTON" desc="This button signs the user out and delete all the data from the user device. The data remain in their Google account. Related to IDS_IOS_SIGNOUT_DIALOG_TITLE [iOS only].">
         Clear Data
       </message>
       <message name="IDS_IOS_SIGNOUT_DIALOG_KEEP_DATA_BUTTON" desc="This button signs the user out and all its data stays on the device. Related to IDS_IOS_SIGNOUT_DIALOG_TITLE [iOS only].">
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SYNC_PASSPHRASE_RECOVER.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SYNC_PASSPHRASE_RECOVER.png.sha1
new file mode 100644
index 0000000..cac3ab07
--- /dev/null
+++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SYNC_PASSPHRASE_RECOVER.png.sha1
@@ -0,0 +1 @@
+6accee5cb386d5fcd25ad1ee534ba61201e714a8
\ No newline at end of file
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_ar.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_ar.xtb
index cfdd260..48fcdf7c 100644
--- a/ios/chrome/app/strings/resources/ios_chromium_strings_ar.xtb
+++ b/ios/chrome/app/strings/resources/ios_chromium_strings_ar.xtb
@@ -249,6 +249,7 @@
 <translation id="800195749539500647">‏يمكنك الاستفادة إلى أقصى حدّ من Chromium.</translation>
 <translation id="8013573822802650211">‏للاطّلاع على علامات التبويب من أي جهاز تستخدم فيه Chromium، سجِّل الدخول على جميع أجهزتك.</translation>
 <translation id="8071041515667087705">‏انتقِل إلى إعدادات Chromium.</translation>
+<translation id="8104697640054703121">‏الحصول على أعلى مستويات الحماية من المواقع الإلكترونية الخطيرة في Chromium</translation>
 <translation id="8115308261377517697">‏اختيار Chromium ليكون متصفِّحك التلقائي</translation>
 <translation id="8197822717502700527">‏يمكنك الآن الاستفادة بشكل أفضل من Chromium على جهازك.</translation>
 <translation id="8234150821523419638">‏فتح قائمة Chromium</translation>
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_ms.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_ms.xtb
index 3abbef1..e8b93fd 100644
--- a/ios/chrome/app/strings/resources/ios_chromium_strings_ms.xtb
+++ b/ios/chrome/app/strings/resources/ios_chromium_strings_ms.xtb
@@ -73,6 +73,7 @@
 <translation id="2918709798697875261">Organisasi anda menghendaki anda kekal dilog keluar daripada Chromium.</translation>
 <translation id="2942241131342758843">Gunakan Chromium secara lalai untuk membuka pautan, mencari daripada widget dan melengkapkan kata laluan secara automatik dalam apl lain</translation>
 <translation id="2977470724722393594">Chromium telah dikemas kini</translation>
+<translation id="3044857325852340337">Data Chromium yang dipadamkan</translation>
 <translation id="3078941082359356771">{COUNT,plural, =1{Chromium boleh membantu anda menjejaki pakej ini pada Halaman Tab Baharu.}other{Chromium boleh membantu anda menjejaki pakej ini pada Halaman Tab Baharu.}}</translation>
 <translation id="3102849287235003384">Untuk log keluar daripada Google Account dalam semua laman web, <ph name="BEGIN_LINK" />log keluar daripada Chromium<ph name="END_LINK" />.</translation>
 <translation id="3219277919172823720">Cari Dengan Suara dalam Chromium</translation>
@@ -124,6 +125,7 @@
 <translation id="4633738821577273991">Dapatkan juga Penyemakan Imbas Selamat Dipertingkat untuk profil Chromium ini</translation>
 <translation id="4638625642619341392">Muat turun Chromium di sini.</translation>
 <translation id="4654936625574199632">Untuk membantu dalam usaha meningkatkan apl, Chromium menghantar data penggunaan dan ranap sistem kepada Google. <ph name="BEGIN_LINK" />Urus<ph name="END_LINK" /></translation>
+<translation id="4675485352217495362">Padamkan Data Semakan Imbas dalam Chromium</translation>
 <translation id="4681781466797808448">Hidupkan pengimbas Chromium</translation>
 <translation id="4736424910885271643">Akaun anda diurus oleh <ph name="HOSTED_DOMAIN" />, oleh itu data Chromium anda akan dikosongkan daripada peranti ini</translation>
 <translation id="4773487571745795781">Anda mematikan log masuk ke Chromium.</translation>
@@ -191,6 +193,7 @@
 <translation id="6324041800010509197">Lawati Grid Tab dalam Chromium</translation>
 <translation id="6325378625795868881">Gunakan Chromium pada bila-bila masa anda mengetik pautan dalam mesej dan apl lain.</translation>
 <translation id="632825460376924298">Benarkan Log Masuk Chromium</translation>
+<translation id="6332129548244419716">Padamkan Data Semakan Imbas dalam Chromium.</translation>
 <translation id="6337530241089703714">Pilih sama ada anda hendak mengosongkan data Chromium anda daripada peranti ini atau mengekalkan data tersebut</translation>
 <translation id="6348483005826990855">3. Pilih Chromium</translation>
 <translation id="6383607155624074112">Akses Chromium lebih pantas daripada Dok Skrin Utama anda</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_ar.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_ar.xtb
index f9e8d78..be7b300 100644
--- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_ar.xtb
+++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_ar.xtb
@@ -217,6 +217,7 @@
 <translation id="7272930098487145294">‏لحفظ الصور، يُرجى النقر على "الإعدادات" للسماح لمتصفّح Chrome بأن يضيف إلى صورك.</translation>
 <translation id="7275945473750112644">‏سيتم محو بيانات Chrome المخزَّنة على هذا الجهاز لأنّ حسابك تتم إدارته من خلال <ph name="HOSTED_DOMAIN" /></translation>
 <translation id="7304491752269485262">‏عرض موسَّع لميزة "الملء التلقائي" في Chrome</translation>
+<translation id="7344094882820374540">‏الحصول على أعلى مستويات الحماية من المواقع الإلكترونية الخطيرة في Chrome</translation>
 <translation id="7349129508108954623">‏يرجى السماح لمتصفِّح Chrome باستخدام "خرائط Google" لإعلامك بالاتجاهات مع معلومات محلية عن العناوين المكتشفة.</translation>
 <translation id="7394108421562933108">‏"خرائط Google" في Chrome</translation>
 <translation id="7400722733683201933">‏لمحة عن Google Chrome</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_ms.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_ms.xtb
index 5ba667ad..0f3f7eced 100644
--- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_ms.xtb
+++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_ms.xtb
@@ -117,10 +117,12 @@
 <translation id="417201473131094001">Tidak disokong pada Chrome Canary</translation>
 <translation id="424864128008805179">Log keluar daripada Chrome?</translation>
 <translation id="4251174643044751591">Buka Halaman Tetapan Kaedah Pembayaran dalam Chrome.</translation>
+<translation id="4286914711740227883">Padamkan Data Semakan Imbas dalam Chrome</translation>
 <translation id="4453284704333523777">Urus Tetapan Chrome</translation>
 <translation id="4523886039239821078">Beberapa tambahan menyebabkan Chrome ranap. Sila nyahpasang:</translation>
 <translation id="4633328489441962921">Chrome tidak dapat menyemak kemas kini</translation>
 <translation id="4636900170638246267">Log masuk ke laman ini dan Chrome.</translation>
+<translation id="4742795653798179840">Data Chrome yang dipadamkan</translation>
 <translation id="4761869838909035636">Jalankan Semakan Keselamatan Chrome</translation>
 <translation id="4798859546468762093">Untuk mendapatkan pemeribadian dan ciri lain, sertakan Chrome dalam <ph name="FEATURE_NAME_1" /> dan <ph name="FEATURE_NAME_2" /></translation>
 <translation id="4819268619367838612">Untuk membantu dalam usaha meningkatkan apl, Chrome menghantar data penggunaan dan ranap sistem kepada Google. <ph name="BEGIN_LINK" />Urus<ph name="END_LINK" /></translation>
@@ -131,6 +133,7 @@
 <translation id="4840404732697892756">Google Password Manager boleh menyemak kata laluan anda apabila anda log masuk menggunakan Google Account anda.</translation>
 <translation id="4860330141789125848">{COUNT,plural, =1{Chrome boleh membantu anda menjejaki pakej ini pada Halaman Tab Baharu.}other{Chrome boleh membantu anda menjejaki pakej ini pada Halaman Tab Baharu.}}</translation>
 <translation id="4903674399067644695">Kad ini menunjukkan cadangan tentang cara memanfaatkan Chrome sepenuhnya.</translation>
+<translation id="4919069428879420545">Padamkan Data Semakan Imbas pada Chrome.</translation>
 <translation id="49200511069271369">Organisasi anda, <ph name="DOMAIN" />, mengurus akaun yang anda log masuk dan cara Chrome boleh digunakan. Pentadbir anda boleh menyediakan atau mengehadkan ciri tertentu.</translation>
 <translation id="498985224078955265">Untuk menghantar tab ini ke peranti lain, log masuk Chrome pada kedua-dua peranti.</translation>
 <translation id="5030102366287574140">Chrome dapat membantu untuk memastikan anda selamat daripada pelanggaran data, laman web yang tidak selamat dan pelbagai lagi.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ar.xtb b/ios/chrome/app/strings/resources/ios_strings_ar.xtb
index 5c774d2..b07c48b3 100644
--- a/ios/chrome/app/strings/resources/ios_strings_ar.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_ar.xtb
@@ -137,6 +137,7 @@
 <translation id="1687475363370981210">وضع العلامة كمقروءة على الكل</translation>
 <translation id="1689333818294560261">اللقب</translation>
 <translation id="1700629756560807968">تم اختيار <ph name="NUMBER_OF_SELECTED_BOOKMARKS" /></translation>
+<translation id="1710698977900873766">تفعيل مستوى "الحماية المحسَّنة"</translation>
 <translation id="1713777106376424209">التسليم بحلول</translation>
 <translation id="1715515772563243997">إذا كنت تثق بالموقع الإلكتروني <ph name="SITE" />، يمكنك استخدام كلمة مرور محفوظة لتسجيل الدخول.</translation>
 <translation id="1740468249224277719">انقر مرّتين للتثبيت.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_id.xtb b/ios/chrome/app/strings/resources/ios_strings_id.xtb
index 62a4ef1..f720e058 100644
--- a/ios/chrome/app/strings/resources/ios_strings_id.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_id.xtb
@@ -842,6 +842,7 @@
 <translation id="5407969256130905701">Hapus Perubahan</translation>
 <translation id="5414763847370083940">Anda akan mendapatkan notifikasi jika ada diskon di situs mana pun.</translation>
 <translation id="5416022985862681400">7 Hari Terakhir</translation>
+<translation id="5416455648658732408">Pindahkan ke Grup Tab</translation>
 <translation id="5423269318075950257">Pantau Harga</translation>
 <translation id="543338862236136125">Edit sandi</translation>
 <translation id="5433691172869980887">Nama pengguna disalin</translation>
@@ -1327,6 +1328,7 @@
 <translation id="7853202427316060426">Aktivitas</translation>
 <translation id="7856733331829174190">Tidak Dapat Mendownload</translation>
 <translation id="7859704718976024901">Histori Browsing</translation>
+<translation id="7860900259978879139">Hapus dari Grup</translation>
 <translation id="7866501058614003444">Pelacakan paket ini telah berhasil dibatalkan.</translation>
 <translation id="7866872729285243843">Untuk mendapatkan daftar bacaan di semua perangkat, aktifkan "Daftar Bacaan" di setelan.</translation>
 <translation id="7866993391592926595">Menyembunyikan Kartu Ini Akan Menonaktifkan Pelacakan Paket dan Menghapus Semua Data Anda</translation>
@@ -1414,9 +1416,11 @@
 <translation id="8273982424131314219">Anda akan mengisi info ke <ph name="URL" /></translation>
 <translation id="8281781826761538115">Default - <ph name="DEFAULT_LOCALE" /></translation>
 <translation id="8281886186245836920">Lewati</translation>
+<translation id="8282657446819506217">Buka di Grup Tab</translation>
 <translation id="828291969289324795">{count,plural, =1{Tambahkan Tab ke Grup Baru}other{Tambahkan Tab ke Grup Baru}}</translation>
 <translation id="8283172974887967105">Setel …</translation>
 <translation id="8286036467436129157">Login</translation>
+<translation id="8289930144142009940">Notifikasi <ph name="FEATURE_NAME" /> dinonaktifkan</translation>
 <translation id="8292843446079898078">Dapatkan notifikasi penurunan harga untuk produk yang Anda pantau.</translation>
 <translation id="8299417921174340354">Untuk menggunakan sandi, Anda harus menyetel kode sandi di perangkat terlebih dahulu.</translation>
 <translation id="8299613349954694191">Buka tab Samaran untuk menjelajahi web secara pribadi.</translation>
@@ -1424,6 +1428,7 @@
 <translation id="8313645224014086262">Simpan file</translation>
 <translation id="8319076807703933069">Penelusuran Baru</translation>
 <translation id="8328777765163860529">Tutup Semua</translation>
+<translation id="8343286328361420468">Nonaktifkan Notifikasi untuk <ph name="FEATURE_NAME" /></translation>
 <translation id="8343993175958086504">Cadangkan data Anda dan gunakan di perangkat mana pun.</translation>
 <translation id="834783239627985533">Situs yang Paling Sering Dikunjungi</translation>
 <translation id="8358401059263985056">Aktifkan Notifikasi</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ka.xtb b/ios/chrome/app/strings/resources/ios_strings_ka.xtb
index f6b67832..684b8f1 100644
--- a/ios/chrome/app/strings/resources/ios_strings_ka.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_ka.xtb
@@ -130,6 +130,7 @@
 <translation id="1653432787084483144">{count,plural, =1{კლავიატურის ზემოთ ხელმისაწვდომია {count} შენახული პაროლი.}other{კლავიატურის ზემოთ ხელმისაწვდომია {count} შენახული პაროლი.}}</translation>
 <translation id="1657011748321897393">ვერ გაზიარდა, რადგან არ ხართ დაკავშირებული ქსელთან.</translation>
 <translation id="165877110639533037">გახსნილი ჩანართები არ არის</translation>
+<translation id="1668001730617725852">ჩანართების ახალ ჯგუფში გახსნა</translation>
 <translation id="1674504678466460478"><ph name="SOURCE_LANGUAGE" /> — <ph name="TARGET_LANGUAGE" /></translation>
 <translation id="1683483432843341018">მობილური საიტის მოთხოვნა</translation>
 <translation id="1687475363370981210">ყველას წაკითხულად მონიშვნა</translation>
@@ -1199,6 +1200,7 @@
 <translation id="7162168282402939716">ინკოგნიტო ჩანართების განსაბლოკად გამოყენებული იყოს <ph name="BIOMETRIC_AUTHENITCATION_TYPE" /></translation>
 <translation id="7173114856073700355">პარამეტრების გახსნა</translation>
 <translation id="7186568385131859684">აკონტროლეთ, როგორ გამოიყენება ვების დათვალიერების ისტორია თქვენს სხვა მონაცემებთან ერთად Google სერვისებში</translation>
+<translation id="7187190640134722091">ჯგუფის შექმნა</translation>
 <translation id="7189598951263744875">გაზიარება…</translation>
 <translation id="719133302483559673">მართეთ თქვენი ინტერესები და პარამეტრები.</translation>
 <translation id="7192050974311852563">ჟურნალირების დაწყება</translation>
@@ -1595,6 +1597,7 @@
 <translation id="9109699888944026290">{count,plural, =1{ახალი პაროლი ამ საიტისთვის}other{ახალი პაროლები ამ საიტისთვის}}</translation>
 <translation id="9120217828624527905">გვერდის მთლიანად თარგმნაზე გადართვა</translation>
 <translation id="9124387962554796433">თქვენი ისტორიის მეშვეობით Google შეძლებს Search-ისა და Google-ის სხვა სერვისების თქვენზე მორგებას.</translation>
+<translation id="913036870884277353">ბმულების სხვა აპებში მარტივად გახსნა.</translation>
 <translation id="9137526406337347448">Google სერვისები</translation>
 <translation id="9144931028079269381">საკითხავი სიის დამალვა</translation>
 <translation id="9148126808321036104">ხელახლა შედით</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_lo.xtb b/ios/chrome/app/strings/resources/ios_strings_lo.xtb
index f5d14130..f9c8bfa 100644
--- a/ios/chrome/app/strings/resources/ios_strings_lo.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_lo.xtb
@@ -130,6 +130,7 @@
 <translation id="1653432787084483144">{count,plural, =1{ລະຫັດຜ່ານທີ່ບັນທຶກໄວ້ {count} ລາຍການຈະສາມາດໃຊ້ໄດ້ຢູ່ທາງເທິງແປ້ນພິມຂອງທ່ານ.}other{ລະຫັດຜ່ານທີ່ບັນທຶກໄວ້ {count} ລາຍການຈະສາມາດໃຊ້ໄດ້ຢູ່ທາງເທິງແປ້ນພິມຂອງທ່ານ.}}</translation>
 <translation id="1657011748321897393">ການ​ແບ່ງ​ປັນ​ຂອງ​ທ່ານ​ບໍ່​ສຳ​ເລັດ ເພາະ​ວ່າ​ທ່ານ​ບໍ່​ໄດ້​ເຊື່ອມ​ຕໍ່​ກັບ​ເຄືອ​ຂ່າຍ.</translation>
 <translation id="165877110639533037">ບໍ່​ມີ​ແຖບ​ເປີດ</translation>
+<translation id="1668001730617725852">ເປີດໃນກຸ່ມແຖບໃໝ່</translation>
 <translation id="1674504678466460478"><ph name="SOURCE_LANGUAGE" /> ເປັນ <ph name="TARGET_LANGUAGE" /></translation>
 <translation id="1683483432843341018">ຮ້ອງຂໍເວັບໄຊມືຖື</translation>
 <translation id="1687475363370981210">ໝາຍທັງໝົດວ່າອ່ານແລ້ວ</translation>
@@ -1199,6 +1200,7 @@
 <translation id="7162168282402939716">ປົດລັອກແຖບບໍ່ເປີດເຜີຍຕົວຕົນດ້ວຍ <ph name="BIOMETRIC_AUTHENITCATION_TYPE" /></translation>
 <translation id="7173114856073700355">ເປີດການຕັ້ງຄ່າ</translation>
 <translation id="7186568385131859684">ຄວບຄຸມການໃຊ້ປະຫວັດການທ່ອງເວັບກັບຂໍ້ມູນອື່ນໆຂອງທ່ານໃນບໍລິການຕ່າງໆຂອງ Google</translation>
+<translation id="7187190640134722091">ສ້າງກຸ່ມ</translation>
 <translation id="7189598951263744875">ແບ່ງປັນ...</translation>
 <translation id="719133302483559673">ຈັດການຄວາມສົນໃຈ ແລະ ການຕັ້ງຄ່າຂອງທ່ານ.</translation>
 <translation id="7192050974311852563">ເລີ່ມການບັນທຶກ</translation>
@@ -1595,6 +1597,7 @@
 <translation id="9109699888944026290">{count,plural, =1{ລະຫັດຜ່ານໃໝ່ສຳລັບເວັບໄຊນີ້}other{ລະຫັດຜ່ານໃໝ່ສຳລັບເວັບໄຊນີ້}}</translation>
 <translation id="9120217828624527905">ສະຫຼັບໄປຫາການແປພາສາແບບເຕັມໜ້າ</translation>
 <translation id="9124387962554796433">Google ອາດໃຊ້ປະຫວັດຂອງທ່ານເພື່ອປັບແຕ່ງການຊອກຫາ ແລະ ບໍລິການອື່ນໆຂອງ Google ໃຫ້ເປັນແບບສ່ວນຕົວ.</translation>
+<translation id="913036870884277353">ເປີດລິ້ງໃນແອັບອື່ນໆໄດ້ຢ່າງງ່າຍດາຍ.</translation>
 <translation id="9137526406337347448">ການບໍລິການ Google</translation>
 <translation id="9144931028079269381">ເຊື່ອງລາຍຊື່ການອ່ານ</translation>
 <translation id="9148126808321036104">ລົງຊື່ເຂົ້າ​ໃຊ້ອີກ</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ms.xtb b/ios/chrome/app/strings/resources/ios_strings_ms.xtb
index a63fdf79..a37878b5 100644
--- a/ios/chrome/app/strings/resources/ios_strings_ms.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_ms.xtb
@@ -102,6 +102,7 @@
 <translation id="152234381334907219">Tidak Pernah Disimpan</translation>
 <translation id="1523341279170789507">Benarkan Semua Kuki</translation>
 <translation id="1524563461097350801">Tidak Perlu</translation>
+<translation id="1539173178539798367">Sembunyikan Pemadaman Data Semakan Imbas</translation>
 <translation id="1540800554400757039">Alamat 1</translation>
 <translation id="1545749641540134597">Imbas Kod QR</translation>
 <translation id="1552525382687785070">Penyegerakan Dilumpuhkan oleh Pentadbir Anda</translation>
@@ -320,6 +321,7 @@
 
 Enjin carian anda ialah <ph name="DSE_NAME" />. Lihat arahan enjin carian itu untuk memadamkan sejarah carian anda, jika berkenaan.</translation>
 <translation id="2697526135132990015">Log Keluar dan Kosongkan Data</translation>
+<translation id="269819437389494246">Anda dapat melihat halaman yang telah dilawati atau memadamkan halaman tersebut daripada sejarah anda</translation>
 <translation id="2700241355396984822">Pilihan untuk Menetapkan Kebenaran</translation>
 <translation id="2702801445560668637">Senarai Bacaan</translation>
 <translation id="2704606927547763573">Disalin</translation>
@@ -393,6 +395,7 @@
 <translation id="3039722182465315531">Jangan Log Masuk</translation>
 <translation id="3053332585453689122">Menghantar URL yang anda lawati dan sedikit sampel kandungan halaman, muat turun, aktiviti sambungan dan maklumat sistem kepada Penyemakan Imbas Selamat Google untuk disemak jika sampel tersebut berbahaya.</translation>
 <translation id="3054631738875941048">Sembunyikan Tambahkan pada Senarai Bacaan</translation>
+<translation id="3064295814838126921">Memadamkan data semakan imbas...</translation>
 <translation id="3074499504015191586">Terjemahkan Halaman Penuh</translation>
 <translation id="3076846064362030967">Anda tidak akan dilog keluar daripada Google Account anda. <ph name="BEGIN_LINK" />Bentuk aktiviti lain<ph name="END_LINK" /> mungkin disimpan dalam Google Account anda semasa anda dilog masuk. Anda boleh memadamkan data tersebut pada bila-bila masa.
 
@@ -858,6 +861,7 @@
 <translation id="5490005495580364134">Sekat Semua Kuki (Tidak Disyorkan)</translation>
 <translation id="5497202150450073388">Penghantaran Dicuba. Akan mencuba lagi</translation>
 <translation id="5511959326926949696">Perlindungan pilihan yang ekstrem untuk penyemak imbas anda. Pilihan tersebut hanya boleh digunakan jika anda percaya bahawa anda menjadi sasaran serangan siber yang sangat canggih.</translation>
+<translation id="5512759250809559631">Menu → Sejarah → Padamkan Data Semakan Imbas</translation>
 <translation id="5513681519188741830"><ph name="TIME" /> j yang lalu</translation>
 <translation id="5525269841082836315">Buat Frasa Laluan</translation>
 <translation id="553151287733286479">{COUNT,plural, =1{{COUNT} kata laluan lemah}other{{COUNT} kata laluan lemah}}</translation>
@@ -933,6 +937,7 @@
 <translation id="5859715514067755465">Mundar</translation>
 <translation id="5860033963881614850">Dimatikan</translation>
 <translation id="5860491529813859533">Hidupkan</translation>
+<translation id="5889333064153755823">Padamkan Data Semakan Imbas</translation>
 <translation id="5896576662943111387">Dibina untuk iOS</translation>
 <translation id="5897749768294722429">Untuk segera kembali kepada laman yang telah anda lawati, segerakkan tab dan sejarah anda.</translation>
 <translation id="5897956970858271241">Lawati Pautan Disalin</translation>
@@ -1030,6 +1035,7 @@
 <translation id="6346549652287021269">Mulakan Muat Turun Baharu?</translation>
 <translation id="6347953390226388422">{count,plural, =1{Alamat ini akan dipadamkan daripada Google Account (<ph name="USER_EMAIL" />) anda dan daripada peranti ini.}other{Alamat ini akan dipadamkan daripada Google Account (<ph name="USER_EMAIL" />) anda dan daripada peranti ini.}}</translation>
 <translation id="634878792104344809">Segerakkan kata laluan, sejarah dan pelbagai lagi pada semua peranti anda</translation>
+<translation id="6351658970066645919">Padamkan Data Semakan Imbas</translation>
 <translation id="63519665078626091">Untuk menggunakan Pemeriksa Web, sambungkan kepada Safari pada komputer anda menggunakan kabel dan akses iPad anda daripada menu Pembangun. Anda boleh mendayakan menu pembangun pada bahagian Lanjutan tetapan Safari pada komputer anda.</translation>
 <translation id="6355820205320395730">Kata laluan yang lemah mudah diteka. Pastikan anda sedang membuat kata laluan yang kukuh. <ph name="BEGIN_LINK" />Lihat lebih banyak petua keselamatan.<ph name="END_LINK" /></translation>
 <translation id="6361681885917591592">Selesai</translation>
@@ -1151,6 +1157,7 @@
 <translation id="687135068089457384">Tunjukkan Tetapan</translation>
 <translation id="6873263987691478642">Paparan Pisah</translation>
 <translation id="6882836635272038266">Perlindungan standard daripada laman web, muat turun dan sambungan yang diketahui berbahaya.</translation>
+<translation id="6887173972066406796">Sahkan Pemadaman Data Semakan Imbas</translation>
 <translation id="6888009575607455378">Adakah anda pasti anda mahu membuang perubahan anda?</translation>
 <translation id="6896758677409633944">Salin</translation>
 <translation id="6897187120838603299">Kata laluan anda akan disimpan pada peranti anda.</translation>
@@ -1345,6 +1352,7 @@
 <translation id="7930998711684428189">Memberi anda amaran jika kata laluan terdedah dalam pelanggaran data.</translation>
 <translation id="7938254975914653459">FaceTime</translation>
 <translation id="7939128259257418052">Eksport Kata Laluan...</translation>
+<translation id="7939856641500914040">Padamkan Data Semakan Imbas…</translation>
 <translation id="794799177247607889">Berhenti Mengelog</translation>
 <translation id="7959441099968534758">PERGI KE SUAPAN</translation>
 <translation id="7961015016161918242">Tidak sama sekali</translation>
diff --git a/ios/chrome/browser/app_launcher/model/app_launcher_abuse_detector.h b/ios/chrome/browser/app_launcher/model/app_launcher_abuse_detector.h
index e8a5259..ecaf449 100644
--- a/ios/chrome/browser/app_launcher/model/app_launcher_abuse_detector.h
+++ b/ios/chrome/browser/app_launcher/model/app_launcher_abuse_detector.h
@@ -16,7 +16,8 @@
   // application or launch it.
   ExternalAppLaunchPolicyPrompt,
   // Block launching the application for this session.
-  // TODO(crbug.com/989316): Remove this policy once non-modal dialogs are used
+  // TODO(crbug.com/41473755): Remove this policy once non-modal dialogs are
+  // used
   // by default.
   ExternalAppLaunchPolicyBlock,
 };
diff --git a/ios/chrome/browser/autofill/model/autofill_controller_unittest.mm b/ios/chrome/browser/autofill/model/autofill_controller_unittest.mm
index 694abe9..aa525e3 100644
--- a/ios/chrome/browser/autofill/model/autofill_controller_unittest.mm
+++ b/ios/chrome/browser/autofill/model/autofill_controller_unittest.mm
@@ -15,6 +15,7 @@
 #import "base/test/ios/wait_util.h"
 #import "base/test/metrics/histogram_tester.h"
 #import "base/uuid.h"
+#import "components/autofill/core/browser/address_data_manager_test_api.h"
 #import "components/autofill/core/browser/browser_autofill_manager.h"
 #import "components/autofill/core/browser/form_structure.h"
 #import "components/autofill/core/browser/metrics/autofill_metrics.h"
@@ -453,7 +454,8 @@
   PersonalDataManager* personal_data_manager =
       PersonalDataManagerFactory::GetForBrowserState(
           ChromeBrowserState::FromBrowserState(browser_state_.get()));
-  personal_data_manager->set_auto_accept_address_imports_for_testing(true);
+  test_api(personal_data_manager->address_data_manager())
+      .set_auto_accept_address_imports(true);
   // Check there are no registered profiles already.
   EXPECT_EQ(0U, personal_data_manager->GetProfiles().size());
   ASSERT_TRUE(LoadHtmlAndWaitForFormFetched(kProfileFormHtml, 1));
diff --git a/ios/chrome/browser/commerce/model/shopping_persisted_data_tab_helper.mm b/ios/chrome/browser/commerce/model/shopping_persisted_data_tab_helper.mm
index 41f90a9f..18a7dda 100644
--- a/ios/chrome/browser/commerce/model/shopping_persisted_data_tab_helper.mm
+++ b/ios/chrome/browser/commerce/model/shopping_persisted_data_tab_helper.mm
@@ -236,7 +236,7 @@
   if (!price_metadata) {
     return;
   }
-  // TODO(crbug.com/1270473) Change PriceDrop to PriceData.
+  // TODO(crbug.com/40205382) Change PriceDrop to PriceData.
   price_drop_ = std::make_unique<PriceDrop>();
   if (price_metadata->has_buyable_product() &&
       price_metadata->buyable_product().has_offer_id()) {
diff --git a/ios/chrome/browser/complex_tasks/model/ios_content_record_task_id.h b/ios/chrome/browser/complex_tasks/model/ios_content_record_task_id.h
index c384b9f..9af649e 100644
--- a/ios/chrome/browser/complex_tasks/model/ios_content_record_task_id.h
+++ b/ios/chrome/browser/complex_tasks/model/ios_content_record_task_id.h
@@ -13,7 +13,7 @@
 // Stores Task ID data in a NavigationItem. Task IDs track navigations and
 // relationships between navigations
 //
-// TODO(crbug.com/976501)
+// TODO(crbug.com/40632717)
 // Move common logic to components/sessionss/core and have
 // IOSContentRecordTaskId inherit from there. Common logic in
 // components/sessions/content/content_record_task_id.h will inherit from
diff --git a/ios/chrome/browser/credential_provider/model/credential_provider_service.mm b/ios/chrome/browser/credential_provider/model/credential_provider_service.mm
index 03f1a26..155425e9 100644
--- a/ios/chrome/browser/credential_provider/model/credential_provider_service.mm
+++ b/ios/chrome/browser/credential_provider/model/credential_provider_service.mm
@@ -178,7 +178,7 @@
   // Make sure the initial value of the pref is stored.
   OnSavingPasswordsEnabledChanged();
 
-  // TODO(crbug.com/1441012): Remove after 04/2024.
+  // TODO(crbug.com/40909655): Remove after 04/2024.
   NSArray<NSString*>* obsolete_keys = @[
     @"UserDefaultsCredentialProviderASIdentityStoreSyncCompleted.V1",
     @"UserDefaultsCredentialProviderFirstTimeSyncCompleted.V1"
diff --git a/ios/chrome/browser/download/model/browser_download_service.mm b/ios/chrome/browser/download/model/browser_download_service.mm
index 8e944b1..c12b1e0 100644
--- a/ios/chrome/browser/download/model/browser_download_service.mm
+++ b/ios/chrome/browser/download/model/browser_download_service.mm
@@ -94,7 +94,7 @@
   } else {
     DownloadManagerTabHelper* tab_helper =
         DownloadManagerTabHelper::FromWebState(web_state);
-    // TODO(crbug.com/1300151): Investigate why tab_helper is sometimes nil.
+    // TODO(crbug.com/40216128): Investigate why tab_helper is sometimes nil.
     if (tab_helper)
       tab_helper->SetCurrentDownload(std::move(task));
   }
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index 6cd24789..2ccd31e 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -563,12 +563,18 @@
     {kRichAutocompletionParam, kRichAutocompletionParamLabel}};
 const FeatureEntry::FeatureParam kRichAutocompletionImplementationTextField[] =
     {{kRichAutocompletionParam, kRichAutocompletionParamTextField}};
+const FeatureEntry::FeatureParam
+    kRichAutocompletionImplementationNoAdditionalText[] = {
+        {kRichAutocompletionParam, kRichAutocompletionParamNoAdditionalText}};
 const FeatureEntry::FeatureVariation
     kRichAutocompletionImplementationVariations[] = {
         {"In Label", kRichAutocompletionImplementationLabel,
          std::size(kRichAutocompletionImplementationLabel), nullptr},
         {"In TextField", kRichAutocompletionImplementationTextField,
          std::size(kRichAutocompletionImplementationTextField), nullptr},
+        {"No Additional Text",
+         kRichAutocompletionImplementationNoAdditionalText,
+         std::size(kRichAutocompletionImplementationNoAdditionalText), nullptr},
 };
 
 const FeatureEntry::FeatureParam kOneTapForMapsConsentModeDefault[] = {
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
index 9b81eff51..1d04baf0 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -610,7 +610,7 @@
 extern const char kMigrateSyncingUserToSignedInName[];
 extern const char kMigrateSyncingUserToSignedInDescription[];
 
-// TODO(crbug.com/1128242): Remove this flag after the refactoring work is
+// TODO(crbug.com/40148908): Remove this flag after the refactoring work is
 // finished.
 // Title and description for the flag used to test the newly
 // implemented tabstrip.
diff --git a/ios/chrome/browser/iph_for_new_chrome_user/model/tab_based_iph_browser_agent.h b/ios/chrome/browser/iph_for_new_chrome_user/model/tab_based_iph_browser_agent.h
index 9bbfbb7c..f97f3bfe 100644
--- a/ios/chrome/browser/iph_for_new_chrome_user/model/tab_based_iph_browser_agent.h
+++ b/ios/chrome/browser/iph_for_new_chrome_user/model/tab_based_iph_browser_agent.h
@@ -43,6 +43,12 @@
   // so that the related in-product help would be attempted.
   void NotifyBackForwardButtonTap();
 
+  // Notifies that the user has used the tab grid solely to switch to an
+  // adjacent tab.
+  void NotifySwitchToAdjacentTabFromTabGrid() {
+    // TODO(crbug.com/40276959): implement in implementation file.
+  }
+
 #pragma mark - Observer headers
 
   // BrowserObserver
diff --git a/ios/chrome/browser/passwords/model/password_controller_unittest.mm b/ios/chrome/browser/passwords/model/password_controller_unittest.mm
index 76579603..5c7da4e 100644
--- a/ios/chrome/browser/passwords/model/password_controller_unittest.mm
+++ b/ios/chrome/browser/passwords/model/password_controller_unittest.mm
@@ -1012,7 +1012,7 @@
                       GetWebFrame(/*is_main_frame=*/true));
 }
 
-// TODO(crbug.com/817755): Move them HTML const to separate HTML files.
+// TODO(crbug.com/41374066): Move them HTML const to separate HTML files.
 // An HTML page without a password form.
 static NSString* kHtmlWithoutPasswordForm =
     @"<h2>The rain in Spain stays <i>mainly</i> in the plain.</h2>";
diff --git a/ios/chrome/browser/plus_addresses/ui/plus_addresses_egtest.mm b/ios/chrome/browser/plus_addresses/ui/plus_addresses_egtest.mm
index e3608fd..f0bf11fba 100644
--- a/ios/chrome/browser/plus_addresses/ui/plus_addresses_egtest.mm
+++ b/ios/chrome/browser/plus_addresses/ui/plus_addresses_egtest.mm
@@ -259,7 +259,7 @@
 }
 
 - (void)testSwipeToDismiss {
-  // TODO(crbug.com/1508365): Test fails on iPad.
+  // TODO(crbug.com/40949085): Test fails on iPad.
   if ([ChromeEarlGrey isIPadIdiom]) {
     EARL_GREY_TEST_DISABLED(@"Fails on iPad.");
   }
diff --git a/ios/chrome/browser/policy/model/policy_incognito_mode_availability_egtest.mm b/ios/chrome/browser/policy/model/policy_incognito_mode_availability_egtest.mm
index 50c9683f..15af2e88 100644
--- a/ios/chrome/browser/policy/model/policy_incognito_mode_availability_egtest.mm
+++ b/ios/chrome/browser/policy/model/policy_incognito_mode_availability_egtest.mm
@@ -189,6 +189,6 @@
                   @"should stay in regular mode");
 }
 
-// TODO(crbug.com/1165655): Add test to new tab long-press menu.
+// TODO(crbug.com/40163908): Add test to new tab long-press menu.
 
 @end
diff --git a/ios/chrome/browser/qr_scanner/ui_bundled/qr_scanner_view_controller_egtest.mm b/ios/chrome/browser/qr_scanner/ui_bundled/qr_scanner_view_controller_egtest.mm
index e10f26a..44c4d3b 100644
--- a/ios/chrome/browser/qr_scanner/ui_bundled/qr_scanner_view_controller_egtest.mm
+++ b/ios/chrome/browser/qr_scanner/ui_bundled/qr_scanner_view_controller_egtest.mm
@@ -592,7 +592,7 @@
 }
 
 // Tests that a new dialog replaces an old dialog if the camera state changes.
-// TODO(crbug.com/1019211): Re-enable test on iOS12.
+// TODO(crbug.com/40105250): Re-enable test on iOS12.
 #if TARGET_IPHONE_SIMULATOR
 #define MAYBE_testDialogIsReplacedIfCameraStateChanges \
   testDialogIsReplacedIfCameraStateChanges
diff --git a/ios/chrome/browser/rlz/rlz_tracker_delegate_impl.mm b/ios/chrome/browser/rlz/rlz_tracker_delegate_impl.mm
index dacd7f5..1dc6c0b 100644
--- a/ios/chrome/browser/rlz/rlz_tracker_delegate_impl.mm
+++ b/ios/chrome/browser/rlz/rlz_tracker_delegate_impl.mm
@@ -86,7 +86,7 @@
 }
 
 bool RLZTrackerDelegateImpl::GetLanguage(std::u16string* language) {
-  // TODO(crbug.com/1288100): Implement.
+  // TODO(crbug.com/40816693): Implement.
   NOTIMPLEMENTED();
   return false;
 }
diff --git a/ios/chrome/browser/search_engines/model/BUILD.gn b/ios/chrome/browser/search_engines/model/BUILD.gn
index 01f63b5..8ff61a2 100644
--- a/ios/chrome/browser/search_engines/model/BUILD.gn
+++ b/ios/chrome/browser/search_engines/model/BUILD.gn
@@ -113,7 +113,7 @@
 }
 
 source_set("template_url_service_factory") {
-  # TODO(crbug.com/1382864): This target was added to prevent dependency
+  # TODO(crbug.com/40245854): This target was added to prevent dependency
   # cycles for Lens navigation.
   # Remove this target after fixing the Lens / Web dependency cycle.
   sources = [ "template_url_service_factory.h" ]
diff --git a/ios/chrome/browser/sessions/session_restoration_browser_agent_unittest.mm b/ios/chrome/browser/sessions/session_restoration_browser_agent_unittest.mm
index cd4be911..719c56c 100644
--- a/ios/chrome/browser/sessions/session_restoration_browser_agent_unittest.mm
+++ b/ios/chrome/browser/sessions/session_restoration_browser_agent_unittest.mm
@@ -312,7 +312,7 @@
       "Tabs.DroppedDuplicatesCountOnSessionRestore", 0, 1);
 }
 
-// TODO(crbug.com/888674): This test requires commiting item to
+// TODO(crbug.com/41416872): This test requires commiting item to
 // NavigationManagerImpl which is not possible, migrate this to EG test so
 // it can be tested.
 TEST_F(SessionRestorationBrowserAgentTest, DISABLED_RestoreSessionOnNTPTest) {
diff --git a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
index a4348be6..440e3ee9 100644
--- a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
+++ b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
@@ -300,8 +300,11 @@
   item->SetURL(GURL(kChromeUINewTabURL));
   items.push_back(std::move(item));
   web_state->GetNavigationManager()->Restore(0, std::move(items));
-  NewTabPageTabHelper::CreateForWebState(web_state.get());
-  NewTabPageTabHelper::FromWebState(web_state.get())->SetShowStartSurface(true);
+  if (!browser->GetBrowserState()->IsOffTheRecord()) {
+    NewTabPageTabHelper::CreateForWebState(web_state.get());
+    NewTabPageTabHelper::FromWebState(web_state.get())
+        ->SetShowStartSurface(true);
+  }
   browser->GetWebStateList()->InsertWebState(
       std::move(web_state),
       WebStateList::InsertionParams::Automatic().Activate());
@@ -1284,7 +1287,7 @@
   _mainWebStateObserver.reset();
   _policyWatcherObserver.reset();
 
-  // TODO(crbug.com/1229306): Consider moving this at the beginning of
+  // TODO(crbug.com/40778288): Consider moving this at the beginning of
   // teardownUI to indicate that the UI is about to be torn down and that the
   // dependencies depending on the browser UI models has to be cleaned up
   // agent).
diff --git a/ios/chrome/browser/shared/coordinator/scene/scene_controller_unittest.mm b/ios/chrome/browser/shared/coordinator/scene/scene_controller_unittest.mm
index 242ed4c4..088e396 100644
--- a/ios/chrome/browser/shared/coordinator/scene/scene_controller_unittest.mm
+++ b/ios/chrome/browser/shared/coordinator/scene/scene_controller_unittest.mm
@@ -223,7 +223,7 @@
 
 // Tests that scene controller correctly handles an external intent to
 // OpenIncognitoSearch.
-// TODO(crbug.com/1506950): re-enabled the test.
+// TODO(crbug.com/40947630): re-enabled the test.
 TEST_F(SceneControllerTest, DISABLED_TestOpenIncognitoSearchForShortcutItem) {
   UIApplicationShortcutItem* shortcut = [[UIApplicationShortcutItem alloc]
         initWithType:kShortcutNewIncognitoSearch
diff --git a/ios/chrome/browser/shared/model/browser/browser_provider.h b/ios/chrome/browser/shared/model/browser/browser_provider.h
index aa2733aa..8480fdf 100644
--- a/ios/chrome/browser/shared/model/browser/browser_provider.h
+++ b/ios/chrome/browser/shared/model/browser/browser_provider.h
@@ -24,7 +24,7 @@
 
 /*
  Properties that should be removed.
-  TODO(crbug.com/914306): The long-term goal is to reduce the size of this
+  TODO(crbug.com/40606165): The long-term goal is to reduce the size of this
   interface; this protocol allows for easy encapsulation of that process.
  */
 
diff --git a/ios/chrome/browser/shared/model/browser_state/DEPS b/ios/chrome/browser/shared/model/browser_state/DEPS
index ef98308..ba87f5a5 100644
--- a/ios/chrome/browser/shared/model/browser_state/DEPS
+++ b/ios/chrome/browser/shared/model/browser_state/DEPS
@@ -4,7 +4,7 @@
 
 specific_include_rules = {
   "chrome_browser_state.mm": [
-    # TODO(crbug.com/583685): remove once the //ios/web public API allow
+    # TODO(crbug.com/41237926): remove once the //ios/web public API allow
     # access to that class.
     "+ios/web/webui/url_data_manager_ios_backend.h"
   ],
diff --git a/ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h b/ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h
index 005aa60..fd03811 100644
--- a/ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h
+++ b/ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h
@@ -12,8 +12,8 @@
 class GURL;
 
 // Protocol for commands that will be handled by the BrowserCoordinator.
-// TODO(crbug.com/906662) : Rename this protocol to one that is more descriptive
-// and representative of the contents.
+// TODO(crbug.com/41427057) : Rename this protocol to one that is more
+// descriptive and representative of the contents.
 @protocol BrowserCoordinatorCommands
 
 // Prints the currently active tab.
diff --git a/ios/chrome/browser/shared/ui/list_model/list_model.mm b/ios/chrome/browser/shared/ui/list_model/list_model.mm
index 7766d9f..b824ba5 100644
--- a/ios/chrome/browser/shared/ui/list_model/list_model.mm
+++ b/ios/chrome/browser/shared/ui/list_model/list_model.mm
@@ -440,7 +440,7 @@
 
 @end
 
-// TODO(crbug.com/419346): Store in the browser state preference or in
+// TODO(crbug.com/41134911): Store in the browser state preference or in
 // UISceneSession.unserInfo instead of NSUserDefaults.
 @implementation ListModelCollapsedMediator
 
diff --git a/ios/chrome/browser/shared/ui/symbols/chrome_icon.mm b/ios/chrome/browser/shared/ui/symbols/chrome_icon.mm
index b9c91bb..5135cc9 100644
--- a/ios/chrome/browser/shared/ui/symbols/chrome_icon.mm
+++ b/ios/chrome/browser/shared/ui/symbols/chrome_icon.mm
@@ -38,7 +38,8 @@
 
 // Wraps -[UIImage imageFlippedForRightToLeftLayoutDirection] to also support
 // porting accessibility properties.
-// TODO(crbug.com/622543): remove this workaround if Apple fixes rdar://26962660
+// TODO(crbug.com/41260431): remove this workaround if Apple fixes
+// rdar://26962660
 UIImage* ImageFlippedForRightToLeftLayoutDirection(UIImage* image) {
   UIImage* imageFlipped = [image imageFlippedForRightToLeftLayoutDirection];
   imageFlipped.accessibilityIdentifier = image.accessibilityIdentifier;
diff --git a/ios/chrome/browser/shared/ui/symbols/symbol_names.mm b/ios/chrome/browser/shared/ui/symbols/symbol_names.mm
index 8e67b51..c6ea4344 100644
--- a/ios/chrome/browser/shared/ui/symbols/symbol_names.mm
+++ b/ios/chrome/browser/shared/ui/symbols/symbol_names.mm
@@ -12,7 +12,7 @@
 NSString* const kGoogleMapsSymbol = @"google_maps";
 NSString* const kGooglePhotosSymbol = @"google_photos";
 NSString* const kPageInsightsSymbol = @"page_insights";
-// TODO(crbug.com/1489185): Move PNG images out of this file.
+// TODO(crbug.com/40934931): Move PNG images out of this file.
 NSString* const kFedexCarrierImage = @"parcel_tracking_carrier_fedex";
 NSString* const kUPSCarrierImage = @"parcel_tracking_carrier_ups";
 NSString* const kUSPSCarrierImage = @"parcel_tracking_carrier_usps";
diff --git a/ios/chrome/browser/shared/ui/table_view/legacy_chrome_table_view_controller.mm b/ios/chrome/browser/shared/ui/table_view/legacy_chrome_table_view_controller.mm
index 204408e..1d6e3c35 100644
--- a/ios/chrome/browser/shared/ui/table_view/legacy_chrome_table_view_controller.mm
+++ b/ios/chrome/browser/shared/ui/table_view/legacy_chrome_table_view_controller.mm
@@ -277,7 +277,7 @@
   // there's a need for `exclusiveTouch` to be disabled for some cells,
   // `exclusiveTouch` can be overridden for those cells in the
   // LegacyChromeTableViewController subclass that implments them.
-  // TODO(crbug.com/1471527): Make Chrome Coordinators robust against the
+  // TODO(crbug.com/40926228): Make Chrome Coordinators robust against the
   // launch of multiple child coordinators.
   cell.exclusiveTouch = YES;
 
diff --git a/ios/chrome/browser/shared/ui/util/reversed_animation.mm b/ios/chrome/browser/shared/ui/util/reversed_animation.mm
index c4b525b..e8771c3 100644
--- a/ios/chrome/browser/shared/ui/util/reversed_animation.mm
+++ b/ios/chrome/browser/shared/ui/util/reversed_animation.mm
@@ -198,7 +198,7 @@
                                                         parent:parent
                                                parentBeginTime:parentBeginTime];
   } else {
-    // TODO(crbug.com/546202): Investigate possible general-case reversals.  It
+    // TODO(crbug.com/41211316): Investigate possible general-case reversals. It
     // may be possible to implement this by manipulating the CAMediaTiming
     // properties.
   }
diff --git a/ios/chrome/browser/sync/model/sync_service_factory_unittest.cc b/ios/chrome/browser/sync/model/sync_service_factory_unittest.cc
index 25b2022..d5d7bbc 100644
--- a/ios/chrome/browser/sync/model/sync_service_factory_unittest.cc
+++ b/ios/chrome/browser/sync/model/sync_service_factory_unittest.cc
@@ -77,7 +77,8 @@
     datatypes.Put(syncer::PREFERENCES);
     datatypes.Put(syncer::PRIORITY_PREFERENCES);
     datatypes.Put(syncer::READING_LIST);
-    // TODO(crbug.com/919489) Add SECURITY_EVENTS data type once it is enabled.
+    // TODO(crbug.com/41434211) Add SECURITY_EVENTS data type once it is
+    // enabled.
     datatypes.Put(syncer::SESSIONS);
     datatypes.Put(syncer::SUPERVISED_USER_SETTINGS);
     datatypes.Put(syncer::USER_EVENTS);
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
index 7f03c71..c14370a 100644
--- a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
+++ b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
@@ -232,7 +232,7 @@
     if (!strongSelf)
       return;
 
-    // TODO(crbug.com/1326767): Nullify the browser object in the
+    // TODO(crbug.com/40225944): Nullify the browser object in the
     // AlertCoordinator when the coordinator is stopped to avoid using the
     // browser object at that moment, in which case the browser object may have
     // been deleted before the callback block is called. This is to avoid
diff --git a/ios/chrome/browser/ui/authentication/signin_earl_grey.h b/ios/chrome/browser/ui/authentication/signin_earl_grey.h
index 4f20720f..7087504 100644
--- a/ios/chrome/browser/ui/authentication/signin_earl_grey.h
+++ b/ios/chrome/browser/ui/authentication/signin_earl_grey.h
@@ -23,7 +23,7 @@
   [SigninEarlGreyImpl invokedFromFile:@"" __FILE__ lineNumber:__LINE__]
 
 // Methods used for the EarlGrey tests.
-// TODO(crbug.com/974833): Consider moving these into ChromeEarlGrey.
+// TODO(crbug.com/41465348): Consider moving these into ChromeEarlGrey.
 @interface SigninEarlGreyImpl : BaseEGTestHelperImpl
 
 // Calls -[SigninEarlGreyImpl addFakeIdentity:withUnknownCapabilities:NO].
diff --git a/ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.mm b/ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.mm
index 7bed08c..28548f2 100644
--- a/ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.mm
+++ b/ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.mm
@@ -208,7 +208,7 @@
           assertWithMatcher:grey_nil()];
       break;
     case SigninPromoViewModeSigninWithAccount:
-      // TODO(crbug.com/1210846): Determine when the SecondarySignInButton
+      // TODO(crbug.com/40182627): Determine when the SecondarySignInButton
       // should be present and assert that.
       break;
   }
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.h b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.h
index 5bb5a9ec..d4fcc41 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.h
+++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_injection_handler.h
@@ -14,7 +14,8 @@
 class WebStateList;
 
 // Handler with the common logic for injecting data from manual fill.
-// TODO(crbug.com/1116980): Convert ManualFillInjectionHandler to browser agent.
+// TODO(crbug.com/40144948): Convert ManualFillInjectionHandler to browser
+// agent.
 @interface ManualFillInjectionHandler : NSObject <ManualFillContentInjector>
 
 // Returns a handler using the `WebStateList` to inject JS to the active web
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm
index 73c47214..c15fd54 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm
@@ -285,7 +285,7 @@
 // Tests that the passwords view controller contains the "Manage Passwords..."
 // and "Manage Settings..." actions.
 - (void)testPasswordsViewControllerContainsManageActions {
-  // TODO(crbug.com/1352059): Re-enable when flake fixed.
+  // TODO(crbug.com/40857537): Re-enable when flake fixed.
   if ([ChromeEarlGrey isIPadIdiom]) {
     EARL_GREY_TEST_DISABLED(@"Test flaky failing on iPad.")
   }
@@ -735,7 +735,7 @@
 
 // Tests that the Password View Controller is dismissed when tapping the
 // keyboard.
-// TODO(crbug.com/909629): started to be flaky and sometimes opens full list
+// TODO(crbug.com/41428686): started to be flaky and sometimes opens full list
 // when typing text.
 - (void)DISABLED_testTappingKeyboardDismissPasswordControllerPopOver {
   if (![ChromeEarlGrey isIPadIdiom]) {
diff --git a/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm b/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm
index 4f66879a..f767bd3 100644
--- a/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm
+++ b/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm
@@ -572,7 +572,7 @@
 // Ensures that submitting the form should query Google Payments; but the
 // fallback local save infobar should not appear if the maximum StrikeDatabase
 // strike limit is reached.
-// TODO(crbug.com/925670): remove SetFormFillMaxStrikes() and incur
+// TODO(crbug.com/41437589): remove SetFormFillMaxStrikes() and incur
 // the maximum number of strikes by showing and declining save infobar instead.
 - (void)testNotOfferLocalSave_MaxStrikesReached {
   [ChromeEarlGrey
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h
index 5e00f2b5..2d53934a 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h
@@ -130,7 +130,7 @@
 // undo the performed action. Returns nil if there's nothing to undo.
 // Note: This function might invalidate `node` if `folder` and `node` belong to
 // different `BookmarkModel` instances.
-// TODO(crbug.com/1099901): Refactor to include position and replace two
+// TODO(crbug.com/40137712): Refactor to include position and replace two
 // functions below.
 MDCSnackbarMessage* UpdateBookmarkWithUndoToast(
     const bookmarks::BookmarkNode* node,
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
index 7228d58..4e75eeb 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.mm
@@ -304,7 +304,6 @@
     if (syncingBookmark) {
       // The user is signed-in, and syncing bookmark, but default bookmark
       // account is on a local folder.
-      CHECK(chosenByUser);
       std::u16string title = base::SysNSStringToUTF16(folderTitle);
       std::u16string pattern = l10n_util::GetStringUTF16(
           (showCount) ? IDS_IOS_BOOKMARK_PAGE_BULK_SAVED_FOLDER_TO_DEVICE
diff --git a/ios/chrome/browser/ui/bookmarks/cells/table_view_bookmarks_folder_item.mm b/ios/chrome/browser/ui/bookmarks/cells/table_view_bookmarks_folder_item.mm
index 6bf848c..e353fb9 100644
--- a/ios/chrome/browser/ui/bookmarks/cells/table_view_bookmarks_folder_item.mm
+++ b/ios/chrome/browser/ui/bookmarks/cells/table_view_bookmarks_folder_item.mm
@@ -181,7 +181,7 @@
     case BookmarksFolderAccessoryTypeDisclosureIndicator: {
       self.accessoryView = [[UIImageView alloc]
           initWithImage:[UIImage imageNamed:@"table_view_cell_chevron"]];
-      // TODO(crbug.com/870841): Use default accessory type.
+      // TODO(crbug.com/41405943): Use default accessory type.
       if (base::i18n::IsRTL()) {
         self.accessoryView.transform = CGAffineTransformMakeRotation(M_PI);
       }
diff --git a/ios/chrome/browser/ui/bookmarks/managed_bookmarks_egtest.mm b/ios/chrome/browser/ui/bookmarks/managed_bookmarks_egtest.mm
index a446bad..d6cdb8e 100644
--- a/ios/chrome/browser/ui/bookmarks/managed_bookmarks_egtest.mm
+++ b/ios/chrome/browser/ui/bookmarks/managed_bookmarks_egtest.mm
@@ -142,7 +142,7 @@
 
 // Tests that the managed bookmarks folder does not exist when the policy data
 // is empty.
-// Flaky. TODO(crbug.com/1132310): Re-enable.
+// Flaky. TODO(crbug.com/40721889): Re-enable.
 - (void)DISABLED_testEmptyManagedBookmarks {
   [BookmarkEarlGreyUI openBookmarks];
 
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
index ddbdc7e7..e4f18ee 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -596,7 +596,7 @@
   [self updateViewControllerDependencies];
 
   // Force the view load at a specific time.
-  // TODO(crbug.com/1431971): This should ideally go in createViewController,
+  // TODO(crbug.com/40263730): This should ideally go in createViewController,
   // but part of creating the view controller involves setting up a dispatch to
   // a command that isn't handled until updateViewControllerDependencies
   // (OmniboxCommands).
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.h b/ios/chrome/browser/ui/browser_view/browser_view_controller.h
index 709075ee..eadd4200 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.h
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.h
@@ -94,7 +94,7 @@
 // Initializes a new BVC.
 // `browserContainerViewController` is the container object this BVC will exist
 // inside.
-// TODO(crbug.com/992582): Remove references to model objects from this class.
+// TODO(crbug.com/41475381): Remove references to model objects from this class.
 - (instancetype)
     initWithBrowserContainerViewController:
         (BrowserContainerViewController*)browserContainerViewController
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index 6250da23..262b7cdf 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -1028,10 +1028,10 @@
 
   self.fullscreenController->BrowserTraitCollectionChangedBegin();
 
-  // TODO(crbug.com/527092): - traitCollectionDidChange: is not always forwarded
-  // because in some cases the presented view controller isn't a child of the
-  // BVC in the view controller hierarchy (some intervening object isn't a
-  // view controller).
+  // TODO(crbug.com/41198852): - traitCollectionDidChange: is not always
+  // forwarded because in some cases the presented view controller isn't a child
+  // of the BVC in the view controller hierarchy (some intervening object isn't
+  // a view controller).
   [self.presentedViewController
       traitCollectionDidChange:previousTraitCollection];
 
@@ -1159,7 +1159,7 @@
     // The second call would dismiss the BVC itself, so look for that case and
     // return early.
     //
-    // TODO(crbug.com/811671): A similar bug exists on all iOS versions with
+    // TODO(crbug.com/41370278): A similar bug exists on all iOS versions with
     // WKFileUploadPanel and UIDocumentPickerViewController.
     //
     // To make M65 as safe as possible, return early whenever this method is
@@ -1197,7 +1197,7 @@
                      animated:(BOOL)flag
                    completion:(void (^)())completion {
   ProceduralBlock finalCompletionHandler = [completion copy];
-  // TODO(crbug.com/580098) This is an interim fix for the flicker between the
+  // TODO(crbug.com/41235932) This is an interim fix for the flicker between the
   // launch screen and the FRE Animation. The fix is, if the FRE is about to be
   // presented, to show a temporary view of the launch screen and then remove it
   // when the controller for the FRE has been presented. This fix should be
@@ -1356,8 +1356,8 @@
   CGFloat height = self.toolbarCoordinator.expandedPrimaryToolbarHeight;
   // If the primary toolbar is not the topmost header, it does not overlap with
   // the unsafe area.
-  // TODO(crbug.com/806437): Update implementation such that this calculates the
-  // topmost header's height.
+  // TODO(crbug.com/41367346): Update implementation such that this calculates
+  // the topmost header's height.
   UIView* primaryToolbar =
       self.toolbarCoordinator.primaryToolbarViewController.view;
   UIView* topmostHeader = [self.headerViews firstObject].view;
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.mm b/ios/chrome/browser/ui/bubble/bubble_presenter.mm
index 44d1de5..40395db 100644
--- a/ios/chrome/browser/ui/bubble/bubble_presenter.mm
+++ b/ios/chrome/browser/ui/bubble/bubble_presenter.mm
@@ -588,7 +588,7 @@
 
 - (void)presentPullToRefreshGestureInProductHelp {
   if (UIAccessibilityIsVoiceOverRunning() || (![self canPresentBubble])) {
-    // TODO(crbug.com/1521489): Add voice over announcement once fixed.
+    // TODO(crbug.com/41494458): Add voice over announcement once fixed.
     return;
   }
   const base::Feature& pullToRefreshFeature =
@@ -849,7 +849,7 @@
 }
 
 // Returns whether the tab can present a bubble tip.
-// TODO(crbug.com/1448656): make most callsites pass NO for
+// TODO(crbug.com/40914423): make most callsites pass NO for
 // `CheckTabScrolledToTop` as it's error-prone.
 - (BOOL)canPresentBubble {
   return [self canPresentBubbleWithCheckTabScrolledToTop:YES];
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_consumer.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_consumer.h
index 9b8c236..b4457726 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_consumer.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_consumer.h
@@ -52,7 +52,7 @@
 
 // Indicates to the consumer to update the Magic Stack module order for a given
 // module `type` with the latest `status` change.
-// TODO(crbug.com/1477962) Also pass the view configs through this API instead
+// TODO(crbug.com/40280443) Also pass the view configs through this API instead
 // of having to call the feature-specific calls in this protocol.
 - (void)updateMagicStackOrder:(MagicStackOrderChange)change;
 
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm
index 30a28c3..5b496fe 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm
@@ -275,7 +275,7 @@
 
 // Tests that the "All Set" module is shown after completing all Set Up List
 // Hero Cell modules in the Magic Stack.
-// TODO(crbug.com/1520954): Test is flaky, re-enable when fixed.
+// TODO(crbug.com/41493926): Test is flaky, re-enable when fixed.
 - (void)DISABLED_testMagicStackSetUpListCompleteAllItems {
   [self prepareToTestSetUpListInMagicStack];
 
diff --git a/ios/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_module_container.mm b/ios/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_module_container.mm
index 2165548..8d70d38 100644
--- a/ios/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_module_container.mm
+++ b/ios/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_module_container.mm
@@ -249,7 +249,7 @@
   _seeMoreButton.hidden = !config.shouldShowSeeMore;
 
   if ([self shouldShowSubtitle]) {
-    // TODO(crbug.com/1474992): Update MagicStackModuleContainer to take an id
+    // TODO(crbug.com/40279482): Update MagicStackModuleContainer to take an id
     // config in its initializer so the container can build itself from a
     // passed config/state object.
     NSString* subtitle = [self subtitleStringForConfig:config];
@@ -325,7 +325,7 @@
       return kMagicStackContentSuggestionsModuleTabResumptionAccessibilityIdentifier;
 
     default:
-      // TODO(crbug.com/1506038): the code should use constants for
+      // TODO(crbug.com/40946679): the code should use constants for
       // accessibility identifiers, and not localized strings.
       return [self titleStringForModule:type];
   }
diff --git a/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm b/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm
index d63408b..7abb322 100644
--- a/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm
+++ b/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm
@@ -138,7 +138,7 @@
 
 #pragma mark - Private
 
-// TODO(crbug.com/1318432): rafactor long method.
+// TODO(crbug.com/40835387): rafactor long method.
 - (UIContextMenuActionProvider)
     contextMenuActionProviderForWebState:(web::WebState*)webState
                                   params:(web::ContextMenuParams)params {
diff --git a/ios/chrome/browser/ui/default_promo/post_restore/post_restore_default_browser_egtest.mm b/ios/chrome/browser/ui/default_promo/post_restore/post_restore_default_browser_egtest.mm
index 053f9d6..caf96b76 100644
--- a/ios/chrome/browser/ui/default_promo/post_restore/post_restore_default_browser_egtest.mm
+++ b/ios/chrome/browser/ui/default_promo/post_restore/post_restore_default_browser_egtest.mm
@@ -80,7 +80,7 @@
 #pragma mark - Tests
 
 // Verifies that the secondary action button opens dismisses the promo.
-// TODO(crbug.com/1477791): re-enable once test is no longer flaky.
+// TODO(crbug.com/40929054): re-enable once test is no longer flaky.
 - (void)DISABLED_testDismiss {
   [ChromeEarlGrey waitForUIElementToAppearWithMatcher:TitleMatcher()
                                               timeout:kPromoAppearanceTimeout];
diff --git a/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm b/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm
index c138528b..a13769e 100644
--- a/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm
+++ b/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm
@@ -480,7 +480,7 @@
 }
 
 // Tests that an alert is presented after displaying the share menu.
-// TODO(crbug.com/747622): re-enable this test once earl grey can interact
+// TODO(crbug.com/41334973): re-enable this test once earl grey can interact
 // with the share menu.
 - (void)DISABLED_testShowJavaScriptAfterShareMenu {
   // Load the blank test page.
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_controller_impl.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_controller_impl.mm
index 70a41c84..5ecbad5 100644
--- a/ios/chrome/browser/ui/fullscreen/fullscreen_controller_impl.mm
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_controller_impl.mm
@@ -6,8 +6,6 @@
 
 #import "base/memory/ptr_util.h"
 #import "base/metrics/histogram_functions.h"
-#import "base/metrics/user_metrics.h"
-#import "base/metrics/user_metrics_action.h"
 #import "ios/chrome/browser/download/model/mime_type_util.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/browser_state_otr_helper.h"
@@ -156,17 +154,14 @@
 }
 
 void FullscreenControllerImpl::EnterFullscreen() {
-  base::RecordAction(base::UserMetricsAction("MobileFullscreenEntered"));
   mediator_.EnterFullscreen();
 }
 
 void FullscreenControllerImpl::ExitFullscreen() {
-  base::RecordAction(base::UserMetricsAction("MobileFullscreenExited"));
   mediator_.ExitFullscreen();
 }
 
 void FullscreenControllerImpl::ExitFullscreenWithoutAnimation() {
-  base::RecordAction(base::UserMetricsAction("MobileFullscreenExited"));
   mediator_.ExitFullscreenWithoutAnimation();
 }
 
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_mediator.h b/ios/chrome/browser/ui/fullscreen/fullscreen_mediator.h
index 78fa2bb..e26e0a1a 100644
--- a/ios/chrome/browser/ui/fullscreen/fullscreen_mediator.h
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_mediator.h
@@ -90,6 +90,8 @@
 
   // Progress value when scroll event started.
   float start_progress_;
+  // True if metrics as not been recorded and should be.
+  bool should_record_metrics_;
   // The controller.
   raw_ptr<FullscreenController> controller_ = nullptr;
   // The model.
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_mediator.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_mediator.mm
index d579851..0723c2a 100644
--- a/ios/chrome/browser/ui/fullscreen/fullscreen_mediator.mm
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_mediator.mm
@@ -6,6 +6,8 @@
 
 #import "base/check_op.h"
 #import "base/memory/ptr_util.h"
+#import "base/metrics/user_metrics.h"
+#import "base/metrics/user_metrics_action.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_animator.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_content_adjustment_util.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_controller_observer.h"
@@ -117,6 +119,15 @@
   for (auto& observer : observers_) {
     observer.FullscreenProgressUpdated(controller_, model_->progress());
   }
+  if (should_record_metrics_) {
+    if (model_->progress() == 0) {
+      base::RecordAction(base::UserMetricsAction("MobileFullscreenEntered"));
+      should_record_metrics_ = false;
+    } else if (model_->progress() == 1) {
+      base::RecordAction(base::UserMetricsAction("MobileFullscreenExited"));
+      should_record_metrics_ = false;
+    }
+  }
 
   [resizer_ updateForCurrentState];
 }
@@ -150,6 +161,7 @@
 void FullscreenMediator::FullscreenModelScrollEventEnded(
     FullscreenModel* model) {
   DCHECK_EQ(model_, model);
+  should_record_metrics_ = true;
   FullscreenAnimatorStyle animatorStyle;
   if (base::FeatureList::IsEnabled(web::features::kSmoothScrollingDefault)) {
     AnimateWithStyle(model_->progress() >= 0.5
@@ -165,6 +177,8 @@
         AreCGFloatsEqual(model_->progress(), 0.0) &&
         model_->can_collapse_toolbar()) {
       animatorStyle = FullscreenAnimatorStyle::EXIT_FULLSCREEN;
+      base::RecordAction(
+          base::UserMetricsAction("MobileFullscreenExitedBottomReached"));
     } else if (model_->progress() >= 0.5) {
       animatorStyle = FullscreenAnimatorStyle::EXIT_FULLSCREEN;
     } else if (direction < 0) {
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm
index 7f22012..1aca971 100644
--- a/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm
+++ b/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm
@@ -378,9 +378,9 @@
     // After reloads, pages whose viewports fit the screen are sometimes resized
     // to account for the safe area insets.  Adding these to the threshold helps
     // prevent fullscreen from beeing re-enabled in this case.
-    // TODO(crbug.com/924807): This logic can potentially disable fullscreen for
-    // short pages in which this bug does not occur.  It should be removed once
-    // the page can be reloaded without resizing.
+    // TODO(crbug.com/41437113): This logic can potentially disable fullscreen
+    // for short pages in which this bug does not occur.  It should be removed
+    // once the page can be reloaded without resizing.
     disabling_threshold += safe_area_insets_.top + safe_area_insets_.bottom;
   }
 
diff --git a/ios/chrome/browser/ui/history/history_table_view_controller.mm b/ios/chrome/browser/ui/history/history_table_view_controller.mm
index 383aebb994..8d52e6cf 100644
--- a/ios/chrome/browser/ui/history/history_table_view_controller.mm
+++ b/ios/chrome/browser/ui/history/history_table_view_controller.mm
@@ -357,7 +357,7 @@
 
 - (void)historyEntriesStatusItem:(HistoryEntriesStatusItem*)item
                didRequestOpenURL:(const GURL&)URL {
-  // TODO(crbug.com/805190): Migrate. This will navigate to the status message
+  // TODO(crbug.com/41366648): Migrate. This will navigate to the status message
   // "Show Full History" URL.
 }
 
@@ -1286,7 +1286,7 @@
   return _cancelButton;
 }
 
-// TODO(crbug.com/831865): Find a way to disable the button when a VC is
+// TODO(crbug.com/41382611): Find a way to disable the button when a VC is
 // presented.
 - (UIBarButtonItem*)clearBrowsingDataButton {
   if (!_clearBrowsingDataButton) {
diff --git a/ios/chrome/browser/ui/history/history_ui_egtest.mm b/ios/chrome/browser/ui/history/history_ui_egtest.mm
index 040522b..bf0eb25 100644
--- a/ios/chrome/browser/ui/history/history_ui_egtest.mm
+++ b/ios/chrome/browser/ui/history/history_ui_egtest.mm
@@ -821,7 +821,7 @@
 #pragma mark Multiwindow
 
 - (void)testHistorySyncInMultiwindow {
-  // TODO(crbug.com/1252457): Test is flaky on iPad devices.
+  // TODO(crbug.com/40198758): Test is flaky on iPad devices.
   if ([ChromeEarlGrey isIPadIdiom]) {
     EARL_GREY_TEST_DISABLED(@"This test is flaky on iPad devices.");
   }
diff --git a/ios/chrome/browser/ui/infobars/translate_infobar_egtest.mm b/ios/chrome/browser/ui/infobars/translate_infobar_egtest.mm
index d837cbe..d8ee2194 100644
--- a/ios/chrome/browser/ui/infobars/translate_infobar_egtest.mm
+++ b/ios/chrome/browser/ui/infobars/translate_infobar_egtest.mm
@@ -91,7 +91,7 @@
     "<meta http-equiv=\"content-language\" content=\"it\">";
 
 // Various link components.
-// TODO(crbug.com/729195): Re-write the hardcoded address.
+// TODO(crbug.com/41322998): Re-write the hardcoded address.
 const char kHttpServerDomain[] = "127.0.0.1";
 const char kLanguagePath[] = "/languagepath/";
 const char kLinkPath[] = "/linkpath/";
diff --git a/ios/chrome/browser/ui/lens/lens_coordinator.mm b/ios/chrome/browser/ui/lens/lens_coordinator.mm
index 78e05b0..45fccdb 100644
--- a/ios/chrome/browser/ui/lens/lens_coordinator.mm
+++ b/ios/chrome/browser/ui/lens/lens_coordinator.mm
@@ -244,7 +244,7 @@
   UIViewController* viewController =
       [lensController inputSelectionViewController];
 
-  // TODO(crbug.com/1353430): the returned UIViewController
+  // TODO(crbug.com/40235185): the returned UIViewController
   // must not be nil, remove this check once the internal
   // implementation of the method is complete.
   if (!viewController) {
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_model_delegate_ios.mm b/ios/chrome/browser/ui/location_bar/location_bar_model_delegate_ios.mm
index 7f239c7..e23fa98 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_model_delegate_ios.mm
+++ b/ios/chrome/browser/ui/location_bar/location_bar_model_delegate_ios.mm
@@ -128,9 +128,9 @@
   // This is currently only called by the OmniboxEditModel to determine if the
   // Google landing page is showing.
   //
-  // TODO(crbug.com/315563)(lliabraa): This should also check the user's default
-  // search engine because if they're not using Google the Google landing page
-  // is not shown.
+  // TODO(crbug.com/40340113)(lliabraa): This should also check the user's
+  // default search engine because if they're not using Google the Google
+  // landing page is not shown.
   GURL currentURL;
   if (!GetURL(&currentURL))
     return false;
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_steady_view.h b/ios/chrome/browser/ui/location_bar/location_bar_steady_view.h
index d5ab009..250dcc7 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_steady_view.h
+++ b/ios/chrome/browser/ui/location_bar/location_bar_steady_view.h
@@ -63,7 +63,7 @@
 // The label displaying the current location URL.
 @property(nonatomic, strong) UILabel* locationLabel;
 // The view displaying badges in the leading corner of the view.
-// TODO(crbug.com/991241): Pass into init as parameter.
+// TODO(crbug.com/40639170): Pass into init as parameter.
 @property(nonatomic, strong) UIView* badgeView;
 // The view displaying the Contextual Panel's entrypoint.
 @property(nonatomic, strong) UIView* contextualPanelEntrypointView;
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_steady_view_mediator_unittest.mm b/ios/chrome/browser/ui/location_bar/location_bar_steady_view_mediator_unittest.mm
index a7f06c3eb..954f0f82 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_steady_view_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/location_bar/location_bar_steady_view_mediator_unittest.mm
@@ -144,4 +144,4 @@
   EXPECT_TRUE(consumer_.icon);
 }
 
-// TODO(crbug.com/992578): Add more tests to this suite.
+// TODO(crbug.com/41475379): Add more tests to this suite.
diff --git a/ios/chrome/browser/ui/main_content/main_content_ui_state.mm b/ios/chrome/browser/ui/main_content/main_content_ui_state.mm
index dffe5f8..db7248f 100644
--- a/ios/chrome/browser/ui/main_content/main_content_ui_state.mm
+++ b/ios/chrome/browser/ui/main_content/main_content_ui_state.mm
@@ -63,7 +63,7 @@
 
 @interface MainContentUIStateUpdater ()
 // The pan gesture driving the current scroll event.
-// TODO(crbug.com/785508): Use this gesture recognizer to broadcast the scroll
+// TODO(crbug.com/41355675): Use this gesture recognizer to broadcast the scroll
 // touch location.
 @property(nonatomic, weak) UIPanGestureRecognizer* panGesture;
 @end
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm
index 2f4f2ad2..5971846 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm
@@ -505,8 +505,8 @@
                                   self.fakeOmnibox);
 }
 
-// TODO(crbug.com/807330) The fakebox is currently a collection of views spread
-// between NewTabPageHeaderViewController and inside
+// TODO(crbug.com/41367911) The fakebox is currently a collection of views
+// spread between NewTabPageHeaderViewController and inside
 // NewTabPageHeaderView.  Post refresh this can be coalesced into one
 // control, and the KVO highlight logic below can be removed.
 - (void)observeValueForKeyPath:(NSString*)keyPath
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_container_view.mm b/ios/chrome/browser/ui/omnibox/omnibox_container_view.mm
index 21ccfe8..055cf2a 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_container_view.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_container_view.mm
@@ -279,7 +279,8 @@
                   range:NSMakeRange(0, addditionalAttributedText.length)];
       _textField.additionalText = addditionalAttributedText;
     }
-  } else {
+  } else if (IsRichAutocompletionEnabled(
+                 RichAutocompletionImplementation::kLabel)) {
     // Additional text in Label.
     _additionalTextLabel.text = additionalText;
     _additionalTextLabel.hidden = !additionalText.length;
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_ui_features.cc b/ios/chrome/browser/ui/omnibox/omnibox_ui_features.cc
index 8d6000c..97c83d5 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_ui_features.cc
+++ b/ios/chrome/browser/ui/omnibox/omnibox_ui_features.cc
@@ -44,6 +44,7 @@
 const char kRichAutocompletionParam[] = "RichAutocompletionParam";
 const char kRichAutocompletionParamLabel[] = "Label";
 const char kRichAutocompletionParamTextField[] = "TextField";
+const char kRichAutocompletionParamNoAdditionalText[] = "NoAdditionalText";
 
 bool IsRichAutocompletionEnabled(RichAutocompletionImplementation type) {
   if (!IsRichAutocompletionEnabled()) {
@@ -58,6 +59,8 @@
       omnibox::kRichAutocompletion, kRichAutocompletionParam);
   if (type == RichAutocompletionImplementation::kLabel) {
     return featureParam == kRichAutocompletionParamLabel;
+  } else if (type == RichAutocompletionImplementation::kNoAdditionalText) {
+    return featureParam == kRichAutocompletionParamNoAdditionalText;
   }
 
   // TextField is the default.
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_ui_features.h b/ios/chrome/browser/ui/omnibox/omnibox_ui_features.h
index 23619aa3..696356c 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_ui_features.h
+++ b/ios/chrome/browser/ui/omnibox/omnibox_ui_features.h
@@ -37,6 +37,8 @@
   kLabel,
   // kRichAutocompletionParamTextField.
   kTextField,
+  // kRichAutocompletionParamNoAdditionalText.
+  kNoAdditionalText,
   // Any implementation type.
   kAny,
 };
@@ -53,5 +55,7 @@
 extern const char kRichAutocompletionParamLabel[];
 // Rich autocompletion is shown inside of the text field.
 extern const char kRichAutocompletionParamTextField[];
+// Rich autocompletion with no additional text.
+extern const char kRichAutocompletionParamNoAdditionalText[];
 
 #endif  // IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_UI_FEATURES_H_
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm
index 84aa5e3..c9366f73 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm
@@ -262,7 +262,9 @@
 }
 
 void OmniboxViewIOS::SetAdditionalText(const std::u16string& text) {
-  if (!IsRichAutocompletionEnabled()) {
+  if (!IsRichAutocompletionEnabled() ||
+      IsRichAutocompletionEnabled(
+          RichAutocompletionImplementation::kNoAdditionalText)) {
     return;
   }
 
@@ -525,7 +527,7 @@
   if (!processing_user_event && !proceed_without_user_event)
     return;
 
-  // TODO(crbug.com/564599): OnAfterPossibleChange() now takes an argument. It
+  // TODO(crbug.com/41225237): OnAfterPossibleChange() now takes an argument. It
   // use to not take an argument and was defaulting to false, so as it is
   // unclear what the correct value is, using what was that before seems
   // consistent.
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
index ee3654e..f882d65 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
@@ -1089,8 +1089,8 @@
 #pragma mark - UIScrollViewDelegate
 
 - (void)scrollViewDidScroll:(UIScrollView*)scrollView {
-  // TODO(crbug.com/733650): Default to the dragging check once it's been tested
-  // on trunk.
+  // TODO(crbug.com/41325585): Default to the dragging check once it's been
+  // tested on trunk.
   if (!scrollView.dragging)
     return;
 
diff --git a/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.mm b/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.mm
index cd91cf1..cc00b7b 100644
--- a/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.mm
+++ b/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.mm
@@ -61,7 +61,7 @@
 
 // Returns the OverlayRequestCoordinator subclass responsible for showing
 // `request`'s overlay UI.
-// TODO(crbug.com/1447483): Clean the switch when the default flow is added.
+// TODO(crbug.com/40268990): Clean the switch when the default flow is added.
 - (Class)coordinatorClassForRequest:(OverlayRequest*)request {
   if (DefaultInfobarOverlayRequestConfig::RequestSupport()->IsRequestSupported(
           request)) {
diff --git a/ios/chrome/browser/ui/page_info/page_info_site_security_mediator.mm b/ios/chrome/browser/ui/page_info/page_info_site_security_mediator.mm
index 531e69d..8785dce 100644
--- a/ios/chrome/browser/ui/page_info/page_info_site_security_mediator.mm
+++ b/ios/chrome/browser/ui/page_info/page_info_site_security_mediator.mm
@@ -169,7 +169,7 @@
   NSString* certificateDetails = @"";
   if (!issuerName.empty()) {
     // Show the issuer name if it's available.
-    // TODO(crbug.com/502470): Implement a certificate viewer instead.
+    // TODO(crbug.com/41183995): Implement a certificate viewer instead.
     certificateDetails = l10n_util::GetNSStringF(
         IDS_IOS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY, issuerName);
   }
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_coordinator.mm b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_coordinator.mm
index b619815..08bc2a8 100644
--- a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_coordinator.mm
+++ b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_coordinator.mm
@@ -160,7 +160,7 @@
   [self.baseViewController.presentedViewController
       dismissViewControllerAnimated:NO
                          completion:^{
-                           // TODO(crbug.com/1422344): Add metric for when the
+                           // TODO(crbug.com/40896839): Add metric for when the
                            // credential is nil.
                            if (credential.has_value()) {
                              [weakSelf
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_mediator_unittest.mm b/ios/chrome/browser/ui/reading_list/reading_list_mediator_unittest.mm
index ab9e96bc..ed1ff38 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_mediator_unittest.mm
@@ -37,7 +37,7 @@
 
 // ReadingListMediatorTest is parameterized on this enum to test both
 // FaviconAttributesProvider and FaviconLoader.
-// TODO(crbug.com/878796): Remove as part of UIRefresh cleanup.
+// TODO(crbug.com/41410664): Remove as part of UIRefresh cleanup.
 enum class FaviconServiceType {
   FAVICON_LOADER,
   ATTRIBUTES_PROVIDER,
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_menu_notifier.mm b/ios/chrome/browser/ui/reading_list/reading_list_menu_notifier.mm
index 6387bb9..752a4a7 100644
--- a/ios/chrome/browser/ui/reading_list/reading_list_menu_notifier.mm
+++ b/ios/chrome/browser/ui/reading_list/reading_list_menu_notifier.mm
@@ -32,8 +32,8 @@
 
 @end
 
-// TODO(crbug.com/590725): use the one-and-only protocol-based implementation of
-// ReadingListModelObserver
+// TODO(crbug.com/41241675): use the one-and-only protocol-based implementation
+// of ReadingListModelObserver
 class ReadingListObserverBridge : public ReadingListModelObserver {
  public:
   explicit ReadingListObserverBridge(ReadingListMenuNotifier* owner)
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_egtest.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_egtest.mm
index 4927f4c..3f4f911 100644
--- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_egtest.mm
+++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_egtest.mm
@@ -647,7 +647,7 @@
 
 // Tests no promo to sync is shown to a signed-in non-syncing user if sync is
 // disabled by policy.
-// TODO(crbug.com/1487984): Test fails on official builds.
+// TODO(crbug.com/40073777): Test fails on official builds.
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 #define MAYBE_testNoPromoIfSignedInAndSyncDisabledByPolicy \
   DISABLED_testNoPromoIfSignedInAndSyncDisabledByPolicy
@@ -942,7 +942,7 @@
 }
 
 // Tests the Open in New Window action on a recent tab's context menu.
-// TODO(crbug.com/1273942) Test is flaky.
+// TODO(crbug.com/40807242) Test is flaky.
 - (void)FLAKY_testContextMenuOpenInNewWindow {
   if (![ChromeEarlGrey areMultipleWindowsSupported]) {
     EARL_GREY_TEST_DISABLED(@"Multiple windows can't be opened.");
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
index 3bdd58c..7209b0eb 100644
--- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
+++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -1870,7 +1870,7 @@
 
 // Returns YES if the History Sync Opt-In should be shown when the promo action
 // button is tapped.
-// TODO(crbug.com/1462326): This logic should be moved outside of the
+// TODO(crbug.com/40921836): This logic should be moved outside of the
 // ViewController.
 - (BOOL)shouldShowHistorySyncOnPromoAction {
   AuthenticationService* authenticationService =
diff --git a/ios/chrome/browser/ui/sad_tab/sad_tab_view_egtest.mm b/ios/chrome/browser/ui/sad_tab/sad_tab_view_egtest.mm
index f845e7f..d2dbdeb 100644
--- a/ios/chrome/browser/ui/sad_tab/sad_tab_view_egtest.mm
+++ b/ios/chrome/browser/ui/sad_tab/sad_tab_view_egtest.mm
@@ -44,7 +44,7 @@
 // visited within 60 seconds, for this reason this one test can not
 // be easily split up across multiple tests
 // as visiting Sad Tab may not be idempotent.
-// TODO(crbug.com/1047238): Test fails when run on iOS 13.
+// TODO(crbug.com/40671245): Test fails when run on iOS 13.
 - (void)DISABLED_testSadTabView {
   // Prepare a simple but known URL to avoid testing from the NTP.
   GREYAssertTrue(self.testServer->Start(), @"Server did not start.");
diff --git a/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator.mm b/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator.mm
index 852eb77c..eb9be37 100644
--- a/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator.mm
+++ b/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator.mm
@@ -366,7 +366,7 @@
     _identity = nil;
     base::UmaHistogramTimes(kSaveToPhotosUploadFailureLatencyHistogram,
                             base::TimeTicks::Now() - _uploadStart);
-    // TODO(crbug.com/1513891): Emit the failure type as-is once the service is
+    // TODO(crbug.com/41486457): Emit the failure type as-is once the service is
     // able to identify out-of-storage errors by itself.
     if (result.failure_type == PhotosServiceUploadFailureType::kUploadPhoto2 &&
         [result.error.localizedDescription
diff --git a/ios/chrome/browser/ui/scanner/scanner_view.mm b/ios/chrome/browser/ui/scanner/scanner_view.mm
index a74e9d0..59bb84ab 100644
--- a/ios/chrome/browser/ui/scanner/scanner_view.mm
+++ b/ios/chrome/browser/ui/scanner/scanner_view.mm
@@ -71,7 +71,7 @@
 
 #pragma mark - UIView
 
-// TODO(crbug.com/633577): Replace the preview overlay with a UIView which is
+// TODO(crbug.com/40478852): Replace the preview overlay with a UIView which is
 // not resized.
 - (void)layoutSubviews {
   [super layoutSubviews];
diff --git a/ios/chrome/browser/ui/search_with/search_with_mediator_egtest.mm b/ios/chrome/browser/ui/search_with/search_with_mediator_egtest.mm
index 7ec3e45..f6e2c103 100644
--- a/ios/chrome/browser/ui/search_with/search_with_mediator_egtest.mm
+++ b/ios/chrome/browser/ui/search_with/search_with_mediator_egtest.mm
@@ -120,7 +120,7 @@
 }
 
 // Convenient function to trigger the Edit Menu on `kElementToLongPress`.
-// TODO(crbug.com/1434686): extract this function and have all edit menu
+// TODO(crbug.com/40264849): extract this function and have all edit menu
 // tests use it.
 void TriggerEditMenu() {
   [[EarlGrey selectElementWithMatcher:[EditMenuAppInterface editMenuMatcher]]
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_egtest.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_egtest.mm
index a28ef4a..a4cfdd6 100644
--- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_egtest.mm
+++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_egtest.mm
@@ -319,7 +319,7 @@
 // entries. Also verifies that the user is still signed in when the dialog
 // Cancel button is tapped.
 - (void)testUnsyncedDataDialogShowsInCaseOfUnsyncedReadingListEntry {
-  // TODO(crbug.com/1521690): Test fails on iPhone device and simulator.
+  // TODO(crbug.com/41494658): Test fails on iPhone device and simulator.
   if (![ChromeEarlGrey isIPadIdiom]) {
     EARL_GREY_TEST_DISABLED(@"Fails on iPhone.");
   }
diff --git a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_egtest.mm b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_egtest.mm
index 2de756e3..d3fd13a3 100644
--- a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_egtest.mm
+++ b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_egtest.mm
@@ -430,9 +430,9 @@
 }
 
 // Tests the loading state of the Password Checkup Homepage.
-// TODO(crbug.com/1462095): Fix and re enable the test.
+// TODO(crbug.com/40921746): Fix and re enable the test.
 - (void)DISABLED_testPasswordCheckupHomepageLoadingState {
-  // TODO(crbug.com/1512150): Test fails on iPad.
+  // TODO(crbug.com/41484731): Test fails on iPad.
   if ([ChromeEarlGrey isIPadIdiom]) {
     EARL_GREY_TEST_DISABLED(@"Fails on iPad.");
   }
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
index 0592468..5c08046d 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_mediator.mm
@@ -439,7 +439,7 @@
 - (NSMutableDictionary<NSString*, NSMutableSet<NSString*>*>*)
     usernamesWithSameDomainDict {
   if (!_usernamesWithSameDomainDict) {
-    // TODO(crbug.com/1400692): Improve saved passwords logic when helper is
+    // TODO(crbug.com/40883869): Improve saved passwords logic when helper is
     // available in SavedPasswordsPresenter.
     _usernamesWithSameDomainDict = [[NSMutableDictionary alloc] init];
     NSMutableSet<NSString*>* signonRealms = [[NSMutableSet alloc] init];
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
index 2efc8c1..a4343c29 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
@@ -274,7 +274,7 @@
     // Editing mode will be exited only if user confirms saving.
     if ([self passwordsDidChange]) {
       DCHECK(self.handler);
-      // TODO(crbug.com/1401035): Show Password Edit Dialog when Password
+      // TODO(crbug.com/40884045): Show Password Edit Dialog when Password
       // Grouping is enabled.
       [self.handler showPasswordEditDialogWithOrigin:self.pageTitle];
     } else {
@@ -647,7 +647,7 @@
   }
 #if !defined(__IPHONE_16_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_16_0
   else {
-    // TODO(crbug.com/1481223): Replace UIMenuController with
+    // TODO(crbug.com/40930648): Replace UIMenuController with
     // UIEditMenuInteraction in iOS 16+.
     UIMenuController* menu = [UIMenuController sharedMenuController];
     if (![menu isMenuVisible]) {
diff --git a/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm b/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm
index f7ab0aa..08840b7f 100644
--- a/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm
+++ b/ios/chrome/browser/ui/settings/password/password_manager_egtest.mm
@@ -1621,7 +1621,7 @@
 // storing just about enough passwords to ensure filling more than one page on
 // any device. To limit the effect of (2), custom large scrolling steps are
 // added to the usual scrolling actions.
-// TODO(crbug.com/1442985): This test is flaky.
+// TODO(crbug.com/40910877): This test is flaky.
 - (void)FLAKY_testManyPasswords {
   if ([ChromeEarlGrey isIPadIdiom]) {
     // TODO(crbug.com/40602996): Enable the test on iPad once the bug is fixed.
@@ -2349,7 +2349,7 @@
 // Tests that when a new credential is saved or an existing one is updated via
 // the add credential flow, the VC auto scrolls to the newly created or the
 // updated entry.
-// TODO(crbug.com/1377079): Flaky, please re-enable once fixed.
+// TODO(crbug.com/40874087): Flaky, please re-enable once fixed.
 - (void)testAutoScroll {
   for (int i = 0; i < 20; i++) {
     NSString* username = [NSString stringWithFormat:@"username %d", i];
diff --git a/ios/chrome/browser/ui/settings/password/password_manager_view_controller_items.mm b/ios/chrome/browser/ui/settings/password/password_manager_view_controller_items.mm
index 2c987a16..d7bc7a52 100644
--- a/ios/chrome/browser/ui/settings/password/password_manager_view_controller_items.mm
+++ b/ios/chrome/browser/ui/settings/password/password_manager_view_controller_items.mm
@@ -225,7 +225,7 @@
   cell.titleLabel.lineBreakMode = NSLineBreakByTruncatingHead;
   cell.detailLabel.text = self.detailText;
   cell.detailLabel.hidden = !cell.detailLabel.text.length;
-  // TODO(crbug.com/1355956): Use AffiliationGroup::GetIconURL() instead.
+  // TODO(crbug.com/40860113): Use AffiliationGroup::GetIconURL() instead.
   cell.faviconPageURL = self.affiliatedGroup.GetCredentials().begin()->GetURL();
   cell.localOnlyIcon.hidden = !self.showLocalOnlyIcon;
   if (styler.cellTitleColor) {
diff --git a/ios/chrome/browser/ui/settings/password/password_manager_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/password/password_manager_view_controller_unittest.mm
index 325a6d7..b9396f9 100644
--- a/ios/chrome/browser/ui/settings/password/password_manager_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/password/password_manager_view_controller_unittest.mm
@@ -66,7 +66,7 @@
 using password_manager::TestPasswordStore;
 using ::testing::Return;
 
-// TODO(crbug.com/1324555): Remove this double and uses TestSyncUserSettings
+// TODO(crbug.com/40839348): Remove this double and uses TestSyncUserSettings
 @interface TestPasswordsMediator : PasswordsMediator
 
 @property(nonatomic) OnDeviceEncryptionState encryptionState;
diff --git a/ios/chrome/browser/ui/settings/password/password_settings/password_settings_mediator.mm b/ios/chrome/browser/ui/settings/password/password_settings/password_settings_mediator.mm
index b0fca11..f734232c 100644
--- a/ios/chrome/browser/ui/settings/password/password_settings/password_settings_mediator.mm
+++ b/ios/chrome/browser/ui/settings/password/password_settings/password_settings_mediator.mm
@@ -178,7 +178,7 @@
   _syncService->TriggerLocalDataMigration(
       syncer::ModelTypeSet{syncer::ModelType::PASSWORDS});
 
-  // TODO(crbug.com/1482293): Remove this histogram enumeration when using
+  // TODO(crbug.com/40281800): Remove this histogram enumeration when using
   // `MoveCredentialsToAccount`.
   base::UmaHistogramEnumeration(
       "PasswordManager.AccountStorage.MoveToAccountStoreFlowAccepted2",
diff --git a/ios/chrome/browser/ui/settings/password/password_settings/password_settings_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_settings/password_settings_view_controller.mm
index ba34f73..7e63804 100644
--- a/ios/chrome/browser/ui/settings/password/password_settings/password_settings_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/password/password_settings/password_settings_view_controller.mm
@@ -348,7 +348,7 @@
       initWithType:ItemTypeBulkMovePasswordsToAccountDescription];
   _bulkMovePasswordsToAccountDescriptionItem.title = l10n_util::GetNSString(
       IDS_IOS_PASSWORD_SETTINGS_BULK_UPLOAD_PASSWORDS_SECTION_TITLE);
-  // TODO(crbug.com/1488868): Without setting the table view image item to
+  // TODO(crbug.com/40283775): Without setting the table view image item to
   // enabled, the accessibility voiceover reads out dimmed.
   _bulkMovePasswordsToAccountDescriptionItem.enabled = YES;
   _bulkMovePasswordsToAccountDescriptionItem.accessibilityIdentifier =
diff --git a/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_egtest.mm b/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_egtest.mm
index 3fbe0d7..2422b81 100644
--- a/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_egtest.mm
+++ b/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_egtest.mm
@@ -624,7 +624,7 @@
 }
 
 - (void)testTappingLearnMoreInFirstRunExperienceView {
-  // TODO(crbug.com/1488977): Test fails on iPad simulator.
+  // TODO(crbug.com/40283859): Test fails on iPad simulator.
   if ([ChromeEarlGrey isIPadIdiom]) {
     EARL_GREY_TEST_DISABLED(@"Failing on iPad Simulator");
   }
diff --git a/ios/chrome/browser/ui/settings/privacy/privacy_guide/privacy_guide_history_sync_coordinator.mm b/ios/chrome/browser/ui/settings/privacy/privacy_guide/privacy_guide_history_sync_coordinator.mm
index afc72fc..5cbe856 100644
--- a/ios/chrome/browser/ui/settings/privacy/privacy_guide/privacy_guide_history_sync_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/privacy/privacy_guide/privacy_guide_history_sync_coordinator.mm
@@ -46,7 +46,7 @@
   _viewController = [[PrivacyGuideHistorySyncViewController alloc] init];
   _viewController.delegate = self;
   _viewController.presentationDelegate = self;
-  // TODO(crbug.com/1520481): Implement History Sync mediator.
+  // TODO(crbug.com/41493454): Implement History Sync mediator.
 
   CHECK(self.baseNavigationController);
   [self.baseNavigationController pushViewController:_viewController
diff --git a/ios/chrome/browser/ui/settings/privacy/privacy_guide/privacy_guide_utils.mm b/ios/chrome/browser/ui/settings/privacy/privacy_guide/privacy_guide_utils.mm
index bded5d11..fc843dc 100644
--- a/ios/chrome/browser/ui/settings/privacy/privacy_guide/privacy_guide_utils.mm
+++ b/ios/chrome/browser/ui/settings/privacy/privacy_guide/privacy_guide_utils.mm
@@ -26,7 +26,7 @@
     UITableView* table_view,
     int text_id,
     NSString* symbol_name) {
-  // TODO(crbug.com/1519511): Remove the default insets in the
+  // TODO(crbug.com/41492491): Remove the default insets in the
   // SettingsImageDetailTextCell.
   SettingsImageDetailTextCell* cell =
       DequeueTableViewCell<SettingsImageDetailTextCell>(table_view);
diff --git a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h
index fb8ee5a..cb532f59 100644
--- a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h
+++ b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h
@@ -52,7 +52,7 @@
 // Updates the edit or done button to reflect editing state.  If the
 // tableView is not in edit mode (and thus showing the 'Done' button) it is
 // using shouldHideDoneButton to know if it should display the edit button.
-// TODO(crbug.com/952227): This method should probably be called from the
+// TODO(crbug.com/41452612): This method should probably be called from the
 // setEditing:animated: method instead of being manually triggered.
 - (void)updateUIForEditState;
 
diff --git a/ios/chrome/browser/ui/sharing/qr_generator/qr_generator_util_unittest.mm b/ios/chrome/browser/ui/sharing/qr_generator/qr_generator_util_unittest.mm
index dbc03850..cae7d700 100644
--- a/ios/chrome/browser/ui/sharing/qr_generator/qr_generator_util_unittest.mm
+++ b/ios/chrome/browser/ui/sharing/qr_generator/qr_generator_util_unittest.mm
@@ -33,7 +33,7 @@
 };
 
 // Tests that the GenerateQRCode utility function creates a valid QR code image.
-// TODO(crbug.com/1214776): reenable this test.
+// TODO(crbug.com/40769543): reenable this test.
 TEST_F(QRGeneratorUtilTest, DISABLED_GenerateQRCode_ValidData) {
   NSData* qrData = [sampleUrl_ dataUsingEncoding:NSUTF8StringEncoding];
 
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_mediator.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_mediator.mm
index 459d966..6d4e40e8 100644
--- a/ios/chrome/browser/ui/side_swipe/side_swipe_mediator.mm
+++ b/ios/chrome/browser/ui/side_swipe/side_swipe_mediator.mm
@@ -154,7 +154,7 @@
 }
 
 - (void)dealloc {
-  // TODO(crbug.com/1466454);
+  // TODO(crbug.com/40276402);
   DUMP_WILL_BE_CHECK(!_fullscreenController);
 }
 
diff --git a/ios/chrome/browser/ui/start_surface/BUILD.gn b/ios/chrome/browser/ui/start_surface/BUILD.gn
index af67507..62bf35f 100644
--- a/ios/chrome/browser/ui/start_surface/BUILD.gn
+++ b/ios/chrome/browser/ui/start_surface/BUILD.gn
@@ -37,6 +37,7 @@
     "//ios/chrome/browser/ntp/model",
     "//ios/chrome/browser/shared/coordinator/scene:observing_scene_agent",
     "//ios/chrome/browser/shared/coordinator/scene:scene_state_header",
+    "//ios/chrome/browser/shared/model/browser_state",
     "//ios/chrome/browser/shared/model/url",
     "//ios/chrome/browser/shared/model/url:constants",
     "//ios/chrome/browser/shared/model/web_state_list",
@@ -74,7 +75,9 @@
     "//ios/chrome/browser/shared/model/url:constants",
     "//ios/chrome/browser/shared/model/web_state_list",
     "//ios/chrome/browser/shared/public/features",
+    "//ios/chrome/browser/tab_insertion/model",
     "//ios/chrome/test:test_support",
+    "//ios/web/public/test",
     "//ios/web/public/test/fakes",
     "//testing/gtest",
     "//third_party/ocmock",
diff --git a/ios/chrome/browser/ui/start_surface/start_surface_scene_agent.mm b/ios/chrome/browser/ui/start_surface/start_surface_scene_agent.mm
index d9a93d8..73043519c 100644
--- a/ios/chrome/browser/ui/start_surface/start_surface_scene_agent.mm
+++ b/ios/chrome/browser/ui/start_surface/start_surface_scene_agent.mm
@@ -17,15 +17,18 @@
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/model/browser/browser_provider.h"
 #import "ios/chrome/browser/shared/model/browser/browser_provider_interface.h"
+#import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/url/chrome_url_constants.h"
 #import "ios/chrome/browser/shared/model/url/url_util.h"
 #import "ios/chrome/browser/shared/model/web_state_list/removing_indexes.h"
+#import "ios/chrome/browser/shared/model/web_state_list/tab_group.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.h"
 #import "ios/chrome/browser/ui/start_surface/start_surface_features.h"
 #import "ios/chrome/browser/ui/start_surface/start_surface_recent_tab_browser_agent.h"
 #import "ios/chrome/browser/ui/start_surface/start_surface_util.h"
+#import "ios/web/public/navigation/navigation_item.h"
 #import "ios/web/public/navigation/navigation_manager.h"
 #import "ios/web/public/web_state.h"
 #import "url/gurl.h"
@@ -36,12 +39,12 @@
 const char kExcessNTPTabsRemoved[] = "IOS.NTP.ExcessRemovedTabCount";
 
 // Whether `web_state` shows the NTP.
-bool IsNTP(web::WebState* web_state) {
+bool IsNTP(const web::WebState* web_state) {
   return IsUrlNtp(web_state->GetVisibleURL());
 }
 
 // Whether `web_state` shows the NTP and never had a navigation.
-bool IsEmptyNTP(web::WebState* web_state) {
+bool IsEmptyNTP(const web::WebState* web_state) {
   return IsNTP(web_state) && web_state->GetNavigationItemCount() <= 1;
 }
 
@@ -101,7 +104,7 @@
     transitionedToActivationLevel:(SceneActivationLevel)level {
   if (level != SceneActivationLevelForegroundActive &&
       self.previousActivationLevel == SceneActivationLevelForegroundActive) {
-    // TODO(crbug.com/1173160): Consider when to clear the session object since
+    // TODO(crbug.com/40167003): Consider when to clear the session object since
     // Chrome may be closed without transiting to inactive, e.g. device power
     // off, then the previous session object is staled.
     SetStartSurfaceSessionObjectForSceneState(sceneState);
@@ -191,74 +194,82 @@
 // Removes empty NTP tabs (i.e. NTPs with no further navigation) in `browser`'s
 // WebStateList.
 //
-// NTPs with navigations are all preserved. If there are none, an empty NTP is
+// NTPs with navigation are all preserved. If there are none, an empty NTP is
 // preserved.
-// TODO(crbug.com/330328126): NTPs in tab groups are currently all preserved.
-// Instead, preserve only NTPs with navigations or at most one empty NTP per
-// group.
 - (void)removeExcessNTPsInBrowser:(Browser*)browser {
   WebStateList* webStateList = browser->GetWebStateList();
 
-  // Find all empty NTPs, i.e. NTPs with no navigation. Also keep track of the
-  // last NTP with a navigation, if any, and whether the active tab is amongst
-  // the candidates for removal.
-  std::vector<int> indicesToRemove;
-  web::WebState* lastNTPWithNavigation = nullptr;
-  for (int i = 0; i < webStateList->count(); i++) {
-    if (webStateList->GetGroupOfWebStateAt(i) != nullptr) {
-      // The tab is grouped. Preserve it unconditionally for now.
-      // TODO(crbug.com/330328126): Remove empty NTPs.
-      continue;
-    }
-    web::WebState* webState = webStateList->GetWebStateAt(i);
+  // Map groups to the indices of its empty NTPs, and whether the group contains
+  // at least one non-empty NTP (an NTP with navigation), which will be kept.
+  // Ungrouped tabs correspond to the `nullptr` entry in the map.
+  std::map<const TabGroup*, std::pair<std::vector<int>, bool>> groupsToNTPs;
+  for (int index = 0; index < webStateList->count(); ++index) {
+    const web::WebState* webState = webStateList->GetWebStateAt(index);
+    const TabGroup* tabGroup = webStateList->GetGroupOfWebStateAt(index);
     if (IsEmptyNTP(webState)) {
-      indicesToRemove.push_back(i);
+      groupsToNTPs[tabGroup].first.push_back(index);
     } else if (IsNTP(webState)) {
-      lastNTPWithNavigation = webState;
+      groupsToNTPs[tabGroup].second = true;
     }
   }
 
-  // Find whether the active tab is currently scheduled to be removed.
-  const int activeWebStateIndex =
-      webStateList->GetIndexOfWebState(webStateList->GetActiveWebState());
-  bool activeWebStateRemoved =
-      base::Contains(indicesToRemove, activeWebStateIndex);
+  // For each group (respectively the ungrouped tabs case), if there are only
+  // empty NTPs, preserve one NTP by removing it from the list of indices to
+  // close for the group (respectively the ungrouped tabs case).
+  for (auto& [group, NTPs] : groupsToNTPs) {
+    auto& indicesToRemoveInGroup = NTPs.first;
+    const bool groupHasNonEmptyNTP = NTPs.second;
+    if (indicesToRemoveInGroup.empty() || groupHasNonEmptyNTP) {
+      continue;
+    }
+    // Remove the last empty NTP from the list of tabs to close.
+    indicesToRemoveInGroup.pop_back();
+  }
 
-  // If there are only empty NTPs, preserve one NTP by removing
-  // it from the list of indices to close.
-  if (!lastNTPWithNavigation && !indicesToRemove.empty()) {
-    // Preserve the last empty NTP (i.e. the most recent)…
-    auto indexToPreserveIter = indicesToRemove.end() - 1;
-    // … or preserve the active tab, if it was in the list of empty NTPs.
-    if (activeWebStateRemoved) {
-      indexToPreserveIter =
-          std::find(indicesToRemove.begin(), indicesToRemove.end(),
-                    activeWebStateIndex);
-      CHECK(indexToPreserveIter != indicesToRemove.end());
+  // Flatten the list of indices to remove.
+  std::vector<int> indicesToRemove;
+  for (const auto& [group, NTPs] : groupsToNTPs) {
+    const auto& indicesToRemoveInGroup = NTPs.first;
+    indicesToRemove.insert(indicesToRemove.end(),
+                           indicesToRemoveInGroup.begin(),
+                           indicesToRemoveInGroup.end());
+  }
+
+  // Perform the operations on the WebStateList.
+  const WebStateList::ScopedBatchOperation batch =
+      webStateList->StartBatchOperation();
+
+  // If the active tab is going to be closed, pick the last ungrouped
+  // NTP as the new active tab, otherwise insert a new NTP.
+  if (base::Contains(indicesToRemove, webStateList->active_index())) {
+    int lastUngroupedNTPIndex = WebStateList::kInvalidIndex;
+    for (int index = webStateList->count() - 1; index >= 0; --index) {
+      const web::WebState* webState = webStateList->GetWebStateAt(index);
+      const TabGroup* tabGroup = webStateList->GetGroupOfWebStateAt(index);
+      if (IsNTP(webState) && !tabGroup &&
+          !base::Contains(indicesToRemove, index)) {
+        lastUngroupedNTPIndex = index;
+        break;
+      }
     }
-    // Update `activeWebStateRemoved` if the active tab ends up preserved.
-    if (*indexToPreserveIter == activeWebStateIndex) {
-      activeWebStateRemoved = NO;
+    if (lastUngroupedNTPIndex != WebStateList::kInvalidIndex) {
+      webStateList->ActivateWebStateAt(lastUngroupedNTPIndex);
+    } else {
+      // Insert a new NTP at the very end (this won't invalidate other indices).
+      web::NavigationManager::WebLoadParams webLoadParams =
+          web::NavigationManager::WebLoadParams(GURL(kChromeUINewTabURL));
+      TabInsertion::Params tabInsertionParams;
+      tabInsertionParams.should_skip_new_tab_animation = true;
+      TabInsertionBrowserAgent::FromBrowser(browser)->InsertWebState(
+          webLoadParams, tabInsertionParams);
     }
-    indicesToRemove.erase(indexToPreserveIter);
   }
 
   // Close the excessive NTPs.
   UMA_HISTOGRAM_COUNTS_100(kExcessNTPTabsRemoved, indicesToRemove.size());
-  const WebStateList::ScopedBatchOperation batch =
-      webStateList->StartBatchOperation();
   webStateList->CloseWebStatesAtIndices(
       WebStateList::CLOSE_NO_FLAGS,
       RemovingIndexes(std::move(indicesToRemove)));
-
-  // If the active WebState was removed because it was empty,
-  // switch to another NTP: the most recent NTP with navigation. It exists,
-  // otherwise the active WebState would have been kept.
-  if (activeWebStateRemoved) {
-    DCHECK(lastNTPWithNavigation);
-    int newActiveIndex = webStateList->GetIndexOfWebState(lastNTPWithNavigation);
-    webStateList->ActivateWebStateAt(newActiveIndex);
-  }
 }
 
 - (void)logBackgroundDurationMetricForActivationLevel:
diff --git a/ios/chrome/browser/ui/start_surface/start_surface_scene_agent_unittest.mm b/ios/chrome/browser/ui/start_surface/start_surface_scene_agent_unittest.mm
index 7d67e88..64bb8be5 100644
--- a/ios/chrome/browser/ui/start_surface/start_surface_scene_agent_unittest.mm
+++ b/ios/chrome/browser/ui/start_surface/start_surface_scene_agent_unittest.mm
@@ -6,7 +6,6 @@
 
 #import "base/test/metrics/histogram_tester.h"
 #import "base/test/scoped_feature_list.h"
-#import "base/test/task_environment.h"
 #import "components/favicon/ios/web_favicon_driver.h"
 #import "components/sync_preferences/testing_pref_service_syncable.h"
 #import "ios/chrome/app/application_delegate/app_state.h"
@@ -22,12 +21,14 @@
 #import "ios/chrome/browser/shared/model/url/url_util.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
+#import "ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.h"
 #import "ios/chrome/browser/ui/start_surface/start_surface_features.h"
 #import "ios/chrome/browser/ui/start_surface/start_surface_recent_tab_browser_agent.h"
 #import "ios/chrome/browser/ui/start_surface/start_surface_util.h"
 #import "ios/chrome/test/scoped_key_window.h"
 #import "ios/chrome/test/testing_application_context.h"
 #import "ios/web/public/test/fakes/fake_web_state.h"
+#import "ios/web/public/test/web_task_environment.h"
 #import "testing/gtest/include/gtest/gtest.h"
 #import "testing/platform_test.h"
 #import "third_party/ocmock/OCMock/OCMock.h"
@@ -70,6 +71,7 @@
     Browser* browser =
         scene_state_.browserProviderInterface.mainBrowserProvider.browser;
     StartSurfaceRecentTabBrowserAgent::CreateForBrowser(browser);
+    TabInsertionBrowserAgent::CreateForBrowser(browser);
     histogram_tester_ = std::make_unique<base::HistogramTester>();
     TestingApplicationContext::GetGlobal()->SetLocalState(&pref_service_);
   }
@@ -82,7 +84,7 @@
   }
 
  protected:
-  base::test::TaskEnvironment task_environment_;
+  web::WebTaskEnvironment task_environment_;
   sync_preferences::TestingPrefServiceSyncable pref_service_;
   std::unique_ptr<TestChromeBrowserState> browser_state_;
   FakeStartupInformation* startup_information_;
@@ -241,9 +243,9 @@
   EXPECT_EQ(web_state_list->GetWebStateAt(1)->GetVisibleURL(), kURL);
 }
 
-// Tests that empty NTPs in tab groups are preserved.
-// TODO(crbug.com/330328126): Only keep at most one empty NTP per group.
-TEST_F(StartSurfaceSceneAgentTest, KeepEmptyNTPsInGroups) {
+// Tests that empty NTPs in tab groups are removed, keeping at most one per
+// group, and one for the ungrouped tabs.
+TEST_F(StartSurfaceSceneAgentTest, KeepAtMostOneEmptyNTPPerGroup) {
   base::test::ScopedFeatureList scoped_feature_list;
   std::vector<base::test::FeatureRef> enabled_features;
   enabled_features.push_back(kRemoveExcessNTPs);
@@ -259,7 +261,8 @@
   WebStateList* web_state_list =
       scene_state_.browserProviderInterface.mainBrowserProvider.browser
           ->GetWebStateList();
-  web_state_list->CreateGroup({0, 1, 2, 3}, {});
+  const TabGroup* group_0 = web_state_list->CreateGroup({0, 1, 2, 3}, {});
+  const TabGroup* group_1 = web_state_list->CreateGroup({6}, {});
   [agent_ sceneState:scene_state_
       transitionedToActivationLevel:SceneActivationLevelForegroundActive];
   histogram_tester_->ExpectTotalCount("IOS.NTP.ExcessRemovedTabCount", 0);
@@ -271,18 +274,70 @@
   // Expect 2 calls to IOS.NTP.ExcessRemovedTabCount. One for the regular
   // browser, one for the incognito browser.
   histogram_tester_->ExpectTotalCount("IOS.NTP.ExcessRemovedTabCount", 2);
-  // Regular browser got 2 NTP removed.
-  histogram_tester_->ExpectBucketCount("IOS.NTP.ExcessRemovedTabCount", 2, 1);
+  // Regular browser got 3 NTP removed.
+  histogram_tester_->ExpectBucketCount("IOS.NTP.ExcessRemovedTabCount", 3, 1);
   // Incognito browser got no NTP removed.
   histogram_tester_->ExpectBucketCount("IOS.NTP.ExcessRemovedTabCount", 0, 1);
-  ASSERT_EQ(5, web_state_list->count());
+  ASSERT_EQ(4, web_state_list->count());
+  // First is NTP with navigation, in `group_0`.
   EXPECT_TRUE(IsUrlNtp(web_state_list->GetWebStateAt(0)->GetVisibleURL()));
   EXPECT_GT(web_state_list->GetWebStateAt(0)->GetNavigationItemCount(), 1);
+  EXPECT_EQ(group_0, web_state_list->GetGroupOfWebStateAt(0));
+  // Second is non-NTP, in group_0.
   EXPECT_EQ(web_state_list->GetWebStateAt(1)->GetVisibleURL(), kURL);
+  EXPECT_EQ(group_0, web_state_list->GetGroupOfWebStateAt(1));
+  // Third is NTP with navigation, in no group.
   EXPECT_TRUE(IsUrlNtp(web_state_list->GetWebStateAt(2)->GetVisibleURL()));
+  EXPECT_GT(web_state_list->GetWebStateAt(2)->GetNavigationItemCount(), 1);
+  EXPECT_EQ(nullptr, web_state_list->GetGroupOfWebStateAt(2));
+  // Fourth is empty NTP (no navigation), in group_1.
   EXPECT_TRUE(IsUrlNtp(web_state_list->GetWebStateAt(3)->GetVisibleURL()));
-  EXPECT_TRUE(IsUrlNtp(web_state_list->GetWebStateAt(4)->GetVisibleURL()));
-  EXPECT_GT(web_state_list->GetWebStateAt(4)->GetNavigationItemCount(), 1);
+  EXPECT_LE(web_state_list->GetWebStateAt(3)->GetNavigationItemCount(), 1);
+  EXPECT_EQ(group_1, web_state_list->GetGroupOfWebStateAt(3));
+}
+
+// Tests that when the active tab is a grouped NTP that gets closed, a new
+// ungrouped NTP is opened and activated.
+TEST_F(StartSurfaceSceneAgentTest,
+       ClosingGroupedActiveNTPSpawnsNewUngroupedNTP) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  std::vector<base::test::FeatureRef> enabled_features;
+  enabled_features.push_back(kRemoveExcessNTPs);
+
+  scoped_feature_list.InitWithFeatures(enabled_features, {});
+  InsertNewWebState(0, GURL(kChromeUINewTabURL));
+  InsertNewWebState(1, GURL(kChromeUINewTabURL));
+  WebStateList* web_state_list =
+      scene_state_.browserProviderInterface.mainBrowserProvider.browser
+          ->GetWebStateList();
+  web_state_list->ActivateWebStateAt(0);
+  const TabGroup* group_0 = web_state_list->CreateGroup({0, 1}, {});
+  [agent_ sceneState:scene_state_
+      transitionedToActivationLevel:SceneActivationLevelForegroundActive];
+  histogram_tester_->ExpectTotalCount("IOS.NTP.ExcessRemovedTabCount", 0);
+
+  // Transition to the background, triggering the NTP clean up.
+  [agent_ sceneState:scene_state_
+      transitionedToActivationLevel:SceneActivationLevelBackground];
+
+  // Expect 2 calls to IOS.NTP.ExcessRemovedTabCount. One for the regular
+  // browser, one for the incognito browser.
+  histogram_tester_->ExpectTotalCount("IOS.NTP.ExcessRemovedTabCount", 2);
+  // Regular browser got 1 NTP removed.
+  histogram_tester_->ExpectBucketCount("IOS.NTP.ExcessRemovedTabCount", 1, 1);
+  // Incognito browser got no NTP removed.
+  histogram_tester_->ExpectBucketCount("IOS.NTP.ExcessRemovedTabCount", 0, 1);
+  ASSERT_EQ(2, web_state_list->count());
+  // First is NTP initially at index 1, in `group_0`.
+  EXPECT_TRUE(IsUrlNtp(web_state_list->GetWebStateAt(0)->GetVisibleURL()));
+  EXPECT_LE(web_state_list->GetWebStateAt(0)->GetNavigationItemCount(), 1);
+  EXPECT_EQ(group_0, web_state_list->GetGroupOfWebStateAt(0));
+  // Second is a newly-opened empty NTP, in no group. It needs to load first, as
+  // it's a real WebState.
+  web_state_list->GetWebStateAt(1)->GetNavigationManager()->LoadIfNecessary();
+  EXPECT_TRUE(IsUrlNtp(web_state_list->GetWebStateAt(1)->GetVisibleURL()));
+  EXPECT_LE(web_state_list->GetWebStateAt(1)->GetNavigationItemCount(), 1);
+  EXPECT_EQ(nullptr, web_state_list->GetGroupOfWebStateAt(1));
 }
 
 // Tests that IOS.StartSurfaceShown is correctly logged for a valid warm start
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
index 33eaac8..909ce96b 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/BUILD.gn
@@ -104,6 +104,10 @@
   ]
 }
 
+source_set("tab_grid_idle_status_handler") {
+  sources = [ "tab_grid_idle_status_handler.h" ]
+}
+
 source_set("tab_grid_metrics") {
   sources = [
     "tab_grid_metrics.h",
@@ -150,6 +154,7 @@
 
   deps = [
     ":tab_grid_activity_observer",
+    ":tab_grid_idle_status_handler",
     ":tab_grid_metrics",
     ":tab_grid_page_mutator",
     ":tab_grid_paging",
@@ -266,6 +271,7 @@
     "//ios/chrome/browser/ui/settings:eg_test_support+eg2",
     "//ios/chrome/browser/ui/start_surface:feature_flags",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid/grid:grid_ui_constants",
+    "//ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs:inactive_tabs_constants",
     "//ios/chrome/browser/ui/tab_switcher/test:utils",
     "//ios/chrome/common/ui/table_view:cells_constants",
     "//ios/chrome/test:eg_test_support+eg2",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn
index 28037349..a293d79 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/BUILD.gn
@@ -13,6 +13,7 @@
     ":grid_mediator",
     ":grid_ui",
     "//base",
+    "//ios/chrome/browser/iph_for_new_chrome_user/model",
     "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
     "//ios/chrome/browser/shared/model/browser",
     "//ios/chrome/browser/shared/model/web_state_list",
@@ -50,6 +51,7 @@
     "//ios/chrome/browser/commerce/model",
     "//ios/chrome/browser/default_browser/model:utils",
     "//ios/chrome/browser/drag_and_drop/model",
+    "//ios/chrome/browser/iph_for_new_chrome_user/model",
     "//ios/chrome/browser/main/model",
     "//ios/chrome/browser/policy/model:policy_util",
     "//ios/chrome/browser/reading_list/model",
@@ -73,6 +75,7 @@
     "//ios/chrome/browser/ui/tab_switcher",
     "//ios/chrome/browser/ui/tab_switcher:items",
     "//ios/chrome/browser/ui/tab_switcher:utils",
+    "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_idle_status_handler",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_metrics",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_page_mutator",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_paging",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_coordinator.mm
index 27f9206..ce52083af 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_coordinator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_coordinator.mm
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #import "base/check.h"
+#import "ios/chrome/browser/iph_for_new_chrome_user/model/tab_based_iph_browser_agent.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/model/web_state_list/tab_group.h"
 #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
@@ -77,6 +78,8 @@
   self.mediator.browser = self.browser;
   self.mediator.delegate = self.gridMediatorDelegate;
   self.mediator.toolbarsMutator = self.toolbarsMutator;
+  self.mediator.tabBasedIPHBrowserAgent =
+      TabBasedIPHBrowserAgent::FromBrowser(self.browser);
 }
 
 - (void)stop {
@@ -172,6 +175,8 @@
                         tabGroup:tabGroup];
   _tabGroupCoordinator.tabContextMenuDelegate = self.tabContextMenuDelegate;
   _tabGroupCoordinator.smallerMotions = tabGridOpening;
+  _tabGroupCoordinator.tabGridIdleStatusHandler =
+      self.mediator.tabGridIdleStatusHandler;
   [_tabGroupCoordinator start];
 }
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.h
index c18cbd9f..8738e6a0 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.h
@@ -22,10 +22,12 @@
 @protocol GridToolbarsConfigurationProvider;
 @protocol GridToolbarsMutator;
 @protocol TabCollectionConsumer;
+@protocol TabGridIdleStatusHandler;
 @class TabGridToolbarsConfiguration;
 @protocol TabGridToolbarsMainTabGridDelegate;
 @protocol TabGroupsCommands;
 @protocol TabPresentationDelegate;
+class TabBasedIPHBrowserAgent;
 class WebStateList;
 
 namespace web {
@@ -62,6 +64,11 @@
 @property(nonatomic, weak) id<TabPresentationDelegate> tabPresentationDelegate;
 // Tab Groups Dispatcher.
 @property(nonatomic, weak) id<TabGroupsCommands> dispatcher;
+// Tab grid idle status handler.
+@property(nonatomic, weak) id<TabGridIdleStatusHandler>
+    tabGridIdleStatusHandler;
+// Browser agent to trigger tab based IPH.
+@property(nonatomic, assign) TabBasedIPHBrowserAgent* tabBasedIPHBrowserAgent;
 
 @end
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.mm
index 7b4491f..1856626 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator.mm
@@ -26,6 +26,7 @@
 #import "ios/chrome/browser/commerce/model/shopping_persisted_data_tab_helper.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
 #import "ios/chrome/browser/drag_and_drop/model/drag_item_util.h"
+#import "ios/chrome/browser/iph_for_new_chrome_user/model/tab_based_iph_browser_agent.h"
 #import "ios/chrome/browser/main/model/browser_util.h"
 #import "ios/chrome/browser/policy/model/policy_util.h"
 #import "ios/chrome/browser/reading_list/model/reading_list_browser_agent.h"
@@ -65,6 +66,7 @@
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/selected_grid_items.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_groups_commands.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_item.h"
+#import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_idle_status_handler.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_metrics.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/toolbars/tab_grid_toolbars_configuration.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/toolbars/tab_grid_toolbars_main_tab_grid_delegate.h"
@@ -648,6 +650,7 @@
       GridItemIdentifier* groupItemIdentifier =
           [GridItemIdentifier groupIdentifier:groupDeleteChange.deleted_group()
                              withWebStateList:_webStateList];
+      [_selectedEditingItems removeItem:groupItemIdentifier];
       [self.consumer removeItemWithIdentifier:groupItemIdentifier
                        selectedItemIdentifier:[self activeIdentifier]];
       break;
@@ -667,6 +670,9 @@
 - (void)webStateListBatchOperationEnded:(WebStateList*)webStateList {
   DCHECK_EQ(_webStateList, webStateList);
 
+  // Clear selections.
+  [_selectedEditingItems removeAllItems];
+
   [self addWebStateObservations];
   [self populateConsumerItems];
   [self updateToolbarAfterNumberOfItemsChanged];
@@ -728,7 +734,9 @@
   return YES;
 }
 
-- (void)selectItemWithID:(web::WebStateID)itemID pinned:(BOOL)pinned {
+- (void)selectItemWithID:(web::WebStateID)itemID
+                    pinned:(BOOL)pinned
+    isFirstActionOnTabGrid:(BOOL)isFirstActionOnTabGrid {
   WebStateSearchCriteria searchCriteria{
       .identifier = itemID,
       .pinned_state = pinned ? PinnedState::kPinned : PinnedState::kNonPinned,
@@ -808,6 +816,16 @@
   } else {
     base::RecordAction(
         base::UserMetricsAction("MobileTabGridMoveToExistingTab"));
+    if (isFirstActionOnTabGrid) {
+      int activeWebStateIndex = itemWebStateList->active_index();
+      BOOL adjacentTabSelected =
+          std::abs(index - activeWebStateIndex) == 1 &&
+          index != WebStateList::kInvalidIndex &&
+          activeWebStateIndex != WebStateList::kInvalidIndex;
+      if (adjacentTabSelected) {
+        self.tabBasedIPHBrowserAgent->NotifySwitchToAdjacentTabFromTabGrid();
+      }
+    }
   }
 
   // Avoid a reentrant activation. This is a fix for crbug.com/1134663, although
@@ -888,7 +906,8 @@
 }
 
 - (void)closeItemWithID:(web::WebStateID)itemID {
-  [self.gridConsumer setPageIdleStatus:NO];
+  [self.tabGridIdleStatusHandler
+      tabGridDidPerformAction:TabGridActionType::kInPageAction];
   int index = GetWebStateIndex(self.webStateList,
                                WebStateSearchCriteria{
                                    .identifier = itemID,
@@ -1494,7 +1513,8 @@
 // Closes all the tabs (webStates) in a given `group` and deletes the `group`
 // from the `webStateList`.
 - (void)closeTabsAndDeleteGroup:(const TabGroup*)group {
-  [self.gridConsumer setPageIdleStatus:NO];
+  [self.tabGridIdleStatusHandler
+      tabGridDidPerformAction:TabGridActionType::kInPageAction];
   if (_webStateList->ContainsGroup(group)) {
     // Using `CloseAllWebStatesInGroup` will result in calling the web state
     // list observers which will take care of updating the consumer.
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator_unittest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator_unittest.mm
index 1811515..f57469a1 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_mediator_unittest.mm
@@ -195,7 +195,7 @@
   // Previous selected index is 1.
   web::WebStateID identifier =
       browser_->GetWebStateList()->GetWebStateAt(2)->GetUniqueIdentifier();
-  [mediator_ selectItemWithID:identifier pinned:NO];
+  [mediator_ selectItemWithID:identifier pinned:NO isFirstActionOnTabGrid:NO];
   EXPECT_EQ(2, browser_->GetWebStateList()->active_index());
   EXPECT_EQ(identifier, consumer_.selectedItemID);
 }
@@ -218,18 +218,20 @@
   ASSERT_EQ(1, browser_->GetWebStateList()->active_index());
   ASSERT_EQ(identifier_1, consumer_.selectedItemID);
 
-  [mediator_ selectItemWithID:identifier_0 pinned:YES];
+  [mediator_ selectItemWithID:identifier_0
+                       pinned:YES
+       isFirstActionOnTabGrid:NO];
 
   EXPECT_EQ(0, browser_->GetWebStateList()->active_index());
   EXPECT_EQ(identifier_0, consumer_.selectedItemID);
 
-  [mediator_ selectItemWithID:identifier_2 pinned:NO];
+  [mediator_ selectItemWithID:identifier_2 pinned:NO isFirstActionOnTabGrid:NO];
 
   EXPECT_EQ(2, browser_->GetWebStateList()->active_index());
   EXPECT_EQ(identifier_2, consumer_.selectedItemID);
 
   // Selecting the pinned one with pinned = NO fails.
-  [mediator_ selectItemWithID:identifier_0 pinned:NO];
+  [mediator_ selectItemWithID:identifier_0 pinned:NO isFirstActionOnTabGrid:NO];
 
   EXPECT_EQ(2, browser_->GetWebStateList()->active_index());
   EXPECT_EQ(identifier_2, consumer_.selectedItemID);
@@ -719,6 +721,45 @@
   EXPECT_EQ(nullptr, web_state_list->GetGroupOfWebStateAt(1));
 }
 
+// Tests that closing the last tab of a selected group clears the selection.
+TEST_P(BaseGridMediatorTest, CloseSelectedGroup) {
+  WebStateList* web_state_list = browser_->GetWebStateList();
+  web_state_list->CreateGroup({1}, {});
+  const TabGroup* group = web_state_list->GetGroupOfWebStateAt(1);
+  [mediator_ switchToMode:TabGridModeSelection];
+  [mediator_
+      addToSelectionItemID:[GridItemIdentifier groupIdentifier:group
+                                              withWebStateList:web_state_list]];
+  EXPECT_EQ(1UL, [mediator_ allSelectedDragItems].count);
+
+  browser_->GetWebStateList()->CloseWebStateAt(1,
+                                               WebStateList::CLOSE_USER_ACTION);
+
+  EXPECT_EQ(0UL, [mediator_ allSelectedDragItems].count);
+}
+
+// Tests that closing the last tab of a selected group in a batch operation
+// clears the selection.
+TEST_P(BaseGridMediatorTest, CloseSelectedGroupInBatch) {
+  WebStateList* web_state_list = browser_->GetWebStateList();
+  web_state_list->CreateGroup({1}, {});
+  const TabGroup* group = web_state_list->GetGroupOfWebStateAt(1);
+  [mediator_ switchToMode:TabGridModeSelection];
+  [mediator_
+      addToSelectionItemID:[GridItemIdentifier groupIdentifier:group
+                                              withWebStateList:web_state_list]];
+  EXPECT_EQ(1UL, [mediator_ allSelectedDragItems].count);
+
+  {
+    WebStateList::ScopedBatchOperation lock =
+        browser_->GetWebStateList()->StartBatchOperation();
+    browser_->GetWebStateList()->CloseWebStateAt(
+        1, WebStateList::CLOSE_USER_ACTION);
+  }
+
+  EXPECT_EQ(0UL, [mediator_ allSelectedDragItems].count);
+}
+
 INSTANTIATE_TEST_SUITE_P(
     /* No InstantiationName */,
     BaseGridMediatorTest,
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.h
index 7d8fd7b..b110077 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.h
@@ -88,6 +88,11 @@
 - (void)didTapInactiveTabsSettingsLinkInGridViewController:
     (BaseGridViewController*)gridViewController;
 
+// Tells the delegate that the item with `itemID` has been long pressed to
+// request the context menu.
+- (void)gridViewController:(BaseGridViewController*)gridViewController
+    didRequestContextMenuForItemWithID:(web::WebStateID)itemID;
+
 @end
 
 // A view controller that contains a grid of items.
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm
index 748249a..130d680 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/base_grid_view_controller.mm
@@ -685,6 +685,13 @@
     return nil;
   }
 
+  GridItemIdentifier* itemIdentifier =
+      [self.diffableDataSource itemIdentifierForIndexPath:indexPath];
+  if (itemIdentifier.type == GridItemType::Tab) {
+    [self.delegate gridViewController:self
+        didRequestContextMenuForItemWithID:itemIdentifier.tabSwitcherItem
+                                               .identifier];
+  }
   UICollectionViewCell* collectionViewCell =
       [self.collectionView cellForItemAtIndexPath:indexPath];
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_commands.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_commands.h
index 73960e9..01b9408 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_commands.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_commands.h
@@ -52,8 +52,13 @@
                                    completion:(void (^)(size_t))completion;
 
 // Tells the receiver to select the item with identifier `itemID`. If there is
-// no item with that identifier, no change in selection should be made.
-- (void)selectItemWithID:(web::WebStateID)itemID pinned:(BOOL)pinned;
+// no item with that identifier, no change in selection should be made. `pinned`
+// is `YES` If the selected item is a pinned item. `isFirstActionOnTabGrid` is
+// whether the itme selection is the first action that happens since the user
+// enters tab grid.
+- (void)selectItemWithID:(web::WebStateID)itemID
+                    pinned:(BOOL)pinned
+    isFirstActionOnTabGrid:(BOOL)isFirstActionOnTabGrid;
 
 // Tells the receiver to select the `tabGroup`.
 - (void)selectTabGroup:(const TabGroup*)tabGroup;
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_consumer.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_consumer.h
index a1b7e939..67f438e 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_consumer.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_consumer.h
@@ -9,8 +9,6 @@
 
 @protocol GridConsumer
 
-// Sets the idle page status.
-- (void)setPageIdleStatus:(BOOL)status;
 // Sets the active page.
 - (void)setActivePageFromPage:(TabGridPage)page;
 // Sets the page mode.
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.mm
index 6c490b0..fe015bf 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.mm
@@ -5,7 +5,6 @@
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_layout.h"
 
 #import "base/notreached.h"
-#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/util/rtl_geometry.h"
 #import "ios/chrome/common/ui/util/ui_util.h"
 #import "ios/web/common/uikit_ui_util.h"
@@ -397,19 +396,8 @@
   if (sectionIndex == 0) {
     return TabsSection(layoutEnvironment, self.tabsSectionHeaderType,
                        self.sectionInsets, self.mode);
-  }
-  if (IsTabGroupInGridEnabled()) {
-    if (sectionIndex == 1) {
-      return TabsSection(layoutEnvironment, self.tabsSectionHeaderType,
-                         self.sectionInsets, self.mode);
-    }
-    if (sectionIndex == 2) {
-      return SuggestedActionsSection(layoutEnvironment, self.sectionInsets);
-    }
-  } else {
-    if (sectionIndex == 1) {
-      return SuggestedActionsSection(layoutEnvironment, self.sectionInsets);
-    }
+  } else if (sectionIndex == 1) {
+    return SuggestedActionsSection(layoutEnvironment, self.sectionInsets);
   }
 
   NOTREACHED_NORETURN();
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller_unittest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller_unittest.mm
index 88d99a3..0283f02 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller_unittest.mm
@@ -97,6 +97,11 @@
   // No-op for unittests.
 }
 
+- (void)gridViewController:(BaseGridViewController*)gridViewController
+    didRequestContextMenuForItemWithID:(web::WebStateID)itemID {
+  // No-op for unittests.
+}
+
 @end
 
 class BaseGridViewControllerTest : public RootViewControllerTest,
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm
index d29f9928..e5720d6 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/group_grid_cell.mm
@@ -209,7 +209,7 @@
   // title and close button.
   return YES;
 }
-// TODO(crbug.com/1511982): Add the accessibility custom actions.
+// TODO(crbug.com/41484563): Add the accessibility custom actions.
 
 #pragma mark - Public
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/incognito/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/incognito/BUILD.gn
index 6dc52dd8..4635718 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/incognito/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/incognito/BUILD.gn
@@ -27,6 +27,7 @@
     "//ios/chrome/browser/shared/public/commands",
     "//ios/chrome/browser/snapshots/model",
     "//ios/chrome/browser/ui/incognito_reauth:incognito_reauth_scene_agent",
+    "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_idle_status_handler",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_metrics",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_paging",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_ui",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/incognito/incognito_grid_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/incognito/incognito_grid_mediator.mm
index 7ee0570b..586fda4 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/incognito/incognito_grid_mediator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/incognito/incognito_grid_mediator.mm
@@ -21,6 +21,7 @@
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_consumer.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_toolbars_mutator.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/incognito/incognito_grid_mediator_delegate.h"
+#import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_idle_status_handler.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_metrics.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_paging.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/toolbars/tab_grid_toolbars_configuration.h"
@@ -109,7 +110,8 @@
     return;
   }
 
-  [self.gridConsumer setPageIdleStatus:NO];
+  [self.tabGridIdleStatusHandler
+      tabGridDidPerformAction:TabGridActionType::kInPageAction];
   base::RecordAction(base::UserMetricsAction("MobileTabNewTab"));
   [self.gridConsumer prepareForDismissal];
   // Present the tab only if it have been added.
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/BUILD.gn
index fc185468..9ca54d3 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/BUILD.gn
@@ -23,6 +23,7 @@
     "//ios/chrome/browser/snapshots/model",
     "//ios/chrome/browser/tabs/model",
     "//ios/chrome/browser/ui/tab_switcher",
+    "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_idle_status_handler",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_metrics",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_paging",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_ui",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/regular_grid_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/regular_grid_mediator.mm
index b56b5fc..1043109 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/regular_grid_mediator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/regular/regular_grid_mediator.mm
@@ -17,6 +17,7 @@
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_consumer.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_toolbars_configuration_provider.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_toolbars_mutator.h"
+#import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_idle_status_handler.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_metrics.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_paging.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/toolbars/tab_grid_toolbars_configuration.h"
@@ -133,7 +134,8 @@
     return;
   }
 
-  [self.gridConsumer setPageIdleStatus:NO];
+  [self.tabGridIdleStatusHandler
+      tabGridDidPerformAction:TabGridActionType::kInPageAction];
   base::RecordAction(base::UserMetricsAction("MobileTabNewTab"));
   [self.gridConsumer prepareForDismissal];
   // Shows the tab only if has been created.
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/BUILD.gn
index 04d7fa0..eb90fe7 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/BUILD.gn
@@ -17,6 +17,7 @@
     ":tab_groups_ui",
     "//base",
     "//ios/chrome/browser/drag_and_drop/model",
+    "//ios/chrome/browser/iph_for_new_chrome_user/model",
     "//ios/chrome/browser/main/model",
     "//ios/chrome/browser/policy/model:policy_util",
     "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
@@ -30,6 +31,7 @@
     "//ios/chrome/browser/ui/tab_switcher",
     "//ios/chrome/browser/ui/tab_switcher:items",
     "//ios/chrome/browser/ui/tab_switcher:utils",
+    "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_idle_status_handler",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid/grid:grid_item_identifier",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid/grid:grid_mediator",
     "//ios/chrome/browser/ui/tab_switcher/tab_grid/grid:grid_ui",
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_view_controller.mm
index 96f312f3..d01324e9 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/create_tab_group_view_controller.mm
@@ -48,7 +48,7 @@
 const CGFloat kSnapshotViewMaxHeight = 190;
 const CGFloat kSnapshotViewCornerRadius = 18;
 const CGFloat kSnapshotViewVerticalMargin = 25;
-const CGFloat kSingleSnapshotRatio = 0.75;
+const CGFloat kSingleSnapshotRatio = 0.7;
 const CGFloat kMultipleSnapshotsRatio = 0.90;
 
 // Group title constants
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_coordinator.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_coordinator.h
index 77e98d8..57c9cf1 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_coordinator.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_coordinator.h
@@ -8,6 +8,7 @@
 #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h"
 
 @protocol TabContextMenuDelegate;
+@protocol TabGridIdleStatusHandler;
 class TabGroup;
 @class TabGroupViewController;
 
@@ -21,6 +22,10 @@
 // NO.
 @property(nonatomic, assign) BOOL smallerMotions;
 
+// Handler that trackes and updates the idle status of the tab grid.
+@property(nonatomic, weak) id<TabGridIdleStatusHandler>
+    tabGridIdleStatusHandler;
+
 // Tab Context Menu delegate.
 @property(nonatomic, weak) id<TabContextMenuDelegate> tabContextMenuDelegate;
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_coordinator.mm
index 6b0da5e3..c6474e8 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_coordinator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_coordinator.mm
@@ -6,6 +6,7 @@
 
 #import "base/check.h"
 #import "base/metrics/user_metrics.h"
+#import "ios/chrome/browser/iph_for_new_chrome_user/model/tab_based_iph_browser_agent.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/web_state_list/tab_group.h"
@@ -17,6 +18,7 @@
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_view_controller.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_groups_commands.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_context_menu/tab_context_menu_helper.h"
+#import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_idle_status_handler.h"
 #import "ios/web/public/web_state_id.h"
 
 @interface TabGroupCoordinator () <GridViewControllerDelegate>
@@ -74,6 +76,9 @@
               gridConsumer:_viewController.gridViewController];
   _mediator.browser = self.browser;
   _mediator.tabGroupsHandler = handler;
+  _mediator.tabBasedIPHBrowserAgent =
+      TabBasedIPHBrowserAgent::FromBrowser(self.browser);
+  _mediator.tabGridIdleStatusHandler = self.tabGridIdleStatusHandler;
 
   _tabContextMenuHelper = [[TabContextMenuHelper alloc]
         initWithBrowserState:self.browser->GetBrowserState()
@@ -123,12 +128,16 @@
       base::RecordAction(
           base::UserMetricsAction("MobileTabRegularGridTabGroupOpenTab"));
     }
-    [_mediator selectItemWithID:itemID pinned:NO];
+    [_mediator selectItemWithID:itemID
+                         pinned:NO
+         isFirstActionOnTabGrid:[self.tabGridIdleStatusHandler status]];
   }
 
   id<TabGroupsCommands> handler = HandlerForProtocol(
       self.browser->GetCommandDispatcher(), TabGroupsCommands);
 
+  [self.tabGridIdleStatusHandler
+      tabGridDidPerformAction:TabGridActionType::kInPageAction];
   [handler hideTabGroup];
   [handler showActiveTab];
 }
@@ -200,4 +209,10 @@
   NOTREACHED_NORETURN();
 }
 
+- (void)gridViewController:(BaseGridViewController*)gridViewController
+    didRequestContextMenuForItemWithID:(web::WebStateID)itemID {
+  [self.tabGridIdleStatusHandler
+      tabGridDidPerformAction:TabGridActionType::kInPageAction];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_mediator.mm
index 4cb6db1f..88178fb 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_mediator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_mediator.mm
@@ -24,6 +24,7 @@
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_utils.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_group_consumer.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/tab_groups/tab_groups_commands.h"
+#import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_idle_status_handler.h"
 #import "ios/chrome/browser/ui/tab_switcher/web_state_tab_switcher_item.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/web/public/navigation/navigation_manager.h"
@@ -65,16 +66,22 @@
 #pragma mark - TabGroupMutator
 
 - (BOOL)addNewItemInGroup {
+  [self.tabGridIdleStatusHandler
+      tabGridDidPerformAction:TabGridActionType::kInPageAction];
   return [self addTabToGroup:_tabGroup.get()];
 }
 
 - (void)ungroup {
+  [self.tabGridIdleStatusHandler
+      tabGridDidPerformAction:TabGridActionType::kInPageAction];
   auto scoped_lock = self.webStateList->StartBatchOperation();
   self.webStateList->DeleteGroup(_tabGroup.get());
   _tabGroup.reset();
 }
 
 - (void)deleteGroup {
+  [self.tabGridIdleStatusHandler
+      tabGridDidPerformAction:TabGridActionType::kInPageAction];
   CloseAllWebStatesInGroup(*self.webStateList, _tabGroup.get(),
                            WebStateList::CLOSE_USER_ACTION);
   _tabGroup.reset();
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_coordinator.mm
index d89517c..25dff40 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_coordinator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_coordinator.mm
@@ -386,6 +386,11 @@
   [self presentSettings];
 }
 
+- (void)gridViewController:(BaseGridViewController*)gridViewController
+    didRequestContextMenuForItemWithID:(web::WebStateID)itemID {
+  // No-op.
+}
+
 #pragma mark - InactiveTabsUserEducationCoordinatorDelegate
 
 - (void)inactiveTabsUserEducationCoordinatorDidTapSettingsButton:
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.mm
index 7c79ce03..83ac158 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.mm
@@ -399,7 +399,9 @@
   NOTREACHED_NORETURN();
 }
 
-- (void)selectItemWithID:(web::WebStateID)itemID pinned:(BOOL)pinned {
+- (void)selectItemWithID:(web::WebStateID)itemID
+                    pinned:(BOOL)pinned
+    isFirstActionOnTabGrid:(BOOL)isFirstActionOnTabGrid {
   NOTREACHED_NORETURN();
 }
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_view_controller.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_view_controller.h
index a15fe1ad..d2af70c 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_view_controller.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_view_controller.h
@@ -64,6 +64,11 @@
 - (void)pinnedViewControllerDragSessionDidEnd:
     (PinnedTabsViewController*)pinnedTabsViewController;
 
+// Tells the delegate that the item with `itemID` has been long pressed to
+// request the context menu.
+- (void)pinnedViewController:(PinnedTabsViewController*)pinnedTabsViewController
+    didRequestContextMenuForItemWithID:(web::WebStateID)itemID;
+
 @end
 
 // UICollectionViewController used to display pinned tabs.
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_view_controller.mm
index 4bcd8fc..8abd10b9 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_view_controller.mm
@@ -471,6 +471,12 @@
 - (UIContextMenuConfiguration*)collectionView:(UICollectionView*)collectionView
     contextMenuConfigurationForItemAtIndexPath:(NSIndexPath*)indexPath
                                          point:(CGPoint)point {
+  NSUInteger index = base::checked_cast<NSUInteger>(indexPath.item);
+  CHECK_LT(index, _items.count);
+  const web::WebStateID itemID = _items[index].identifier;
+  [self.delegate pinnedViewController:self
+      didRequestContextMenuForItemWithID:itemID];
+
   PinnedCell* cell = base::apple::ObjCCastStrict<PinnedCell>(
       [self.collectionView cellForItemAtIndexPath:indexPath]);
   return [self.menuProvider
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
index 5df31dc8..88fa86e9 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
@@ -897,7 +897,7 @@
 
   self.firstPresentation = YES;
 
-  // TODO(crbug.com/850387) : Currently, consumer calls from the mediator
+  // TODO(crbug.com/41393201) : Currently, consumer calls from the mediator
   // prematurely loads the view in `RecentTabsTableViewController`. Fix this so
   // that the view is loaded only by an explicit placement in the view
   // hierarchy. As a workaround, the view controller hierarchy is loaded here
@@ -923,6 +923,9 @@
   self.regularTabsMediator.gridConsumer = self.baseViewController;
   self.remoteTabsMediator.gridConsumer = self.baseViewController;
 
+  self.incognitoTabsMediator.tabGridIdleStatusHandler = self.baseViewController;
+  self.regularTabsMediator.tabGridIdleStatusHandler = self.baseViewController;
+
   self.snackbarCoordinator =
       [[SnackbarCoordinator alloc] initWithBaseViewController:baseViewController
                                                       browser:_regularBrowser
@@ -1465,6 +1468,12 @@
     // When going in the background, hide the Inactive Tabs UI.
     [self.inactiveTabsCoordinator hide];
   }
+  if (level < SceneActivationLevelForegroundActive) {
+    // User has put the app into background, which constitutes of a meaningful
+    // action.
+    [self.baseViewController
+        tabGridDidPerformAction:TabGridActionType::kBackground];
+  }
 }
 
 #pragma mark - BringAndroidTabsCommands
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
index 9c02dfd..a967dc7 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
@@ -584,7 +584,7 @@
 // Tests that the Undo button is no longer available after tapping Close All,
 // then creating a new tab, then coming back to the tab grid.
 // Validates this case when Tab Grid Bulk Actions feature is enabled.
-// TODO(crbug.com/1521789): Test fails on device.
+// TODO(crbug.com/41494757): Test fails on device.
 #if !TARGET_IPHONE_SIMULATOR
 #define MAYBE_testUndoCloseAllNotAvailableAfterNewTabCreation \
   DISABLED_testUndoCloseAllNotAvailableAfterNewTabCreation
@@ -1172,7 +1172,7 @@
 }
 
 // Tests dragging incognito tab grid item between windows.
-// TODO(crbug.com/1325246): Re-enable this test.
+// TODO(crbug.com/40839724): Re-enable this test.
 - (void)FLAKY_testDragAndDropIncognitoBetweenWindows {
   if (![ChromeEarlGrey areMultipleWindowsSupported])
     EARL_GREY_TEST_SKIPPED(@"Multiple windows can't be opened.");
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_idle_status_handler.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_idle_status_handler.h
new file mode 100644
index 0000000..dc0566d
--- /dev/null
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_idle_status_handler.h
@@ -0,0 +1,34 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_TAB_GRID_IDLE_STATUS_HANDLER_H_
+#define IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_TAB_GRID_IDLE_STATUS_HANDLER_H_
+
+/// The types of action the user can perform on the tab grid.
+enum class TabGridActionType {
+  /// In page actions, including the following:
+  /// - Selecting another tab or tab group
+  /// - Creating, closing, moving, long pressing, grouping and ungrouping tabs
+  /// - Entering search or selection mode
+  /// - Entering inactive tabs
+  kInPageAction,
+  /// Actions of switching between pages.
+  kChangePage,
+  /// Action of putting app to background
+  kBackground,
+};
+
+/// Handler protocol that tracks the idle status of the track grid.
+@protocol TabGridIdleStatusHandler
+
+/// Idle status taking into account of all possible `TabGridActionType`s. If
+/// `YES`, the user has not done anything meaningful since entering the tab
+/// grid.
+- (BOOL)status;
+
+/// Informs the handler that  tab grid action of `type` has happened.
+- (void)tabGridDidPerformAction:(TabGridActionType)type;
+
+@end
+#endif  // IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_TAB_GRID_IDLE_STATUS_HANDLER_H_
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_transition_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_transition_egtest.mm
index 058c9f4..4091eae 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_transition_egtest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_transition_egtest.mm
@@ -8,6 +8,8 @@
 #import "base/functional/bind.h"
 #import "base/strings/sys_string_conversions.h"
 #import "ios/chrome/browser/metrics/model/metrics_app_interface.h"
+#import "ios/chrome/browser/tabs/model/inactive_tabs/features.h"
+#import "ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_constants.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.h"
 #import "ios/chrome/browser/ui/tab_switcher/test/query_title_server_util.h"
 #import "ios/chrome/grit/ios_strings.h"
@@ -15,7 +17,10 @@
 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
 #import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/testing/earl_grey/app_launch_configuration.h"
+#import "ios/testing/earl_grey/app_launch_manager.h"
 #import "ios/testing/earl_grey/earl_grey_test.h"
+#import "ios/testing/earl_grey/matchers.h"
 #import "net/test/embedded_test_server/http_request.h"
 #import "net/test/embedded_test_server/http_response.h"
 #import "net/test/embedded_test_server/request_handler_util.h"
@@ -28,6 +33,9 @@
 using chrome_test_util::TabGridNewTabButton;
 using chrome_test_util::TabGridOpenTabsPanelButton;
 using chrome_test_util::TabGridOtherDevicesPanelButton;
+using chrome_test_util::TabGridSearchCancelButton;
+using chrome_test_util::TabGridSearchModeToolbar;
+using chrome_test_util::TabGridSearchTabsButton;
 
 namespace {
 
@@ -589,6 +597,101 @@
       kUMATabSwitcherIdleIncognitoTabGridPageHistogram, 1, NO);
 }
 
+// Tests leaving tab grid after entering and exit the tab grid search mode.
+- (void)testLeaveSwitcherAfterEnteringAndExittingSearch {
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleRegularTabGridPageHistogram, 0);
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleIncognitoTabGridPageHistogram, 0);
+
+  [ChromeEarlGrey showTabSwitcher];
+  // Enter search mode and verify active.
+  [[EarlGrey selectElementWithMatcher:TabGridSearchTabsButton()]
+      performAction:grey_tap()];
+  [[EarlGrey selectElementWithMatcher:TabGridSearchModeToolbar()]
+      assertWithMatcher:grey_notNil()];
+  // Exit search mode.
+  [[EarlGrey selectElementWithMatcher:TabGridSearchCancelButton()]
+      performAction:grey_tap()];
+  // Leave switcher by tap "Done" button.
+  ShowTabViewController();
+
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleRecentTabsHistogram, 0);
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleIncognitoTabGridPageHistogram, 0);
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleRegularTabGridPageHistogram, 1);
+  ExpectIdleHistogramBucketCount(kUMATabSwitcherIdleRegularTabGridPageHistogram,
+                                 1, NO);
+}
+
+// Tests leaving tab grid after long press on a tab.
+- (void)testLeaveSwitcherAfterLongPressOnTab {
+  NSString* title = @"NormalTabLongerStringForTest1";
+  [self setUpTestServer];
+  [ChromeEarlGrey loadURL:[self makeURLForTitle:title]];
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleRegularTabGridPageHistogram, 0);
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleIncognitoTabGridPageHistogram, 0);
+
+  [ChromeEarlGrey showTabSwitcher];
+  // Long press on the tab and dismiss context menu.
+  [[[EarlGrey
+      selectElementWithMatcher:grey_allOf(grey_accessibilityLabel(title),
+                                          grey_sufficientlyVisible(), nil)]
+      atIndex:0] performAction:grey_longPress()];
+  // Tap somewhere else to dismiss and leave switcher by tap "Done" button.
+  [[EarlGrey selectElementWithMatcher:grey_keyWindow()]
+      performAction:grey_tap()];
+  [ChromeEarlGrey
+      waitForSufficientlyVisibleElementWithMatcher:TabGridDoneButton()];
+  ShowTabViewController();
+
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleRecentTabsHistogram, 0);
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleIncognitoTabGridPageHistogram, 0);
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleRegularTabGridPageHistogram, 1);
+  ExpectIdleHistogramBucketCount(kUMATabSwitcherIdleRegularTabGridPageHistogram,
+                                 1, NO);
+}
+
+// Tests leaving tab grid after entering and exit inactive tabs grid.
+- (void)testLeaveSwitcherAfterEnteringAndExittingInactiveTabs {
+  if ([ChromeEarlGrey isIPadIdiom]) {
+    EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is "
+                           @"only supported on iPhone.");
+  }
+  // Mark the User Education screen as already-seen by default.
+  [ChromeEarlGrey setUserDefaultsObject:@YES
+                                 forKey:kInactiveTabsUserEducationShownOnceKey];
+  NSString* title = @"NormalTabLongerStringForTest1";
+  [self setUpTestServer];
+  [ChromeEarlGrey loadURL:[self makeURLForTitle:title]];
+
+  // Relaunch with inactive tabs enabled.
+  AppLaunchConfiguration config;
+  config.relaunch_policy = ForceRelaunchByCleanShutdown;
+  config.additional_args.push_back(
+      "--enable-features=" + std::string(kTabInactivityThreshold.name) + ":" +
+      kTabInactivityThresholdParameterName + "/" +
+      kTabInactivityThresholdImmediateDemoParam);
+  [[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config];
+
+  GREYAssertNil([MetricsAppInterface setupHistogramTester],
+                @"Cannot setup histogram tester.");
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleRegularTabGridPageHistogram, 0);
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleIncognitoTabGridPageHistogram, 0);
+
+  [ChromeEarlGrey showTabSwitcher];
+  [[EarlGrey
+      selectElementWithMatcher:grey_accessibilityID(
+                                   kInactiveTabsButtonAccessibilityIdentifier)]
+      performAction:grey_tap()];
+  [[EarlGrey selectElementWithMatcher:testing::NavigationBarBackButton()]
+      performAction:grey_tap()];
+  ShowTabViewController();
+
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleRecentTabsHistogram, 0);
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleIncognitoTabGridPageHistogram, 0);
+  ExpectIdleHistogramCount(kUMATabSwitcherIdleRegularTabGridPageHistogram, 1);
+  ExpectIdleHistogramBucketCount(kUMATabSwitcherIdleRegularTabGridPageHistogram,
+                                 1, NO);
+}
+
 // Tests switching back and forth between the normal and incognito BVCs.
 - (void)testSwappingBVCModesWithoutEnteringSwitcher {
   // Opening a new tab from the menu will force a change in BVC.
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h
index 856f3c2..81b2c3e 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.h
@@ -11,6 +11,7 @@
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/disabled_grid_view_controller.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_consumer.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_consumer.h"
+#import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_idle_status_handler.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_paging.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/toolbars/tab_grid_toolbars_main_tab_grid_delegate.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_grid/transitions/legacy_grid_transition_animation_layout_providing.h"
@@ -100,6 +101,7 @@
                         KeyCommandActions,
                         TabGridConsumer,
                         LegacyGridTransitionAnimationLayoutProviding,
+                        TabGridIdleStatusHandler,
                         TabGridPaging,
                         TabGridToolbarsMainTabGridDelegate,
                         TabGridTransitionLayoutProviding,
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm
index fe1f657..9c4d95e 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm
@@ -160,12 +160,15 @@
 @implementation TabGridViewController {
   // Idle page status.
   // Tracks whether the user closed the tab switcher without doing any
-  // meaningful action.
-  BOOL _idleRegularTabGrid;
-  BOOL _idleIncognitoTabGrid;
+  // `TabGridActionType::kInPageAction`s.
+  BOOL _idleTabGrid;
+  // Whether the user has done anything meaningful when recent tabs page is
+  // visible.
   BOOL _idleRecentTabs;
-
-  TabGridPage _activePageWhenAppear;
+  // Whether the user has changed pages since entering the tab grid.
+  BOOL _pageChangedSinceEntering;
+  // Whether the user has put the app to background since entering tab grid.
+  BOOL _backgroundedSinceEntering;
 }
 
 // TabGridPaging property.
@@ -416,10 +419,11 @@
 #pragma mark - Public Methods
 
 - (void)contentWillAppearAnimated:(BOOL)animated {
+  _pageChangedSinceEntering = NO;
+  _backgroundedSinceEntering = NO;
   [self resetIdlePageStatus];
   self.viewVisible = YES;
   [self.topToolbar.pageControl setSelectedPage:self.currentPage animated:NO];
-  _activePageWhenAppear = self.currentPage;
   [self configureViewControllerForCurrentSizeClassesAndPage];
 
   // The toolbars should be hidden (alpha 0.0) before the tab appears, so that
@@ -583,6 +587,11 @@
 - (void)setActivePage:(TabGridPage)activePage {
   [self scrollToPage:activePage animated:YES];
   [self.activityObserver updateLastActiveTabPage:activePage];
+  if (activePage != _activePage) {
+    // Usually, an active page change is a result of an in-page action happening
+    // on a previously non-active page.
+    [self tabGridDidPerformAction:TabGridActionType::kInPageAction];
+  }
   _activePage = activePage;
 }
 
@@ -592,6 +601,7 @@
   if (_tabGridMode == mode) {
     return;
   }
+  [self tabGridDidPerformAction:TabGridActionType::kInPageAction];
   if (self.swipeToIncognitoIPH) {
     [self.swipeToIncognitoIPH
         dismissWithReason:IPHDismissalReasonType::
@@ -633,18 +643,14 @@
     return;
   }
 
-  // If the page has changed, the idle status of tab grid pages is `NO`.
-  BOOL onSamePage = self.currentPage == _activePageWhenAppear;
-
   switch (self.currentPage) {
     case TabGridPage::TabGridPageIncognitoTabs:
       base::UmaHistogramBoolean(
-          kUMATabSwitcherIdleIncognitoTabGridPageHistogram,
-          _idleIncognitoTabGrid && onSamePage);
+          kUMATabSwitcherIdleIncognitoTabGridPageHistogram, _idleTabGrid);
       break;
     case TabGridPage::TabGridPageRegularTabs:
       base::UmaHistogramBoolean(kUMATabSwitcherIdleRegularTabGridPageHistogram,
-                                _idleRegularTabGrid && onSamePage);
+                                _idleTabGrid);
       break;
     case TabGridPage::TabGridPageRemoteTabs:
       base::UmaHistogramBoolean(kUMATabSwitcherIdleRecentTabsHistogram,
@@ -653,29 +659,9 @@
   }
 }
 
-// Sets the idle page status of the `currentPage`.
-- (void)setCurrentIdlePageStatus:(BOOL)idlePageStatus {
-  if (!self.viewVisible) {
-    return;
-  }
-
-  switch (self.currentPage) {
-    case TabGridPage::TabGridPageIncognitoTabs:
-      _idleIncognitoTabGrid = idlePageStatus;
-      break;
-    case TabGridPage::TabGridPageRegularTabs:
-      _idleRegularTabGrid = idlePageStatus;
-      break;
-    case TabGridPage::TabGridPageRemoteTabs:
-      _idleRecentTabs = idlePageStatus;
-      break;
-  }
-}
-
 // Resets idle page status.
 - (void)resetIdlePageStatus {
-  _idleIncognitoTabGrid = YES;
-  _idleRegularTabGrid = YES;
+  _idleTabGrid = YES;
   // `_idleRecentTabs` is set to 'YES' if the "Done" button has been tapped from
   // the "TabGridPageRemoteTabs" or if the page has changed.
   _idleRecentTabs = NO;
@@ -859,13 +845,14 @@
 }
 
 - (void)setCurrentPage:(TabGridPage)currentPage {
-  BOOL samePage = _currentPage == currentPage;
-
   // Record the idle metric if the previous page was `TabGridPageRemoteTabs`.
-  if (!samePage && _currentPage == TabGridPageRemoteTabs) {
-    [self setCurrentIdlePageStatus:YES];
-    [self recordIdlePageStatus];
-    [self setCurrentIdlePageStatus:NO];
+  if (_currentPage != currentPage) {
+    [self tabGridDidPerformAction:TabGridActionType::kChangePage];
+    if (_currentPage == TabGridPageRemoteTabs) {
+      _idleRecentTabs = YES;
+      [self recordIdlePageStatus];
+      _idleRecentTabs = NO;
+    }
   }
 
   // Original current page is about to not be visible. Disable it from being
@@ -970,7 +957,7 @@
     }
   }
 
-  // TODO(crbug.com/872303) : This is a workaround because TabRestoreService
+  // TODO(crbug.com/41406890) : This is a workaround because TabRestoreService
   // does not notify observers when entries are removed. When close all tabs
   // removes entries, the remote tabs page in the tab grid are not updated. This
   // ensures that the table is updated whenever scrolling to it.
@@ -1064,7 +1051,7 @@
 // will be created.
 - (void)setupRemoteTabsViewController {
   self.remoteTabsViewController.UIDelegate = self;
-  // TODO(crbug.com/804589) : Dark style on remote tabs.
+  // TODO(crbug.com/41366321) : Dark style on remote tabs.
   // The styler must be set before the view controller is loaded.
   ChromeTableViewStyler* styler = [[ChromeTableViewStyler alloc] init];
   styler.tableViewBackgroundColor = [UIColor colorNamed:kGridBackgroundColor];
@@ -1720,10 +1707,12 @@
   // Record how long it took to select an item.
   [self reportTabSelectionTime];
 
-  [self.regularGridHandler selectItemWithID:itemID pinned:YES];
+  [self.regularGridHandler selectItemWithID:itemID
+                                     pinned:YES
+                     isFirstActionOnTabGrid:_idleTabGrid];
 
   self.activePage = self.currentPage;
-  [self setCurrentIdlePageStatus:NO];
+  [self tabGridDidPerformAction:TabGridActionType::kInPageAction];
 
   [self.tabPresentationDelegate showActiveTabInPage:self.currentPage
                                        focusOmnibox:NO];
@@ -1751,12 +1740,12 @@
 
 - (void)pinnedTabsViewControllerDidMoveItem:
     (PinnedTabsViewController*)pinnedTabsViewController {
-  [self setCurrentIdlePageStatus:NO];
+  [self tabGridDidPerformAction:TabGridActionType::kInPageAction];
 }
 
 - (void)pinnedTabsViewController:(BaseGridViewController*)gridViewController
              didRemoveItemWIthID:(web::WebStateID)itemID {
-  [self setCurrentIdlePageStatus:NO];
+  [self tabGridDidPerformAction:TabGridActionType::kInPageAction];
 }
 
 - (void)pinnedViewControllerDropAnimationWillBegin:
@@ -1781,6 +1770,11 @@
   [self.mutator dragAndDropSessionEnded];
 }
 
+- (void)pinnedViewController:(PinnedTabsViewController*)pinnedTabsViewController
+    didRequestContextMenuForItemWithID:(web::WebStateID)itemID {
+  [self tabGridDidPerformAction:TabGridActionType::kInPageAction];
+}
+
 #pragma mark - BaseGridViewControllerDelegate
 
 - (void)gridViewController:(BaseGridViewController*)gridViewController
@@ -1823,11 +1817,14 @@
 
   // Check if the tab being selected is already selected.
   BOOL alreadySelected = [tabsDelegate isItemWithIDSelected:itemID];
-  if (!alreadySelected) {
-    [self setCurrentIdlePageStatus:NO];
-  }
 
-  [tabsDelegate selectItemWithID:itemID pinned:NO];
+  [tabsDelegate selectItemWithID:itemID
+                          pinned:NO
+          isFirstActionOnTabGrid:_idleTabGrid];
+
+  if (!alreadySelected) {
+    [self tabGridDidPerformAction:TabGridActionType::kInPageAction];
+  }
 
   if (self.tabGridMode == TabGridModeSearch) {
     if (![tabsDelegate isItemWithIDSelected:itemID]) {
@@ -1885,7 +1882,7 @@
     }
   }
 
-  [self setCurrentIdlePageStatus:NO];
+  [self tabGridDidPerformAction:TabGridActionType::kInPageAction];
 
   [tabsDelegate selectTabGroup:group];
 
@@ -1904,7 +1901,7 @@
 
 - (void)gridViewControllerDidMoveItem:
     (BaseGridViewController*)gridViewController {
-  [self setCurrentIdlePageStatus:NO];
+  [self tabGridDidPerformAction:TabGridActionType::kInPageAction];
 }
 
 - (void)gridViewController:(BaseGridViewController*)gridViewController
@@ -1924,7 +1921,7 @@
 
 - (void)gridViewController:(BaseGridViewController*)gridViewController
        didRemoveItemWIthID:(web::WebStateID)itemID {
-  [self setCurrentIdlePageStatus:NO];
+  [self tabGridDidPerformAction:TabGridActionType::kInPageAction];
 }
 
 - (void)gridViewControllerDragSessionWillBeginForTab:
@@ -1976,6 +1973,7 @@
   CHECK_EQ(self.currentPage, TabGridPageRegularTabs);
   base::RecordAction(base::UserMetricsAction("MobileTabGridShowInactiveTabs"));
   [self.delegate showInactiveTabs];
+  [self tabGridDidPerformAction:TabGridActionType::kInPageAction];
 }
 
 - (void)didTapInactiveTabsSettingsLinkInGridViewController:
@@ -1983,13 +1981,18 @@
   NOTREACHED();
 }
 
+- (void)gridViewController:(BaseGridViewController*)gridViewController
+    didRequestContextMenuForItemWithID:(web::WebStateID)itemID {
+  [self tabGridDidPerformAction:TabGridActionType::kInPageAction];
+}
+
 #pragma mark - TabGridToolbarsMainTabGridDelegate
 
 - (void)doneButtonTapped:(id)sender {
   TabGridPage newActivePage = self.currentPage;
 
   if (self.currentPage == TabGridPageRemoteTabs) {
-    [self setCurrentIdlePageStatus:YES];
+    _idleRecentTabs = YES;
     newActivePage = self.activePage;
   }
 
@@ -2228,10 +2231,6 @@
 
 #pragma mark - GridConsumer
 
-- (void)setPageIdleStatus:(BOOL)status {
-  [self setCurrentIdlePageStatus:status];
-}
-
 - (void)setActivePageFromPage:(TabGridPage)page {
   self.activePage = page;
 }
@@ -2259,4 +2258,27 @@
   [self setCurrentPageAndPageControl:TabGridPageIncognitoTabs animated:YES];
 }
 
+#pragma mark - TabGridIdleStatusHandler
+
+- (BOOL)status {
+  return _idleTabGrid && !_pageChangedSinceEntering &&
+         !_backgroundedSinceEntering;
+}
+
+- (void)tabGridDidPerformAction:(TabGridActionType)type {
+  if (self.viewVisible) {
+    switch (type) {
+      case TabGridActionType::kInPageAction:
+        _idleTabGrid = NO;
+        break;
+      case TabGridActionType::kChangePage:
+        _pageChangedSinceEntering = YES;
+        break;
+      case TabGridActionType::kBackground:
+        _backgroundedSinceEntering = YES;
+        break;
+    }
+  }
+}
+
 @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/toolbars/tab_grid_page_control.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/toolbars/tab_grid_page_control.mm
index a65ce53..05858a8 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/toolbars/tab_grid_page_control.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/toolbars/tab_grid_page_control.mm
@@ -692,7 +692,7 @@
   } else {
     // bug: taps in the left- or rightmost `kSliderOverhang` points of the
     // control will fall through to this case.
-    // TODO(crbug.com/804500): Fix this.
+    // TODO(crbug.com/41366258): Fix this.
     page = TabGridPageRegularTabs;
   }
   if (page != self.selectedPage) {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/transitions/legacy_tab_grid_transition_handler.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/transitions/legacy_tab_grid_transition_handler.mm
index 0305e9ff..f826f13f 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/transitions/legacy_tab_grid_transition_handler.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/transitions/legacy_tab_grid_transition_handler.mm
@@ -225,7 +225,7 @@
   // the view controller that contains the BVC. Unfortunatley, the layout guide
   // needed here is attached to the BVC's view, which is the first (and only)
   // subview of the BVCContainerViewController's view.
-  // TODO(crbug.com/860234) Clean up this arrangement.
+  // TODO(crbug.com/40583629) Clean up this arrangement.
   UIView* tabContentView = viewControllerForTab.view.subviews[0];
 
   CGRect contentArea = [NamedGuide guideWithName:kContentAreaGuide
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator.mm
index 824b990..bfd31143 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator.mm
@@ -816,7 +816,7 @@
       [self moveItemWithID:tabInfo.tabID toIndex:destinationIndex];
     } else {
       // The tab lives in another Browser.
-      // TODO(crbug.com/1515821): Need to be updated for pinned tabs.
+      // TODO(crbug.com/41488813): Need to be updated for pinned tabs.
       base::UmaHistogramEnumeration(kUmaTabStripViewDragOrigin,
                                     DragItemOrigin::kOtherBrwoser);
       [self moveItemWithIDFromDifferentBrowser:tabInfo.tabID
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_layout.swift b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_layout.swift
index 0221636..2d0ca84c 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_layout.swift
+++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/ui/tab_strip_layout.swift
@@ -232,7 +232,6 @@
     let leftBounds: CGFloat = contentOffset.x + sectionInset.left
     let rightBounds: CGFloat = collectionViewWidth + contentOffset.x - sectionInset.right
     let isScrollable: Bool = collectionView.contentSize.width > collectionView.frame.width
-    let isRTL: Bool = collectionView.effectiveUserInterfaceLayoutDirection == .rightToLeft
 
     /// Hide the `trailingSeparator`if the next cell is selected.
     let isNextCellSelected = (indexPath.item + 1) == selectedIndexPath?.item
diff --git a/ios/chrome/browser/ui/tabs/tab_pickup/tab_pickup_egtest.mm b/ios/chrome/browser/ui/tabs/tab_pickup/tab_pickup_egtest.mm
index 5348467..671304e 100644
--- a/ios/chrome/browser/ui/tabs/tab_pickup/tab_pickup_egtest.mm
+++ b/ios/chrome/browser/ui/tabs/tab_pickup/tab_pickup_egtest.mm
@@ -118,7 +118,7 @@
 // resumption feature is enabled.
 - (void)testBannerNotDisplayedOnNTPWhenTabResumptionEnbaled {
   // This test is failing on iOS 16.7 only.
-  // TODO(crbug.com/1516761): Re-enable the test.
+  // TODO(crbug.com/41489744): Re-enable the test.
   if (@available(iOS 16.7, *)) {
     if (@available(iOS 17.0, *)) {
     } else {
@@ -144,7 +144,7 @@
 // was synced before the defined threshold.
 - (void)testBannerVisibleBeforeThreshold {
   // This test is failing on iOS 16.7 only.
-  // TODO(crbug.com/1516761): Re-enable the test.
+  // TODO(crbug.com/41489744): Re-enable the test.
   if (@available(iOS 16.7, *)) {
     if (@available(iOS 17.0, *)) {
     } else {
@@ -172,7 +172,7 @@
 // synced after the defined threshold.
 - (void)testBannerNotVisibleAfterThreshold {
   // This test is failing on iOS 16.7 only.
-  // TODO(crbug.com/1516761): Re-enable the test.
+  // TODO(crbug.com/41489744): Re-enable the test.
   if (@available(iOS 16.7, *)) {
     if (@available(iOS 17.0, *)) {
     } else {
@@ -197,7 +197,7 @@
 // Verifies that tapping on the open button of the TabPickup banner correctly
 // opens the distant tab.
 - (void)testAcceptBanner {  // This test is failing on iOS 16.7 only.
-  // TODO(crbug.com/1516761): Re-enable the test.
+  // TODO(crbug.com/41489744): Re-enable the test.
   if (@available(iOS 16.7, *)) {
     if (@available(iOS 17.0, *)) {
     } else {
@@ -235,7 +235,7 @@
 // modal.
 - (void)testOpenModalFromBanner {
   // This test is failing on iOS 16.7 only.
-  // TODO(crbug.com/1516761): Re-enable the test.
+  // TODO(crbug.com/41489744): Re-enable the test.
   if (@available(iOS 16.7, *)) {
     if (@available(iOS 17.0, *)) {
     } else {
@@ -278,7 +278,7 @@
 // Verifies that the TabPickup banner is displayed only once.
 - (void)testBannerDisplayedOnce {
   // This test is failing on iOS 16.7 only.
-  // TODO(crbug.com/1516761): Re-enable the test.
+  // TODO(crbug.com/41489744): Re-enable the test.
   if (@available(iOS 16.7, *)) {
     if (@available(iOS 17.0, *)) {
     } else {
@@ -325,7 +325,7 @@
 // delay between the presentation of two tab pickup banners.
 - (void)testBannerDisplayedAfterBackground {
   // This test is failing on iOS 16.7 only.
-  // TODO(crbug.com/1516761): Re-enable the test.
+  // TODO(crbug.com/41489744): Re-enable the test.
   if (@available(iOS 16.7, *)) {
     if (@available(iOS 17.0, *)) {
     } else {
@@ -377,7 +377,7 @@
 // and foregrounding the app.
 - (void)testBannerNotDisplayedAfterBackground {
   // This test is failing on iOS 16.7 only.
-  // TODO(crbug.com/1516761): Re-enable the test.
+  // TODO(crbug.com/41489744): Re-enable the test.
   if (@available(iOS 16.7, *)) {
     if (@available(iOS 17.0, *)) {
     } else {
@@ -425,7 +425,7 @@
 // Verifies that the same TabPickup banner is not displayed twice.
 - (void)testSameBannerNotDisplayedTwice {
   // This test is failing on iOS 16.7 only.
-  // TODO(crbug.com/1516761): Re-enable the test.
+  // TODO(crbug.com/41489744): Re-enable the test.
   if (@available(iOS 16.7, *)) {
     if (@available(iOS 17.0, *)) {
     } else {
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
index b425595..d00bf94 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
+++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
@@ -950,7 +950,7 @@
   _fullscreenDisabler = nullptr;
 
   int fromIndex = [self webStateListIndexForTabView:_draggedTab];
-  // TODO(crbug.com/1049882): We're seeing crashes where fromIndex is
+  // TODO(crbug.com/40117861): We're seeing crashes where fromIndex is
   // kInvalidIndex, indicating that the dragged tab is no longer in the
   // WebStateList. This could happen if a tab closed itself during a drag.
   // Investigate this further, but for now, simply test `fromIndex` before
diff --git a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm
index afd42b8..cf8f180 100644
--- a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.mm
@@ -207,7 +207,7 @@
 
 - (void)viewDidLayoutSubviews {
   [super viewDidLayoutSubviews];
-  // TODO(crbug.com/882723): Remove this call once iPad trait collection
+  // TODO(crbug.com/41413004): Remove this call once iPad trait collection
   // override issue is fixed.
   [self updateAllButtonsVisibility];
 }
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm b/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm
index 45f95fd..211863d 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm
+++ b/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm
@@ -132,7 +132,8 @@
 // button and asserts it doesn't commit the omnibox contents if the input is
 // canceled.
 - (void)testToolbarOmniboxHideKeyboard {
-  // TODO(crbug.com/642559): Enable the test for iPad when typing bug is fixed.
+  // TODO(crbug.com/41272886): Enable the test for iPad when typing bug is
+  // fixed.
   if ([ChromeEarlGrey isIPadIdiom]) {
     EARL_GREY_TEST_DISABLED(@"Disabled for iPad due to a simulator bug.");
   }
diff --git a/ios/chrome/browser/ui/unit_conversion/unit_conversion_view_controller.mm b/ios/chrome/browser/ui/unit_conversion/unit_conversion_view_controller.mm
index 62be56d..613dd74 100644
--- a/ios/chrome/browser/ui/unit_conversion/unit_conversion_view_controller.mm
+++ b/ios/chrome/browser/ui/unit_conversion/unit_conversion_view_controller.mm
@@ -475,7 +475,7 @@
   // crbug/1512445) but this could not be reproduced. To prevent further
   // crash, set the title to a valid string and log more info so this can
   // be debugged.
-  // TODO(crbug.com/1513168): remove when the issue is fixed.
+  // TODO(crbug.com/41485741): remove when the issue is fixed.
   NSString* debugSourceUnit = _formattedSourceUnit;
   if (!debugSourceUnit) {
     debugSourceUnit = [_sourceUnit description];
diff --git a/ios/chrome/browser/ui/whats_new/strings/resources/ios_whats_new_strings_ar.xtb b/ios/chrome/browser/ui/whats_new/strings/resources/ios_whats_new_strings_ar.xtb
index 3a28fad..737d1a7 100644
--- a/ios/chrome/browser/ui/whats_new/strings/resources/ios_whats_new_strings_ar.xtb
+++ b/ios/chrome/browser/ui/whats_new/strings/resources/ios_whats_new_strings_ar.xtb
@@ -1,7 +1,25 @@
 <?xml version="1.0" ?>
 <!DOCTYPE translationbundle>
 <translationbundle lang="ar">
+<translation id="1533488253335887280">يمكنك الوصول بسهولة وأمان إلى كلمات المرور من الشاشة الرئيسية.</translation>
+<translation id="1590550141045148182">افتح أو أغلِق علامات التبويب حسبما تريد.</translation>
+<translation id="2036020471903443693">ستظهر أسفل الشاشة علامة التبويب مثبَّتة.</translation>
+<translation id="2984477737332162971">انتقِل إلى علامات التبويب المفتوحة.</translation>
+<translation id="3595188309555410362">‏إذا كانت لديك علامات تبويب لم يتم استخدامها منذ فترة، فسيتم نقلها الآن إلى قسم "علامات التبويب غير النشطة" (Inactive Tabs).</translation>
+<translation id="3941788408634637840">‏انقر على "علامات التبويب غير النشطة" (Inactive Tabs) (في حال توفُّرها).</translation>
+<translation id="3942215673032261195">يمكنك تثبيت مواقعك الإلكترونية المفضّلة للوصول إليها بسهولة لاحقًا.</translation>
+<translation id="4196935312151003338">‏اختَر "تثبيت علامة التبويب" (Pin Tab) من القائمة.</translation>
+<translation id="4497631794981705027">انقر مع الاستمرار على الشاشة الرئيسية.</translation>
+<translation id="463279609093232564">في أعلى يمين الشاشة، انقر على رمز الإضافة.</translation>
+<translation id="5604467549230434026">‏أدخِل كلمة Chrome في مربّع "البحث في التطبيقات المصغّرة" (Search Widgets).</translation>
+<translation id="5639067007765618198">‏تطبيق "مدير كلمات المرور في Google" المصغّر</translation>
 <translation id="5922999516621365983">اسحب علامة التبويب هنا لتثبيتها.</translation>
 <translation id="5979837087407522202">البحث عن كلمات المرور</translation>
+<translation id="6109989197058801417">اضغط مع الاستمرار على علامة التبويب التي تريد تثبيتها.</translation>
+<translation id="639614003069108254">‏اختَر "مدير كلمات المرور" (Password Manager)، ثم انقر على "إضافة تطبيق مصغّر" (Add Widget).</translation>
+<translation id="6905308710260460250">علامات التبويب المثبَّتة</translation>
+<translation id="720206380500582061">‏يمكنك إدارة إعدادات "علامات التبويب غير النشطة" (Inactive Tabs) ضِمن "الإعدادات" (Settings) &gt; "علامات التبويب" (Tabs).</translation>
 <translation id="8077675488769462025">علامات التبويب غير النشطة</translation>
+<translation id="8602952180069641300">‏انتقِل إلى أعلى "علامات التبويب" (Tabs).</translation>
+<translation id="979990360845983227">لم يتم استخدامها منذ 14 يومًا أو أكثر</translation>
 </translationbundle>
\ No newline at end of file
diff --git a/ios/chrome/browser/ui/whats_new/whats_new_mediator.mm b/ios/chrome/browser/ui/whats_new/whats_new_mediator.mm
index 154a631..db236b1 100644
--- a/ios/chrome/browser/ui/whats_new/whats_new_mediator.mm
+++ b/ios/chrome/browser/ui/whats_new/whats_new_mediator.mm
@@ -72,7 +72,7 @@
       break;
     case WhatsNewPrimaryAction::kLens:
       // Handles actions that open Lens.
-      // TODO(crbug.com/1502927): Add the Lens promo that contains the
+      // TODO(crbug.com/40943329): Add the Lens promo that contains the
       // button that triggers the Lens action.
       [self openLens];
       break;
diff --git a/ios/chrome/browser/web/model/chrome_main_parts.mm b/ios/chrome/browser/web/model/chrome_main_parts.mm
index f531fb2..c0c0abc 100644
--- a/ios/chrome/browser/web/model/chrome_main_parts.mm
+++ b/ios/chrome/browser/web/model/chrome_main_parts.mm
@@ -262,7 +262,7 @@
 
   metrics::EnableExpiryChecker(::kExpiredHistogramsHashes);
 
-  // TODO(crbug.com/1164533): Remove code below some time after February 2021.
+  // TODO(crbug.com/40163579): Remove code below some time after February 2021.
   NSString* const kRemoveProtectionFromPrefFileKey =
       @"RemoveProtectionFromPrefKey";
   if ([NSUserDefaults.standardUserDefaults
diff --git a/ios/chrome/browser/web/model/error_page_egtest.mm b/ios/chrome/browser/web/model/error_page_egtest.mm
index 0b39e699..a71d8ee 100644
--- a/ios/chrome/browser/web/model/error_page_egtest.mm
+++ b/ios/chrome/browser/web/model/error_page_egtest.mm
@@ -187,8 +187,8 @@
 - (void)testRedirectToData {
   // Disable the test on iOS 16.4 as WKWebView handles this internally now as of
   // https://bugs.webkit.org/show_bug.cgi?id=230158
-  // TODO(crbug.com/1442647): Remove redirect logic completely when dropping iOS
-  // 16.
+  // TODO(crbug.com/40267045): Remove redirect logic completely when dropping
+  // iOS 16.
   if (@available(iOS 16.4, *)) {
     EARL_GREY_TEST_DISABLED(@"Test disabled on iOS 16.4.");
   }
diff --git a/ios/chrome/browser/web/model/font_size/resources/font_size.ts b/ios/chrome/browser/web/model/font_size/resources/font_size.ts
index dd6fca3..29dbd064 100644
--- a/ios/chrome/browser/web/model/font_size/resources/font_size.ts
+++ b/ios/chrome/browser/web/model/font_size/resources/font_size.ts
@@ -21,7 +21,7 @@
 /**
  * Adjust the font size of current web page by "size%"
  *
- * TODO(crbug.com/836962): Consider the original value of
+ * TODO(crbug.com/41385551): Consider the original value of
  *                         -webkit-text-size-adjust on the web page. Add it
  *                         if it's a number or abort if it's 'none'.
  *
diff --git a/ios/chrome/browser/web/model/web_state_delegate_browser_agent.mm b/ios/chrome/browser/web/model/web_state_delegate_browser_agent.mm
index 24e69ff3..6d3f37b 100644
--- a/ios/chrome/browser/web/model/web_state_delegate_browser_agent.mm
+++ b/ios/chrome/browser/web/model/web_state_delegate_browser_agent.mm
@@ -295,7 +295,7 @@
 
   switch (warning_type) {
     case web::FormWarningType::kRepost:
-      // TODO(crbug.com/1266052) : Clean up this API.
+      // TODO(crbug.com/40203973) : Clean up this API.
       RepostFormTabHelper::FromWebState(source)->PresentDialog(
           [container_view_provider_ dialogLocation], std::move(callback));
       return;
diff --git a/ios/chrome/browser/webui/ui_bundled/prefs_internals_ui.cc b/ios/chrome/browser/webui/ui_bundled/prefs_internals_ui.cc
index 28a32c5..a9e54c9 100644
--- a/ios/chrome/browser/webui/ui_bundled/prefs_internals_ui.cc
+++ b/ios/chrome/browser/webui/ui_bundled/prefs_internals_ui.cc
@@ -41,7 +41,7 @@
   void StartDataRequest(
       const std::string& path,
       web::URLDataSourceIOS::GotDataCallback callback) override {
-    // TODO(crbug.com/1006711): Properly disable this webui provider for
+    // TODO(crbug.com/40099982): Properly disable this webui provider for
     // incognito browser states.
     if (browser_state_->IsOffTheRecord()) {
       std::move(callback).Run(nullptr);
diff --git a/ios/chrome/browser/webui/ui_bundled/web_ui_test_utils.mm b/ios/chrome/browser/webui/ui_bundled/web_ui_test_utils.mm
index a06f8bc8..5b868f7922 100644
--- a/ios/chrome/browser/webui/ui_bundled/web_ui_test_utils.mm
+++ b/ios/chrome/browser/webui/ui_bundled/web_ui_test_utils.mm
@@ -31,7 +31,7 @@
   const std::string trimmed_URL(
       base::TrimString(url, "/", TrimPositions::TRIM_TRAILING));
 
-  // TODO(crbug.com/642207): Unify with the omniboxText matcher or move to the
+  // TODO(crbug.com/41272687): Unify with the omniboxText matcher or move to the
   // same location with the omniboxText matcher.
   return base::test::ios::WaitUntilConditionOrTimeout(
       base::test::ios::kWaitForUIElementTimeout, ^{
diff --git a/ios/chrome/common/app_group/app_group_constants.h b/ios/chrome/common/app_group/app_group_constants.h
index 02ef2d9..add3625 100644
--- a/ios/chrome/common/app_group/app_group_constants.h
+++ b/ios/chrome/common/app_group/app_group_constants.h
@@ -203,7 +203,7 @@
 // Gets the legacy share extension folder URL.
 // This folder is deprecated and will be removed soon. Please do not add items
 // to it.
-// TODO(crbug.com/695381): Remove this value.
+// TODO(crbug.com/41303853): Remove this value.
 NSURL* LegacyShareExtensionItemsFolder();
 
 // Gets the shared folder URL containing commands from other applications.
diff --git a/ios/chrome/common/ui/elements/popover_label_view_controller.mm b/ios/chrome/common/ui/elements/popover_label_view_controller.mm
index dedb7b6..0a7a4ed 100644
--- a/ios/chrome/common/ui/elements/popover_label_view_controller.mm
+++ b/ios/chrome/common/ui/elements/popover_label_view_controller.mm
@@ -110,7 +110,7 @@
 
   AddSameConstraints(self.view.safeAreaLayoutGuide, _scrollView);
 
-  // TODO(crbug.com/1100884): Remove the following workaround:
+  // TODO(crbug.com/40138105): Remove the following workaround:
   // Using a UIView instead of UILayoutGuide as the later behaves weirdly with
   // the scroll view.
   UIView* textContainerView = [[UIView alloc] init];
diff --git a/ios/chrome/common/ui/reauthentication/reauthentication_module.h b/ios/chrome/common/ui/reauthentication/reauthentication_module.h
index 3b8c890..f4d28db6 100644
--- a/ios/chrome/common/ui/reauthentication/reauthentication_module.h
+++ b/ios/chrome/common/ui/reauthentication/reauthentication_module.h
@@ -27,7 +27,7 @@
  * This is used by `PasswordsDetailsCollectionViewController` and
  * `PasswordExporter|to re-authenticate the user before displaying the password
  * in plain text, allowing it to be copied, or exporting passwords.
- * TODO(crbug.com/1116979): Convert reauthentication module to model object
+ * TODO(crbug.com/40144947): Convert reauthentication module to model object
  * (keyed service or browser agent).
  */
 @interface ReauthenticationModule : NSObject <ReauthenticationProtocol>
diff --git a/ios/chrome/test/app/chrome_test_util.h b/ios/chrome/test/app/chrome_test_util.h
index 909c198..dd761de 100644
--- a/ios/chrome/test/app/chrome_test_util.h
+++ b/ios/chrome/test/app/chrome_test_util.h
@@ -66,7 +66,7 @@
 void PresentSignInAccountsViewControllerIfNecessary();
 
 // Sets the value of a boolean local state pref.
-// TODO(crbug.com/647022): Clean up other tests that use this helper function.
+// TODO(crbug.com/41275546): Clean up other tests that use this helper function.
 void SetBooleanLocalStatePref(const char* pref_name, bool value);
 
 // Sets the value of a boolean user pref in the given browser state.
diff --git a/ios/chrome/test/app/histogram_test_util.h b/ios/chrome/test/app/histogram_test_util.h
index d3b5788..1ec4bd87 100644
--- a/ios/chrome/test/app/histogram_test_util.h
+++ b/ios/chrome/test/app/histogram_test_util.h
@@ -13,7 +13,7 @@
 #include "base/metrics/histogram.h"
 #include "base/metrics/histogram_base.h"
 
-// TODO(crbug.com/640141): factorize with base::HistogramTester and add
+// TODO(crbug.com/41271490): factorize with base::HistogramTester and add
 // unittests.
 
 typedef void (^FailureBlock)(NSString*);
diff --git a/ios/chrome/test/earl_grey/accessibility_util.mm b/ios/chrome/test/earl_grey/accessibility_util.mm
index 8012639..baec1da1 100644
--- a/ios/chrome/test/earl_grey/accessibility_util.mm
+++ b/ios/chrome/test/earl_grey/accessibility_util.mm
@@ -11,7 +11,7 @@
 namespace chrome_test_util {
 
 BOOL VerifyAccessibilityForCurrentScreen(NSError* __strong* error) {
-  // TODO(crbug.com/972681): The GTX analytics ping is preventing the app from
+  // TODO(crbug.com/41464129): The GTX analytics ping is preventing the app from
   // idling, causing EG tests to fail.  Disabling analytics will allow tests to
   // run, but may not be the correct long-term solution.
   [GTXAnalytics setEnabled:NO];
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
index cf7ea1b8..7ded7292 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey_ui.mm
@@ -387,7 +387,7 @@
   EG_TEST_HELPER_ASSERT_TRUE(tabGridButtonVisible,
                              @"Show tab grid button was not visible.");
 
-  // TODO(crbug.com/933953) For an unknown reason synchronization doesn't work
+  // TODO(crbug.com/41442441) For an unknown reason synchronization doesn't work
   // well with tapping on the tabgrid button, and instead triggers the long
   // press gesture recognizer.  Disable this here so the test can be re-enabled.
   ScopedSynchronizationDisabler disabler;
diff --git a/ios/chrome/test/earl_grey/chrome_test_case.mm b/ios/chrome/test/earl_grey/chrome_test_case.mm
index f50f805d..0b973dc 100644
--- a/ios/chrome/test/earl_grey/chrome_test_case.mm
+++ b/ios/chrome/test/earl_grey/chrome_test_case.mm
@@ -79,7 +79,7 @@
     @"testErrorPage",                  // ErrorPageTestCase
     @"testFindInPage",                 // FindInPageTestCase
     @"testDismissFirstRun",            // FirstRunTestCase
-    // TODO(crbug.com/872788) Failing after move to Xcode 10.
+    // TODO(crbug.com/41407180) Failing after move to Xcode 10.
     // @"testLongPDFScroll",                         // FullscreenTestCase
     @"testDeleteHistory",                         // HistoryUITestCase
     @"testInfobarsDismissOnNavigate",             // InfobarTestCase
@@ -103,7 +103,7 @@
   ]];
 
   if (base::ios::IsRunningOnIOS17OrLater()) {
-    // TODO(crbug.com/1469233): Test is failing on iOS17.
+    // TODO(crbug.com/40925281): Test is failing on iOS17.
     [tests removeObject:@"testQRScannerUIIsShown"];
   }
   return tests;
diff --git a/ios/chrome/test/earl_grey2/smoke_egtest.mm b/ios/chrome/test/earl_grey2/smoke_egtest.mm
index 52b05cc..55c626b 100644
--- a/ios/chrome/test/earl_grey2/smoke_egtest.mm
+++ b/ios/chrome/test/earl_grey2/smoke_egtest.mm
@@ -36,7 +36,7 @@
   [ChromeEarlGreyUI openToolsMenu];
 
   // Open new tab.
-  // TODO(crbug.com/917114): Calling the string directly is temporary while we
+  // TODO(crbug.com/41432876): Calling the string directly is temporary while we
   // roll out a solution to access constants across the code base for EG2.
   id<GREYMatcher> newTabButtonMatcher =
       grey_accessibilityID(@"kToolsMenuNewTabId");
diff --git a/ios/net/cookies/cookie_store_ios.mm b/ios/net/cookies/cookie_store_ios.mm
index 05e18f3..627a27b4 100644
--- a/ios/net/cookies/cookie_store_ios.mm
+++ b/ios/net/cookies/cookie_store_ios.mm
@@ -298,8 +298,8 @@
   // instead.
   DCHECK(SystemCookiesAllowed());
 
-  // TODO(crbug.com/459154): If/when iOS supports Same-Site cookies, we'll need
-  // to pass options in here as well.
+  // TODO(crbug.com/40406003): If/when iOS supports Same-Site cookies, we'll
+  // need to pass options in here as well.
   system_store_->GetAllCookiesAsync(
       base::BindOnce(&CookieStoreIOS::RunGetAllCookiesCallbackOnSystemCookies,
                      weak_factory_.GetWeakPtr(), std::move(callback)));
diff --git a/ios/web/find_in_page/resources/find_in_page_native_api.ts b/ios/web/find_in_page/resources/find_in_page_native_api.ts
index 60dad806..1eae01a0 100644
--- a/ios/web/find_in_page/resources/find_in_page_native_api.ts
+++ b/ios/web/find_in_page/resources/find_in_page_native_api.ts
@@ -392,7 +392,7 @@
  * @return {number} that represents the total matches found.
  */
 function pumpSearch(timeout: number): number {
-  // TODO(crbug.com/895531): It would be better if this DCHECKed.
+  // TODO(crbug.com/41420794): It would be better if this DCHECKed.
   if (searchInProgress_ == false) {
     return 0;
   }
diff --git a/ios/web/init/web_main_loop.mm b/ios/web/init/web_main_loop.mm
index b38aa2c6..d1129bf 100644
--- a/ios/web/init/web_main_loop.mm
+++ b/ios/web/init/web_main_loop.mm
@@ -34,7 +34,7 @@
 namespace web {
 
 // The currently-running WebMainLoop.  There can be one or zero.
-// TODO(crbug.com/965889): Desktop uses this to implement
+// TODO(crbug.com/41460416): Desktop uses this to implement
 // ImmediateShutdownAndExitProcess.  If we don't need that functionality, we can
 // remove this.
 WebMainLoop* g_current_web_main_loop = nullptr;
diff --git a/ios/web/init/web_main_runner_impl.mm b/ios/web/init/web_main_runner_impl.mm
index 84f13af..5395632 100644
--- a/ios/web/init/web_main_runner_impl.mm
+++ b/ios/web/init/web_main_runner_impl.mm
@@ -48,7 +48,7 @@
 
   mojo::core::Init();
 
-  // TODO(crbug.com/965894): Should we instead require that all embedders call
+  // TODO(crbug.com/41460421): Should we instead require that all embedders call
   // SetWebClient()?
   if (!GetWebClient()) {
     SetWebClient(&empty_web_client_);
diff --git a/ios/web/navigation/crw_js_navigation_handler.mm b/ios/web/navigation/crw_js_navigation_handler.mm
index 151780a..06f0e3fd 100644
--- a/ios/web/navigation/crw_js_navigation_handler.mm
+++ b/ios/web/navigation/crw_js_navigation_handler.mm
@@ -23,8 +23,8 @@
 // will round-trip a URL through the escaping process so that it can be adjusted
 // pre-storing, to allow later comparisons to work as expected.
 GURL URLEscapedForHistory(const GURL& url) {
-  // TODO(crbug.com/973871): This is a very large hammer; see if limited unicode
-  // escaping would be sufficient.
+  // TODO(crbug.com/41464782): This is a very large hammer; see if limited
+  // unicode escaping would be sufficient.
   return net::GURLWithNSURL(net::NSURLWithGURL(url));
 }
 
diff --git a/ios/web/navigation/crw_web_view_navigation_observer.mm b/ios/web/navigation/crw_web_view_navigation_observer.mm
index 84e4cce..c21cb57 100644
--- a/ios/web/navigation/crw_web_view_navigation_observer.mm
+++ b/ios/web/navigation/crw_web_view_navigation_observer.mm
@@ -209,7 +209,7 @@
 
 // Called when WKWebView URL has been changed.
 - (void)webViewURLDidChange {
-  // TODO(crbug.com/966412): Determine if there are any cases where this still
+  // TODO(crbug.com/41460688): Determine if there are any cases where this still
   // happens, and if so whether anything should be done when it does.
   if (self.webView.URL.absoluteString.length == 0) {
     DVLOG(1) << "Received nil/empty URL callback";
diff --git a/ios/web/navigation/crw_wk_navigation_handler.mm b/ios/web/navigation/crw_wk_navigation_handler.mm
index 6a9e694a..0b8e54d 100644
--- a/ios/web/navigation/crw_wk_navigation_handler.mm
+++ b/ios/web/navigation/crw_wk_navigation_handler.mm
@@ -2108,7 +2108,7 @@
                }];
         }
 
-        // TODO(crbug.com/973765): This is a workaround because `item` might
+        // TODO(crbug.com/41464714): This is a workaround because `item` might
         // get released after
         // `self.navigationManagerImpl->
         // CommitPendingItem(context->ReleaseItem()`.
@@ -2289,8 +2289,8 @@
   // is the post-policy value, and the source policy is no longer available,
   // the policy is set to Always so that whatever WebKit decided to send will be
   // re-sent when replaying the entry.
-  // TODO(crbug.com/227769): When possible, get the real referrer and policy in
-  // advance and use that instead.
+  // TODO(crbug.com/41004475): When possible, get the real referrer and policy
+  // in advance and use that instead.
   return web::Referrer(GURL(base::SysNSStringToUTF8(referrerString)),
                        web::ReferrerPolicyAlways);
 }
diff --git a/ios/web/navigation/navigation_manager_impl.h b/ios/web/navigation/navigation_manager_impl.h
index f772426..c5a747a8 100644
--- a/ios/web/navigation/navigation_manager_impl.h
+++ b/ios/web/navigation/navigation_manager_impl.h
@@ -154,7 +154,7 @@
                       web::HttpsUpgradeType https_upgrade_type);
 
   // Commits the pending item, if any.
-  // TODO(crbug.com/936933): Remove this method.
+  // TODO(crbug.com/41444193): Remove this method.
   void CommitPendingItem();
 
   // Commits given pending `item` stored outside of navigation manager
diff --git a/ios/web/public/init/web_main_delegate.h b/ios/web/public/init/web_main_delegate.h
index a38bb3c..35410bb6 100644
--- a/ios/web/public/init/web_main_delegate.h
+++ b/ios/web/public/init/web_main_delegate.h
@@ -21,7 +21,7 @@
   virtual void BasicStartupComplete() {}
 
   // Called right before the process exits.
-  // TODO(crbug.com/965895): This may not be used for anything.  Remove if
+  // TODO(crbug.com/41460422): This may not be used for anything.  Remove if
   // useless.
   virtual void ProcessExiting() {}
 };
diff --git a/ios/web/public/test/earl_grey/web_view_matchers.mm b/ios/web/public/test/earl_grey/web_view_matchers.mm
index a21d2af..e1eaa06a 100644
--- a/ios/web/public/test/earl_grey/web_view_matchers.mm
+++ b/ios/web/public/test/earl_grey/web_view_matchers.mm
@@ -15,7 +15,7 @@
 #import "ios/web/public/web_state.h"
 #import "net/base/apple/url_conversions.h"
 
-// TODO(crbug.com/757982): Remove this class, after LoadImage() is removed.
+// TODO(crbug.com/41340619): Remove this class, after LoadImage() is removed.
 // A helper delegate class that allows downloading responses with invalid
 // SSL certs.
 @interface TestURLSessionDelegateDeprecated : NSObject<NSURLSessionDelegate>
diff --git a/ios/web/public/test/fakes/fake_web_state_observer.h b/ios/web/public/test/fakes/fake_web_state_observer.h
index 7b33b06..66fe754 100644
--- a/ios/web/public/test/fakes/fake_web_state_observer.h
+++ b/ios/web/public/test/fakes/fake_web_state_observer.h
@@ -15,7 +15,7 @@
 
 // Test observer to check that the WebStateObserver methods are called as
 // expected. Can only observe a single WebState.
-// TODO(crbug.com/775684): fix this to allow observing multiple WebStates.
+// TODO(crbug.com/41350286): fix this to allow observing multiple WebStates.
 class FakeWebStateObserver : public WebStateObserver {
  public:
   FakeWebStateObserver(WebState* web_state);
diff --git a/ios/web/public/test/http_server/data_response_provider.mm b/ios/web/public/test/http_server/data_response_provider.mm
index 09d5e67..9f4aa5f 100644
--- a/ios/web/public/test/http_server/data_response_provider.mm
+++ b/ios/web/public/test/http_server/data_response_provider.mm
@@ -27,7 +27,7 @@
   std::string name;
   std::string value;
   while (response_headers->EnumerateHeaderLines(&iter, &name, &value)) {
-    // TODO(crbug.com/435350): Extract out other names that can't be set by
+    // TODO(crbug.com/40394910): Extract out other names that can't be set by
     // using the `setValue:forAdditionalHeader:` API such as "ETag" etc.
     if (name == "Content-type") {
       data_response->set_content_type(value);
diff --git a/ios/web/public/test/http_server/http_server.mm b/ios/web/public/test/http_server/http_server.mm
index 3ac070730d..738b11b 100644
--- a/ios/web/public/test/http_server/http_server.mm
+++ b/ios/web/public/test/http_server/http_server.mm
@@ -122,7 +122,7 @@
   DCHECK([NSThread isMainThread]);
   DCHECK(IsRunning()) << "Cannot stop an already stopped server.";
   RemoveAllResponseProviders();
-  // TODO(crbug.com/711723): Re-write the Stop() function when shutting down
+  // TODO(crbug.com/41313142): Re-write the Stop() function when shutting down
   // server works for iOS.
   embedded_test_server_.release();
   SetPort(0);
diff --git a/ios/web/shell/test/context_menu_egtest.mm b/ios/web/shell/test/context_menu_egtest.mm
index 992b1cff..4f2a958c 100644
--- a/ios/web/shell/test/context_menu_egtest.mm
+++ b/ios/web/shell/test/context_menu_egtest.mm
@@ -32,7 +32,8 @@
 @implementation ContextMenuTestCase
 
 // Tests context menu appears on a regular link.
-// TODO(crbug.com/1421691): Test is flaky on iPad simulator. Re-enable the test.
+// TODO(crbug.com/40896394): Test is flaky on iPad simulator. Re-enable the
+// test.
 #if TARGET_OS_SIMULATOR
 #define MAYBE_testContextMenu FLAKY_testContextMenu
 #else
diff --git a/ios/web/shell/test/page_state_egtest.mm b/ios/web/shell/test/page_state_egtest.mm
index 77911895..7332643 100644
--- a/ios/web/shell/test/page_state_egtest.mm
+++ b/ios/web/shell/test/page_state_egtest.mm
@@ -68,7 +68,7 @@
 // Tests that page scroll position of a page is restored upon returning to the
 // page via the back/forward buttons.
 // grey_scrollInDirection scrolls incorrect distance on iOS 13.
-// TODO(crbug.com/983144): Enable this test on iOS 13.
+// TODO(crbug.com/41470294): Enable this test on iOS 13.
 - (void)DISABLED_testScrollPositionRestoring {
   // Scroll the first page and verify the offset.
   ScrollLongPageToTop(self.testServer->GetURL(kLongPage1));
diff --git a/ios/web/web_state/error_page_inttest.mm b/ios/web/web_state/error_page_inttest.mm
index e244d15..4ff324a 100644
--- a/ios/web/web_state/error_page_inttest.mm
+++ b/ios/web/web_state/error_page_inttest.mm
@@ -305,7 +305,7 @@
 // Sucessfully loads the page, then loads the URL which fails to load, then
 // sucessfully goes back to the first page and goes forward to error page.
 // Back-forward navigations are renderer-initiated.
-// TODO(crbug.com/867927): Re-enable this test.
+// TODO(crbug.com/41404136): Re-enable this test.
 TEST_F(ErrorPageTest,
        DISABLED_RendererInitiatedGoBackFromErrorPageAndForwardToErrorPage) {
   // First page loads sucessfully.
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index 215c1e6..f3565e2a 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -484,7 +484,7 @@
   _webStateImpl = nullptr;
 
   DCHECK(!self.webView);
-  // TODO(crbug.com/662860): Don't set the delegate to nil.
+  // TODO(crbug.com/41284914): Don't set the delegate to nil.
   [_containerView setDelegate:nil];
   _touchTrackingRecognizer.touchTrackingDelegate = nil;
   [[_webViewProxy scrollViewProxy] removeObserver:self];
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm
index 09db6ce..4924a446 100644
--- a/ios/web/web_state/ui/crw_web_controller_unittest.mm
+++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -1170,7 +1170,7 @@
 }
 
 // Tests that window.close closes the web state.
-// TODO(crbug.com/1307043): Flaky test.
+// TODO(crbug.com/40218609): Flaky test.
 TEST_F(WindowOpenByDomTest, CloseWindow) {
   delegate_.allow_popups(opener_url_);
   ASSERT_NSEQ(@"[object Window]", OpenWindowByDom());
diff --git a/ios/web/web_state/web_state_unittest.mm b/ios/web/web_state/web_state_unittest.mm
index 5039a735..f66db1d5 100644
--- a/ios/web/web_state/web_state_unittest.mm
+++ b/ios/web/web_state/web_state_unittest.mm
@@ -492,7 +492,7 @@
   EXPECT_TRUE(navigation_manager->CanGoForward());
 
   // Now wait until the last committed item is fully loaded.
-  // TODO(crbug.com/996544) On Xcode 11 beta 6 this became very slow.  This
+  // TODO(crbug.com/41477584) On Xcode 11 beta 6 this became very slow.  This
   // appears to only affect simulator, and will hopefully be fixed in a future
   // Xcode release.  Revert this to `kWaitForPageLoadTimeout` alone when fixed.
   EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForPageLoadTimeout * 7, ^{
diff --git a/ios/web_view/internal/cwv_web_view.mm b/ios/web_view/internal/cwv_web_view.mm
index 8c9a10b..d271663 100644
--- a/ios/web_view/internal/cwv_web_view.mm
+++ b/ios/web_view/internal/cwv_web_view.mm
@@ -726,7 +726,7 @@
   [self updateNavigationAvailability];
   [self updateCurrentURLs];
 
-  // TODO(crbug.com/898357): Remove this once crbug.com/898357 is fixed.
+  // TODO(crbug.com/41422373): Remove this once crbug.com/898357 is fixed.
   [self updateVisibleSSLStatus];
 
   if (navigation->HasCommitted() && !navigation->IsSameDocument() &&
diff --git a/ios/web_view/internal/web_view_message_handler_java_script_feature.mm b/ios/web_view/internal/web_view_message_handler_java_script_feature.mm
index fc5d4be..3880d43 100644
--- a/ios/web_view/internal/web_view_message_handler_java_script_feature.mm
+++ b/ios/web_view/internal/web_view_message_handler_java_script_feature.mm
@@ -88,7 +88,7 @@
 
   // Pass messages from the non-static instances to the static instance during
   // transition.
-  // TODO(crbug.com/1426917): Remove static instance of feature.
+  // TODO(crbug.com/40899585): Remove static instance of feature.
   WebViewMessageHandlerJavaScriptFeature* static_instance =
       WebViewMessageHandlerJavaScriptFeature::GetInstance();
   if (this != static_instance) {
diff --git a/ios/web_view/public/cwv_preferences.h b/ios/web_view/public/cwv_preferences.h
index 8f6f8f5..65d6376 100644
--- a/ios/web_view/public/cwv_preferences.h
+++ b/ios/web_view/public/cwv_preferences.h
@@ -38,8 +38,8 @@
 // |YES|. When it is NO, it doesn't ask if you want to save passwords but will
 // continue to fill passwords.
 //
-// TODO(crbug.com/905221): Preference should also control autofill behavior for
-// the passwords.
+// TODO(crbug.com/40602365): Preference should also control autofill behavior
+// for the passwords.
 @property(nonatomic, assign, getter=isPasswordAutofillEnabled)
     BOOL passwordAutofillEnabled;
 
diff --git a/ios/web_view/shell/test/shell_egtest.mm b/ios/web_view/shell/test/shell_egtest.mm
index 99adb6f0..3039a40 100644
--- a/ios/web_view/shell/test/shell_egtest.mm
+++ b/ios/web_view/shell/test/shell_egtest.mm
@@ -46,7 +46,7 @@
 // shown, since this isn't a case a user would encounter (i.e. they would
 // dismiss the alert first).
 + (NSArray*)testInvocations {
-  // TODO(crbug.com/654085): Simply skipping all tests isn't the best way to
+  // TODO(crbug.com/41279721): Simply skipping all tests isn't the best way to
   // handle this, it would be better to have something that is more obvious
   // on the bots that this is wrong, without making it look like test flake.
   NSError* error = nil;
diff --git a/ios_internal b/ios_internal
index 7414643..31db9b5 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit 7414643e72f711bd1d0e4e20a0de078a26b791d1
+Subproject commit 31db9b52cb0b5f645f5f7cce78e3cd4863d81d4c
diff --git a/media/base/android/android_util.h b/media/base/android/android_util.h
index 9098e2e..dd6be3c 100644
--- a/media/base/android/android_util.h
+++ b/media/base/android/android_util.h
@@ -11,7 +11,7 @@
 
 namespace media {
 
-// TODO(crbug.com/765862): Remove the type. Use ScopedJavaGlobalRef directly.
+// TODO(crbug.com/40540372): Remove the type. Use ScopedJavaGlobalRef directly.
 using JavaObjectPtr =
     std::unique_ptr<base::android::ScopedJavaGlobalRef<jobject>>;
 
diff --git a/media/base/decoder.h b/media/base/decoder.h
index 5b2c5fe..605be87a 100644
--- a/media/base/decoder.h
+++ b/media/base/decoder.h
@@ -76,7 +76,7 @@
 
   // Returns true if the implementation supports decoding configs with
   // encryption.
-  // TODO(crbug.com/1099488): Sometimes it's not possible to give a definitive
+  // TODO(crbug.com/40137516): Sometimes it's not possible to give a definitive
   // yes or no answer unless more context is given. While this doesn't pose any
   // problems, it does allow incompatible decoders to pass the filtering step in
   // |DecoderSelector| potentially slowing down the selection process.
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index d42255f..a34ef37 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -399,7 +399,7 @@
              base::FEATURE_DISABLED_BY_DEFAULT);
 
 // Allows usage of OS-level (platform) audio encoders.
-// TODO(crbug.com/1522976): re-enable platform audio encoders on arm64 win when
+// TODO(crbug.com/41495931): re-enable platform audio encoders on arm64 win when
 //                          querying for OS support works as expected.
 BASE_FEATURE(kPlatformAudioEncoder,
              "PlatformAudioEncoder",
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc
index 7ac7a9e6..8b3a98c 100644
--- a/media/base/pipeline_impl.cc
+++ b/media/base/pipeline_impl.cc
@@ -691,7 +691,8 @@
   CheckPlaybackEnded();
 }
 
-// TODO(crbug/817089): Combine this functionality into renderer->GetMediaTime().
+// TODO(crbug.com/40564930): Combine this functionality into
+// renderer->GetMediaTime().
 base::TimeDelta PipelineImpl::RendererWrapper::GetCurrentTimestamp() {
   DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
   DCHECK(demuxer_);
diff --git a/media/capture/BUILD.gn b/media/capture/BUILD.gn
index 909087525..2aae6c8 100644
--- a/media/capture/BUILD.gn
+++ b/media/capture/BUILD.gn
@@ -348,6 +348,7 @@
     ]
     data_deps = [
       ":camera_hal_dispatcher_mojo_policy",
+      ":document_scanner_mojo_policy",
       ":jpeg_accelerator_mojo_policy",
       ":system_event_monitor_mojo_policy",
       ":video_capture_device_info_monitor_mojo_policy",
diff --git a/media/capture/video/apple/video_capture_device_avfoundation.mm b/media/capture/video/apple/video_capture_device_avfoundation.mm
index 7fdf66b..386b422 100644
--- a/media/capture/video/apple/video_capture_device_avfoundation.mm
+++ b/media/capture/video/apple/video_capture_device_avfoundation.mm
@@ -47,6 +47,10 @@
              "AVFoundationCaptureForwardSampleTimestamps",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+BASE_FEATURE(kAVFoundationCaptureSonomaStallCheck,
+             "AVFoundationCaptureSonomaStallCheck",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 namespace {
 
 // Logitech 4K Pro
@@ -81,6 +85,16 @@
   return std::nullopt;
 }
 
+bool ShouldRunStallCheck() {
+  // The stall check should not be needed on macOS 14 due to a redesign of the
+  // camera capture in macOS 14. It also interferes with the Presenter's Overlay
+  // feature that was introduced in macOS 14. See https://crbug.com/335210401.
+  if (@available(macOS 14.0, *)) {
+    return base::FeatureList::IsEnabled(kAVFoundationCaptureSonomaStallCheck);
+  }
+  return true;
+}
+
 constexpr size_t kPixelBufferPoolSize = 10;
 
 }  // anonymous namespace
@@ -553,7 +567,9 @@
     _capturedFirstFrame = false;
     _capturedFrameSinceLastStallCheck = NO;
   }
-  [self doStallCheck:0];
+  if (ShouldRunStallCheck()) {
+    [self doStallCheck:0];
+  }
   return YES;
 }
 
diff --git a/media/capture/video/fake_video_capture_device_factory.cc b/media/capture/video/fake_video_capture_device_factory.cc
index 9c9b383c..1fc15f33 100644
--- a/media/capture/video/fake_video_capture_device_factory.cc
+++ b/media/capture/video/fake_video_capture_device_factory.cc
@@ -5,6 +5,7 @@
 #include "media/capture/video/fake_video_capture_device_factory.h"
 
 #include <array>
+#include <string_view>
 
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
@@ -293,7 +294,7 @@
       FakeVideoCaptureDevice::DisplayMediaType::ANY;
 
   while (option_tokenizer.GetNext()) {
-    std::vector<base::StringPiece> param = base::SplitStringPiece(
+    std::vector<std::string_view> param = base::SplitStringPiece(
         option_tokenizer.token_piece(), "=", base::TRIM_WHITESPACE,
         base::SPLIT_WANT_NONEMPTY);
 
diff --git a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
index 0ef266a..527fefda 100644
--- a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
@@ -569,7 +569,7 @@
     return;
   }
 
-  // TODO(crbug.com/982172): ARC++ may adjust the size of the buffer due to
+  // TODO(crbug.com/41469754): ARC++ may adjust the size of the buffer due to
   // allocator constraints, but the VDA API does not provide a way for it to
   // communicate the actual buffer size. If we are importing, make sure that the
   // actual buffer size is coherent with what we expect, and adjust our size if
@@ -2592,7 +2592,7 @@
   DVLOGF(4) << "ip_buffer_index=" << ip_buffer_index
             << ", bitstream_buffer_id=" << bitstream_buffer_id;
   DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
-  // TODO(crbug.com/921825): Remove this workaround once reset callback is
+  // TODO(crbug.com/40609453): Remove this workaround once reset callback is
   // implemented.
   if (buffers_at_ip_.empty() ||
       buffers_at_ip_.front().first != bitstream_buffer_id ||
diff --git a/media/gpu/windows/d3d11_vp9_accelerator.h b/media/gpu/windows/d3d11_vp9_accelerator.h
index e96942a1..863af90 100644
--- a/media/gpu/windows/d3d11_vp9_accelerator.h
+++ b/media/gpu/windows/d3d11_vp9_accelerator.h
@@ -42,7 +42,7 @@
   // Helper methods for SubmitDecode
   bool BeginFrame(const D3D11VP9Picture& pic);
 
-  // TODO(crbug/890054): Use constref instead of scoped_refptr.
+  // TODO(crbug.com/40595783): Use constref instead of scoped_refptr.
   void CopyFrameParams(const D3D11VP9Picture& pic,
                        DXVA_PicParams_VP9* pic_params);
   void CopyReferenceFrames(const D3D11VP9Picture& pic,
diff --git a/media/midi/midi_manager_win.cc b/media/midi/midi_manager_win.cc
index 06db323..493f523 100644
--- a/media/midi/midi_manager_win.cc
+++ b/media/midi/midi_manager_win.cc
@@ -253,7 +253,7 @@
   if (id == MM_MICROSOFT)
     return "Microsoft Corporation";
 
-  // TODO(crbug.com/472341): Support other manufacture IDs.
+  // TODO(crbug.com/41165639): Support other manufacture IDs.
   return "";
 }
 
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc
index d7c7925c1..0fd40bb 100644
--- a/media/renderers/paint_canvas_video_renderer.cc
+++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -1481,7 +1481,7 @@
     // accurate.
     // NOTE: The direct upload path is not supported on Android (see comment on
     // UploadVideoFrameToGLTexture()).
-    // TODO(crbug.com/1494365): Enable on Android.
+    // TODO(crbug.com/40075313): Enable on Android.
 #if !BUILDFLAG(IS_ANDROID)
     if ((media::IsOpaque(video_frame->format()) || premultiply_alpha) &&
         level == 0 &&
diff --git a/media/renderers/video_frame_rgba_to_yuva_converter.cc b/media/renderers/video_frame_rgba_to_yuva_converter.cc
index 2916b4d..3e86df8 100644
--- a/media/renderers/video_frame_rgba_to_yuva_converter.cc
+++ b/media/renderers/video_frame_rgba_to_yuva_converter.cc
@@ -189,7 +189,7 @@
       // `unpack_flip_y` should be set if the surface origin of the source
       // doesn't match that of the destination, which is created with
       // kTopLeft_GrSurfaceOrigin.
-      // TODO(crbug.com/1453515): If this codepath is used with destinations
+      // TODO(crbug.com/40271944): If this codepath is used with destinations
       // that are created with other surface origins, will need to generalize
       // this.
       bool unpack_flip_y = (src_surface_origin != kTopLeft_GrSurfaceOrigin);
diff --git a/media/renderers/video_frame_yuv_mailboxes_holder.cc b/media/renderers/video_frame_yuv_mailboxes_holder.cc
index 328d85b..f587b1f 100644
--- a/media/renderers/video_frame_yuv_mailboxes_holder.cc
+++ b/media/renderers/video_frame_yuv_mailboxes_holder.cc
@@ -176,7 +176,7 @@
     // RASTER_{READ, WRITE} usages should be included as these SharedImages are
     // both read and written via raster, but historically these usages were not
     // included. Currently in the process of adding with a killswitch.
-    // TODO(crbug.com/1524009): Remove this killswitch post-safe rollout.
+    // TODO(crbug.com/41496957): Remove this killswitch post-safe rollout.
     // NOTE: It is critical to specify that this raster usage is *only* over
     // GLES2 to the service side to ensure that the correct SharedImage backing
     // is created (see crbug.com/328472684).
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc
index b2f0452..dbf3b01c 100644
--- a/media/renderers/video_resource_updater.cc
+++ b/media/renderers/video_resource_updater.cc
@@ -245,7 +245,7 @@
         DCHECK_EQ(num_textures, 2u);
         // TODO(mcasas): Support other formats such as e.g. P012.
         si_formats[0] = viz::SinglePlaneFormat::kR_16;
-        // TODO(https://crbug.com/1233228): This needs to be
+        // TODO(crbug.com/40191425): This needs to be
         // gfx::BufferFormat::RG_1616.
 #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
         si_formats[1] = viz::SinglePlaneFormat::kRG_1616;
diff --git a/mojo/core/channel.h b/mojo/core/channel.h
index 9c8160da..c1c5c42 100644
--- a/mojo/core/channel.h
+++ b/mojo/core/channel.h
@@ -74,7 +74,7 @@
     enum class MessageType : uint16_t {
       // An old format normal message, that uses the LegacyHeader.
       // Only used on Android and ChromeOS.
-      // TODO(https://crbug.com/695645): remove legacy support when Arc++ has
+      // TODO(crbug.com/41303999): remove legacy support when Arc++ has
       // updated to Mojo with normal versioned messages.
       NORMAL_LEGACY = 0,
 #if BUILDFLAG(IS_IOS)
diff --git a/mojo/core/mojo_core_unittest.cc b/mojo/core/mojo_core_unittest.cc
index 106bb03..1a06a40 100644
--- a/mojo/core/mojo_core_unittest.cc
+++ b/mojo/core/mojo_core_unittest.cc
@@ -28,7 +28,7 @@
 
 namespace {
 
-// TODO(https://crbug.com/902135): Re-enable this on MSAN. Currently hangs
+// TODO(crbug.com/41424555): Re-enable this on MSAN. Currently hangs
 // because of an apparent deadlock in MSAN's fork() in multithreaded
 // environments.
 #if !defined(MEMORY_SANITIZER)
diff --git a/mojo/public/cpp/platform/platform_channel_endpoint.cc b/mojo/public/cpp/platform/platform_channel_endpoint.cc
index ce5bf44..e5662865 100644
--- a/mojo/public/cpp/platform/platform_channel_endpoint.cc
+++ b/mojo/public/cpp/platform/platform_channel_endpoint.cc
@@ -37,7 +37,7 @@
 
 #if BUILDFLAG(IS_ANDROID)
 // Leave room for any other descriptors defined in content for example.
-// TODO(https://crbug.com/676442): Consider changing base::GlobalDescriptors to
+// TODO(crbug.com/40499227): Consider changing base::GlobalDescriptors to
 // generate a key when setting the file descriptor.
 constexpr int kAndroidClientHandleDescriptor =
     base::GlobalDescriptors::kBaseDescriptor + 10000;
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 0692153..806769f 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -1419,7 +1419,7 @@
       ]
     }
 
-    # TODO(https://crbug.com/978854): This is a public config because
+    # TODO(crbug.com/41467965): This is a public config because
     # multi_threaded_cert_verifier.h depends on NSS. When the linked bug is
     # fixed, switch this to a non-public config, so NSS usage must be explicit
     # in the build.
@@ -3235,7 +3235,7 @@
 
 # !is_android && !is_win && !is_mac
 if (!is_ios) {
-  # TODO(crbug.com/594965): this should be converted to "app" template and
+  # TODO(crbug.com/40460932): this should be converted to "app" template and
   # enabled on iOS too.
   test("net_perftests") {
     sources = [
diff --git a/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java b/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java
index f4e9645..7df8a0e 100644
--- a/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java
+++ b/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java
@@ -1419,9 +1419,8 @@
 
     /**
      * Extracts NetID of Network on Lollipop and NetworkHandle (which is munged NetID) on
-     * Marshmallow and newer releases.
-     * TODO(crbug.com/1489183): Rename networkToNetId to something meaningful and update
-     * javadoc comment.
+     * Marshmallow and newer releases. TODO(crbug.com/40283930): Rename networkToNetId to something
+     * meaningful and update javadoc comment.
      */
     public static long networkToNetId(Network network) {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc
index 0f20772..1ff0997 100644
--- a/net/base/mime_util.cc
+++ b/net/base/mime_util.cc
@@ -244,7 +244,7 @@
     const char* extensions = mapping.extensions;
     for (;;) {
       size_t end_pos = strcspn(extensions, ",");
-      // The length check is required to prevent the StringPiece below from
+      // The length check is required to prevent the std::string_view below from
       // including uninitialized memory if ext is longer than extensions.
       if (end_pos == ext.size() &&
           base::EqualsCaseInsensitiveASCII(
diff --git a/net/base/registry_controlled_domains/registry_controlled_domain.cc b/net/base/registry_controlled_domains/registry_controlled_domain.cc
index b28cadc..315c88c 100644
--- a/net/base/registry_controlled_domains/registry_controlled_domain.cc
+++ b/net/base/registry_controlled_domains/registry_controlled_domain.cc
@@ -205,8 +205,9 @@
 }
 
 // Same as GetDomainAndRegistry, but returns the domain and registry as a
-// StringPiece that references the underlying string of the passed-in |gurl|.
-// TODO(pkalinnikov): Eliminate this helper by exposing StringPiece as the
+// std::string_view that references the underlying string of the passed-in
+// |gurl|.
+// TODO(pkalinnikov): Eliminate this helper by exposing std::string_view as the
 // interface type for all the APIs.
 std::string_view GetDomainAndRegistryAsStringPiece(
     std::string_view host,
diff --git a/net/base/schemeful_site.h b/net/base/schemeful_site.h
index dd2334a..c1e13a91 100644
--- a/net/base/schemeful_site.h
+++ b/net/base/schemeful_site.h
@@ -166,7 +166,7 @@
   friend class SiteForCookies;
 
   // Needed to create a bogus origin from a site.
-  // TODO(https://crbug.com/1148927): Give IsolationInfos empty origins instead,
+  // TODO(crbug.com/40157262): Give IsolationInfos empty origins instead,
   // in this case, and unfriend IsolationInfo.
   friend class IsolationInfo;
 
diff --git a/net/base/transport_info.h b/net/base/transport_info.h
index beccb481..ac48ebd 100644
--- a/net/base/transport_info.h
+++ b/net/base/transport_info.h
@@ -28,7 +28,7 @@
 };
 
 // Returns a string representation of the given transport type.
-// The returned StringPiece is static, has no lifetime restrictions.
+// The returned std::string_view is static, has no lifetime restrictions.
 NET_EXPORT std::string_view TransportTypeToString(TransportType type);
 
 // Describes a network transport.
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc
index ea3ea7c..66cac1d 100644
--- a/net/cert/cert_verify_proc_unittest.cc
+++ b/net/cert/cert_verify_proc_unittest.cc
@@ -1120,7 +1120,7 @@
 
  private:
   // Overwrites the AlgorithmIdentifier pointed to by |algorithm_sequence| with
-  // |algorithm|. Note this violates the constness of StringPiece.
+  // |algorithm|. Note this violates the constness of std::string_view.
   [[nodiscard]] static bool SetAlgorithmSequence(
       bssl::DigestAlgorithm algorithm,
       std::string_view* algorithm_sequence) {
@@ -2996,7 +2996,7 @@
 
 // Tries verifying a certificate chain that is missing an intermediate. The
 // intermediate is available via AIA.
-// TODO(crbug.com/860189): Failing on iOS
+// TODO(crbug.com/41399468): Failing on iOS
 #if BUILDFLAG(IS_IOS)
 #define MAYBE_IntermediateFromAia200Der DISABLED_IntermediateFromAia200Der
 #else
@@ -3054,7 +3054,7 @@
 // Tries verifying a certificate chain that is missing an intermediate. The
 // intermediate is available via AIA, however is served as a PEM file rather
 // than DER.
-// TODO(crbug.com/860189): Failing on iOS
+// TODO(crbug.com/41399468): Failing on iOS
 #if BUILDFLAG(IS_IOS)
 #define MAYBE_IntermediateFromAia200Pem DISABLED_IntermediateFromAia200Pem
 #else
@@ -3106,7 +3106,7 @@
 // This test is the same as IntermediateFromAia200Pem, but with a different
 // formatting on the PEM data.
 //
-// TODO(crbug.com/860189): Failing on iOS
+// TODO(crbug.com/41399468): Failing on iOS
 #if BUILDFLAG(IS_IOS)
 #define MAYBE_IntermediateFromAia200Pem2 DISABLED_IntermediateFromAia200Pem2
 #else
diff --git a/net/cert/internal/cert_issuer_source_aia.cc b/net/cert/internal/cert_issuer_source_aia.cc
index 2a268e7..d4901ddd 100644
--- a/net/cert/internal/cert_issuer_source_aia.cc
+++ b/net/cert/internal/cert_issuer_source_aia.cc
@@ -143,7 +143,7 @@
   //    certificates MUST be able to accept individual DER encoded
   //    certificates and SHOULD be able to accept "certs-only" CMS messages.
 
-  // TODO(https://crbug.com/870359): Some AIA responses are served as PEM, which
+  // TODO(crbug.com/41405652): Some AIA responses are served as PEM, which
   // is not part of RFC 5280's profile.
   return ParseCertFromDer(fetched_bytes, results) ||
          ParseCertsFromCms(fetched_bytes, results) ||
diff --git a/net/cert/internal/trust_store_nss_unittest.cc b/net/cert/internal/trust_store_nss_unittest.cc
index 994dbb3..e7d7c88f 100644
--- a/net/cert/internal/trust_store_nss_unittest.cc
+++ b/net/cert/internal/trust_store_nss_unittest.cc
@@ -932,7 +932,7 @@
   EXPECT_TRUE(HasTrust({system_root}, ExpectedTrustForLeaf()));
 }
 
-// TODO(https://crbug.com/980443): If the internal non-removable slot is
+// TODO(crbug.com/41468842): If the internal non-removable slot is
 // relevant on Chrome OS, add a test for allowing trust for certificates
 // stored on that slot.
 
diff --git a/net/cert/x509_util.h b/net/cert/x509_util.h
index 1fba5f64..30d18af0 100644
--- a/net/cert/x509_util.h
+++ b/net/cert/x509_util.h
@@ -142,7 +142,7 @@
     std::string_view data);
 
 // Overload with no definition, to disallow creating a CRYPTO_BUFFER from a
-// char* due to StringPiece implicit ctor.
+// char* due to std::string_view implicit ctor.
 NET_EXPORT bssl::UniquePtr<CRYPTO_BUFFER> CreateCryptoBuffer(
     const char* invalid_data);
 
@@ -156,7 +156,7 @@
 NET_EXPORT bool CryptoBufferEqual(const CRYPTO_BUFFER* a,
                                   const CRYPTO_BUFFER* b);
 
-// Returns a StringPiece pointing to the data in |buffer|.
+// Returns a std::string_view pointing to the data in |buffer|.
 NET_EXPORT std::string_view CryptoBufferAsStringPiece(
     const CRYPTO_BUFFER* buffer);
 
diff --git a/net/cert/x509_util_apple.cc b/net/cert/x509_util_apple.cc
index 5768b14..db64e88 100644
--- a/net/cert/x509_util_apple.cc
+++ b/net/cert/x509_util_apple.cc
@@ -150,7 +150,7 @@
         SecTrustCopyCertificateChain(trust));
   }
 
-// TODO(crbug.com/1426476): Remove code when it is no longer needed.
+// TODO(crbug.com/40899365): Remove code when it is no longer needed.
 #if (BUILDFLAG(IS_MAC) &&                                    \
      MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_VERSION_12_0) || \
     (BUILDFLAG(IS_IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_15_0)
diff --git a/net/dns/dns_config_service_win.cc b/net/dns/dns_config_service_win.cc
index 3595124..daa785c 100644
--- a/net/dns/dns_config_service_win.cc
+++ b/net/dns/dns_config_service_win.cc
@@ -27,7 +27,6 @@
 #include "base/sequence_checker.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
diff --git a/net/dns/dns_hosts.cc b/net/dns/dns_hosts.cc
index 5f10895..5093600d 100644
--- a/net/dns/dns_hosts.cc
+++ b/net/dns/dns_hosts.cc
@@ -5,13 +5,13 @@
 #include "net/dns/dns_hosts.h"
 
 #include <string>
+#include <string_view>
 #include <utility>
 
 #include "base/check.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/metrics/histogram_functions.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/trace_event/memory_usage_estimator.h"
 #include "build/build_config.h"
@@ -20,18 +20,16 @@
 #include "net/dns/dns_util.h"
 #include "url/url_canon.h"
 
-using base::StringPiece;
-
 namespace net {
 
 namespace {
 
 // Parses the contents of a hosts file.  Returns one token (IP or hostname) at
-// a time.  Doesn't copy anything; accepts the file as a StringPiece and
+// a time.  Doesn't copy anything; accepts the file as a std::string_view and
 // returns tokens as StringPieces.
 class HostsParser {
  public:
-  explicit HostsParser(const StringPiece& text, ParseHostsCommaMode comma_mode)
+  explicit HostsParser(std::string_view text, ParseHostsCommaMode comma_mode)
       : text_(text),
         data_(text.data()),
         end_(text.size()),
@@ -76,7 +74,8 @@
           SkipToken();
           size_t token_end = (pos_ == std::string::npos) ? end_ : pos_;
 
-          token_ = StringPiece(data_ + token_start, token_end - token_start);
+          token_ =
+              std::string_view(data_ + token_start, token_end - token_start);
           token_is_ip_ = next_is_ip;
 
           return true;
@@ -96,11 +95,11 @@
   // hostname (false).
   bool token_is_ip() { return token_is_ip_; }
 
-  // Returns the text of the last-parsed token as a StringPiece referencing
-  // the same underlying memory as the StringPiece passed to the constructor.
-  // Returns an empty StringPiece if no token has been parsed or the end of
-  // the input string has been reached.
-  const StringPiece& token() { return token_; }
+  // Returns the text of the last-parsed token as a std::string_view referencing
+  // the same underlying memory as the std::string_view passed to the
+  // constructor. Returns an empty std::string_view if no token has been parsed
+  // or the end of the input string has been reached.
+  std::string_view token() { return token_; }
 
  private:
   void SkipToken() {
@@ -125,12 +124,12 @@
     }
   }
 
-  const StringPiece text_;
+  const std::string_view text_;
   const char* data_;
   const size_t end_;
 
   size_t pos_ = 0;
-  StringPiece token_;
+  std::string_view token_;
   bool token_is_ip_ = false;
 
   const ParseHostsCommaMode comma_mode_;
@@ -141,13 +140,13 @@
                              ParseHostsCommaMode comma_mode) {
   CHECK(dns_hosts);
 
-  StringPiece ip_text;
+  std::string_view ip_text;
   IPAddress ip;
   AddressFamily family = ADDRESS_FAMILY_IPV4;
   HostsParser parser(contents, comma_mode);
   while (parser.Advance()) {
     if (parser.token_is_ip()) {
-      StringPiece new_ip_text = parser.token();
+      std::string_view new_ip_text = parser.token();
       // Some ad-blocking hosts files contain thousands of entries pointing to
       // the same IP address (usually 127.0.0.1).  Don't bother parsing the IP
       // again if it's the same as the one above it.
diff --git a/net/dns/host_resolver_cache.cc b/net/dns/host_resolver_cache.cc
index a448c9e..93032e14 100644
--- a/net/dns/host_resolver_cache.cc
+++ b/net/dns/host_resolver_cache.cc
@@ -307,8 +307,8 @@
                                &host_info);
 
   // For performance, when canonicalization can't canonicalize, minimize string
-  // copies and just reuse the input StringPiece. This optimization prevents
-  // easily reusing a MaybeCanoncalize util with similar code.
+  // copies and just reuse the input std::string_view. This optimization
+  // prevents easily reusing a MaybeCanoncalize util with similar code.
   std::string_view lookup_name = domain_name;
   if (host_info.family == url::CanonHostInfo::Family::NEUTRAL) {
     output.Complete();
diff --git a/net/dns/opt_record_rdata_unittest.cc b/net/dns/opt_record_rdata_unittest.cc
index e297fc1..c72f2684 100644
--- a/net/dns/opt_record_rdata_unittest.cc
+++ b/net/dns/opt_record_rdata_unittest.cc
@@ -57,7 +57,7 @@
 
   // Check elements
 
-  // Note: When passing string or StringPiece as argument, make sure to
+  // Note: When passing string or std::string_view as argument, make sure to
   // construct arguments with length. Otherwise, strings containing a '\0'
   // character will be truncated.
   // https://crbug.com/1348679
diff --git a/net/http/BUILD.gn b/net/http/BUILD.gn
index 4cf3c466..0b55f57 100644
--- a/net/http/BUILD.gn
+++ b/net/http/BUILD.gn
@@ -55,7 +55,7 @@
   ]
 
   # All possible inputs to ensure correctness when files change.
-  # TODO(crbug/1508893): Use {{source_name_part}}_pins.json.
+  # TODO(crbug.com/41481512): Use {{source_name_part}}_pins.json.
   inputs = [
              "transport_security_state_static_unittest1_pins.json",
              "transport_security_state_static_unittest2_pins.json",
diff --git a/net/http/http_auth_challenge_tokenizer.cc b/net/http/http_auth_challenge_tokenizer.cc
index 4fd48aad..31b9e64 100644
--- a/net/http/http_auth_challenge_tokenizer.cc
+++ b/net/http/http_auth_challenge_tokenizer.cc
@@ -4,7 +4,8 @@
 
 #include "net/http/http_auth_challenge_tokenizer.h"
 
-#include "base/strings/string_piece.h"
+#include <string_view>
+
 #include "base/strings/string_tokenizer.h"
 #include "base/strings/string_util.h"
 
diff --git a/net/http/http_auth_handler_digest.cc b/net/http/http_auth_handler_digest.cc
index 4fca79f..6a00a99d 100644
--- a/net/http/http_auth_handler_digest.cc
+++ b/net/http/http_auth_handler_digest.cc
@@ -278,7 +278,7 @@
     // auth is the only supported qop, and all other values are ignored.
     //
     // TODO(https://crbug.com/820198): Remove this copy when
-    // HttpUtil::ValuesIterator can take a StringPiece.
+    // HttpUtil::ValuesIterator can take a std::string_view.
     std::string value_str(value);
     HttpUtil::ValuesIterator qop_values(value_str.begin(), value_str.end(),
                                         ',');
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 704ff5e..6a861c2d 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -25195,7 +25195,7 @@
 
       // The retry succeeds.
       //
-      // TODO(https://crbug.com/950705): If |reject_error| is
+      // TODO(crbug.com/41451775): If |reject_error| is
       // ERR_EARLY_DATA_REJECTED, the retry should happen over the same socket.
       MockWrite data2_writes[] = {
           request.method == "POST"
diff --git a/net/http/http_util.cc b/net/http/http_util.cc
index 89dd0b7..d2483a1 100644
--- a/net/http/http_util.cc
+++ b/net/http/http_util.cc
@@ -429,7 +429,7 @@
       // one.
       "strict-transport-security"};
 
-  for (const std::string_view& header : kNonCoalescingHeaders) {
+  for (std::string_view header : kNonCoalescingHeaders) {
     if (base::EqualsCaseInsensitiveASCII(name, header)) {
       return true;
     }
diff --git a/net/quic/crypto/proof_verifier_chromium_test.cc b/net/quic/crypto/proof_verifier_chromium_test.cc
index d78894f..b096d70b 100644
--- a/net/quic/crypto/proof_verifier_chromium_test.cc
+++ b/net/quic/crypto/proof_verifier_chromium_test.cc
@@ -5,11 +5,11 @@
 #include "net/quic/crypto/proof_verifier_chromium.h"
 
 #include <memory>
+#include <string_view>
 #include <utility>
 
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
-#include "base/strings/string_piece.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "net/base/completion_once_callback.h"
diff --git a/net/quic/dedicated_web_transport_http3_client_test.cc b/net/quic/dedicated_web_transport_http3_client_test.cc
index dee856f63af..81b04f8 100644
--- a/net/quic/dedicated_web_transport_http3_client_test.cc
+++ b/net/quic/dedicated_web_transport_http3_client_test.cc
@@ -205,7 +205,7 @@
   Run();
 }
 
-// TODO(https://crbug.com/1288036): The test is flaky on Mac and iOS.
+// TODO(crbug.com/40816637): The test is flaky on Mac and iOS.
 #if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_MAC)
 #define MAYBE_CloseTimeout DISABLED_CloseTimeout
 #else
diff --git a/net/quic/quic_chromium_client_session_test.cc b/net/quic/quic_chromium_client_session_test.cc
index 6607aad..3d0bb9d 100644
--- a/net/quic/quic_chromium_client_session_test.cc
+++ b/net/quic/quic_chromium_client_session_test.cc
@@ -159,8 +159,9 @@
 
  protected:
   void Initialize() {
-    if (socket_data_)
+    if (socket_data_) {
       socket_factory_.AddSocketDataProvider(socket_data_.get());
+    }
     std::unique_ptr<DatagramClientSocket> socket =
         socket_factory_.CreateDatagramClientSocket(
             DatagramSocket::DEFAULT_BIND, NetLog::Get(), NetLogSource());
@@ -215,8 +216,9 @@
 
   void TearDown() override {
     if (session_) {
-      if (connectivity_monitor_)
+      if (connectivity_monitor_) {
         session_->RemoveConnectivityObserver(connectivity_monitor_.get());
+      }
       session_->CloseSessionOnError(
           ERR_ABORTED, quic::QUIC_INTERNAL_ERROR,
           quic::ConnectionCloseBehavior::SILENT_CLOSE);
@@ -1522,10 +1524,13 @@
   MockQuicData quic_data2(version_);
   client_maker_.set_connection_id(cid_on_new_path);
   quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
-  quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeAckAndPingPacket(
-                                       packet_num++,
+  quic_data2.AddWrite(SYNCHRONOUS,
+                      client_maker_.Packet(packet_num++)
+                          .AddAckFrame(/*first_received=*/1,
                                        /*largest_received=*/peer_packet_num - 1,
-                                       /*smallest_received=*/1));
+                                       /*smallest_received=*/1)
+                          .AddPingFrame()
+                          .Build());
   quic_data2.AddWrite(
       SYNCHRONOUS,
       client_maker_.MakeDataPacket(
@@ -1601,11 +1606,13 @@
   for (size_t i = 0; i < kMaxReadersPerQuicSession - 1; ++i) {
     MockQuicData quic_data2(version_);
     client_maker_.set_connection_id(next_cid);
-    quic_data2.AddWrite(SYNCHRONOUS,
-                        client_maker_.MakeAckAndPingPacket(
-                            packet_num++,
-                            /*largest_received=*/peer_packet_num - 1,
-                            /*smallest_received=*/1));
+    quic_data2.AddWrite(
+        SYNCHRONOUS, client_maker_.Packet(packet_num++)
+                         .AddAckFrame(/*first_received=*/1,
+                                      /*largest_received=*/peer_packet_num - 1,
+                                      /*smallest_received=*/1)
+                         .AddPingFrame()
+                         .Build());
     quic_data2.AddRead(ASYNC, ERR_IO_PENDING);
     quic_data2.AddWrite(ASYNC,
                         client_maker_.MakeRetireConnectionIdPacket(
@@ -1718,11 +1725,13 @@
 
   MockQuicData quic_data2(version_);
   client_maker_.set_connection_id(cid_on_new_path);
-  quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeAckAndPingPacket(
-                                       packet_num++,
-
+  quic_data2.AddWrite(SYNCHRONOUS,
+                      client_maker_.Packet(packet_num++)
+                          .AddAckFrame(/*first_received=*/1,
                                        /*largest_received=*/peer_packet_num - 1,
-                                       /*smallest_received=*/1));
+                                       /*smallest_received=*/1)
+                          .AddPingFrame()
+                          .Build());
   quic_data2.AddRead(ASYNC, ERR_IO_PENDING);
   quic_data2.AddRead(ASYNC, server_maker_.MakePingPacket(1));
   quic_data2.AddRead(ASYNC, ERR_IO_PENDING);
diff --git a/net/quic/quic_session_pool_test.cc b/net/quic/quic_session_pool_test.cc
index e621c79f5..793aadb 100644
--- a/net/quic/quic_session_pool_test.cc
+++ b/net/quic/quic_session_pool_test.cc
@@ -2667,9 +2667,13 @@
   quic_data2.AddWrite(ASYNC,
                       client_maker_.MakeCombinedRetransmissionPacket(
                           /*original_packet_numbers=*/{1, 2}, packet_num++));
-  quic_data2.AddWrite(
-      SYNCHRONOUS,
-      client_maker_.MakeAckAndRetireConnectionIdPacket(packet_num++, 2, 1, 0u));
+  quic_data2.AddWrite(SYNCHRONOUS,
+                      client_maker_.Packet(packet_num++)
+                          .AddAckFrame(/*first_received=*/1,
+                                       /*largest_received=*/2,
+                                       /*smallest_received=*/1)
+                          .AddRetireConnectionIdFrame(/*sequence_number=*/0u)
+                          .Build());
   quic_data2.AddWrite(SYNCHRONOUS,
                       client_maker_.MakeDataPacket(
                           packet_num++, GetQpackDecoderStreamId(), false,
@@ -4228,10 +4232,12 @@
       ASYNC, ConstructOkResponsePacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false));
   quic_data2.AddReadPause();
-  quic_data2.AddWrite(
-      ASYNC, client_maker_.MakeAckAndPingPacket(4,
-                                                /*largest_received=*/2,
-                                                /*smallest_received=*/1));
+  quic_data2.AddWrite(ASYNC, client_maker_.Packet(4)
+                                 .AddAckFrame(/*first_received=*/1,
+                                              /*largest_received=*/2,
+                                              /*smallest_received=*/1)
+                                 .AddPingFrame()
+                                 .Build());
   quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
                                        5, /*sequence_number=*/0u));
   quic_data2.AddRead(ASYNC, server_maker_.MakeAckPacket(3, 5, 1));
@@ -5473,10 +5479,12 @@
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false));
   quic_data2.AddReadPauseForever();
   quic_data2.AddWrite(SYNCHRONOUS,
-                      client_maker_.MakeAckAndRetireConnectionIdPacket(
-                          packet_number++,
-                          /*largest_received=*/2,
-                          /*smallest_received=*/1, /*sequence_number=*/0u));
+                      client_maker_.Packet(packet_number++)
+                          .AddAckFrame(/*first_received=*/1,
+                                       /*largest_received=*/2,
+                                       /*smallest_received=*/1)
+                          .AddRetireConnectionIdFrame(/*sequence_number=*/0u)
+                          .Build());
   quic_data2.AddWrite(
       SYNCHRONOUS,
       client_maker_.MakeDataPacket(
@@ -5680,8 +5688,12 @@
                           client_maker_.MakePingPacket(packet_number++));
     } else if (i != 4) {
       quic_data2.AddWrite(SYNCHRONOUS,
-                          client_maker_.MakeAckAndRetireConnectionIdPacket(
-                              packet_number++, 1 + 2 * i, 1 + 2 * i, i));
+                          client_maker_.Packet(packet_number++)
+                              .AddAckFrame(/*first_received=*/1,
+                                           /*largest_received=*/1 + 2 * i,
+                                           /*smallest_received=*/1 + 2 * i)
+                              .AddRetireConnectionIdFrame(/*sequence_number=*/i)
+                              .Build());
       quic_data2.AddWrite(SYNCHRONOUS,
                           client_maker_.MakePingPacket(packet_number++));
     }
@@ -5822,8 +5834,12 @@
   quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(2));
   quic_data2.AddReadPauseForever();
   // Ping packet to send after migration is completed.
-  quic_data2.AddWrite(
-      ASYNC, client_maker_.MakeAckAndPingPacket(packet_number++, 2, 1));
+  quic_data2.AddWrite(ASYNC, client_maker_.Packet(packet_number++)
+                                 .AddAckFrame(/*first_received=*/1,
+                                              /*largest_received=*/2,
+                                              /*smallest_received=*/1)
+                                 .AddPingFrame()
+                                 .Build());
 
   quic_data2.AddWrite(SYNCHRONOUS,
                       client_maker_.MakeRetireConnectionIdPacket(
@@ -6960,10 +6976,15 @@
   quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
                                        packet_num++,
                                        /*sequence_number=*/0u));
-  quic_data2.AddRead(ASYNC, server_maker_.MakeAckAndNewConnectionIdPacket(
-                                peer_packet_num++, packet_num - 1, 1u, cid2,
-                                /*sequence_number=*/2u,
-                                /*retire_prior_to=*/1u));
+  quic_data2.AddRead(ASYNC,
+                     server_maker_.Packet(peer_packet_num++)
+                         .AddAckFrame(1, packet_num - 1, 1u)
+                         .AddNewConnectionIdFrame(
+                             cid2,
+                             /*sequence_number=*/2u,
+                             /*retire_prior_to=*/1u,
+                             quic::QuicUtils::GenerateStatelessResetToken(cid2))
+                         .Build());
   quic_data2.AddRead(ASYNC,
                      ConstructOkResponsePacket(
                          peer_packet_num++,
@@ -10527,11 +10548,12 @@
                                                      /*retire_prior_to=*/1u));
   ++packet_num;  // Probing packet on default network encounters write error.
   alternate_socket_data.AddWrite(
-      ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
-                 packet_num++,
-                 /*largest_received=*/peer_packet_num - 1,
-                 /*smallest_received=*/1,
-                 /*sequence_number=*/2u));
+      ASYNC, client_maker_.Packet(packet_num++)
+                 .AddAckFrame(/*first_received=*/1,
+                              /*largest_received=*/peer_packet_num - 1,
+                              /*smallest_received=*/1)
+                 .AddRetireConnectionIdFrame(/*sequence_number=*/2u)
+                 .Build());
   alternate_socket_data.AddReadPause();
   alternate_socket_data.AddRead(
       ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid3,
@@ -10539,11 +10561,12 @@
                                                      /*retire_prior_to=*/1u));
   ++packet_num;  // Probing packet on default network encounters write error.
   alternate_socket_data.AddWrite(
-      ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
-                 packet_num++,
-                 /*largest_received=*/peer_packet_num - 1,
-                 /*smallest_received=*/1,
-                 /*sequence_number=*/3u));
+      ASYNC, client_maker_.Packet(packet_num++)
+                 .AddAckFrame(/*first_received=*/1,
+                              /*largest_received=*/peer_packet_num - 1,
+                              /*smallest_received=*/1)
+                 .AddRetireConnectionIdFrame(/*sequence_number=*/3u)
+                 .Build());
   alternate_socket_data.AddReadPause();
   alternate_socket_data.AddRead(
       ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid4,
@@ -10551,11 +10574,12 @@
                                                      /*retire_prior_to=*/1u));
   ++packet_num;  // Probing packet on default network encounters write error.
   alternate_socket_data.AddWrite(
-      ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
-                 packet_num++,
-                 /*largest_received=*/peer_packet_num - 1,
-                 /*smallest_received=*/1,
-                 /*sequence_number=*/4u));
+      ASYNC, client_maker_.Packet(packet_num++)
+                 .AddAckFrame(/*first_received=*/1,
+                              /*largest_received=*/peer_packet_num - 1,
+                              /*smallest_received=*/1)
+                 .AddRetireConnectionIdFrame(/*sequence_number=*/4u)
+                 .Build());
   alternate_socket_data.AddReadPause();
   alternate_socket_data.AddRead(
       ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid5,
@@ -10563,11 +10587,12 @@
                                                      /*retire_prior_to=*/1u));
   ++packet_num;  // Probing packet on default network encounters write error.
   alternate_socket_data.AddWrite(
-      ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
-                 packet_num++,
-                 /*largest_received=*/peer_packet_num - 1,
-                 /*smallest_received=*/1,
-                 /*sequence_number=*/5u));
+      ASYNC, client_maker_.Packet(packet_num++)
+                 .AddAckFrame(/*first_received=*/1,
+                              /*largest_received=*/peer_packet_num - 1,
+                              /*smallest_received=*/1)
+                 .AddRetireConnectionIdFrame(/*sequence_number=*/5u)
+                 .Build());
   alternate_socket_data.AddReadPause();
   alternate_socket_data.AddRead(
       ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid6,
@@ -10575,11 +10600,12 @@
                                                      /*retire_prior_to=*/1u));
   ++packet_num;  // Probing packet on default network encounters write error.
   alternate_socket_data.AddWrite(
-      ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
-                 packet_num++,
-                 /*largest_received=*/peer_packet_num - 1,
-                 /*smallest_received=*/1,
-                 /*sequence_number=*/6u));
+      ASYNC, client_maker_.Packet(packet_num++)
+                 .AddAckFrame(/*first_received=*/1,
+                              /*largest_received=*/peer_packet_num - 1,
+                              /*smallest_received=*/1)
+                 .AddRetireConnectionIdFrame(/*sequence_number=*/6u)
+                 .Build());
   alternate_socket_data.AddReadPause();
   alternate_socket_data.AddRead(
       ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid7,
@@ -10736,11 +10762,12 @@
                                                      /*retire_prior_to=*/1u));
   ++packet_num;  // Probing packet on default network encounters write error.
   alternate_socket_data.AddWrite(
-      ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
-                 packet_num++,
-                 /*largest_received=*/peer_packet_num - 1,
-                 /*smallest_received=*/1,
-                 /*sequence_number=*/2u));
+      ASYNC, client_maker_.Packet(packet_num++)
+                 .AddAckFrame(/*first_received=*/1,
+                              /*largest_received=*/peer_packet_num - 1,
+                              /*smallest_received=*/1)
+                 .AddRetireConnectionIdFrame(/*sequence_number=*/2u)
+                 .Build());
   alternate_socket_data.AddReadPause();
   alternate_socket_data.AddRead(
       ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid3,
@@ -10748,11 +10775,12 @@
                                                      /*retire_prior_to=*/1u));
   ++packet_num;  // Probing packet on default network encounters write error.
   alternate_socket_data.AddWrite(
-      ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
-                 packet_num++,
-                 /*largest_received=*/peer_packet_num - 1,
-                 /*smallest_received=*/1,
-                 /*sequence_number=*/3u));
+      ASYNC, client_maker_.Packet(packet_num++)
+                 .AddAckFrame(/*first_received=*/1,
+                              /*largest_received=*/peer_packet_num - 1,
+                              /*smallest_received=*/1)
+                 .AddRetireConnectionIdFrame(/*sequence_number=*/3u)
+                 .Build());
   alternate_socket_data.AddReadPause();
   alternate_socket_data.AddRead(
       ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid4,
@@ -10760,11 +10788,12 @@
                                                      /*retire_prior_to=*/1u));
   ++packet_num;  // Probing packet on default network encounters write error.
   alternate_socket_data.AddWrite(
-      ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
-                 packet_num++,
-                 /*largest_received=*/peer_packet_num - 1,
-                 /*smallest_received=*/1,
-                 /*sequence_number=*/4u));
+      ASYNC, client_maker_.Packet(packet_num++)
+                 .AddAckFrame(/*first_received=*/1,
+                              /*largest_received=*/peer_packet_num - 1,
+                              /*smallest_received=*/1)
+                 .AddRetireConnectionIdFrame(/*sequence_number=*/4u)
+                 .Build());
   alternate_socket_data.AddReadPause();
   alternate_socket_data.AddRead(
       ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid5,
diff --git a/net/quic/quic_test_packet_maker.cc b/net/quic/quic_test_packet_maker.cc
index e78a30b..28dc8ce 100644
--- a/net/quic/quic_test_packet_maker.cc
+++ b/net/quic/quic_test_packet_maker.cc
@@ -7,8 +7,10 @@
 #include <list>
 #include <utility>
 
+#include "base/functional/callback.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/test/bind.h"
 #include "net/base/features.h"
 #include "net/quic/mock_crypto_client_stream.h"
 #include "net/quic/quic_chromium_client_session.h"
@@ -100,9 +102,26 @@
   return new_frames;
 }
 
-
 }  // namespace
 
+QuicTestPacketMaker::ConnectionState::ConnectionState() = default;
+
+QuicTestPacketMaker::ConnectionState::~ConnectionState() {
+  for (auto& kv : saved_frames) {
+    quic::DeleteFrames(&(kv.second));
+  }
+}
+
+std::string_view QuicTestPacketMaker::ConnectionState::SaveStreamData(
+    std::string_view data) {
+  saved_stream_data.push_back(std::make_unique<std::string>(data));
+  return *saved_stream_data.back();
+}
+
+void QuicTestPacketMaker::ConnectionState::Reset() {
+  stream_offsets.clear();
+}
+
 QuicTestPacketMaker::QuicTestPacketMaker(quic::ParsedQuicVersion version,
                                          quic::QuicConnectionId connection_id,
                                          const quic::QuicClock* clock,
@@ -111,7 +130,6 @@
                                          bool client_priority_uses_incremental,
                                          bool use_priority_header)
     : version_(version),
-      connection_id_(connection_id),
       clock_(clock),
       host_(host),
       qpack_encoder_(&decoder_stream_error_delegate_,
@@ -123,323 +141,246 @@
   DCHECK(!(perspective_ == quic::Perspective::IS_SERVER &&
            client_priority_uses_incremental_));
 
+  set_connection_id(connection_id);
   qpack_encoder_.set_qpack_stream_sender_delegate(
       &encoder_stream_sender_delegate_);
 }
 
 QuicTestPacketMaker::~QuicTestPacketMaker() {
-  for (auto& kv : saved_frames_) {
-    quic::DeleteFrames(&(kv.second));
-  }
+  CHECK(!builder_) << "QuicTestPacketMacker destroyed with unfinished packet "
+                      "build operation";
 }
 
 void QuicTestPacketMaker::set_hostname(const std::string& host) {
   host_.assign(host);
 }
 
+QuicTestPacketBuilder& QuicTestPacketMaker::Packet(uint64_t packet_number) {
+  CHECK(!builder_);
+  builder_ = std::make_unique<QuicTestPacketBuilder>(packet_number, this,
+                                                     &connection_state_);
+  return *builder_.get();
+}
+
 std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeConnectivityProbingPacket(uint64_t num) {
-  InitializeHeader(num);
-
+QuicTestPacketMaker::MakeConnectivityProbingPacket(uint64_t packet_number) {
+  auto& builder = Packet(packet_number);
   if (perspective_ == quic::Perspective::IS_CLIENT) {
-    AddQuicPathChallengeFrame();
+    builder.AddPathChallengeFrame();
   } else {
-    AddQuicPathResponseFrame();
+    builder.AddPathResponseFrame();
   }
-
-  AddQuicPaddingFrame();
-
-  return BuildPacket();
+  return builder.AddPaddingFrame().Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakePingPacket(
-    uint64_t num) {
-  InitializeHeader(num);
-  AddQuicPingFrame();
-  return BuildPacket();
+    uint64_t packet_number) {
+  return Packet(packet_number).AddPingFrame().Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeRetireConnectionIdPacket(uint64_t num,
+QuicTestPacketMaker::MakeRetireConnectionIdPacket(uint64_t packet_number,
                                                   uint64_t sequence_number) {
-  InitializeHeader(num);
-  AddQuicRetireConnectionIdFrame(sequence_number);
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddRetireConnectionIdFrame(sequence_number)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeNewConnectionIdPacket(
-    uint64_t num,
+    uint64_t packet_number,
     const quic::QuicConnectionId& cid,
     uint64_t sequence_number,
     uint64_t retire_prior_to) {
-  InitializeHeader(num);
-  AddQuicNewConnectionIdFrame(
-      cid, sequence_number, retire_prior_to,
-      quic::QuicUtils::GenerateStatelessResetToken(cid));
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddNewConnectionIdFrame(
+          cid, sequence_number, retire_prior_to,
+          quic::QuicUtils::GenerateStatelessResetToken(cid))
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeAckAndNewConnectionIdPacket(
-    uint64_t num,
-    uint64_t largest_received,
-    uint64_t smallest_received,
-    const quic::QuicConnectionId& cid,
-    uint64_t sequence_number,
-    uint64_t retire_prior_to) {
-  InitializeHeader(num);
-  AddQuicAckFrame(largest_received, smallest_received);
-  AddQuicNewConnectionIdFrame(
-      cid, sequence_number, retire_prior_to,
-      quic::QuicUtils::GenerateStatelessResetToken(cid));
-  return BuildPacket();
-}
-
-std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeDummyCHLOPacket(uint64_t packet_num) {
+QuicTestPacketMaker::MakeDummyCHLOPacket(uint64_t packet_number) {
   SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
-  InitializeHeader(packet_num);
+
+  auto& builder = Packet(packet_number);
 
   quic::CryptoHandshakeMessage message =
       MockCryptoClientStream::GetDummyCHLOMessage();
   const quic::QuicData& data = message.GetSerialized();
 
-  AddQuicCryptoFrame(quic::ENCRYPTION_INITIAL, 0, data.length());
+  builder.AddCryptoFrame(quic::ENCRYPTION_INITIAL, 0, data);
 
-  data_producer_ = std::make_unique<quic::test::SimpleDataProducer>();
-  data_producer_->SaveCryptoData(quic::ENCRYPTION_INITIAL, 0,
-                                 data.AsStringPiece());
-
-  AddQuicPaddingFrame();
-
-  return BuildPacket();
-}
-
-std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeAckAndPingPacket(uint64_t num,
-                                          uint64_t largest_received,
-                                          uint64_t smallest_received) {
-  InitializeHeader(num);
-  AddQuicAckFrame(largest_received, smallest_received);
-  AddQuicPingFrame();
-  return BuildPacket();
-}
-
-std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeAckAndRetireConnectionIdPacket(
-    uint64_t num,
-    uint64_t largest_received,
-    uint64_t smallest_received,
-    uint64_t sequence_number) {
-  InitializeHeader(num);
-  AddQuicAckFrame(largest_received, smallest_received);
-  AddQuicRetireConnectionIdFrame(sequence_number);
-  return BuildPacket();
+  builder.AddPaddingFrame();
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRetransmissionAndRetireConnectionIdPacket(
-    uint64_t num,
+    uint64_t packet_number,
     const std::vector<uint64_t>& original_packet_numbers,
     uint64_t sequence_number) {
-  InitializeHeader(num);
+  auto& builder = Packet(packet_number);
   for (auto it : original_packet_numbers) {
-    for (auto frame : saved_frames_[quic::QuicPacketNumber(it)]) {
-      if (!MaybeCoalesceStreamFrame(frame)) {
-        frames_.push_back(frame);
-      }
+    for (auto frame :
+         connection_state_.saved_frames[quic::QuicPacketNumber(it)]) {
+      builder.AddFrameWithCoalescing(frame);
     }
   }
-  AddQuicRetireConnectionIdFrame(sequence_number);
-  return BuildPacket();
+
+  builder.AddRetireConnectionIdFrame(sequence_number);
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeStreamsBlockedPacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamCount stream_count,
     bool unidirectional) {
-  InitializeHeader(num);
-  AddQuicStreamsBlockedFrame(1, stream_count, unidirectional);
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddStreamsBlockedFrame(1, stream_count, unidirectional)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeMaxStreamsPacket(uint64_t num,
+QuicTestPacketMaker::MakeMaxStreamsPacket(uint64_t packet_number,
                                           quic::QuicStreamCount stream_count,
                                           bool unidirectional) {
-  InitializeHeader(num);
-  AddQuicMaxStreamsFrame(1, stream_count, unidirectional);
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddMaxStreamsFrame(1, stream_count, unidirectional)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeRstPacket(
-    uint64_t num,
-    quic::QuicStreamId stream_id,
-    quic::QuicRstStreamErrorCode error_code) {
-  return MakeRstPacket(num, stream_id, error_code,
-                       /*include_stop_sending_if_v99=*/true);
-}
-
-std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeRstPacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     quic::QuicRstStreamErrorCode error_code,
     bool include_stop_sending_if_v99) {
-  InitializeHeader(num);
-
+  auto& builder = Packet(packet_number);
   if (include_stop_sending_if_v99) {
-    AddQuicStopSendingFrame(stream_id, error_code);
+    builder.AddStopSendingFrame(stream_id, error_code);
   }
   if (quic::QuicUtils::IsBidirectionalStreamId(stream_id, version_)) {
-    AddQuicRstStreamFrame(stream_id, error_code);
+    builder.AddRstStreamFrame(stream_id, error_code);
   }
-
-  return BuildPacket();
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRstAndDataPacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamId rst_stream_id,
     quic::QuicRstStreamErrorCode rst_error_code,
     quic::QuicStreamId data_stream_id,
     std::string_view data) {
-  InitializeHeader(num);
-
-  AddQuicStopSendingFrame(rst_stream_id, rst_error_code);
-  AddQuicRstStreamFrame(rst_stream_id, rst_error_code);
-  AddQuicStreamFrame(data_stream_id, /* fin = */ false, data);
-
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddStopSendingFrame(rst_stream_id, rst_error_code)
+      .AddRstStreamFrame(rst_stream_id, rst_error_code)
+      .AddStreamFrame(data_stream_id, /* fin = */ false, data)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRetransmissionRstAndDataPacket(
     const std::vector<uint64_t>& original_packet_numbers,
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamId rst_stream_id,
     quic::QuicRstStreamErrorCode rst_error_code,
     quic::QuicStreamId data_stream_id,
     std::string_view data,
     uint64_t retransmit_frame_count) {
-  DCHECK(save_packet_frames_);
-  InitializeHeader(num);
-
+  DCHECK(connection_state_.save_packet_frames);
+  auto& builder = Packet(packet_number);
   uint64_t frame_count = 0;
   for (auto it : original_packet_numbers) {
-    for (auto frame : saved_frames_[quic::QuicPacketNumber(it)]) {
+    for (auto frame :
+         connection_state_.saved_frames[quic::QuicPacketNumber(it)]) {
       frame_count++;
       if (retransmit_frame_count == 0 ||
           frame_count <= retransmit_frame_count) {
-        if (!MaybeCoalesceStreamFrame(frame)) {
-          frames_.push_back(frame);
-        }
+        builder.AddFrameWithCoalescing(frame);
       }
     }
   }
 
-  AddQuicStopSendingFrame(rst_stream_id, rst_error_code);
-  AddQuicRstStreamFrame(rst_stream_id, rst_error_code);
-  AddQuicStreamFrame(data_stream_id, /* fin = */ false, data);
-
-  return BuildPacket();
+  builder.AddStopSendingFrame(rst_stream_id, rst_error_code);
+  builder.AddRstStreamFrame(rst_stream_id, rst_error_code);
+  builder.AddStreamFrame(data_stream_id, /* fin = */ false, data);
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeDataAndRstPacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamId data_stream_id,
     std::string_view data,
     quic::QuicStreamId rst_stream_id,
     quic::QuicRstStreamErrorCode rst_error_code) {
-  InitializeHeader(num);
-
-  AddQuicStreamFrame(data_stream_id, /* fin = */ false, data);
-  AddQuicStopSendingFrame(rst_stream_id, rst_error_code);
-  AddQuicRstStreamFrame(rst_stream_id, rst_error_code);
-
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddStreamFrame(data_stream_id, /* fin = */ false, data)
+      .AddStopSendingFrame(rst_stream_id, rst_error_code)
+      .AddRstStreamFrame(rst_stream_id, rst_error_code)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeDataRstAndAckPacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamId data_stream_id,
     std::string_view data,
     quic::QuicStreamId rst_stream_id,
     quic::QuicRstStreamErrorCode rst_error_code,
     uint64_t largest_received,
     uint64_t smallest_received) {
-  InitializeHeader(num);
-
-  AddQuicAckFrame(largest_received, smallest_received);
-
-  AddQuicStreamFrame(data_stream_id, /* fin = */ false, data);
-  AddQuicStopSendingFrame(rst_stream_id, rst_error_code);
-  AddQuicRstStreamFrame(rst_stream_id, rst_error_code);
-
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddAckFrame(/*first_received=*/1, largest_received, smallest_received)
+      .AddStreamFrame(data_stream_id, /* fin = */ false, data)
+      .AddStopSendingFrame(rst_stream_id, rst_error_code)
+      .AddRstStreamFrame(rst_stream_id, rst_error_code)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeAckAndRstPacket(
-    uint64_t num,
-    quic::QuicStreamId stream_id,
-    quic::QuicRstStreamErrorCode error_code,
-    uint64_t largest_received,
-    uint64_t smallest_received) {
-  return MakeAckAndRstPacket(num, stream_id, error_code, largest_received,
-                             smallest_received,
-                             /*include_stop_sending_if_v99=*/true);
-}
-
-std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeAckAndRstPacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     quic::QuicRstStreamErrorCode error_code,
     uint64_t largest_received,
     uint64_t smallest_received,
     bool include_stop_sending_if_v99) {
-  InitializeHeader(num);
-
-  AddQuicAckFrame(largest_received, smallest_received);
+  auto& builder = Packet(packet_number);
+  builder.AddAckFrame(/*first_received=*/1, largest_received,
+                      smallest_received);
 
   if (include_stop_sending_if_v99) {
-    AddQuicStopSendingFrame(stream_id, error_code);
+    builder.AddStopSendingFrame(stream_id, error_code);
   }
   if (quic::QuicUtils::IsBidirectionalStreamId(stream_id, version_)) {
-    AddQuicRstStreamFrame(stream_id, error_code);
+    builder.AddRstStreamFrame(stream_id, error_code);
   }
-
-  return BuildPacket();
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRstAckAndConnectionClosePacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     quic::QuicRstStreamErrorCode error_code,
     uint64_t largest_received,
     uint64_t smallest_received,
     quic::QuicErrorCode quic_error,
     const std::string& quic_error_details) {
-  InitializeHeader(num);
-
-  AddQuicAckFrame(largest_received, smallest_received);
-
-  AddQuicStopSendingFrame(stream_id, error_code);
-  AddQuicRstStreamFrame(stream_id, error_code);
-  AddQuicConnectionCloseFrame(quic_error, quic_error_details);
-
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddAckFrame(/*first_received=*/1, largest_received, smallest_received)
+      .AddStopSendingFrame(stream_id, error_code)
+      .AddRstStreamFrame(stream_id, error_code)
+      .AddConnectionCloseFrame(quic_error, quic_error_details)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRstAckAndDataPacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     quic::QuicRstStreamErrorCode error_code,
     uint64_t largest_received,
@@ -447,17 +388,15 @@
     quic::QuicStreamId data_id,
     bool fin,
     std::string_view data) {
-  InitializeHeader(num);
-
-  AddQuicRstStreamFrame(stream_id, error_code);
-
-  AddQuicAckFrame(largest_received, smallest_received);
-  AddQuicStreamFrame(data_id, fin, data);
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddRstStreamFrame(stream_id, error_code)
+      .AddAckFrame(/*first_received=*/1, largest_received, smallest_received)
+      .AddStreamFrame(data_id, fin, data)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeAckDataAndRst(uint64_t num,
+QuicTestPacketMaker::MakeAckDataAndRst(uint64_t packet_number,
                                        quic::QuicStreamId stream_id,
                                        quic::QuicRstStreamErrorCode error_code,
                                        uint64_t largest_received,
@@ -465,20 +404,17 @@
                                        quic::QuicStreamId data_id,
                                        bool fin,
                                        std::string_view data) {
-  InitializeHeader(num);
-
-  AddQuicAckFrame(largest_received, smallest_received);
-  AddQuicStreamFrame(data_id, fin, data);
-
-  AddQuicStopSendingFrame(stream_id, error_code);
-  AddQuicRstStreamFrame(stream_id, error_code);
-
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddAckFrame(/*first_received=*/1, largest_received, smallest_received)
+      .AddStreamFrame(data_id, fin, data)
+      .AddStopSendingFrame(stream_id, error_code)
+      .AddRstStreamFrame(stream_id, error_code)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeAckRstAndDataPacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     quic::QuicRstStreamErrorCode error_code,
     uint64_t largest_received,
@@ -486,12 +422,11 @@
     quic::QuicStreamId data_id,
     bool fin,
     std::string_view data) {
-  InitializeHeader(num);
-
-  AddQuicAckFrame(largest_received, smallest_received);
-  AddQuicRstStreamFrame(stream_id, error_code);
-  AddQuicStreamFrame(data_id, fin, data);
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddAckFrame(/*first_received=*/1, largest_received, smallest_received)
+      .AddRstStreamFrame(stream_id, error_code)
+      .AddStreamFrame(data_id, fin, data)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
@@ -501,79 +436,69 @@
     uint64_t largest_received,
     uint64_t smallest_received,
     const std::vector<uint64_t>& original_packet_numbers) {
-  DCHECK(save_packet_frames_);
-  InitializeHeader(packet_number);
-  AddQuicAckFrame(first_received, largest_received, smallest_received);
+  DCHECK(connection_state_.save_packet_frames);
+  auto& builder = Packet(packet_number);
+  builder.AddAckFrame(first_received, largest_received, smallest_received);
   for (auto it : original_packet_numbers) {
-    for (auto frame : saved_frames_[quic::QuicPacketNumber(it)]) {
-      if (!MaybeCoalesceStreamFrame(frame)) {
-        frames_.push_back(frame);
-      }
+    for (auto frame :
+         connection_state_.saved_frames[quic::QuicPacketNumber(it)]) {
+      builder.AddFrameWithCoalescing(frame);
     }
   }
-
-  return BuildPacket();
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeCombinedRetransmissionPacket(
     const std::vector<uint64_t>& original_packet_numbers,
     uint64_t new_packet_number) {
-  DCHECK(save_packet_frames_);
-  InitializeHeader(new_packet_number);
+  DCHECK(connection_state_.save_packet_frames);
+  auto& builder = Packet(new_packet_number);
   for (auto it : original_packet_numbers) {
-    for (auto& frame : CloneFrames(saved_frames_[quic::QuicPacketNumber(it)])) {
+    for (auto& frame : CloneFrames(
+             connection_state_.saved_frames[quic::QuicPacketNumber(it)])) {
       if (frame.type != quic::PADDING_FRAME) {
-        if (!MaybeCoalesceStreamFrame(frame)) {
-          frames_.push_back(frame);
-        }
+        builder.AddFrameWithCoalescing(frame);
       }
     }
   }
-
-  return BuildPacket();
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRstAndConnectionClosePacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     quic::QuicRstStreamErrorCode error_code,
     quic::QuicErrorCode quic_error,
     const std::string& quic_error_details) {
-  InitializeHeader(num);
-
-  AddQuicStopSendingFrame(stream_id, error_code);
-  AddQuicRstStreamFrame(stream_id, error_code);
-
-  AddQuicConnectionCloseFrame(quic_error, quic_error_details);
-
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddStopSendingFrame(stream_id, error_code)
+      .AddRstStreamFrame(stream_id, error_code)
+      .AddConnectionCloseFrame(quic_error, quic_error_details)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeDataRstAndConnectionClosePacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamId data_stream_id,
     std::string_view data,
     quic::QuicStreamId rst_stream_id,
     quic::QuicRstStreamErrorCode error_code,
     quic::QuicErrorCode quic_error,
     const std::string& quic_error_details) {
-  InitializeHeader(num);
-
-  AddQuicStreamFrame(data_stream_id, /* fin = */ false, data);
-  AddQuicStopSendingFrame(rst_stream_id, error_code);
-  AddQuicRstStreamFrame(rst_stream_id, error_code);
-
-  AddQuicConnectionCloseFrame(quic_error, quic_error_details);
-
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddStreamFrame(data_stream_id, /* fin = */ false, data)
+      .AddStopSendingFrame(rst_stream_id, error_code)
+      .AddRstStreamFrame(rst_stream_id, error_code)
+      .AddConnectionCloseFrame(quic_error, quic_error_details)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeDataRstAckAndConnectionClosePacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamId data_stream_id,
     std::string_view data,
     quic::QuicStreamId rst_stream_id,
@@ -582,22 +507,18 @@
     uint64_t smallest_received,
     quic::QuicErrorCode quic_error,
     const std::string& quic_error_details) {
-  InitializeHeader(num);
-
-  AddQuicAckFrame(largest_received, smallest_received);
-
-  AddQuicStreamFrame(data_stream_id, /* fin = */ false, data);
-  AddQuicStopSendingFrame(rst_stream_id, error_code);
-  AddQuicRstStreamFrame(rst_stream_id, error_code);
-
-  AddQuicConnectionCloseFrame(quic_error, quic_error_details);
-
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddAckFrame(/*first_received=*/1, largest_received, smallest_received)
+      .AddStreamFrame(data_stream_id, /* fin = */ false, data)
+      .AddStopSendingFrame(rst_stream_id, error_code)
+      .AddRstStreamFrame(rst_stream_id, error_code)
+      .AddConnectionCloseFrame(quic_error, quic_error_details)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeDataRstAckAndConnectionClosePacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamId data_stream_id,
     std::string_view data,
     quic::QuicStreamId rst_stream_id,
@@ -607,60 +528,56 @@
     quic::QuicErrorCode quic_error,
     const std::string& quic_error_details,
     uint64_t frame_type) {
-  InitializeHeader(num);
-
-  AddQuicStreamFrame(data_stream_id, /* fin = */ false, data);
-  AddQuicStopSendingFrame(rst_stream_id, error_code);
-  AddQuicRstStreamFrame(rst_stream_id, error_code);
-
-  AddQuicAckFrame(largest_received, smallest_received);
-  AddQuicConnectionCloseFrame(quic_error, quic_error_details, frame_type);
-
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddStreamFrame(data_stream_id, /* fin = */ false, data)
+      .AddStopSendingFrame(rst_stream_id, error_code)
+      .AddRstStreamFrame(rst_stream_id, error_code)
+      .AddAckFrame(/*first_received=*/1, largest_received, smallest_received)
+      .AddConnectionCloseFrame(quic_error, quic_error_details, frame_type)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeStopSendingPacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     quic::QuicRstStreamErrorCode error_code) {
-  InitializeHeader(num);
-  AddQuicStopSendingFrame(stream_id, error_code);
-
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddStopSendingFrame(stream_id, error_code)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeAckAndConnectionClosePacket(
-    uint64_t num,
+    uint64_t packet_number,
     uint64_t largest_received,
     uint64_t smallest_received,
     quic::QuicErrorCode quic_error,
     const std::string& quic_error_details,
     uint64_t frame_type) {
-  InitializeHeader(num);
-  AddQuicAckFrame(largest_received, smallest_received);
-  AddQuicConnectionCloseFrame(quic_error, quic_error_details, frame_type);
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddAckFrame(/*first_received=*/1, largest_received, smallest_received)
+      .AddConnectionCloseFrame(quic_error, quic_error_details, frame_type)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeConnectionClosePacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicErrorCode quic_error,
     const std::string& quic_error_details) {
-  InitializeHeader(num);
-  AddQuicConnectionCloseFrame(quic_error, quic_error_details);
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddConnectionCloseFrame(quic_error, quic_error_details)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeGoAwayPacket(
-    uint64_t num,
+    uint64_t packet_number,
     quic::QuicErrorCode error_code,
     std::string reason_phrase) {
-  InitializeHeader(num);
-  AddQuicGoAwayFrame(error_code, reason_phrase);
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddGoAwayFrame(error_code, reason_phrase)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket(
@@ -676,9 +593,9 @@
     uint64_t largest_received,
     uint64_t smallest_received,
     std::optional<quic::QuicEcnCounts> ecn) {
-  InitializeHeader(packet_number);
-  AddQuicAckFrame(first_received, largest_received, smallest_received, ecn);
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddAckFrame(first_received, largest_received, smallest_received, ecn)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeDataPacket(
@@ -686,27 +603,23 @@
     quic::QuicStreamId stream_id,
     bool fin,
     std::string_view data) {
-  InitializeHeader(packet_number);
-  AddQuicStreamFrame(stream_id, fin, data);
-  return BuildPacket();
+  return Packet(packet_number).AddStreamFrame(stream_id, fin, data).Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeDatagramPacket(uint64_t packet_number,
                                         std::string_view datagram) {
-  InitializeHeader(packet_number);
-  AddQuicMessageFrame(datagram);
-  return BuildPacket();
+  return Packet(packet_number).AddMessageFrame(datagram).Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeDatagramPacket(uint64_t packet_number,
                                         std::vector<std::string> datagrams) {
-  InitializeHeader(packet_number);
+  auto& builder = Packet(packet_number);
   for (auto& datagram : datagrams) {
-    AddQuicMessageFrame(datagram);
+    builder.AddMessageFrame(datagram);
   }
-  return BuildPacket();
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
@@ -716,11 +629,10 @@
                                           uint64_t smallest_received,
                                           bool fin,
                                           std::string_view data) {
-  InitializeHeader(packet_number);
-
-  AddQuicAckFrame(largest_received, smallest_received);
-  AddQuicStreamFrame(stream_id, fin, data);
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddAckFrame(/*first_received=*/1, largest_received, smallest_received)
+      .AddStreamFrame(stream_id, fin, data)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
@@ -728,11 +640,10 @@
                                               uint64_t largest_received,
                                               uint64_t smallest_received,
                                               std::string_view data) {
-  InitializeHeader(packet_number);
-
-  AddQuicAckFrame(largest_received, smallest_received);
-  AddQuicMessageFrame(data);
-  return BuildPacket();
+  return Packet(packet_number)
+      .AddAckFrame(/*first_received=*/1, largest_received, smallest_received)
+      .AddMessageFrame(data)
+      .Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
@@ -744,19 +655,17 @@
     uint64_t smallest_received,
     bool fin,
     std::string_view data) {
-  InitializeHeader(packet_number);
-
-  AddQuicAckFrame(largest_received, smallest_received);
+  auto& builder = Packet(packet_number);
+  builder.AddAckFrame(/*first_received=*/1, largest_received,
+                      smallest_received);
   for (auto it : original_packet_numbers) {
-    for (auto frame : saved_frames_[quic::QuicPacketNumber(it)]) {
-      if (!MaybeCoalesceStreamFrame(frame)) {
-        frames_.push_back(frame);
-      }
+    for (auto frame :
+         connection_state_.saved_frames[quic::QuicPacketNumber(it)]) {
+      builder.AddFrameWithCoalescing(frame);
     }
   }
-  AddQuicStreamFrame(stream_id, fin, data);
-
-  return BuildPacket();
+  builder.AddStreamFrame(stream_id, fin, data);
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
@@ -768,14 +677,13 @@
     spdy::Http2HeaderBlock headers,
     size_t* spdy_headers_frame_length,
     const std::vector<std::string>& data_writes) {
-  InitializeHeader(packet_number);
-
-  MaybeAddHttp3SettingsFrames();
+  auto& builder = Packet(packet_number);
+  builder.MaybeAddHttp3SettingsFrames();
 
   std::string priority_data =
       GenerateHttp3PriorityData(spdy_priority, stream_id);
   if (!priority_data.empty()) {
-    AddQuicStreamFrame(2, false, priority_data);
+    builder.AddStreamFrame(2, false, priority_data);
   }
 
   AddPriorityHeader(spdy_priority, &headers);
@@ -784,9 +692,8 @@
   for (const auto& data_write : data_writes) {
     data += data_write;
   }
-  AddQuicStreamFrame(stream_id, fin, data);
-
-  return BuildPacket();
+  builder.AddStreamFrame(stream_id, fin, data);
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
@@ -798,24 +705,22 @@
     spdy::Http2HeaderBlock headers,
     size_t* spdy_headers_frame_length,
     bool should_include_priority_frame) {
-  InitializeHeader(packet_number);
-
-  MaybeAddHttp3SettingsFrames();
+  auto& builder = Packet(packet_number);
+  builder.MaybeAddHttp3SettingsFrames();
 
   if (should_include_priority_frame) {
     std::string priority_data =
         GenerateHttp3PriorityData(spdy_priority, stream_id);
     if (!priority_data.empty()) {
-      AddQuicStreamFrame(2, false, priority_data);
+      builder.AddStreamFrame(2, false, priority_data);
     }
   }
 
   AddPriorityHeader(spdy_priority, &headers);
   std::string data = QpackEncodeHeaders(stream_id, std::move(headers),
                                         spdy_headers_frame_length);
-  AddQuicStreamFrame(stream_id, fin, data);
-
-  return BuildPacket();
+  builder.AddStreamFrame(stream_id, fin, data);
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
@@ -827,31 +732,28 @@
     spdy::SpdyPriority spdy_priority,
     spdy::Http2HeaderBlock headers,
     size_t* spdy_headers_frame_length) {
-  DCHECK(save_packet_frames_);
-  InitializeHeader(packet_number);
-
+  DCHECK(connection_state_.save_packet_frames);
+  auto& builder = Packet(packet_number);
   for (auto it : original_packet_numbers) {
-    for (auto frame : saved_frames_[quic::QuicPacketNumber(it)]) {
-      if (!MaybeCoalesceStreamFrame(frame)) {
-        frames_.push_back(frame);
-      }
+    for (auto frame :
+         connection_state_.saved_frames[quic::QuicPacketNumber(it)]) {
+      builder.AddFrameWithCoalescing(frame);
     }
   }
 
-  MaybeAddHttp3SettingsFrames();
+  builder.MaybeAddHttp3SettingsFrames();
 
   std::string priority_data =
       GenerateHttp3PriorityData(spdy_priority, stream_id);
   if (!priority_data.empty()) {
-    AddQuicStreamFrame(2, false, priority_data);
+    builder.AddStreamFrame(2, false, priority_data);
   }
 
   AddPriorityHeader(spdy_priority, &headers);
   std::string data = QpackEncodeHeaders(stream_id, std::move(headers),
                                         spdy_headers_frame_length);
-  AddQuicStreamFrame(stream_id, fin, data);
-
-  return BuildPacket();
+  builder.AddStreamFrame(stream_id, fin, data);
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
@@ -863,24 +765,22 @@
     spdy::Http2HeaderBlock headers,
     size_t* spdy_headers_frame_length,
     quic::QuicRstStreamErrorCode error_code) {
-  InitializeHeader(packet_number);
-
-  MaybeAddHttp3SettingsFrames();
+  auto& builder = Packet(packet_number);
+  builder.MaybeAddHttp3SettingsFrames();
 
   std::string priority_data =
       GenerateHttp3PriorityData(spdy_priority, stream_id);
   if (!priority_data.empty()) {
-    AddQuicStreamFrame(2, false, priority_data);
+    builder.AddStreamFrame(2, false, priority_data);
   }
 
   AddPriorityHeader(spdy_priority, &headers);
   std::string data = QpackEncodeHeaders(stream_id, std::move(headers),
                                         spdy_headers_frame_length);
-  AddQuicStreamFrame(stream_id, fin, data);
-  AddQuicStopSendingFrame(stream_id, error_code);
-  AddQuicRstStreamFrame(stream_id, error_code);
-
-  return BuildPacket();
+  builder.AddStreamFrame(stream_id, fin, data);
+  builder.AddStopSendingFrame(stream_id, error_code);
+  builder.AddRstStreamFrame(stream_id, error_code);
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
@@ -890,35 +790,26 @@
     bool fin,
     spdy::Http2HeaderBlock headers,
     size_t* spdy_headers_frame_length) {
-  InitializeHeader(packet_number);
-
   std::string data = QpackEncodeHeaders(stream_id, std::move(headers),
                                         spdy_headers_frame_length);
-
-  AddQuicStreamFrame(stream_id, fin, data);
-
-  return BuildPacket();
+  return Packet(packet_number).AddStreamFrame(stream_id, fin, data).Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeInitialSettingsPacket(uint64_t packet_number) {
-  InitializeHeader(packet_number);
-  MaybeAddHttp3SettingsFrames();
-  return BuildPacket();
+  return Packet(packet_number).MaybeAddHttp3SettingsFrames().Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakePriorityPacket(uint64_t packet_number,
                                         quic::QuicStreamId id,
                                         spdy::SpdyPriority spdy_priority) {
-  InitializeHeader(packet_number);
-
+  auto& builder = Packet(packet_number);
   std::string priority_data = GenerateHttp3PriorityData(spdy_priority, id);
   if (!priority_data.empty()) {
-    AddQuicStreamFrame(2, false, priority_data);
+    builder.AddStreamFrame(2, false, priority_data);
   }
-
-  return BuildPacket();
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
@@ -928,16 +819,14 @@
     uint64_t smallest_received,
     quic::QuicStreamId id,
     spdy::SpdyPriority spdy_priority) {
-  InitializeHeader(packet_number);
-
-  AddQuicAckFrame(largest_received, smallest_received);
-
+  auto& builder = Packet(packet_number);
+  builder.AddAckFrame(/*first_received=*/1, largest_received,
+                      smallest_received);
   std::string priority_data = GenerateHttp3PriorityData(spdy_priority, id);
   if (!priority_data.empty()) {
-    AddQuicStreamFrame(2, false, priority_data);
+    builder.AddStreamFrame(2, false, priority_data);
   }
-
-  return BuildPacket();
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
@@ -947,25 +836,28 @@
     uint64_t smallest_received,
     quic::QuicStreamId id,
     spdy::SpdyPriority spdy_priority) {
-  InitializeHeader(packet_number);
-
-  AddQuicAckFrame(largest_received, smallest_received);
+  auto& builder = Packet(packet_number);
+  builder.AddAckFrame(/*first_received=*/1, largest_received,
+                      smallest_received);
 
   std::string priority_data = GenerateHttp3PriorityData(spdy_priority, id);
   if (!priority_data.empty()) {
-    AddQuicStreamFrame(2, false, priority_data);
+    builder.AddStreamFrame(2, false, priority_data);
   }
-
-  return BuildPacket();
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRetransmissionPacket(uint64_t original_packet_number,
                                               uint64_t new_packet_number) {
-  DCHECK(save_packet_frames_);
-  InitializeHeader(new_packet_number);
-  return BuildPacketImpl(
-      saved_frames_[quic::QuicPacketNumber(original_packet_number)], nullptr);
+  DCHECK(connection_state_.save_packet_frames);
+  auto& builder = Packet(new_packet_number);
+  for (auto frame :
+       connection_state_
+           .saved_frames[quic::QuicPacketNumber(original_packet_number)]) {
+    builder.AddFrameWithCoalescing(frame);
+  }
+  return builder.Build();
 }
 
 std::unique_ptr<quic::QuicEncryptedPacket>
@@ -978,7 +870,7 @@
 
 void QuicTestPacketMaker::RemoveSavedStreamFrames(
     quic::QuicStreamId stream_id) {
-  for (auto& kv : saved_frames_) {
+  for (auto& kv : connection_state_.saved_frames) {
     auto* it = kv.second.begin();
     while (it != kv.second.end()) {
       if (it->type == quic::STREAM_FRAME &&
@@ -1048,7 +940,7 @@
 }
 
 void QuicTestPacketMaker::Reset() {
-  stream_offsets_.clear();
+  connection_state_.Reset();
 }
 
 std::string QuicTestPacketMaker::QpackEncodeHeaders(
@@ -1076,229 +968,20 @@
   return data;
 }
 
-void QuicTestPacketMaker::InitializeHeader(uint64_t packet_number) {
-  header_.destination_connection_id = DestinationConnectionId();
-  header_.destination_connection_id_included = quic::CONNECTION_ID_PRESENT;
-  header_.source_connection_id = SourceConnectionId();
-  header_.source_connection_id_included = quic::CONNECTION_ID_PRESENT;
-  header_.reset_flag = false;
-  header_.version_flag = ShouldIncludeVersion();
-  header_.form = header_.version_flag ? quic::IETF_QUIC_LONG_HEADER_PACKET
-                                      : quic::IETF_QUIC_SHORT_HEADER_PACKET;
-  header_.long_packet_type = long_header_type_;
-  header_.packet_number_length = quic::PACKET_1BYTE_PACKET_NUMBER;
-  header_.packet_number = quic::QuicPacketNumber(packet_number);
-  if (header_.version_flag) {
-    if (long_header_type_ == quic::INITIAL) {
-      header_.retry_token_length_length =
-          quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1;
-    }
-    header_.length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
-  }
-}
+std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::FinishPacket(
+    quic::QuicPacketHeader header,
+    quic::QuicFrames frames,
+    std::unique_ptr<quic::QuicStreamFrameDataProducer> data_producer) {
+  CHECK(builder_);
+  builder_ = nullptr;
 
-void QuicTestPacketMaker::AddQuicPaddingFrame() {
-  quic::QuicPaddingFrame padding_frame;
-  frames_.push_back(quic::QuicFrame(padding_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicPingFrame() {
-  quic::QuicPingFrame ping_frame;
-  frames_.push_back(quic::QuicFrame(ping_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicRetireConnectionIdFrame(
-    uint64_t sequence_number) {
-  auto* retire_cid_frame = new quic::QuicRetireConnectionIdFrame();
-  retire_cid_frame->sequence_number = sequence_number;
-  frames_.push_back(quic::QuicFrame(retire_cid_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicNewConnectionIdFrame(
-    const quic::QuicConnectionId& cid,
-    uint64_t sequence_number,
-    uint64_t retire_prior_to,
-    quic::StatelessResetToken reset_token) {
-  auto* new_cid_frame = new quic::QuicNewConnectionIdFrame();
-  new_cid_frame->connection_id = cid;
-  new_cid_frame->sequence_number = sequence_number;
-  new_cid_frame->retire_prior_to = retire_prior_to;
-  new_cid_frame->stateless_reset_token = reset_token;
-  frames_.push_back(quic::QuicFrame(new_cid_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicMaxStreamsFrame(
-    quic::QuicControlFrameId control_frame_id,
-    quic::QuicStreamCount stream_count,
-    bool unidirectional) {
-  quic::QuicMaxStreamsFrame max_streams_frame(control_frame_id, stream_count,
-                                              unidirectional);
-  frames_.push_back(quic::QuicFrame(max_streams_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicStreamsBlockedFrame(
-    quic::QuicControlFrameId control_frame_id,
-    quic::QuicStreamCount stream_count,
-    bool unidirectional) {
-  quic::QuicStreamsBlockedFrame streams_blocked_frame(
-      control_frame_id, stream_count, unidirectional);
-  frames_.push_back(quic::QuicFrame(streams_blocked_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicMessageFrame(std::string_view data) {
-  auto* message_frame = new quic::QuicMessageFrame(
-      /*message_id=*/0, quiche::QuicheMemSlice(quiche::QuicheBuffer::Copy(
-                            quiche::SimpleBufferAllocator::Get(), data)));
-  frames_.push_back(quic::QuicFrame(message_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicStreamFrame(quic::QuicStreamId stream_id,
-                                             bool fin,
-                                             std::string_view data) {
-  AddQuicStreamFrameWithOffset(stream_id, fin, stream_offsets_[stream_id],
-                               data);
-  stream_offsets_[stream_id] += data.length();
-}
-
-void QuicTestPacketMaker::AddQuicStreamFrameWithOffset(
-    quic::QuicStreamId stream_id,
-    bool fin,
-    quic::QuicStreamOffset offset,
-    std::string_view data) {
-  // Save the stream data so that callers can use temporary objects for data.
-  saved_stream_data_.push_back(std::make_unique<std::string>(data));
-  std::string_view saved_data = *saved_stream_data_.back();
-
-  quic::QuicStreamFrame stream_frame(stream_id, fin, offset, saved_data);
-  frames_.push_back(quic::QuicFrame(stream_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicAckFrame(uint64_t largest_received,
-                                          uint64_t smallest_received) {
-  AddQuicAckFrame(1, largest_received, smallest_received);
-}
-
-void QuicTestPacketMaker::AddQuicAckFrame(
-    uint64_t first_received,
-    uint64_t largest_received,
-    uint64_t smallest_received,
-    std::optional<quic::QuicEcnCounts> ecn) {
-  auto* ack_frame = new quic::QuicAckFrame;
-  ack_frame->largest_acked = quic::QuicPacketNumber(largest_received);
-  ack_frame->ack_delay_time = quic::QuicTime::Delta::Zero();
-  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
-    ack_frame->received_packet_times.emplace_back(quic::QuicPacketNumber(i),
-                                                  clock_->Now());
-  }
-  if (largest_received > 0) {
-    DCHECK_GE(largest_received, first_received);
-    ack_frame->packets.AddRange(quic::QuicPacketNumber(first_received),
-                                quic::QuicPacketNumber(largest_received + 1));
-  }
-  ack_frame->ecn_counters = ecn;
-  frames_.push_back(quic::QuicFrame(ack_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicRstStreamFrame(
-    quic::QuicStreamId stream_id,
-    quic::QuicRstStreamErrorCode error_code) {
-  auto* rst_stream_frame = new quic::QuicRstStreamFrame(
-      1, stream_id, error_code, stream_offsets_[stream_id]);
-  frames_.push_back(quic::QuicFrame(rst_stream_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicConnectionCloseFrame(
-    quic::QuicErrorCode quic_error,
-    const std::string& quic_error_details) {
-  AddQuicConnectionCloseFrame(quic_error, quic_error_details, 0);
-}
-
-void QuicTestPacketMaker::AddQuicConnectionCloseFrame(
-    quic::QuicErrorCode quic_error,
-    const std::string& quic_error_details,
-    uint64_t frame_type) {
-  auto* close_frame = new quic::QuicConnectionCloseFrame(
-      version_.transport_version, quic_error, quic::NO_IETF_QUIC_ERROR,
-      quic_error_details, frame_type);
-  frames_.push_back(quic::QuicFrame(close_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicGoAwayFrame(quic::QuicErrorCode error_code,
-                                             std::string reason_phrase) {
-  auto* goaway_frame = new quic::QuicGoAwayFrame();
-  goaway_frame->error_code = error_code;
-  goaway_frame->last_good_stream_id = 0;
-  goaway_frame->reason_phrase = reason_phrase;
-  frames_.push_back(quic::QuicFrame(goaway_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicPathResponseFrame() {
-  quic::test::MockRandom rand(0);
-  quic::QuicPathFrameBuffer payload;
-  rand.RandBytes(payload.data(), payload.size());
-  auto path_response_frame = quic::QuicPathResponseFrame(0, payload);
-  frames_.push_back(quic::QuicFrame(path_response_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicPathChallengeFrame() {
-  quic::test::MockRandom rand(0);
-  quic::QuicPathFrameBuffer payload;
-  rand.RandBytes(payload.data(), payload.size());
-  auto path_challenge_frame = quic::QuicPathChallengeFrame(0, payload);
-  frames_.push_back(quic::QuicFrame(path_challenge_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicStopSendingFrame(
-    quic::QuicStreamId stream_id,
-    quic::QuicRstStreamErrorCode error_code) {
-  auto stop_sending_frame =
-      quic::QuicStopSendingFrame(1, stream_id, error_code);
-  frames_.push_back(quic::QuicFrame(stop_sending_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-void QuicTestPacketMaker::AddQuicCryptoFrame(
-    quic::EncryptionLevel level,
-    quic::QuicStreamOffset offset,
-    quic::QuicPacketLength data_length) {
-  auto* crypto_frame = new quic::QuicCryptoFrame(level, offset, data_length);
-  frames_.push_back(quic::QuicFrame(crypto_frame));
-  DVLOG(1) << "Adding frame: " << frames_.back();
-}
-
-std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::BuildPacket() {
-  auto packet = BuildPacketImpl(frames_, data_producer_.get());
-
-  DeleteFrames(&frames_);
-  data_producer_.reset();
-
-  return packet;
-}
-
-std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::BuildPacketImpl(
-    const quic::QuicFrames& frames,
-    quic::QuicStreamFrameDataProducer* data_producer) {
   quic::QuicFramer framer(quic::test::SupportedVersions(version_),
                           clock_->Now(), perspective_,
                           quic::kQuicDefaultConnectionIdLength);
   if (encryption_level_ == quic::ENCRYPTION_INITIAL) {
     framer.SetInitialObfuscators(perspective_ == quic::Perspective::IS_CLIENT
-                                     ? header_.destination_connection_id
-                                     : header_.source_connection_id);
+                                     ? header.destination_connection_id
+                                     : header.source_connection_id);
   } else {
     framer.SetEncrypter(
         encryption_level_,
@@ -1306,90 +989,57 @@
             encryption_level_));
   }
   if (data_producer != nullptr) {
-    framer.set_data_producer(data_producer);
+    framer.set_data_producer(data_producer.get());
   }
-  quic::QuicFrames frames_copy = CloneFrames(frames);
   size_t max_plaintext_size =
       framer.GetMaxPlaintextSize(quic::kDefaultMaxPacketSize);
   size_t packet_size =
-      quic::GetPacketHeaderSize(version_.transport_version, header_);
+      quic::GetPacketHeaderSize(version_.transport_version, header);
   size_t frames_size = 0;
   for (size_t i = 0; i < frames.size(); ++i) {
     bool first_frame = i == 0;
     bool last_frame = i == frames.size() - 1;
     const size_t frame_size = framer.GetSerializedFrameLength(
         frames[i], max_plaintext_size - packet_size, first_frame, last_frame,
-        header_.packet_number_length);
+        header.packet_number_length);
     packet_size += frame_size;
     frames_size += frame_size;
   }
 
   const size_t min_plaintext_packet_size =
       quic::QuicPacketCreator::MinPlaintextPacketSize(
-          version_, header_.packet_number_length);
+          version_, header.packet_number_length);
   if (frames_size < min_plaintext_packet_size) {
-    frames_copy.insert(frames_copy.begin(),
-                       quic::QuicFrame(quic::QuicPaddingFrame(
-                           min_plaintext_packet_size - frames_size)));
+    frames.insert(frames.begin(),
+                  quic::QuicFrame(quic::QuicPaddingFrame(
+                      min_plaintext_packet_size - frames_size)));
   }
 
   std::unique_ptr<quic::QuicPacket> packet(quic::test::BuildUnsizedDataPacket(
-      &framer, header_, frames_copy, max_plaintext_size));
+      &framer, header, frames, max_plaintext_size));
   char buffer[quic::kMaxOutgoingPacketSize];
   size_t encrypted_size =
-      framer.EncryptPayload(encryption_level_, header_.packet_number, *packet,
+      framer.EncryptPayload(encryption_level_, header.packet_number, *packet,
                             buffer, quic::kMaxOutgoingPacketSize);
   EXPECT_NE(0u, encrypted_size);
   quic::QuicReceivedPacket encrypted(buffer, encrypted_size, clock_->Now(),
                                      false, 0, true, nullptr, 0, false,
                                      ecn_codepoint_);
-  if (save_packet_frames_) {
-    saved_frames_[header_.packet_number] = frames_copy;
+  if (connection_state_.save_packet_frames) {
+    connection_state_.saved_frames[header.packet_number] = std::move(frames);
   } else {
-    saved_stream_data_.clear();
-    DeleteFrames(&frames_copy);
+    connection_state_.saved_stream_data.clear();
+    DeleteFrames(&frames);
   }
 
   return encrypted.Clone();
 }
 
-bool QuicTestPacketMaker::ShouldIncludeVersion() const {
-  return encryption_level_ < quic::ENCRYPTION_FORWARD_SECURE;
-}
-
-quic::QuicConnectionId QuicTestPacketMaker::DestinationConnectionId() const {
-  if (perspective_ == quic::Perspective::IS_SERVER) {
-    return quic::EmptyQuicConnectionId();
-  }
-  return connection_id_;
-}
-
-quic::QuicConnectionId QuicTestPacketMaker::SourceConnectionId() const {
-  if (perspective_ == quic::Perspective::IS_CLIENT) {
-    return quic::EmptyQuicConnectionId();
-  }
-  return connection_id_;
-}
-
 quic::QuicStreamId QuicTestPacketMaker::GetFirstBidirectionalStreamId() const {
   return quic::QuicUtils::GetFirstBidirectionalStreamId(
       version_.transport_version, perspective_);
 }
 
-std::string QuicTestPacketMaker::GenerateHttp3SettingsData() {
-  quic::SettingsFrame settings;
-  settings.values[quic::SETTINGS_MAX_FIELD_SECTION_SIZE] =
-      kQuicMaxHeaderListSize;
-  settings.values[quic::SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
-      quic::kDefaultQpackMaxDynamicTableCapacity;
-  settings.values[quic::SETTINGS_QPACK_BLOCKED_STREAMS] =
-      quic::kDefaultMaximumBlockedStreams;
-  settings.values[quic::SETTINGS_H3_DATAGRAM] = 1;
-  // Greased setting.
-  settings.values[0x40] = 20;
-  return quic::HttpEncoder::SerializeSettingsFrame(settings);
-}
-
 std::string QuicTestPacketMaker::GenerateHttp3PriorityData(
     spdy::SpdyPriority spdy_priority,
     quic::QuicStreamId stream_id) {
@@ -1434,17 +1084,250 @@
   }
 }
 
-std::string QuicTestPacketMaker::GenerateHttp3GreaseData() {
-  return quic::HttpEncoder::SerializeGreasingFrame();
+QuicTestPacketBuilder::QuicTestPacketBuilder(
+    uint64_t packet_number,
+    QuicTestPacketMaker* maker,
+    QuicTestPacketMaker::ConnectionState* connection_state)
+    : maker_(maker), connection_state_(connection_state) {
+  CHECK(maker_);
+  InitializeHeader(packet_number);
 }
 
-void QuicTestPacketMaker::MaybeAddHttp3SettingsFrames() {
+QuicTestPacketBuilder::~QuicTestPacketBuilder() {
+  CHECK(!maker_) << "QuicTestPacketBuilder is missing a call to Build()";
+  DeleteFrames(&frames_);
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddPaddingFrame() {
+  quic::QuicPaddingFrame padding_frame;
+  AddFrame(quic::QuicFrame(padding_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddPingFrame() {
+  quic::QuicPingFrame ping_frame;
+  AddFrame(quic::QuicFrame(ping_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddRetireConnectionIdFrame(
+    uint64_t sequence_number) {
+  auto* retire_cid_frame = new quic::QuicRetireConnectionIdFrame();
+  retire_cid_frame->sequence_number = sequence_number;
+  AddFrame(quic::QuicFrame(retire_cid_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddNewConnectionIdFrame(
+    const quic::QuicConnectionId& cid,
+    uint64_t sequence_number,
+    uint64_t retire_prior_to,
+    quic::StatelessResetToken reset_token) {
+  auto* new_cid_frame = new quic::QuicNewConnectionIdFrame();
+  new_cid_frame->connection_id = cid;
+  new_cid_frame->sequence_number = sequence_number;
+  new_cid_frame->retire_prior_to = retire_prior_to;
+  new_cid_frame->stateless_reset_token = reset_token;
+  AddFrame(quic::QuicFrame(new_cid_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddMaxStreamsFrame(
+    quic::QuicControlFrameId control_frame_id,
+    quic::QuicStreamCount stream_count,
+    bool unidirectional) {
+  quic::QuicMaxStreamsFrame max_streams_frame(control_frame_id, stream_count,
+                                              unidirectional);
+  AddFrame(quic::QuicFrame(max_streams_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddStreamsBlockedFrame(
+    quic::QuicControlFrameId control_frame_id,
+    quic::QuicStreamCount stream_count,
+    bool unidirectional) {
+  quic::QuicStreamsBlockedFrame streams_blocked_frame(
+      control_frame_id, stream_count, unidirectional);
+  AddFrame(quic::QuicFrame(streams_blocked_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddStreamFrame(
+    quic::QuicStreamId stream_id,
+    bool fin,
+    std::string_view data) {
+  quic::QuicStreamOffset offset = connection_state_->stream_offsets[stream_id];
+  std::string_view saved_data = connection_state_->SaveStreamData(data);
+  quic::QuicStreamFrame stream_frame(stream_id, fin, offset, saved_data);
+  AddFrame(quic::QuicFrame(stream_frame));
+  connection_state_->stream_offsets[stream_id] += data.length();
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddAckFrame(
+    uint64_t first_received,
+    uint64_t largest_received,
+    uint64_t smallest_received,
+    std::optional<quic::QuicEcnCounts> ecn) {
+  auto* ack_frame = new quic::QuicAckFrame;
+  ack_frame->largest_acked = quic::QuicPacketNumber(largest_received);
+  ack_frame->ack_delay_time = quic::QuicTime::Delta::Zero();
+  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
+    ack_frame->received_packet_times.emplace_back(quic::QuicPacketNumber(i),
+                                                  maker_->clock()->Now());
+  }
+  if (largest_received > 0) {
+    DCHECK_GE(largest_received, first_received);
+    ack_frame->packets.AddRange(quic::QuicPacketNumber(first_received),
+                                quic::QuicPacketNumber(largest_received + 1));
+  }
+  ack_frame->ecn_counters = ecn;
+  AddFrame(quic::QuicFrame(ack_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddMessageFrame(
+    std::string_view data) {
+  auto* message_frame = new quic::QuicMessageFrame(
+      /*message_id=*/0, quiche::QuicheMemSlice(quiche::QuicheBuffer::Copy(
+                            quiche::SimpleBufferAllocator::Get(), data)));
+  AddFrame(quic::QuicFrame(message_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddRstStreamFrame(
+    quic::QuicStreamId stream_id,
+    quic::QuicRstStreamErrorCode error_code) {
+  auto* rst_stream_frame = new quic::QuicRstStreamFrame(
+      1, stream_id, error_code, connection_state_->stream_offsets[stream_id]);
+  AddFrame(quic::QuicFrame(rst_stream_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddConnectionCloseFrame(
+    quic::QuicErrorCode quic_error,
+    const std::string& quic_error_details,
+    uint64_t frame_type) {
+  auto* close_frame = new quic::QuicConnectionCloseFrame(
+      maker_->version().transport_version, quic_error, quic::NO_IETF_QUIC_ERROR,
+      quic_error_details, frame_type);
+  AddFrame(quic::QuicFrame(close_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddGoAwayFrame(
+    quic::QuicErrorCode error_code,
+    std::string reason_phrase) {
+  auto* goaway_frame = new quic::QuicGoAwayFrame();
+  goaway_frame->error_code = error_code;
+  goaway_frame->last_good_stream_id = 0;
+  goaway_frame->reason_phrase = reason_phrase;
+  AddFrame(quic::QuicFrame(goaway_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddPathResponseFrame() {
+  quic::test::MockRandom rand(0);
+  quic::QuicPathFrameBuffer payload;
+  rand.RandBytes(payload.data(), payload.size());
+  auto path_response_frame = quic::QuicPathResponseFrame(0, payload);
+  AddFrame(quic::QuicFrame(path_response_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddPathChallengeFrame() {
+  quic::test::MockRandom rand(0);
+  quic::QuicPathFrameBuffer payload;
+  rand.RandBytes(payload.data(), payload.size());
+  auto path_challenge_frame = quic::QuicPathChallengeFrame(0, payload);
+  AddFrame(quic::QuicFrame(path_challenge_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddStopSendingFrame(
+    quic::QuicStreamId stream_id,
+    quic::QuicRstStreamErrorCode error_code) {
+  auto stop_sending_frame =
+      quic::QuicStopSendingFrame(1, stream_id, error_code);
+  AddFrame(quic::QuicFrame(stop_sending_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddCryptoFrame(
+    quic::EncryptionLevel level,
+    quic::QuicStreamOffset offset,
+    const quic::QuicData& data) {
+  if (!data_producer_) {
+    data_producer_ =
+        std::make_unique<quic::test::SimpleDataProducer>();  // IN-TEST
+  }
+  data_producer_->SaveCryptoData(level, offset, data.AsStringPiece());
+  auto* crypto_frame = new quic::QuicCryptoFrame(level, offset, data.length());
+  AddFrame(quic::QuicFrame(crypto_frame));
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddFrame(quic::QuicFrame frame) {
+  CHECK(maker_);
+  frames_.push_back(std::move(frame));
+  DVLOG(1) << "Adding frame: " << frames_.back();
+  return *this;
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::AddFrameWithCoalescing(
+    const quic::QuicFrame& frame) {
+  if (frames_.empty()) {
+    return AddFrame(frame);
+  }
+  if (frame.type != quic::STREAM_FRAME ||
+      frames_.back().type != quic::STREAM_FRAME) {
+    return AddFrame(frame);
+  }
+
+  // Make sure they are congruent data segments in the stream.
+  const quic::QuicStreamFrame* new_frame = &frame.stream_frame;
+  quic::QuicStreamFrame* previous_frame = &frames_.back().stream_frame;
+  if (new_frame->stream_id != previous_frame->stream_id ||
+      new_frame->offset !=
+          previous_frame->offset + previous_frame->data_length) {
+    return AddFrame(frame);
+  }
+
+  // Extend the data buffer to include the data from both frames (into a copy
+  // buffer). This doesn't attempt to limit coalescing to a particular packet
+  // size limit and may need to be updated if a test comes along that
+  // retransmits enough stream data to span multiple packets.
+  std::string data(previous_frame->data_buffer, previous_frame->data_length);
+  data += std::string(new_frame->data_buffer, new_frame->data_length);
+  connection_state_->saved_stream_data.push_back(
+      std::make_unique<std::string>(data));
+  std::string_view saved_data = *connection_state_->saved_stream_data.back();
+  previous_frame->data_buffer = saved_data.data();
+  previous_frame->data_length = saved_data.length();
+
+  // Copy the fin state from the last frame.
+  previous_frame->fin = new_frame->fin;
+
+  return *this;
+}
+
+std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketBuilder::Build() {
+  CHECK(maker_);
+  QuicTestPacketMaker* maker = maker_;
+  maker_ = nullptr;
+  return maker->FinishPacket(std::move(header_), std::move(frames_),
+                             std::move(data_producer_));
+}
+
+QuicTestPacketBuilder& QuicTestPacketBuilder::MaybeAddHttp3SettingsFrames() {
   quic::QuicStreamId stream_id =
       quic::QuicUtils::GetFirstUnidirectionalStreamId(
-          version_.transport_version, perspective_);
+          maker_->version().transport_version, maker_->perspective());
 
-  if (stream_offsets_[stream_id] != 0)
-    return;
+  // If the control stream has already been written to, do nothing.
+  if (connection_state_->stream_offsets[stream_id] != 0) {
+    return *this;
+  }
 
   // A stream frame containing stream type will be written on the control
   // stream first.
@@ -1456,43 +1339,65 @@
   // frames.
   std::string data = type + settings_data + grease_data;
 
-  AddQuicStreamFrame(stream_id, false, data);
+  AddStreamFrame(stream_id, false, data);
+  return *this;
 }
 
-bool QuicTestPacketMaker::MaybeCoalesceStreamFrame(
-    const quic::QuicFrame& frame) {
-  if (frames_.empty()) {
-    return false;
+std::string QuicTestPacketBuilder::GenerateHttp3SettingsData() const {
+  quic::SettingsFrame settings;
+  settings.values[quic::SETTINGS_MAX_FIELD_SECTION_SIZE] =
+      kQuicMaxHeaderListSize;
+  settings.values[quic::SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
+      quic::kDefaultQpackMaxDynamicTableCapacity;
+  settings.values[quic::SETTINGS_QPACK_BLOCKED_STREAMS] =
+      quic::kDefaultMaximumBlockedStreams;
+  settings.values[quic::SETTINGS_H3_DATAGRAM] = 1;
+  // Greased setting.
+  settings.values[0x40] = 20;
+  return quic::HttpEncoder::SerializeSettingsFrame(settings);
+}
+
+std::string QuicTestPacketBuilder::GenerateHttp3GreaseData() const {
+  return quic::HttpEncoder::SerializeGreasingFrame();
+}
+
+void QuicTestPacketBuilder::InitializeHeader(uint64_t packet_number) {
+  header_.destination_connection_id = DestinationConnectionId();
+  header_.destination_connection_id_included = quic::CONNECTION_ID_PRESENT;
+  header_.source_connection_id = SourceConnectionId();
+  header_.source_connection_id_included = quic::CONNECTION_ID_PRESENT;
+  header_.reset_flag = false;
+  header_.version_flag = ShouldIncludeVersion();
+  header_.form = header_.version_flag ? quic::IETF_QUIC_LONG_HEADER_PACKET
+                                      : quic::IETF_QUIC_SHORT_HEADER_PACKET;
+  header_.long_packet_type = maker_->long_header_type();
+  header_.packet_number_length = quic::PACKET_1BYTE_PACKET_NUMBER;
+  header_.packet_number = quic::QuicPacketNumber(packet_number);
+  if (header_.version_flag) {
+    if (maker_->long_header_type() == quic::INITIAL) {
+      header_.retry_token_length_length =
+          quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1;
+    }
+    header_.length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
   }
-  if (frame.type != quic::STREAM_FRAME ||
-      frames_.back().type != quic::STREAM_FRAME) {
-    return false;
+}
+
+quic::QuicConnectionId QuicTestPacketBuilder::DestinationConnectionId() const {
+  if (maker_->perspective() == quic::Perspective::IS_SERVER) {
+    return quic::EmptyQuicConnectionId();
   }
+  return maker_->connection_id();
+}
 
-  // Make sure they are congruent data segments in the stream.
-  const quic::QuicStreamFrame* new_frame = &frame.stream_frame;
-  quic::QuicStreamFrame* previous_frame = &frames_.back().stream_frame;
-  if (new_frame->stream_id != previous_frame->stream_id ||
-      new_frame->offset !=
-          previous_frame->offset + previous_frame->data_length) {
-    return false;
+quic::QuicConnectionId QuicTestPacketBuilder::SourceConnectionId() const {
+  if (maker_->perspective() == quic::Perspective::IS_CLIENT) {
+    return quic::EmptyQuicConnectionId();
   }
+  return maker_->connection_id();
+}
 
-  // Extend the data buffer to include the data from both frames (into a copy
-  // buffer). This doesn't attempt to limit coalescing to a particular packet
-  // size limit and may need to be updated if a test comes along that
-  // retransmits enough stream data to span multiple packets.
-  std::string data(previous_frame->data_buffer, previous_frame->data_length);
-  data += std::string(new_frame->data_buffer, new_frame->data_length);
-  saved_stream_data_.push_back(std::make_unique<std::string>(data));
-  std::string_view saved_data = *saved_stream_data_.back();
-  previous_frame->data_buffer = saved_data.data();
-  previous_frame->data_length = saved_data.length();
-
-  // Copy the fin state from the last frame.
-  previous_frame->fin = new_frame->fin;
-
-  return true;
+bool QuicTestPacketBuilder::ShouldIncludeVersion() const {
+  return maker_->encryption_level() < quic::ENCRYPTION_FORWARD_SECURE;
 }
 
 }  // namespace net::test
diff --git a/net/quic/quic_test_packet_maker.h b/net/quic/quic_test_packet_maker.h
index de93d1c..9dcfb83a 100644
--- a/net/quic/quic_test_packet_maker.h
+++ b/net/quic/quic_test_packet_maker.h
@@ -10,9 +10,11 @@
 #include <stddef.h>
 #include <sys/types.h>
 
+#include <map>
 #include <memory>
 #include <optional>
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include "base/memory/raw_ptr.h"
@@ -30,8 +32,34 @@
 
 namespace net::test {
 
+class QuicTestPacketBuilder;
+
 class QuicTestPacketMaker {
  public:
+  // A container for the state of a connection, tracking stream offsets,
+  // frames already sent, and so on.
+  struct ConnectionState {
+    ConnectionState();
+    ~ConnectionState();
+
+    // Save the given stream data to last for the duration of this packet build.
+    std::string_view SaveStreamData(std::string_view data);
+
+    void Reset();
+
+    // Current offset of each QUIC stream on this connection.
+    std::map<quic::QuicStreamId, quic::QuicStreamOffset> stream_offsets;
+
+    // Save a copy of stream frame data that QuicStreamFrame objects can refer
+    // to.
+    std::vector<std::unique_ptr<std::string>> saved_stream_data;
+
+    // If `save_packet_frames_` is true, save generated packets in
+    // `saved_frames_`, allowing retransmission packets to be built.
+    bool save_packet_frames = false;
+    std::map<quic::QuicPacketNumber, quic::QuicFrames> saved_frames;
+  };
+
   // |client_priority_uses_incremental| affects the output of any method that
   // includes HTTP3 priority data. The protocol default is to omit the
   // incremental flag in the priority data but HTTP streams may enable it
@@ -43,12 +71,11 @@
                       quic::Perspective perspective,
                       bool client_priority_uses_incremental = false,
                       bool use_priority_header = false);
+  ~QuicTestPacketMaker();
 
   QuicTestPacketMaker(const QuicTestPacketMaker&) = delete;
   QuicTestPacketMaker& operator=(const QuicTestPacketMaker&) = delete;
 
-  ~QuicTestPacketMaker();
-
   void set_hostname(const std::string& host);
 
   void set_use_priority_header(const bool use_priority_header) {
@@ -59,72 +86,53 @@
     connection_id_ = connection_id;
   }
 
-  std::unique_ptr<quic::QuicReceivedPacket> MakeConnectivityProbingPacket(
-      uint64_t num);
+  // Begin building a packet. Call methods on the returned builder to
+  // define the frames in the packet, and finish with its `Build` method.
+  QuicTestPacketBuilder& Packet(uint64_t packet_number);
 
-  std::unique_ptr<quic::QuicReceivedPacket> MakePingPacket(uint64_t num);
+  std::unique_ptr<quic::QuicReceivedPacket> MakeConnectivityProbingPacket(
+      uint64_t packet_number);
+
+  std::unique_ptr<quic::QuicReceivedPacket> MakePingPacket(
+      uint64_t packet_number);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeRetireConnectionIdPacket(
-      uint64_t num,
+      uint64_t packet_number,
       uint64_t sequence_number);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeNewConnectionIdPacket(
-      uint64_t num,
-      const quic::QuicConnectionId& cid,
-      uint64_t sequence_number,
-      uint64_t retire_prior_to);
-
-  std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndNewConnectionIdPacket(
-      uint64_t num,
-      uint64_t largest_received,
-      uint64_t smallest_received,
+      uint64_t packet_number,
       const quic::QuicConnectionId& cid,
       uint64_t sequence_number,
       uint64_t retire_prior_to);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeDummyCHLOPacket(
-      uint64_t packet_num);
-
-  std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndPingPacket(
-      uint64_t num,
-      uint64_t largest_received,
-      uint64_t smallest_received);
-
-  std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndRetireConnectionIdPacket(
-      uint64_t num,
-      uint64_t largest_received,
-      uint64_t smallest_received,
-      uint64_t sequence_number);
+      uint64_t packet_number);
 
   std::unique_ptr<quic::QuicReceivedPacket>
   MakeRetransmissionAndRetireConnectionIdPacket(
-      uint64_t num,
+      uint64_t packet_number,
       const std::vector<uint64_t>& original_packet_numbers,
       uint64_t sequence_number);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeStreamsBlockedPacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamCount stream_count,
       bool unidirectional);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeMaxStreamsPacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamCount stream_count,
       bool unidirectional);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeRstPacket(
-      uint64_t num,
-      quic::QuicStreamId stream_id,
-      quic::QuicRstStreamErrorCode error_code);
-
-  std::unique_ptr<quic::QuicReceivedPacket> MakeRstPacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code,
-      bool include_stop_sending_if_v99);
+      bool include_stop_sending_if_v99 = true);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeRstAndDataPacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId rst_stream_id,
       quic::QuicRstStreamErrorCode rst_error_code,
       quic::QuicStreamId data_stream_id,
@@ -132,7 +140,7 @@
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeRetransmissionRstAndDataPacket(
       const std::vector<uint64_t>& original_packet_numbers,
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId rst_stream_id,
       quic::QuicRstStreamErrorCode rst_error_code,
       quic::QuicStreamId data_stream_id,
@@ -140,14 +148,14 @@
       uint64_t retransmit_frame_count = 0);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeDataAndRstPacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId data_stream_id,
       std::string_view data,
       quic::QuicStreamId rst_stream_id,
       quic::QuicRstStreamErrorCode rst_error_code);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeDataRstAndAckPacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId data_stream_id,
       std::string_view data,
       quic::QuicStreamId rst_stream_id,
@@ -156,22 +164,15 @@
       uint64_t smallest_received);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndRstPacket(
-      uint64_t num,
-      quic::QuicStreamId stream_id,
-      quic::QuicRstStreamErrorCode error_code,
-      uint64_t largest_received,
-      uint64_t smallest_received);
-
-  std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndRstPacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code,
       uint64_t largest_received,
       uint64_t smallest_received,
-      bool include_stop_sending_if_v99);
+      bool include_stop_sending_if_v99 = true);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeRstAckAndConnectionClosePacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code,
       uint64_t largest_received,
@@ -180,7 +181,7 @@
       const std::string& quic_error_details);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeRstAckAndDataPacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code,
       uint64_t largest_received,
@@ -190,7 +191,7 @@
       std::string_view data);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeAckDataAndRst(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code,
       uint64_t largest_received,
@@ -200,7 +201,7 @@
       std::string_view data);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeAckRstAndDataPacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code,
       uint64_t largest_received,
@@ -210,14 +211,14 @@
       std::string_view data);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeRstAndConnectionClosePacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code,
       quic::QuicErrorCode quic_error,
       const std::string& quic_error_details);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeDataRstAndConnectionClosePacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId data_stream_id,
       std::string_view data,
       quic::QuicStreamId rst_stream_id,
@@ -227,7 +228,7 @@
 
   std::unique_ptr<quic::QuicReceivedPacket>
   MakeDataRstAckAndConnectionClosePacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId data_stream_id,
       std::string_view data,
       quic::QuicStreamId rst_stream_id,
@@ -239,7 +240,7 @@
 
   std::unique_ptr<quic::QuicReceivedPacket>
   MakeDataRstAckAndConnectionClosePacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId data_stream_id,
       std::string_view data,
       quic::QuicStreamId rst_stream_id,
@@ -251,12 +252,12 @@
       uint64_t frame_type);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeStopSendingPacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndConnectionClosePacket(
-      uint64_t num,
+      uint64_t packet_number,
       uint64_t largest_received,
       uint64_t smallest_received,
       quic::QuicErrorCode quic_error,
@@ -264,12 +265,12 @@
       uint64_t frame_type);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeConnectionClosePacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicErrorCode quic_error,
       const std::string& quic_error_details);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeGoAwayPacket(
-      uint64_t num,
+      uint64_t packet_number,
       quic::QuicErrorCode error_code,
       std::string reason_phrase);
 
@@ -429,14 +430,19 @@
   spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status,
                                             const std::string& alt_svc) const;
 
+  // Reset some of the state in the packet maker.
+  // TODO(https://issues.chromium.org/u/1/issues/335279177): reset all state.
   void Reset();
 
-  quic::QuicStreamOffset stream_offset(quic::QuicStreamId stream_id) {
-    return stream_offsets_[stream_id];
-  }
+  quic::ParsedQuicVersion version() { return version_; }
+  quic::Perspective perspective() { return perspective_; }
+  const quic::QuicClock* clock() { return clock_.get(); }
+  quic::EncryptionLevel encryption_level() { return encryption_level_; }
+  quic::QuicLongHeaderType long_header_type() { return long_header_type_; }
+  quic::QuicConnectionId connection_id() { return connection_id_; }
 
   void set_save_packet_frames(bool save_packet_frames) {
-    save_packet_frames_ = save_packet_frames;
+    connection_state_.save_packet_frames = save_packet_frames;
   }
 
   std::string QpackEncodeHeaders(quic::QuicStreamId stream_id,
@@ -445,92 +451,31 @@
 
   void set_ecn_codepoint(quic::QuicEcnCodepoint ecn) { ecn_codepoint_ = ecn; }
 
- private:
-  // Initialize header of next packet to build.
-  void InitializeHeader(uint64_t packet_number);
+ protected:
+  friend class QuicTestPacketBuilder;
+  std::unique_ptr<quic::QuicReceivedPacket> FinishPacket(
+      quic::QuicPacketHeader header,
+      quic::QuicFrames frames,
+      std::unique_ptr<quic::QuicStreamFrameDataProducer> data_producer);
 
-  // Add frames to current packet.
-  void AddQuicPaddingFrame();
-  void AddQuicPingFrame();
-  void AddQuicRetireConnectionIdFrame(uint64_t sequence_number);
-  void AddQuicNewConnectionIdFrame(const quic::QuicConnectionId& cid,
-                                   uint64_t sequence_number,
-                                   uint64_t retire_prior_to,
-                                   quic::StatelessResetToken reset_token);
-  void AddQuicMaxStreamsFrame(quic::QuicControlFrameId control_frame_id,
-                              quic::QuicStreamCount stream_count,
-                              bool unidirectional);
-  void AddQuicStreamsBlockedFrame(quic::QuicControlFrameId control_frame_id,
-                                  quic::QuicStreamCount stream_count,
-                                  bool unidirectional);
-  // Use and increase stream's current offset.
-  void AddQuicStreamFrame(quic::QuicStreamId stream_id,
-                          bool fin,
-                          std::string_view data);
-  // Use |offset| and do not change stream's current offset.
-  void AddQuicStreamFrameWithOffset(quic::QuicStreamId stream_id,
-                                    bool fin,
-                                    quic::QuicStreamOffset offset,
-                                    std::string_view data);
-  void AddQuicAckFrame(uint64_t largest_received, uint64_t smallest_received);
-  void AddQuicAckFrame(uint64_t first_received,
-                       uint64_t largest_received,
-                       uint64_t smallest_received,
-                       std::optional<quic::QuicEcnCounts> ecn = std::nullopt);
-  void AddQuicMessageFrame(std::string_view data);
-  void AddQuicRstStreamFrame(quic::QuicStreamId stream_id,
-                             quic::QuicRstStreamErrorCode error_code);
-  void AddQuicConnectionCloseFrame(quic::QuicErrorCode quic_error,
-                                   const std::string& quic_error_details);
-  void AddQuicConnectionCloseFrame(quic::QuicErrorCode quic_error,
-                                   const std::string& quic_error_details,
-                                   uint64_t frame_type);
-  void AddQuicGoAwayFrame(quic::QuicErrorCode error_code,
-                          std::string reason_phrase);
-  void AddQuicPathResponseFrame();
-  void AddQuicPathChallengeFrame();
-  void AddQuicStopSendingFrame(quic::QuicStreamId stream_id,
-                               quic::QuicRstStreamErrorCode error_code);
-  void AddQuicCryptoFrame(quic::EncryptionLevel level,
-                          quic::QuicStreamOffset offset,
-                          quic::QuicPacketLength data_length);
+ private:
   void AddPriorityHeader(spdy::SpdyPriority spdy_priority,
                          spdy::Http2HeaderBlock* headers);
 
-  // Build packet using |header_|, |frames_|, and |data_producer_|,
-  // and clear |frames_| and |data_producer_| afterwards.
-  std::unique_ptr<quic::QuicReceivedPacket> BuildPacket();
-
-  // Build packet using |header_|, |frames|, and |data_producer|.
-  std::unique_ptr<quic::QuicReceivedPacket> BuildPacketImpl(
-      const quic::QuicFrames& frames,
-      quic::QuicStreamFrameDataProducer* data_producer);
-
-  bool ShouldIncludeVersion() const;
-
-  quic::QuicConnectionId DestinationConnectionId() const;
-  quic::QuicConnectionId SourceConnectionId() const;
-
   quic::QuicStreamId GetFirstBidirectionalStreamId() const;
 
-  std::string GenerateHttp3SettingsData();
   std::string GenerateHttp3PriorityData(spdy::SpdyPriority spdy_priority,
                                         quic::QuicStreamId stream_id);
-  std::string GenerateHttp3GreaseData();
-
-  void MaybeAddHttp3SettingsFrames();
-  bool MaybeCoalesceStreamFrame(const quic::QuicFrame& frame);
 
   // Parameters used throughout the lifetime of the class.
-  quic::ParsedQuicVersion version_;
   quic::QuicConnectionId connection_id_;
+  quic::ParsedQuicVersion version_;
   raw_ptr<const quic::QuicClock> clock_;  // Not owned.
   std::string host_;
   quic::NoopDecoderStreamErrorDelegate decoder_stream_error_delegate_;
   quic::test::NoopQpackStreamSenderDelegate encoder_stream_sender_delegate_;
   quic::QpackEncoder qpack_encoder_;
   quic::test::MockRandom random_generator_;
-  std::map<quic::QuicStreamId, quic::QuicStreamOffset> stream_offsets_;
   quic::Perspective perspective_;
   quic::EncryptionLevel encryption_level_ = quic::ENCRYPTION_FORWARD_SECURE;
   quic::QuicLongHeaderType long_header_type_ = quic::INVALID_PACKET_TYPE;
@@ -541,21 +486,126 @@
   // Add the priority header to outbound requests
   bool use_priority_header_;
 
-  // Save a copy of stream frame data that QuicStreamFrame objects can refer to.
-  std::vector<std::unique_ptr<std::string>> saved_stream_data_;
-  // If |save_packet_frames_| is true, save generated packets in
-  // |saved_frames_|, allowing retransmission packets to be built.
-  bool save_packet_frames_ = false;
-  std::map<quic::QuicPacketNumber, quic::QuicFrames> saved_frames_;
+  ConnectionState connection_state_;
+
+  // The current packet builder, if one is in progress.
+  std::unique_ptr<QuicTestPacketBuilder> builder_;
+
+  // Explicit Congestion Notification (ECN) codepoint to use when making
+  // packets.
+  quic::QuicEcnCodepoint ecn_codepoint_ = quic::ECN_NOT_ECT;
+};
+
+// A packet builder provides methods for building a new packet, usable via
+// `QuicTestPacketMaker::Packet`. Finish building the packet with the `Build`
+// method.
+//
+// This implements a "builder" pattern, and method calls can be chained:
+//
+//   auto packet = maker.Packet(num)
+//     ->AddFooFrame(..)
+//     ->AddBarFrame(..)
+//     ->Build();
+//
+//  Methods may also be called individually:
+//
+//  auto* builder = maker.Packet(num);
+//  builder->AddFooFrame(..);
+//  builder->AddBarFrame(..);
+//  auto packet = builder->Build();
+class QuicTestPacketBuilder {
+ public:
+  QuicTestPacketBuilder(uint64_t packet_number,
+                        QuicTestPacketMaker* maker,
+                        QuicTestPacketMaker::ConnectionState* connection_state);
+  ~QuicTestPacketBuilder();
+
+  QuicTestPacketBuilder& AddPaddingFrame();
+  QuicTestPacketBuilder& AddPingFrame();
+  QuicTestPacketBuilder& AddRetireConnectionIdFrame(uint64_t sequence_number);
+  QuicTestPacketBuilder& AddNewConnectionIdFrame(
+      const quic::QuicConnectionId& cid,
+      uint64_t sequence_number,
+      uint64_t retire_prior_to,
+      quic::StatelessResetToken reset_token);
+  QuicTestPacketBuilder& AddMaxStreamsFrame(
+      quic::QuicControlFrameId control_frame_id,
+      quic::QuicStreamCount stream_count,
+      bool unidirectional);
+  QuicTestPacketBuilder& AddStreamsBlockedFrame(
+      quic::QuicControlFrameId control_frame_id,
+      quic::QuicStreamCount stream_count,
+      bool unidirectional);
+  // Add a stream frame, using an offset calculated from any previous stream
+  // frames with this stream_id. The given data is copied and may be deallocated
+  // after this call.
+  QuicTestPacketBuilder& AddStreamFrame(quic::QuicStreamId stream_id,
+                                        bool fin,
+                                        std::string_view data);
+  QuicTestPacketBuilder& AddAckFrame(
+      uint64_t first_received,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      std::optional<quic::QuicEcnCounts> ecn = std::nullopt);
+  // Add a DATAGRAM frame. The given data is copied and may be deallocated after
+  // this call.
+  QuicTestPacketBuilder& AddMessageFrame(std::string_view data);
+  QuicTestPacketBuilder& AddRstStreamFrame(
+      quic::QuicStreamId stream_id,
+      quic::QuicRstStreamErrorCode error_code);
+  QuicTestPacketBuilder& AddConnectionCloseFrame(
+      quic::QuicErrorCode quic_error,
+      const std::string& quic_error_details,
+      uint64_t frame_type = 0);
+  QuicTestPacketBuilder& AddGoAwayFrame(quic::QuicErrorCode error_code,
+                                        std::string reason_phrase);
+  QuicTestPacketBuilder& AddPathResponseFrame();
+  QuicTestPacketBuilder& AddPathChallengeFrame();
+  QuicTestPacketBuilder& AddStopSendingFrame(
+      quic::QuicStreamId stream_id,
+      quic::QuicRstStreamErrorCode error_code);
+  QuicTestPacketBuilder& AddCryptoFrame(quic::EncryptionLevel level,
+                                        quic::QuicStreamOffset offset,
+                                        const quic::QuicData& data);
+
+  // Add a frame to the packet.
+  QuicTestPacketBuilder& AddFrame(quic::QuicFrame frame);
+
+  // Add a frame to the packet, coalescing adjacent stream frames for the same
+  // stream ID into a single frame.
+  QuicTestPacketBuilder& AddFrameWithCoalescing(const quic::QuicFrame& frame);
+
+  // Complete the building process and return the resulting packet.
+  std::unique_ptr<quic::QuicReceivedPacket> Build();
+
+  // Add an H/3 SETTINGS frame on the control stream if one has not already been
+  // sent.
+  QuicTestPacketBuilder& MaybeAddHttp3SettingsFrames();
+
+ private:
+  std::string GenerateHttp3SettingsData() const;
+  std::string GenerateHttp3GreaseData() const;
+
+  void InitializeHeader(uint64_t packet_number);
+
+  quic::QuicConnectionId DestinationConnectionId() const;
+  quic::QuicConnectionId SourceConnectionId() const;
+
+  bool ShouldIncludeVersion() const;
 
   // State necessary for building the current packet.
   quic::QuicPacketHeader header_;
   quic::QuicFrames frames_;
   std::unique_ptr<quic::test::SimpleDataProducer> data_producer_;
 
-  // Explicit Congestion Notification (ECN) codepoint to use when making
-  // packets.
-  quic::QuicEcnCodepoint ecn_codepoint_ = quic::ECN_NOT_ECT;
+  // The `QuicTestPacketMaker` for which we are building this packet.Reset some
+  // of the state in the packet maker.
+  // TODO(https://issues.chromium.org/u/1/issues/335279177): reset all state.
+  raw_ptr<QuicTestPacketMaker> maker_;
+
+  // The connection state. This is owned by `maker_` but borrowed for
+  // the lifetime of this builder.
+  raw_ptr<QuicTestPacketMaker::ConnectionState> connection_state_;
 };
 
 }  // namespace net::test
diff --git a/net/socket/connect_job_params_factory.cc b/net/socket/connect_job_params_factory.cc
index 53cd4a8..0749f7e 100644
--- a/net/socket/connect_job_params_factory.cc
+++ b/net/socket/connect_job_params_factory.cc
@@ -284,7 +284,7 @@
     ssl_config.disable_cert_verification_network_fetches =
         disable_cert_network_fetches;
 
-    // TODO(https://crbug.com/964642): Also enable 0-RTT for TLS proxies.
+    // TODO(crbug.com/41459647): Also enable 0-RTT for TLS proxies.
     ssl_config.early_data_enabled =
         *common_connect_job_params->enable_early_data;
   }
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index 10cd0df..db52f31 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -377,7 +377,7 @@
   // is called to complete the asynchronous read operation.
   // data.async is ignored, and this read is completed synchronously as
   // part of this call.
-  // TODO(rch): this should take a StringPiece since most of the fields
+  // TODO(rch): this should take a std::string_view since most of the fields
   // are ignored.
   virtual void OnReadComplete(const MockRead& data) = 0;
   // If an async IO is pending because the SocketDataProvider returned
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc
index bd08bd87..223df31 100644
--- a/net/socket/ssl_client_socket_impl.cc
+++ b/net/socket/ssl_client_socket_impl.cc
@@ -804,7 +804,7 @@
   }
 
   if (context_->config().ech_enabled) {
-    // TODO(https://crbug.com/1509597): Enable this unconditionally.
+    // TODO(crbug.com/41482204): Enable this unconditionally.
     SSL_set_enable_ech_grease(ssl_.get(), 1);
   }
   if (!ssl_config_.ech_config_list.empty()) {
@@ -983,7 +983,7 @@
   // too large. See
   // https://boringssl-review.googlesource.com/c/boringssl/+/34948.
   //
-  // TODO(https://crbug.com/958638): It is also a step in making TLS 1.3 client
+  // TODO(crbug.com/41456237): It is also a step in making TLS 1.3 client
   // certificate alerts less unreliable.
   base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
       FROM_HERE,
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc
index 879ad2e..f4c87b8 100644
--- a/net/socket/ssl_client_socket_unittest.cc
+++ b/net/socket/ssl_client_socket_unittest.cc
@@ -5378,7 +5378,7 @@
   ASSERT_TRUE(client->GetSSLInfo(&ssl_info));
   EXPECT_EQ(ssl_info.cert_status, expired_result.cert_status);
 
-  // TODO(https://crbug.com/912383): The server sees
+  // TODO(crbug.com/41430308): The server sees
   // ERR_BAD_SSL_CLIENT_AUTH_CERT because its peer (the client) alerts it with
   // bad_certificate. The alert-mapping code assumes it is running on a client,
   // so it translates bad_certificate to ERR_BAD_SSL_CLIENT_AUTH_CERT, which
diff --git a/net/spdy/spdy_session_pool_unittest.cc b/net/spdy/spdy_session_pool_unittest.cc
index 88b291f..b65ed8e 100644
--- a/net/spdy/spdy_session_pool_unittest.cc
+++ b/net/spdy/spdy_session_pool_unittest.cc
@@ -1991,7 +1991,7 @@
 
   // Close the active stream.
   active_stream->Close();
-  // TODO(https://crbug.com/982499): The invalidated session should be closed
+  // TODO(crbug.com/41469912): The invalidated session should be closed
   // after a RunUntilIdle(), but it is not.
 }
 
diff --git a/net/ssl/ssl_platform_key_mac.cc b/net/ssl/ssl_platform_key_mac.cc
index fb4bc80..02a2276 100644
--- a/net/ssl/ssl_platform_key_mac.cc
+++ b/net/ssl/ssl_platform_key_mac.cc
@@ -90,7 +90,7 @@
   ~SSLPlatformKeySecKey() override = default;
 
   std::string GetProviderName() override {
-    // TODO(https://crbug.com/900721): Is there a more descriptive name to
+    // TODO(crbug.com/41423739): Is there a more descriptive name to
     // return?
     return "SecKey";
   }
diff --git a/net/test/cert_builder.cc b/net/test/cert_builder.cc
index 33248cc..ea43b54c 100644
--- a/net/test/cert_builder.cc
+++ b/net/test/cert_builder.cc
@@ -79,7 +79,7 @@
   return std::string(std::begin(kDer), std::end(kDer));
 }
 
-// Adds bytes (specified as a StringPiece) to the given CBB.
+// Adds bytes (specified as a std::string_view) to the given CBB.
 // The argument ordering follows the boringssl CBB_* api style.
 bool CBBAddBytes(CBB* cbb, std::string_view bytes) {
   return CBB_add_bytes(cbb, reinterpret_cast<const uint8_t*>(bytes.data()),
diff --git a/net/test/embedded_test_server/default_handlers.cc b/net/test/embedded_test_server/default_handlers.cc
index e897b29..e174a517 100644
--- a/net/test/embedded_test_server/default_handlers.cc
+++ b/net/test/embedded_test_server/default_handlers.cc
@@ -137,7 +137,7 @@
   return http_response;
 }
 
-// TODO(https://crbug.com/1138913): Remove when request handlers are
+// TODO(crbug.com/40153192): Remove when request handlers are
 // implementable in Android's embedded test server implementation
 std::unique_ptr<HttpResponse> HandleEchoCriticalHeader(
     const HttpRequest& request) {
diff --git a/net/test/embedded_test_server/http_request.h b/net/test/embedded_test_server/http_request.h
index b9c5c5b..edb1a2b 100644
--- a/net/test/embedded_test_server/http_request.h
+++ b/net/test/embedded_test_server/http_request.h
@@ -41,7 +41,7 @@
 // examine a HTTP request.
 struct HttpRequest {
   struct CaseInsensitiveStringComparator {
-    // Allow using StringPiece instead of string for `find()`.
+    // Allow using std::string_view instead of string for `find()`.
     using is_transparent = void;
 
     bool operator()(std::string_view left, std::string_view right) const {
diff --git a/net/test/gtest_util.h b/net/test/gtest_util.h
index b3e787f5..1c8a462 100644
--- a/net/test/gtest_util.h
+++ b/net/test/gtest_util.h
@@ -39,9 +39,9 @@
   return arg == net::OK;
 }
 
-// A gMock matcher for base::StringPiece arguments.
+// A gMock matcher for std::string_view arguments.
 // gMock's built-in HasSubstrMatcher does not work,
-// because base::StringPiece cannot be implicitly converted to std::string.
+// because std::string_view cannot be implicitly converted to std::string.
 class StringPieceHasSubstrMatcher {
  public:
   explicit StringPieceHasSubstrMatcher(const std::string& substring)
diff --git a/net/test/revocation_builder.cc b/net/test/revocation_builder.cc
index 6e5c5e18..47f8d7b6 100644
--- a/net/test/revocation_builder.cc
+++ b/net/test/revocation_builder.cc
@@ -31,7 +31,7 @@
   return std::string(std::begin(kSHA1), std::end(kSHA1));
 }
 
-// Adds bytes (specified as a StringPiece) to the given CBB.
+// Adds bytes (specified as a std::string_view) to the given CBB.
 // The argument ordering follows the boringssl CBB_* api style.
 bool CBBAddBytes(CBB* cbb, std::string_view bytes) {
   return CBB_add_bytes(cbb, reinterpret_cast<const uint8_t*>(bytes.data()),
diff --git a/net/tools/root_store_tool/root_store_tool.cc b/net/tools/root_store_tool/root_store_tool.cc
index 90e3100..db934af 100644
--- a/net/tools/root_store_tool/root_store_tool.cc
+++ b/net/tools/root_store_tool/root_store_tool.cc
@@ -271,7 +271,7 @@
     // struct EVMetadata {
     //  static const size_t kMaxOIDsPerCA = 2;
     //  SHA256HashValue fingerprint;
-    //  const base::StringPiece policy_oids[kMaxOIDsPerCA];
+    //  const std::string_view policy_oids[kMaxOIDsPerCA];
     // };
     string_to_write += "    {\n";
     string_to_write += "        {{";
diff --git a/net/traffic_annotation/network_traffic_annotation.h b/net/traffic_annotation/network_traffic_annotation.h
index 3a1b5fe..1e931962 100644
--- a/net/traffic_annotation/network_traffic_annotation.h
+++ b/net/traffic_annotation/network_traffic_annotation.h
@@ -147,7 +147,7 @@
 //
 // An empty and a sample template for the text-encoded protobuf can be found in
 // tools/traffic_annotation/sample_traffic_annotation.cc.
-// TODO(crbug.com/690323): Add tools to check annotation text's format during
+// TODO(crbug.com/40505662): Add tools to check annotation text's format during
 // presubmit checks.
 template <size_t N1, size_t N2>
 constexpr NetworkTrafficAnnotationTag DefineNetworkTrafficAnnotation(
diff --git a/remoting/host/win/rdp_client_unittest.cc b/remoting/host/win/rdp_client_unittest.cc
index 48d6245..8e6cde81 100644
--- a/remoting/host/win/rdp_client_unittest.cc
+++ b/remoting/host/win/rdp_client_unittest.cc
@@ -154,7 +154,7 @@
 }
 
 // Creates a loopback RDP connection.
-// TODO(crbug.com/1523705): Consistently times out on Windows 11 ARM64.
+// TODO(crbug.com/41496654): Consistently times out on Windows 11 ARM64.
 #if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_ARM64)
 #define MAYBE_Basic DISABLED_Basic
 #else
diff --git a/remoting/protocol/ssl_hmac_channel_authenticator_unittest.cc b/remoting/protocol/ssl_hmac_channel_authenticator_unittest.cc
index dc46ee0..2659820 100644
--- a/remoting/protocol/ssl_hmac_channel_authenticator_unittest.cc
+++ b/remoting/protocol/ssl_hmac_channel_authenticator_unittest.cc
@@ -206,7 +206,7 @@
   host_auth_ = SslHmacChannelAuthenticator::CreateForHost(host_cert_, key_pair_,
                                                           kTestSharedSecret);
 
-  // TODO(https://crbug.com/912383): The server sees
+  // TODO(crbug.com/41430308): The server sees
   // ERR_BAD_SSL_CLIENT_AUTH_CERT because its peer (the client) alerts it with
   // bad_certificate. The alert-mapping code assumes it is running on a client,
   // so it translates bad_certificate to ERR_BAD_SSL_CLIENT_AUTH_CERT, which
diff --git a/remoting/protocol/webrtc_video_stream.cc b/remoting/protocol/webrtc_video_stream.cc
index f9d9bf0..eeb5885 100644
--- a/remoting/protocol/webrtc_video_stream.cc
+++ b/remoting/protocol/webrtc_video_stream.cc
@@ -508,7 +508,7 @@
   // Convert the frame quantizer to a measure of frame quality between 0 and
   // 100, for a simple visualization of quality over time. The quantizer from
   // VP8/VP9 encoder lies within 0-63, with 0 representing a lossless frame.
-  // TODO(crbug.com/891571): Remove |quantizer| from the WebrtcVideoEncoder
+  // TODO(crbug.com/41418600): Remove |quantizer| from the WebrtcVideoEncoder
   // interface, and move this logic to the encoders.
   stats.frame_quality = (63 - frame.quantizer) * 100 / 63;
 
diff --git a/services/audio/user_input_monitor.h b/services/audio/user_input_monitor.h
index 0698888..26f9b61 100644
--- a/services/audio/user_input_monitor.h
+++ b/services/audio/user_input_monitor.h
@@ -12,7 +12,7 @@
 
 namespace audio {
 
-// TODO(https://crbug.com/836226) remove inheritance after switching to audio
+// TODO(crbug.com/40573245) remove inheritance after switching to audio
 // service input streams.
 class UserInputMonitor : public media::UserInputMonitor {
  public:
diff --git a/services/cert_verifier/integration_tests/network_service_unittest.cc b/services/cert_verifier/integration_tests/network_service_unittest.cc
index e34d127..edca554 100644
--- a/services/cert_verifier/integration_tests/network_service_unittest.cc
+++ b/services/cert_verifier/integration_tests/network_service_unittest.cc
@@ -149,7 +149,7 @@
   mojo::Remote<network::mojom::URLLoader> loader_;
 };
 
-// TODO(crbug.com/860189): AIA tests fail on iOS
+// TODO(crbug.com/41399468): AIA tests fail on iOS
 #if BUILDFLAG(IS_IOS)
 #define MAYBE(test_name) DISABLED_##test_name
 #else
diff --git a/services/network/brokered_udp_client_socket.h b/services/network/brokered_udp_client_socket.h
index 208b5fa..25765a5 100644
--- a/services/network/brokered_udp_client_socket.h
+++ b/services/network/brokered_udp_client_socket.h
@@ -60,7 +60,7 @@
   BrokeredUdpClientSocket& operator=(const BrokeredUdpClientSocket&) = delete;
 
   // DatagramClientSocket implementation.
-  // TODO(https://crbug.com/1444811): Remove Connect, ConnectUsingNetwork, and
+  // TODO(crbug.com/40267879): Remove Connect, ConnectUsingNetwork, and
   // ConnectUsingDefaultNetwork once consumers have been migrated to only call
   // Connect*Async methods.
   int Connect(const net::IPEndPoint& address) override;
diff --git a/services/network/cookie_settings_unittest.cc b/services/network/cookie_settings_unittest.cc
index bcafba94..3c8169d6 100644
--- a/services/network/cookie_settings_unittest.cc
+++ b/services/network/cookie_settings_unittest.cc
@@ -122,7 +122,7 @@
   kHostIndexedMetadataGrantsEnabled
 };
 
-class CookieSettingsTestBase {
+class CookieSettingsTestBase : public testing::Test {
  public:
   CookieSettingsTestBase()
       : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
@@ -155,14 +155,46 @@
   base::test::TaskEnvironment task_environment_;
 };
 
+// Default test class to be used by most tests. If you want to add a new
+// parameter, consider whether all test cases actually require this parameter
+// or whether it is sufficient to add a new subclass of CookieSettingsTestBase.
 class CookieSettingsTest
     : public CookieSettingsTestBase,
-      public testing::TestWithParam<
+      public testing::WithParamInterface<
+          std::tuple</*kHostIndexedMetadataGrantsEnabled*/ bool>> {
+ public:
+  CookieSettingsTest() {
+    std::vector<base::test::FeatureRefAndParams> enabled_features;
+    std::vector<base::test::FeatureRef> disabled_features;
+
+    if (IsHostIndexedMetadataGrantsEnabled()) {
+      enabled_features.push_back(
+          {content_settings::features::kHostIndexedMetadataGrants, {}});
+    } else {
+      disabled_features.push_back(
+          content_settings::features::kHostIndexedMetadataGrants);
+    }
+
+    feature_list_.InitWithFeaturesAndParameters(enabled_features,
+                                                disabled_features);
+  }
+
+  bool IsHostIndexedMetadataGrantsEnabled() const {
+    return std::get<0>(GetParam());
+  }
+};
+
+// Parameterized class that tests combinations of StorageAccess grants and 3pcd
+// grants. Tests that don't need the whole range of combinations should create
+// their own parameterized subclasses.
+class CookieSettingsTestP
+    : public CookieSettingsTestBase,
+      public testing::WithParamInterface<
           std::tuple</*kGrantSource*/ GrantSource,
                      /*kBlockSource*/ BlockSource,
                      /*kHostIndexedMetadataGrantsEnabled*/ bool>> {
  public:
-  CookieSettingsTest() {
+  CookieSettingsTestP() {
     std::vector<base::test::FeatureRefAndParams> enabled_features;
     std::vector<base::test::FeatureRef> disabled_features;
 
@@ -185,8 +217,8 @@
                                                 disabled_features);
   }
 
-  // Indicates whether the setting comes from the testing flag if the test case
-  // has 3pc blocked.
+  // Indicates whether the setting comes from the testing flag if the
+  // test case has 3pc blocked.
   bool IsForceThirdPartyCookieBlockingFlagEnabled() const {
     return std::get<TestVariables::kBlockSource>(GetParam()) ==
            BlockSource::kForceThirdPartyCookieBlockingFlagEnabled;
@@ -224,26 +256,26 @@
     return overrides;
   }
 
-  // Assumes that cookie access would be blocked if not for a Storage Access API
-  // grant. The `allow` parameter indicates the setting to be returned if cookie
-  // access is expected to be allowed.
+  // Assumes that cookie access would be blocked if not for a Storage
+  // Access API grant. The `allow` parameter indicates the setting to
+  // be returned if cookie access is expected to be allowed.
   ContentSetting SettingWithSaaOverride(ContentSetting allow) const {
     DCHECK(allow == CONTENT_SETTING_ALLOW ||
            allow == CONTENT_SETTING_SESSION_ONLY);
     return IsStorageAccessGrantEligible() ? allow : CONTENT_SETTING_BLOCK;
   }
 
-  // A version of above that considers Top-Level Storage Access API grant
-  // instead of Storage Access API grant.
+  // A version of above that considers Top-Level Storage Access API
+  // grant instead of Storage Access API grant.
   ContentSetting SettingWithTopLevelSaaOverride() const {
-    // TODO(crbug.com/40246640): Check TopLevelStorageAccessAPI instead after
-    // separating the feature flag.
+    // TODO(crbug.com/40246640): Check TopLevelStorageAccessAPI
+    // instead after separating the feature flag.
     return IsTopLevelStorageAccessGrantEligible() ? CONTENT_SETTING_ALLOW
                                                   : CONTENT_SETTING_BLOCK;
   }
 
-  // The cookie access result would be blocked if not for a Storage Access API
-  // grant.
+  // The cookie access result would be blocked if not for a Storage
+  // Access API grant.
   net::cookie_util::StorageAccessResult
   BlockedStorageAccessResultWithSaaOverride() const {
     if (IsStorageAccessGrantEligible()) {
@@ -253,12 +285,12 @@
     return net::cookie_util::StorageAccessResult::ACCESS_BLOCKED;
   }
 
-  // A version of above that considers Top-Level Storage Access API grant
-  // instead of Storage Access API grant.
+  // A version of above that considers Top-Level Storage Access API
+  // grant instead of Storage Access API grant.
   net::cookie_util::StorageAccessResult
   BlockedStorageAccessResultWithTopLevelSaaOverride() const {
-    // TODO(crbug.com/40246640): Check TopLevelStorageAccessAPI instead after
-    // separating the feature flag.
+    // TODO(crbug.com/40246640): Check TopLevelStorageAccessAPI
+    // instead after separating the feature flag.
     if (IsTopLevelStorageAccessGrantEligible()) {
       return net::cookie_util::StorageAccessResult::
           ACCESS_ALLOWED_TOP_LEVEL_STORAGE_ACCESS_GRANT;
@@ -270,7 +302,7 @@
 TEST_P(CookieSettingsTest, GetCookieSettingDefault) {
   CookieSettings settings;
   EXPECT_EQ(settings.GetCookieSetting(GURL(kURL), GURL(kURL),
-                                      GetCookieSettingOverrides(), nullptr),
+                                      net::CookieSettingOverrides(), nullptr),
             CONTENT_SETTING_ALLOW);
 }
 
@@ -280,7 +312,7 @@
       ContentSettingsType::COOKIES,
       {CreateSetting(kURL, kURL, CONTENT_SETTING_BLOCK)});
   EXPECT_EQ(settings.GetCookieSetting(GURL(kURL), GURL(kURL),
-                                      GetCookieSettingOverrides(), nullptr),
+                                      net::CookieSettingOverrides(), nullptr),
             CONTENT_SETTING_BLOCK);
 }
 
@@ -296,10 +328,10 @@
        CreateSetting("*", "*", CONTENT_SETTING_ALLOW, base::Time(),
                      "default")});
   EXPECT_EQ(settings.GetCookieSetting(GURL(kURL), GURL(kURL),
-                                      GetCookieSettingOverrides(), nullptr),
+                                      net::CookieSettingOverrides(), nullptr),
             CONTENT_SETTING_SESSION_ONLY);
   EXPECT_EQ(settings.GetCookieSetting(GURL(kOtherURL), GURL(kOtherURL),
-                                      GetCookieSettingOverrides(), nullptr),
+                                      net::CookieSettingOverrides(), nullptr),
             CONTENT_SETTING_BLOCK);
 }
 
@@ -316,14 +348,14 @@
        CreateSetting("*", "*", CONTENT_SETTING_ALLOW, base::Time(), "default",
                      false)});
   EXPECT_EQ(settings.GetCookieSetting(GURL(kURL), GURL(kURL),
-                                      GetCookieSettingOverrides(), nullptr),
+                                      net::CookieSettingOverrides(), nullptr),
             CONTENT_SETTING_SESSION_ONLY);
   EXPECT_EQ(settings.GetCookieSetting(GURL(kOtherURL), GURL(kOtherURL),
-                                      GetCookieSettingOverrides(), nullptr),
+                                      net::CookieSettingOverrides(), nullptr),
             CONTENT_SETTING_BLOCK);
 }
 
-TEST_P(CookieSettingsTest, GetCookieSettingMustMatchBothPatterns) {
+TEST_P(CookieSettingsTestP, GetCookieSettingMustMatchBothPatterns) {
   CookieSettings settings;
   // This setting needs kOtherURL as the secondary pattern.
   settings.set_content_settings(
@@ -351,7 +383,7 @@
       {CreateSetting(kURL, kURL, CONTENT_SETTING_BLOCK),
        CreateSetting("*", kURL, CONTENT_SETTING_SESSION_ONLY)});
   EXPECT_EQ(settings.GetCookieSetting(GURL(kURL), GURL(kURL),
-                                      GetCookieSettingOverrides(), nullptr),
+                                      net::CookieSettingOverrides(), nullptr),
             CONTENT_SETTING_BLOCK);
 }
 
@@ -365,7 +397,7 @@
       {CreateSetting("*", "*", CONTENT_SETTING_ALLOW)});
   settings.set_block_third_party_cookies(false);
   EXPECT_EQ(settings.GetCookieSetting(GURL(kURL), GURL(kOtherURL),
-                                      GetCookieSettingOverrides(), nullptr),
+                                      net::CookieSettingOverrides(), nullptr),
             CONTENT_SETTING_ALLOW);
   histogram_tester.ExpectUniqueSample(
       kAllowedRequestsHistogram,
@@ -379,11 +411,11 @@
       {CreateSetting("*", "*", CONTENT_SETTING_ALLOW)});
   settings.set_block_third_party_cookies(true);
   EXPECT_EQ(settings.GetCookieSetting(GURL(kURL), GURL(kOtherURL),
-                                      GetCookieSettingOverrides(), nullptr),
+                                      net::CookieSettingOverrides(), nullptr),
             CONTENT_SETTING_BLOCK);
 }
 
-TEST_P(CookieSettingsTest,
+TEST_P(CookieSettingsTestP,
        GetCookieSettingOverridePreservesSessionOnlySetting) {
   CookieSettings settings;
   settings.set_content_settings(
@@ -406,13 +438,13 @@
       {CreateSetting(kURL, kOtherURL, CONTENT_SETTING_ALLOW)});
   settings.set_block_third_party_cookies(true);
   EXPECT_EQ(settings.GetCookieSetting(GURL(kURL), GURL(kOtherURL),
-                                      GetCookieSettingOverrides(), nullptr),
+                                      net::CookieSettingOverrides(), nullptr),
             CONTENT_SETTING_ALLOW);
 }
 
 // The Storage Access API should unblock storage access that would otherwise be
 // blocked.
-TEST_P(CookieSettingsTest, GetCookieSettingSAAUnblocks) {
+TEST_P(CookieSettingsTestP, GetCookieSettingSAAUnblocks) {
   GURL top_level_url = GURL(kURL);
   GURL url = GURL(kOtherURL);
   GURL third_url = GURL(kDomainURL);
@@ -492,7 +524,7 @@
   }
 }
 
-TEST_P(CookieSettingsTest, GetCookieSettingSAAUnblocksViaFedCM) {
+TEST_P(CookieSettingsTestP, GetCookieSettingSAAUnblocksViaFedCM) {
   GURL top_level_url = GURL(kURL);
   GURL url = GURL(kOtherURL);
   GURL third_url = GURL(kDomainURL);
@@ -561,7 +593,7 @@
 
 // The Top-Level Storage Access API should unblock storage access that would
 // otherwise be blocked.
-TEST_P(CookieSettingsTest, GetCookieSettingTopLevelStorageAccessUnblocks) {
+TEST_P(CookieSettingsTestP, GetCookieSettingTopLevelStorageAccessUnblocks) {
   const GURL top_level_url(kURL);
   const GURL url(kOtherURL);
   const GURL third_url(kDomainURL);
@@ -648,7 +680,7 @@
 
 // Subdomains of the granted embedding url should not gain access if a valid
 // grant exists.
-TEST_P(CookieSettingsTest, GetCookieSettingSAAResourceWildcards) {
+TEST_P(CookieSettingsTestP, GetCookieSettingSAAResourceWildcards) {
   GURL top_level_url = GURL(kURL);
   GURL url = GURL(kDomainURL);
 
@@ -673,7 +705,7 @@
 
 // Subdomains of the granted top level url should not grant access if a valid
 // grant exists.
-TEST_P(CookieSettingsTest, GetCookieSettingSAATopLevelWildcards) {
+TEST_P(CookieSettingsTestP, GetCookieSettingSAATopLevelWildcards) {
   GURL top_level_url = GURL(kDomainURL);
   GURL url = GURL(kURL);
 
@@ -698,7 +730,7 @@
 
 // Any Storage Access API grant should not override an explicit setting to block
 // cookie access.
-TEST_P(CookieSettingsTest, GetCookieSettingSAARespectsSettings) {
+TEST_P(CookieSettingsTestP, GetCookieSettingSAARespectsSettings) {
   GURL top_level_url = GURL(kURL);
   GURL url = GURL(kOtherURL);
 
@@ -719,7 +751,7 @@
 }
 
 // Once a grant expires access should no longer be given.
-TEST_P(CookieSettingsTest, GetCookieSettingSAAExpiredGrant) {
+TEST_P(CookieSettingsTestP, GetCookieSettingSAAExpiredGrant) {
   GURL top_level_url = GURL(kURL);
   GURL url = GURL(kOtherURL);
 
@@ -751,7 +783,6 @@
             CONTENT_SETTING_BLOCK);
 }
 
-
 TEST_P(CookieSettingsTest, CreateDeleteCookieOnExitPredicateNoSettings) {
   CookieSettings settings;
   EXPECT_FALSE(settings.CreateDeleteCookieOnExitPredicate());
@@ -804,19 +835,19 @@
   EXPECT_EQ(
       settings.GetCookieSetting(GURL("https://foo.com") /* url */,
                                 GURL("chrome://foo") /* first_party_url */,
-                                GetCookieSettingOverrides()),
+                                net::CookieSettingOverrides()),
       CONTENT_SETTING_ALLOW);
 
   EXPECT_EQ(
       settings.GetCookieSetting(GURL("chrome://foo") /* url */,
                                 GURL("https://foo.com") /* first_party_url */,
-                                GetCookieSettingOverrides()),
+                                net::CookieSettingOverrides()),
       CONTENT_SETTING_BLOCK);
 
   EXPECT_EQ(
       settings.GetCookieSetting(GURL("http://foo.com") /* url */,
                                 GURL("chrome://foo") /* first_party_url */,
-                                GetCookieSettingOverrides()),
+                                net::CookieSettingOverrides()),
       CONTENT_SETTING_BLOCK);
 }
 
@@ -828,19 +859,19 @@
   EXPECT_EQ(settings.GetCookieSetting(
                 GURL("http://foo.com") /* url */,
                 GURL("chrome-extension://foo") /* first_party_url */,
-                GetCookieSettingOverrides()),
+                net::CookieSettingOverrides()),
             CONTENT_SETTING_ALLOW);
 
   EXPECT_EQ(settings.GetCookieSetting(
                 GURL("http://foo.com") /* url */,
                 GURL("other-scheme://foo") /* first_party_url */,
-                GetCookieSettingOverrides()),
+                net::CookieSettingOverrides()),
             CONTENT_SETTING_BLOCK);
 
   EXPECT_EQ(
       settings.GetCookieSetting(GURL("chrome-extension://foo") /* url */,
                                 GURL("http://foo.com") /* first_party_url */,
-                                GetCookieSettingOverrides()),
+                                net::CookieSettingOverrides()),
       CONTENT_SETTING_BLOCK);
 }
 
@@ -852,19 +883,19 @@
   EXPECT_EQ(settings.GetCookieSetting(
                 GURL("chrome-extension://bar") /* url */,
                 GURL("chrome-extension://foo") /* first_party_url */,
-                GetCookieSettingOverrides()),
+                net::CookieSettingOverrides()),
             CONTENT_SETTING_ALLOW);
 
   EXPECT_EQ(settings.GetCookieSetting(
                 GURL("http://foo.com") /* url */,
                 GURL("chrome-extension://foo") /* first_party_url */,
-                GetCookieSettingOverrides()),
+                net::CookieSettingOverrides()),
             CONTENT_SETTING_BLOCK);
 
   EXPECT_EQ(
       settings.GetCookieSetting(GURL("chrome-extension://foo") /* url */,
                                 GURL("http://foo.com") /* first_party_url */,
-                                GetCookieSettingOverrides()),
+                                net::CookieSettingOverrides()),
       CONTENT_SETTING_BLOCK);
 }
 
@@ -921,7 +952,7 @@
   }
 }
 
-TEST_P(CookieSettingsTest, IsPrivacyModeEnabled) {
+TEST_P(CookieSettingsTestP, IsPrivacyModeEnabled) {
   CookieSettings settings;
   settings.set_block_third_party_cookies(true);
 
@@ -988,7 +1019,7 @@
                 url::Origin::Create(GURL(kURL)), GetCookieSettingOverrides()));
 }
 
-TEST_P(CookieSettingsTest, IsCookieAccessible) {
+TEST_P(CookieSettingsTestP, IsCookieAccessible) {
   CookieSettings settings;
   net::CookieInclusionStatus status;
   settings.set_block_third_party_cookies(false);
@@ -1072,7 +1103,7 @@
           : net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES));
 }
 
-TEST_P(CookieSettingsTest, IsCookieAccessible_PartitionedCookies) {
+TEST_P(CookieSettingsTestP, IsCookieAccessible_PartitionedCookies) {
   CookieSettings settings;
   net::CookieInclusionStatus status;
   settings.set_block_third_party_cookies(true);
@@ -1152,7 +1183,7 @@
       net::CookieInclusionStatus::EXCLUDE_THIRD_PARTY_PHASEOUT));
 }
 
-TEST_P(CookieSettingsTest, IsCookieAccessible_NoneExemptionReason) {
+TEST_P(CookieSettingsTestP, IsCookieAccessible_NoneExemptionReason) {
   CookieSettings settings;
   net::CookieInclusionStatus status;
   settings.set_block_third_party_cookies(true);
@@ -1213,7 +1244,7 @@
               net::CookieInclusionStatus::ExemptionReason::kNone);
 }
 
-TEST_P(CookieSettingsTest, IsCookieAccessible_SitesInFirstPartySets) {
+TEST_P(CookieSettingsTestP, IsCookieAccessible_SitesInFirstPartySets) {
   CookieSettings settings;
   net::CookieInclusionStatus status;
   url::Origin top_level_origin = url::Origin::Create(GURL(kFPSOwnerURL));
@@ -1260,7 +1291,7 @@
   }
 }
 
-TEST_P(CookieSettingsTest, AnnotateAndMoveUserBlockedCookies_CrossSiteEmbed) {
+TEST_P(CookieSettingsTestP, AnnotateAndMoveUserBlockedCookies_CrossSiteEmbed) {
   CookieSettings settings;
   settings.set_block_third_party_cookies(true);
   if (IsTrackingProtectionEnabledFor3pcd()) {
@@ -1386,7 +1417,7 @@
       net::FirstPartySetMetadata(
           /*frame_entry=*/nullptr,
           /*top_frame_entry=*/nullptr),
-      GetCookieSettingOverrides(), maybe_included_cookies, excluded_cookies));
+      net::CookieSettingOverrides(), maybe_included_cookies, excluded_cookies));
 
   // Verify that the allowed cookie has the expected warning reason.
   EXPECT_THAT(
@@ -1429,7 +1460,7 @@
       net::FirstPartySetMetadata(
           /*frame_entry=*/nullptr,
           /*top_frame_entry=*/nullptr),
-      GetCookieSettingOverrides(), maybe_included_cookies, excluded_cookies));
+      net::CookieSettingOverrides(), maybe_included_cookies, excluded_cookies));
 
   // Verify that the allowed cookie does not have the 3PC warning reason.
   EXPECT_THAT(maybe_included_cookies,
@@ -1449,7 +1480,7 @@
       net::FirstPartySetMetadata(
           /*frame_entry=*/nullptr,
           /*top_frame_entry=*/nullptr),
-      GetCookieSettingOverrides(), maybe_included_cookies, excluded_cookies));
+      net::CookieSettingOverrides(), maybe_included_cookies, excluded_cookies));
 
   // Verify that the allowed cookie has the 3PC warning reason.
   EXPECT_THAT(maybe_included_cookies,
@@ -1463,7 +1494,7 @@
                       _, _, _))));
 }
 
-TEST_P(CookieSettingsTest,
+TEST_P(CookieSettingsTestP,
        AnnotateAndMoveUserBlockedCookies_SameSiteEmbed_ThirdPartyContext) {
   CookieSettings settings;
   settings.set_block_third_party_cookies(true);
@@ -1581,7 +1612,7 @@
   }
 }
 
-TEST_P(CookieSettingsTest,
+TEST_P(CookieSettingsTestP,
        AnnotateAndMoveUserBlockedCookies_SitesInFirstPartySet) {
   CookieSettings settings;
   settings.set_block_third_party_cookies(true);
@@ -1647,7 +1678,7 @@
 }
 
 TEST_P(
-    CookieSettingsTest,
+    CookieSettingsTestP,
     AnnotateAndMoveUserBlockedCookies_SitesInFirstPartySet_FirstPartyURLBlocked) {
   CookieSettings settings;
   net::CookieInclusionStatus status;
@@ -1761,7 +1792,7 @@
       net::FirstPartySetMetadata(
           /*frame_entry=*/nullptr,
           /*top_frame_entry=*/nullptr),
-      GetCookieSettingOverrides(), maybe_included_cookies, excluded_cookies));
+      net::CookieSettingOverrides(), maybe_included_cookies, excluded_cookies));
   EXPECT_THAT(maybe_included_cookies,
               ElementsAre(MatchesCookieWithAccessResult(
                   net::MatchesCookieWithName("__Host-partitioned"),
@@ -1781,7 +1812,7 @@
       net::FirstPartySetMetadata(
           /*frame_entry=*/nullptr,
           /*top_frame_entry=*/nullptr),
-      GetCookieSettingOverrides(), maybe_included_cookies, excluded_cookies));
+      net::CookieSettingOverrides(), maybe_included_cookies, excluded_cookies));
   EXPECT_THAT(maybe_included_cookies, IsEmpty());
   EXPECT_THAT(excluded_cookies,
               UnorderedElementsAre(MatchesCookieWithAccessResult(
@@ -1803,7 +1834,7 @@
       GURL(kURL), net::SiteForCookies(), &top_level_origin,
       net::FirstPartySetMetadata(/*frame_entry=*/nullptr,
                                  /*top_frame_entry=*/nullptr),
-      GetCookieSettingOverrides(), maybe_included_cookies, excluded_cookies));
+      net::CookieSettingOverrides(), maybe_included_cookies, excluded_cookies));
 
   {
     EXPECT_THAT(maybe_included_cookies, IsEmpty());
@@ -1831,7 +1862,7 @@
       net::FirstPartySetMetadata(
           /*frame_entry=*/nullptr,
           /*top_frame_entry=*/nullptr),
-      GetCookieSettingOverrides(), maybe_included_cookies, excluded_cookies));
+      net::CookieSettingOverrides(), maybe_included_cookies, excluded_cookies));
   EXPECT_THAT(maybe_included_cookies,
               ElementsAre(MatchesCookieWithAccessResult(
                   net::MatchesCookieWithName("__Host-partitioned"),
@@ -1839,11 +1870,16 @@
   EXPECT_THAT(excluded_cookies, IsEmpty());
 }
 
+INSTANTIATE_TEST_SUITE_P(
+    /* no prefix */,
+    CookieSettingsTest,
+    testing::Combine(testing::Bool()));
+
 // NOTE: These tests will fail if their FINAL name is of length greater than 256
 // characters. Thus, try to avoid (unnecessary) generalized parameterization
 // when possible.
 std::string CustomTestName(
-    const testing::TestParamInfo<CookieSettingsTest::ParamType>& info) {
+    const testing::TestParamInfo<CookieSettingsTestP::ParamType>& info) {
   std::stringstream custom_test_name;
   // clang-format off
   custom_test_name
@@ -1859,7 +1895,7 @@
 
 INSTANTIATE_TEST_SUITE_P(
     /* no prefix */,
-    CookieSettingsTest,
+    CookieSettingsTestP,
     testing::Combine(testing::Range(GrantSource::kNoneGranted,
                                     GrantSource::kGrantSourceCount),
                      testing::Range(BlockSource::kNoneBlocked,
@@ -1869,8 +1905,9 @@
 
 class CookieSettingsTpcdMetadataGrantsTest
     : public CookieSettingsTestBase,
-      public testing::TestWithParam</* net::features::kTpcdMetadataGrants: */
-                                    bool> {
+      public testing::WithParamInterface</* net::features::kTpcdMetadataGrants:
+                                          */
+                                         bool> {
  public:
   CookieSettingsTpcdMetadataGrantsTest() {
     std::vector<base::test::FeatureRef> enabled_features;
@@ -2103,8 +2140,9 @@
 
 class CookieSettingsTpcdTrialTest
     : public CookieSettingsTestBase,
-      public testing::TestWithParam</* net::features::kTpcdTrialSettings: */
-                                    bool> {
+      public testing::WithParamInterface</* net::features::kTpcdTrialSettings:
+                                          */
+                                         bool> {
  public:
   CookieSettingsTpcdTrialTest() {
     std::vector<base::test::FeatureRef> enabled_features;
@@ -2273,9 +2311,9 @@
 class CookieSettingsTopLevelTpcdTrialTest
     : public CookieSettingsTestBase,
       public testing::
-          TestWithParam</* net::features::kTopLevelTpcdTrialSettings:
-                         */
-                        bool> {
+          WithParamInterface</* net::features::kTopLevelTpcdTrialSettings:
+                              */
+                             bool> {
  public:
   CookieSettingsTopLevelTpcdTrialTest() {
     std::vector<base::test::FeatureRef> enabled_features;
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 388f7b68..4153775 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -1569,7 +1569,7 @@
       // For old certificates (issued before 2018-05-01),
       // CheckCTRequirements() may return CT_NOT_REQUIRED, so we check the
       // compliance status here.
-      // TODO(https://crbug.com/851778): Remove this condition once we require
+      // TODO(crbug.com/40580363): Remove this condition once we require
       // signing certificates to have CanSignHttpExchanges extension, because
       // such certificates should be naturally after 2018-05-01.
       if (cert_verify_result.policy_compliance ==
diff --git a/services/network/proxy_resolving_client_socket.cc b/services/network/proxy_resolving_client_socket.cc
index 4ebc27e..40530958 100644
--- a/services/network/proxy_resolving_client_socket.cc
+++ b/services/network/proxy_resolving_client_socket.cc
@@ -253,8 +253,9 @@
   if (result == net::OK) {
     // Removes unsupported proxies from the list. Currently, this removes
     // just the SCHEME_QUIC proxy.
-    // TODO(crbug.com/876885): Allow QUIC proxy once net::QuicProxyClientSocket
-    // supports ReadIfReady() and CancelReadIfReady().
+    // TODO(crbug.com/41409577): Allow QUIC proxy once
+    // net::QuicProxyClientSocket supports ReadIfReady() and
+    // CancelReadIfReady().
     proxy_info_.RemoveProxiesWithoutScheme(
         net::ProxyServer::SCHEME_HTTP | net::ProxyServer::SCHEME_HTTPS |
         net::ProxyServer::SCHEME_SOCKS4 | net::ProxyServer::SCHEME_SOCKS5);
diff --git a/services/network/public/cpp/url_loader_factory_builder.cc b/services/network/public/cpp/url_loader_factory_builder.cc
index 78d7b4e..687eb70 100644
--- a/services/network/public/cpp/url_loader_factory_builder.cc
+++ b/services/network/public/cpp/url_loader_factory_builder.cc
@@ -44,7 +44,7 @@
 // because theoretically the `URLLoaderFactoryBuilder` interface can't ensure
 // that `terminal_factory` is fuseable.
 //
-// TODO(crbug.com/1506871): Consider removing the `Clone()` calls for
+// TODO(crbug.com/40947547): Consider removing the `Clone()` calls for
 // performance. Probably the `terminal_factory` is actually fusable for the
 // actual `URLLoaderFactoryBuilder` callers reaching here (e.g.
 // `non_network_factories` in `RenderFrameHostImpl::CommitNavigation()` and
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index e899c9c..588aba2 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -1568,8 +1568,8 @@
   // its destruction. If there is no corresponding LoadHttpAuthCache call, the
   // saved HttpAuthCache data will leak.
   //
-  // TODO(crbug.com/914082): Return a scoped handle that can automatically free
-  // the cache when it goes out of scope.
+  // TODO(crbug.com/40606065): Return a scoped handle that can automatically
+  // free the cache when it goes out of scope.
   SaveHttpAuthCacheProxyEntries()
       => (mojo_base.mojom.UnguessableToken cache_key);
 
diff --git a/services/network/public/mojom/url_loader_network_service_observer.mojom b/services/network/public/mojom/url_loader_network_service_observer.mojom
index 6c67b2dc..a5cf6c2 100644
--- a/services/network/public/mojom/url_loader_network_service_observer.mojom
+++ b/services/network/public/mojom/url_loader_network_service_observer.mojom
@@ -174,7 +174,7 @@
   // Called when the Clear-Site-Data header has been received. The callback
   // should be run after the data is deleted.
   // https://www.w3.org/TR/clear-site-data/
-  // TODO(crbug.com/876931): We might want to move header parsing work to
+  // TODO(crbug.com/41409604): We might want to move header parsing work to
   // Network Service for security concerns (e.g. |header_value| => booleans).
   OnClearSiteData(url.mojom.Url url,
                   string header_value,
diff --git a/services/network/udp_socket_unittest.cc b/services/network/udp_socket_unittest.cc
index d3e6542..4682e6b 100644
--- a/services/network/udp_socket_unittest.cc
+++ b/services/network/udp_socket_unittest.cc
@@ -288,7 +288,7 @@
   EXPECT_EQ(net::ERR_UNEXPECTED, result);
 }
 
-// TODO(crbug.com/1014916): These two tests are very flaky on Fuchsia.
+// TODO(crbug.com/40653437): These two tests are very flaky on Fuchsia.
 #if BUILDFLAG(IS_FUCHSIA)
 #define MAYBE_TestReadSendTo DISABLED_TestReadSendTo
 #define MAYBE_TestUnexpectedSequences DISABLED_TestUnexpectedSequences
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc
index c1d92024..b3faa43 100644
--- a/services/network/url_loader_unittest.cc
+++ b/services/network/url_loader_unittest.cc
@@ -4717,7 +4717,7 @@
   // TLS 1.3 client auth errors show up post-handshake, resulting in a read
   // error which on Windows causes the socket to shutdown immediately before the
   // error is read.
-  // TODO(crbug.com/906668): Add support for testing this in TLS 1.3.
+  // TODO(crbug.com/41427061): Add support for testing this in TLS 1.3.
   ssl_config.version_max = net::SSL_PROTOCOL_VERSION_TLS1_2;
 
   test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc b/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc
index c14ce42..b7a4669 100644
--- a/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc
+++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc
@@ -829,7 +829,7 @@
   }
 }
 
-// TODO(crbug.com/1479976): Test is flaky across platforms.
+// TODO(crbug.com/40281135): Test is flaky across platforms.
 TEST_F(CoordinatorImplTest, DISABLED_DumpsAreAddedToTraceWhenRequested) {
   tracing::DataSourceTester data_source_tester(
       TracingObserverProto::GetInstance());
diff --git a/services/service_manager/tests/background_service_manager_unittest.cc b/services/service_manager/tests/background_service_manager_unittest.cc
index 5d65f4d..d695978 100644
--- a/services/service_manager/tests/background_service_manager_unittest.cc
+++ b/services/service_manager/tests/background_service_manager_unittest.cc
@@ -78,7 +78,7 @@
 // and connects to background_service_manager_test_service, verifying we can
 // send a message to the service.
 #if BUILDFLAG(IS_ANDROID)
-// TODO(crbug.com/589784): This test is disabled, as it fails
+// TODO(crbug.com/40458478): This test is disabled, as it fails
 // on the Android GN bot.
 #define MAYBE_Basic DISABLED_Basic
 #else
diff --git a/services/tracing/perfetto/consumer_host_unittest.cc b/services/tracing/perfetto/consumer_host_unittest.cc
index 42f66dd..0ae70c6 100644
--- a/services/tracing/perfetto/consumer_host_unittest.cc
+++ b/services/tracing/perfetto/consumer_host_unittest.cc
@@ -305,7 +305,7 @@
   bool tracing_enabled_ = false;
 };
 
-// TODO(crbug.com/1006541): Switch this to use TracingUnitTest.
+// TODO(crbug.com/42050015): Switch this to use TracingUnitTest.
 class TracingConsumerTest : public testing::Test,
                             public mojo::DataPipeDrainer::Client {
  public:
diff --git a/services/tracing/perfetto/perfetto_integration_unittest.cc b/services/tracing/perfetto/perfetto_integration_unittest.cc
index 05cdca7..60b291ec 100644
--- a/services/tracing/perfetto/perfetto_integration_unittest.cc
+++ b/services/tracing/perfetto/perfetto_integration_unittest.cc
@@ -21,7 +21,7 @@
 #include "third_party/perfetto/include/perfetto/tracing/tracing.h"
 #include "third_party/perfetto/protos/perfetto/common/commit_data_request.pb.h"
 
-// TODO(crbug.com/961066): Fix memory leaks in tests and re-enable on LSAN.
+// TODO(crbug.com/41457644): Fix memory leaks in tests and re-enable on LSAN.
 #ifdef LEAK_SANITIZER
 #define MAYBE_DifferentSharedMemoryBuffersForDifferentAgents \
   DISABLED_DifferentSharedMemoryBuffersForDifferentAgents
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
index 2e95e55b..75beb76 100644
--- a/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
+++ b/services/tracing/public/cpp/perfetto/trace_event_data_source_unittest.cc
@@ -2617,7 +2617,7 @@
   EXPECT_EQ(e_packet->interned_data().histogram_names()[0].name(), "Foo.Bar");
 }
 
-// TODO(crbug.com/1464718): The test is flaky across platforms.
+// TODO(crbug.com/40275723): The test is flaky across platforms.
 TEST_F(TraceEventDataSourceTest, DISABLED_HistogramSampleTraceConfigNotEmpty) {
   std::vector<std::string> histograms;
   histograms.push_back("Foo1.Bar1");
diff --git a/services/tracing/public/mojom/perfetto_service.mojom b/services/tracing/public/mojom/perfetto_service.mojom
index e1eeb68..2bfe570 100644
--- a/services/tracing/public/mojom/perfetto_service.mojom
+++ b/services/tracing/public/mojom/perfetto_service.mojom
@@ -82,8 +82,8 @@
 
 // Passed as part of DataSourceConfig
 struct ChromeConfig {
-  // TODO(crbug/928687): Once we've completed removing the old IPC layer we
-  // should convert this into a struct that represents a
+  // TODO(crbug.com/41439336): Once we've completed removing the old IPC layer
+  // we should convert this into a struct that represents a
   // base::trace_event::TraceConfig object rather then the json encoded string
   // used currently.
   string trace_config;
diff --git a/services/video_capture/lacros/device_factory_adapter_lacros.cc b/services/video_capture/lacros/device_factory_adapter_lacros.cc
index 3de236d..4106c40b 100644
--- a/services/video_capture/lacros/device_factory_adapter_lacros.cc
+++ b/services/video_capture/lacros/device_factory_adapter_lacros.cc
@@ -17,8 +17,11 @@
 
 DeviceFactoryAdapterLacros::DeviceFactoryAdapterLacros(
     mojo::PendingRemote<crosapi::mojom::VideoCaptureDeviceFactory>
-        device_factory_ash)
-    : device_factory_ash_(std::move(device_factory_ash)) {}
+        device_factory_ash,
+    base::OnceClosure cleanup_callback)
+    : device_factory_ash_(std::move(device_factory_ash)) {
+  device_factory_ash_.set_disconnect_handler(std::move(cleanup_callback));
+}
 
 DeviceFactoryAdapterLacros::~DeviceFactoryAdapterLacros() = default;
 
diff --git a/services/video_capture/lacros/device_factory_adapter_lacros.h b/services/video_capture/lacros/device_factory_adapter_lacros.h
index b0042c3b..9114aa4 100644
--- a/services/video_capture/lacros/device_factory_adapter_lacros.h
+++ b/services/video_capture/lacros/device_factory_adapter_lacros.h
@@ -23,9 +23,10 @@
 // video_capture::DeviceFactory in Ash-Chrome.
 class DeviceFactoryAdapterLacros : public DeviceFactory {
  public:
-  explicit DeviceFactoryAdapterLacros(
+  DeviceFactoryAdapterLacros(
       mojo::PendingRemote<crosapi::mojom::VideoCaptureDeviceFactory>
-          device_factory_ash);
+          device_factory_ash,
+      base::OnceClosure cleanup_callback);
   DeviceFactoryAdapterLacros(const DeviceFactoryAdapterLacros&) = delete;
   DeviceFactoryAdapterLacros& operator=(const DeviceFactoryAdapterLacros&) =
       delete;
diff --git a/services/video_capture/video_capture_service_impl.cc b/services/video_capture/video_capture_service_impl.cc
index 75e3c15..5806d1c 100644
--- a/services/video_capture/video_capture_service_impl.cc
+++ b/services/video_capture/video_capture_service_impl.cc
@@ -240,6 +240,7 @@
     bool create_system_monitor)
     : receiver_(this, std::move(receiver)),
       ui_task_runner_(std::move(ui_task_runner)) {
+  DETACH_FROM_SEQUENCE(sequence_checker_);
   if (create_system_monitor && !base::SystemMonitor::Get()) {
     system_monitor_ = std::make_unique<base::SystemMonitor>();
   }
@@ -303,6 +304,8 @@
 }
 
 void VideoCaptureServiceImpl::LazyInitializeGpuDependenciesContext() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   if (!gpu_dependencies_context_)
     gpu_dependencies_context_ = std::make_unique<GpuDependenciesContext>();
 
@@ -322,6 +325,8 @@
 }
 
 void VideoCaptureServiceImpl::LazyInitializeDeviceFactory() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   if (device_factory_)
     return;
 
@@ -366,7 +371,13 @@
         device_factory_ash.InitWithNewPipeAndPassReceiver());
     device_factory_ = std::make_unique<VirtualDeviceEnabledDeviceFactory>(
         std::make_unique<DeviceFactoryAdapterLacros>(
-            std::move(device_factory_ash)));
+            std::move(device_factory_ash),
+            // Unretained(this) is safe, because |this| owns |device_factory_|
+            // and |device_factory_| owns the |DeviceFactoryAdapterLacros|
+            // instance.
+            base::BindOnce(
+                &VideoCaptureServiceImpl::OnDisconnectedFromVCDFactoryAsh,
+                base::Unretained(this))));
   } else {
     if (media::ShouldUseFakeVideoCaptureDeviceFactory()) {
       VLOG(1) << "Use fake device factory with shared memory in Lacros-Chrome";
@@ -385,6 +396,8 @@
 }
 
 void VideoCaptureServiceImpl::LazyInitializeVideoSourceProvider() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   if (video_source_provider_)
     return;
   LazyInitializeDeviceFactory();
@@ -425,4 +438,13 @@
 }
 #endif
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+void VideoCaptureServiceImpl::OnDisconnectedFromVCDFactoryAsh() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  video_source_provider_.reset();
+  device_factory_.reset();
+}
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
 }  // namespace video_capture
diff --git a/services/video_capture/video_capture_service_impl.h b/services/video_capture/video_capture_service_impl.h
index 2ec19d2b..5a4ef6a 100644
--- a/services/video_capture/video_capture_service_impl.h
+++ b/services/video_capture/video_capture_service_impl.h
@@ -9,6 +9,7 @@
 
 #include "base/feature_list.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/sequence_checker.h"
 #include "base/system/system_monitor.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread.h"
@@ -88,6 +89,10 @@
   // this function should be called on service startup.
   void InitializeDeviceMonitor();
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  void OnDisconnectedFromVCDFactoryAsh();
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
 #if BUILDFLAG(IS_MAC)
   std::unique_ptr<media::DeviceMonitorMac> video_capture_device_monitor_mac_;
 #endif
@@ -115,6 +120,8 @@
         // BUILDFLAG(IS_CHROMEOS_ASH)
 
   scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
+
+  SEQUENCE_CHECKER(sequence_checker_);
 };
 
 }  // namespace video_capture
diff --git a/services/viz/public/mojom/compositing/layer_context.mojom b/services/viz/public/mojom/compositing/layer_context.mojom
index 84b8e1b..3a7cee2 100644
--- a/services/viz/public/mojom/compositing/layer_context.mojom
+++ b/services/viz/public/mojom/compositing/layer_context.mojom
@@ -39,7 +39,7 @@
 
 // Parameters needed to bind a LayerContext endpoint via a CompositorFrameSink.
 struct PendingLayerContext {
-  // TODO(https://crbug.com/1431762): De-associate these interfaces from
+  // TODO(crbug.com/40902503): De-associate these interfaces from
   // CompositorFrameSink.
   pending_associated_receiver<LayerContext> receiver;
   pending_associated_remote<LayerContextClient> client;
diff --git a/styleguide/c++/c++-dos-and-donts.md b/styleguide/c++/c++-dos-and-donts.md
index 97b00cd..8565088f 100644
--- a/styleguide/c++/c++-dos-and-donts.md
+++ b/styleguide/c++/c++-dos-and-donts.md
@@ -295,7 +295,7 @@
 * Function names: `` `FooFunction()` ``. The trailing parens disambiguate
   against class names, and occasionally, English words.
 * Variable names: `` `foo_var` ``.
-* Tracking comments for future improvements: `// TODO(crbug.com/12345): ...`,
+* Tracking comments for future improvements: `// TODO(crbug.com/40781525): ...`,
   or, less optimally, `// TODO(knowledgeable_username): ...`.  Tracking bugs
   provide space to give background context and current status; a username might
   at least provide a starting point for asking about an issue.
diff --git a/styleguide/java/java.md b/styleguide/java/java.md
index d55a46c..4cabc56c 100644
--- a/styleguide/java/java.md
+++ b/styleguide/java/java.md
@@ -272,7 +272,7 @@
 
 * TODO should follow chromium convention. Examples:
   * `TODO(username): Some sentence here.`
-  * `TODO(crbug.com/123456): Even better to use a bug for context.`
+  * `TODO(crbug.com/40192027): Even better to use a bug for context.`
 
 ### Parameter Comments
 
diff --git a/testing/android/native_test/java/src/org/chromium/native_test/NativeBrowserTestActivity.java b/testing/android/native_test/java/src/org/chromium/native_test/NativeBrowserTestActivity.java
index 8730422..1bedb20ae 100644
--- a/testing/android/native_test/java/src/org/chromium/native_test/NativeBrowserTestActivity.java
+++ b/testing/android/native_test/java/src/org/chromium/native_test/NativeBrowserTestActivity.java
@@ -62,13 +62,11 @@
     /**
      * Returns the command line switch used to specify the user data directory.
      *
-     *  The default implementation returns an empty string, which means no user
-     *  data directory.
-     *  If this method returns a non-empty value, the user data directory will be overridden to be
-     *  the private data directory, which is cleared at the beginning of each test run.
-     *  NOTE: The switch should not start with "--".
-     *  TODO(crbug.com/617734): Solve this problem holistically for Java and C++ at the level of
-     *  DIR_ANDROID_APP_DATA and eliminate the need for this solution.
+     * <p>The default implementation returns an empty string, which means no user data directory. If
+     * this method returns a non-empty value, the user data directory will be overridden to be the
+     * private data directory, which is cleared at the beginning of each test run. NOTE: The switch
+     * should not start with "--". TODO(crbug.com/40471984): Solve this problem holistically for
+     * Java and C++ at the level of DIR_ANDROID_APP_DATA and eliminate the need for this solution.
      */
     protected String getUserDataDirectoryCommandLineSwitch() {
         return "";
diff --git a/testing/buildbot/filters/chromeos.browser_tests.filter b/testing/buildbot/filters/chromeos.browser_tests.filter
index f58fd710..845755eb 100644
--- a/testing/buildbot/filters/chromeos.browser_tests.filter
+++ b/testing/buildbot/filters/chromeos.browser_tests.filter
@@ -7,7 +7,7 @@
 # TODO(crbug.com/985390): Enable this.
 -OSSettingsPeoplePageAccountManagerTest.AllJsTests
 
-# TODO(crbug.com/977744): Enable this.
+# TODO(crbug.com/41467370): Enable this.
 -ProcessMemoryMetricsEmitterTest.RendererBuildId
 
 # TODO(crbug.com/978051): Enable this.
diff --git a/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_negative.filter b/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_negative.filter
index c92427d..99ae8f0 100644
--- a/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_negative.filter
+++ b/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_negative.filter
@@ -1,5 +1,5 @@
 # Keep in sync with chromeos.msan.browser_tests.oobe_positive.filter.
-# TODO(crbug.com/1071693): Remove this filter when it's safe to do so.
+# TODO(crbug.com/40126889): Remove this filter when it's safe to do so.
 -AccessibilityManagerLoginTest.*
 -ActiveDirectoryJoinTest.*
 -ActiveDirectoryLoginAutocompleteTest.*
diff --git a/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter b/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter
index 3d4bf339..947bf93 100644
--- a/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter
+++ b/testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter
@@ -1,5 +1,5 @@
 # Keep in sync with chromeos.msan.browser_tests.oobe_negative.filter.
-# TODO(crbug.com/1071693): Remove this filter when it's safe to do so.
+# TODO(crbug.com/40126889): Remove this filter when it's safe to do so.
 AccessibilityManagerLoginTest.*
 ActiveDirectoryJoinTest.*
 ActiveDirectoryLoginAutocompleteTest.*
diff --git a/testing/buildbot/filters/ios.cc_unittests.filter b/testing/buildbot/filters/ios.cc_unittests.filter
index 2ebe6e0a..3eace5a 100644
--- a/testing/buildbot/filters/ios.cc_unittests.filter
+++ b/testing/buildbot/filters/ios.cc_unittests.filter
@@ -1,4 +1,4 @@
-# TODO(crbug.com/1507079): Delete lines from this file as these test failures
+# TODO(crbug.com/40947766): Delete lines from this file as these test failures
 # are addressed.
 
 # TODO(crbug.com/1506550): The expected results appear quite clipped.
diff --git a/testing/buildbot/filters/ios.compositor_unittests.filter b/testing/buildbot/filters/ios.compositor_unittests.filter
index 2c69f83..31eac23 100644
--- a/testing/buildbot/filters/ios.compositor_unittests.filter
+++ b/testing/buildbot/filters/ios.compositor_unittests.filter
@@ -1,6 +1,6 @@
 # TODO(crbug.com/1416986): remove lines as more tests are supported on the platform.
 
-# TODO(crbug.com/1501671): The report is not coming during the test.
+# TODO(crbug.com/40941975): The report is not coming during the test.
 -AnimationThroughputReporterTest.ExplicitAnimation
 -AnimationThroughputReporterTest.ImplicitAnimation
 -AnimationThroughputReporterTest.ImplicitAnimationLateAttach
diff --git a/testing/buildbot/filters/ios.content_browsertests.filter b/testing/buildbot/filters/ios.content_browsertests.filter
index 2e6f0766..a87ec2f2 100644
--- a/testing/buildbot/filters/ios.content_browsertests.filter
+++ b/testing/buildbot/filters/ios.content_browsertests.filter
@@ -126,7 +126,7 @@
 -MediaColorTest.Yuvj420pH264
 -MediaSourceTest.Playback_Video_MP4_Audio_WEBM
 
-# TODO(crbug.com/1509461): these flakily timeout.
+# TODO(crbug.com/41482069): these flakily timeout.
 -All/BackForwardCacheNetworkLimitBrowserTest.ImageStillLoading*
 
 # TODO(crbug.com/40276545): hitting unexpected driver errors.
@@ -308,7 +308,7 @@
 -All/YieldingParserDumpAccessibilityTreeTest.ReusedMapChangeMapName/blink
 -All/YieldingParserDumpAccessibilityTreeTest.ReusedMapMoveImage/blink
 
-# TODO(crbug.com/1516750): the following consistently crash.
+# TODO(crbug.com/41489733): the following consistently crash.
 -SystemTracingEndToEndBrowserTest.PerformanceMark
 -SystemTracingEndToEndBrowserTest.SimpleTraceEvent
 
diff --git a/testing/buildbot/filters/ios.use_blink.components_unittests.filter b/testing/buildbot/filters/ios.use_blink.components_unittests.filter
index b41a8949..432e8fc 100644
--- a/testing/buildbot/filters/ios.use_blink.components_unittests.filter
+++ b/testing/buildbot/filters/ios.use_blink.components_unittests.filter
@@ -9,7 +9,7 @@
 -AutofillAcrossIframesTest.SetAndGetParent
 -AutofillAcrossIframesTest.TriggerExtractionInFrame
 
-# TODO(crbug.com/1505321): Test currently fails on iOS blink.
+# TODO(crbug.com/40945935): Test currently fails on iOS blink.
 -AutofillAgentTests.OnFormDataFilledTestWithFrameMessagingUsingRendererIDs
 -AutofillAgentTests.CheckIfSuggestionsAvailable_NonUserInitiatedActivity
 -AutofillAgentTests.DriverFillSpecificFormField
@@ -40,7 +40,7 @@
 -PageContentAnnotationsModelManagerTest.NotifyWhenModelAvailable_VisibilityOnly
 -PageContentAnnotationsModelManagerTest.PageVisibility
 
-# TODO(crbug.com/1505322): Test currently fails on iOS blink.
+# TODO(crbug.com/40945936): Test currently fails on iOS blink.
 -FillJsTest.GetCanonicalActionForForm
 -FillJsTest.GetAriaDescriptionInvalid
 -FillJsTest.GetAriaDescriptionMulti
@@ -53,7 +53,7 @@
 -FillJsTest.GetAriaLabelledByTakesPrecedence
 -FillJsTest.ShouldAutocompleteOneTimeCode
 
-# TODO(crbug.com/1505327): Test currently fails on iOS blink.
+# TODO(crbug.com/40945941): Test currently fails on iOS blink.
 -FormActivityTabHelperTest.AddCustomElement
 -FormActivityTabHelperTest.FocusMainFrame
 -FormActivityTabHelperTest.FocusSameOriginIFrame
@@ -132,10 +132,10 @@
 -FormMutationTest.RemovedAndAddedFormsRegistered_WithDroppedMessages/2
 -FormMutationTest.RemovedAndAddedFormsRegistered_WithDroppedMessages/3
 
-# TODO(crbug.com/1505328): Test currently fails on iOS blink.
+# TODO(crbug.com/40945942): Test currently fails on iOS blink.
 -FormJsTest.GetIframeElements
 
-# TODO(crbug.com/1505332): Test currently fails on iOS blink.
+# TODO(crbug.com/40945946): Test currently fails on iOS blink.
 -PasswordFormHelperTest.FindPasswordFormsInView
 -PasswordFormHelperTest.ExtractPasswordFormData
 -PasswordFormHelperTest.FillPasswordFormWithFillData
@@ -148,7 +148,7 @@
 -PasswordFormHelperTest.HandleFormSubmittedMessage_NoTrustedUrl
 -PasswordFormHelperTest.HandleFormSubmittedMessage_NoWebState
 
-# TODO(crbug.com/1481427): Test currently fails on iOS blink.
+# TODO(crbug.com/40281649): Test currently fails on iOS blink.
 -SharedPasswordControllerTest.PasswordManagerIsNotNotifiedAboutHeuristicsPredictions
 -SharedPasswordControllerTest.CheckIfSuggestionsAvailableForFormCrossOriginIframe
 -SharedPasswordControllerTest.CheckNoSuggestionsAreAvailableForNonPasswordForm
@@ -174,11 +174,11 @@
 -SharedPasswordControllerTest.SuggestsGeneratedPassword
 -SharedPasswordControllerTest.TriggerPasswordGeneration
 
-# TODO(crbug.com/1505334): Test currently fails on iOS blink.
+# TODO(crbug.com/40945948): Test currently fails on iOS blink.
 -SecurityStateUtilsTest.GetMaliciousContentStatus
 -SecurityStateUtilsTest.GetSecurityLevelForWebStateMaliciousContent
 
-# TODO(crbug.com/1505338): Test currently fails on iOS blink.
+# TODO(crbug.com/40945952): Test currently fails on iOS blink.
 -AccountConsistencyServiceTest.SigninAddCookieOnMainDomains
 -AccountConsistencyServiceTest.AddChromeConnectedCookiesOnCookiesRemoved
 -AccountConsistencyServiceTest.ChromeManageAccountsDefault
@@ -201,18 +201,18 @@
 -AccountConsistencyServiceTest.SignInSignOut
 -AccountConsistencyServiceTest.SignOutWithoutDomains
 
-# TODO(crbug.com/1505345): Test currently fails on iOS blink.
+# TODO(crbug.com/40945960): Test currently fails on iOS blink.
 -JsTranslateWebFrameManagerTest.Inject
 -JsTranslateWebFrameManagerTest.Reinject
 -JsTranslateWebFrameManagerTest.Revert
 -JsTranslateWebFrameManagerTest.Translate
 
-# TODO(crbug.com/1505346): Test currently fails on iOS blink.
+# TODO(crbug.com/40945961): Test currently fails on iOS blink.
 -TranslateControllerTest.OnTranslateSendRequestWithValidCommand
 -TranslateControllerTest.OnTranslateSendRequestWithBadURL
 -TranslateControllerTest.OnTranslateSendRequestWithBadMethod
 
-# TODO(crbug.com/1505348): Test currently fails on iOS blink.
+# TODO(crbug.com/40945963): Test currently fails on iOS blink.
 -UkmUrlRecorderTest.Basic
 -UkmUrlRecorderTest.IgnoreDownloadUrl
 -UkmUrlRecorderTest.IgnoreUrlInSubframe
diff --git a/testing/buildbot/filters/lacros-arm.ozone_unittests.filter b/testing/buildbot/filters/lacros-arm.ozone_unittests.filter
index a6862dfe..fbf67728 100644
--- a/testing/buildbot/filters/lacros-arm.ozone_unittests.filter
+++ b/testing/buildbot/filters/lacros-arm.ozone_unittests.filter
@@ -1,4 +1,4 @@
-# TODO(https://crbug.com/1283076): re-enable the tests when they are fixed.
+# TODO(crbug.com/40209748): re-enable the tests when they are fixed.
 -XdgVersionStableTest/WaylandDataDragControllerTest.AsyncNoopStartDrag/0
 -XdgVersionStableTest/WaylandDataDragControllerTest.DestroyEnteredSurface/0
 -XdgVersionStableTest/WaylandDataDragControllerTest.DestroyOriginSurface/0
diff --git a/testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter b/testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter
index 29d7f51a..dfb33ea 100644
--- a/testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter
+++ b/testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter
@@ -33,7 +33,7 @@
 # TODO(crbug.com/1195712): Implement the feature for Wayland.
 -GlobalCommandsApiTest.GlobalCommand
 
-# TODO(crbug.com/1208111): Was flaky with weston-test, fails consistently with
+# TODO(crbug.com/40765889): Was flaky with weston-test, fails consistently with
 # ui-controls.
 -MenuControllerUITest.TestMouseOverShownMenu
 
diff --git a/testing/buildbot/query_optimal_shard_counts_unittest.py b/testing/buildbot/query_optimal_shard_counts_unittest.py
index 6973888..7248833f 100755
--- a/testing/buildbot/query_optimal_shard_counts_unittest.py
+++ b/testing/buildbot/query_optimal_shard_counts_unittest.py
@@ -531,7 +531,7 @@
         query_suite_durations_dict(
             waterfall_builder_group='chromium.android',
             waterfall_builder_name='android-12-x64-rel',
-            try_builder='android-x64-rel',
+            try_builder='android-12-x64-rel',
             test_suite='webview_instrumentation_test_apk',
             shard_count=20,
             percentile_duration_minutes=20,
@@ -541,7 +541,7 @@
         query_test_overheads_dict(
             waterfall_builder_group='chromium.android',
             waterfall_builder_name='android-12-x64-rel',
-            try_builder='android-x64-rel',
+            try_builder='android-12-x64-rel',
             test_suite='webview_instrumentation_test_apk',
             normally_assigned_shard_count=19,
             experimental_shard_count=20,
@@ -551,7 +551,7 @@
         query_test_overheads_dict(
             waterfall_builder_group='chromium.android',
             waterfall_builder_name='android-12-x64-rel',
-            try_builder='android-x64-rel',
+            try_builder='android-12-x64-rel',
             test_suite='webview_instrumentation_test_apk',
             normally_assigned_shard_count=20,
             experimental_shard_count=21,
@@ -560,7 +560,7 @@
         ),
     ])
     avg_num_builds_per_hour = json.dumps([
-        query_average_number_builds_per_hour(try_builder='android-x64-rel'),
+        query_average_number_builds_per_hour(try_builder='android-12-x64-rel'),
     ])
     self._mock_check_output.side_effect = [
         suite_durations,
@@ -583,7 +583,7 @@
         query_suite_durations_dict(
             waterfall_builder_group='chromium.android',
             waterfall_builder_name='android-12-x64-rel',
-            try_builder='android-x64-rel',
+            try_builder='android-12-x64-rel',
             test_suite='webview_instrumentation_test_apk',
             shard_count=10,
             percentile_duration_minutes=14.5,
@@ -598,7 +598,7 @@
         ),
     ])
     avg_num_builds_per_hour = json.dumps([
-        query_average_number_builds_per_hour(try_builder='android-x64-rel'),
+        query_average_number_builds_per_hour(try_builder='android-12-x64-rel'),
     ])
     self._mock_check_output.side_effect = [
         suite_durations,
@@ -632,7 +632,7 @@
         query_suite_durations_dict(
             waterfall_builder_group='chromium.android',
             waterfall_builder_name='android-12-x64-rel',
-            try_builder='android-x64-rel',
+            try_builder='android-12-x64-rel',
             test_suite='webview_instrumentation_test_apk',
             shard_count=10,
             percentile_duration_minutes=14,
@@ -647,7 +647,7 @@
         ),
     ])
     avg_num_builds_per_hour = json.dumps([
-        query_average_number_builds_per_hour(try_builder='android-x64-rel'),
+        query_average_number_builds_per_hour(try_builder='android-12-x64-rel'),
     ])
     self._mock_check_output.side_effect = [
         suite_durations,
@@ -681,7 +681,7 @@
         query_suite_durations_dict(
             waterfall_builder_group='chromium.android',
             waterfall_builder_name='android-12-x64-rel',
-            try_builder='android-x64-rel',
+            try_builder='android-12-x64-rel',
             test_suite='webview_instrumentation_test_apk',
             shard_count=10,
             percentile_duration_minutes=9,
@@ -691,12 +691,12 @@
         query_test_overheads_dict(
             waterfall_builder_group='chromium.android',
             waterfall_builder_name='android-12-x64-rel',
-            try_builder='android-x64-rel',
+            try_builder='android-12-x64-rel',
             test_suite='webview_instrumentation_test_apk',
         ),
     ])
     avg_num_builds_per_hour = json.dumps([
-        query_average_number_builds_per_hour(try_builder='android-x64-rel'),
+        query_average_number_builds_per_hour(try_builder='android-12-x64-rel'),
     ])
     self._mock_check_output.side_effect = [
         suite_durations,
@@ -725,7 +725,7 @@
         query_suite_durations_dict(
             waterfall_builder_group='chromium.android',
             waterfall_builder_name='android-12-x64-rel',
-            try_builder='android-x64-rel',
+            try_builder='android-12-x64-rel',
             test_suite='webview_instrumentation_test_apk',
             shard_count=10,
             percentile_duration_minutes=20,
@@ -735,12 +735,12 @@
         query_test_overheads_dict(
             waterfall_builder_group='chromium.android',
             waterfall_builder_name='android-12-x64-rel',
-            try_builder='android-x64-rel',
+            try_builder='android-12-x64-rel',
             test_suite='webview_instrumentation_test_apk',
         ),
     ])
     avg_num_builds_per_hour = json.dumps([
-        query_average_number_builds_per_hour(try_builder='android-x64-rel'),
+        query_average_number_builds_per_hour(try_builder='android-12-x64-rel'),
     ])
     self._mock_check_output.side_effect = [
         suite_durations,
@@ -791,7 +791,7 @@
         query_suite_durations_dict(
             waterfall_builder_group='chromium.android',
             waterfall_builder_name='android-12-x64-rel',
-            try_builder='android-x64-rel',
+            try_builder='android-12-x64-rel',
             test_suite='webview_instrumentation_test_apk',
             shard_count=10,
             percentile_duration_minutes=20,
@@ -801,12 +801,12 @@
         query_test_overheads_dict(
             waterfall_builder_group='chromium.android',
             waterfall_builder_name='android-12-x64-rel',
-            try_builder='android-x64-rel',
+            try_builder='android-12-x64-rel',
             test_suite='webview_instrumentation_test_apk',
         ),
     ])
     avg_num_builds_per_hour = json.dumps([
-        query_average_number_builds_per_hour(try_builder='android-x64-rel'),
+        query_average_number_builds_per_hour(try_builder='android-12-x64-rel'),
         query_average_number_builds_per_hour(try_builder='linux-rel'),
     ])
     self._mock_check_output.side_effect = [
@@ -874,7 +874,7 @@
         query_test_overheads_dict(
             waterfall_builder_group='chromium.android',
             waterfall_builder_name='android-12-x64-rel',
-            try_builder='android-x64-rel',
+            try_builder='android-12-x64-rel',
             test_suite='webview_instrumentation_test_apk',
         ),
     ])
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 4e72162..67aa0fb 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1668,7 +1668,7 @@
         ],
       },
       'win-asan': {
-        # TODO(crbug.com/1518411): With a single shard seems to hit time limit.
+        # TODO(crbug.com/41491387): With a single shard seems to hit time limit.
         'swarming': {
           'shards': 4,
         },
@@ -1833,7 +1833,7 @@
         },
       },
       'android-12l-x64-dbg-tests': {
-        # TODO(crbug.com/1439624): Remove experiment and ci_only
+        # TODO(crbug.com/40265619): Remove experiment and ci_only
         # once the test suite is stable.
         'ci_only': True,
         'experiment_percentage': 100,
@@ -3110,7 +3110,7 @@
       'Win10 Tests x64 (dbg)': {
         'experiment_percentage': 100,
       },
-      # TODO(crbug.com/970649): Remove these filters.
+      # TODO(crbug.com/40630654): Remove these filters.
       'linux-chromeos-chrome': {
         'args': [
           '--gtest_filter=-SadTabViewInteractiveUITest.ReloadMultipleSadTabs',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index ea74e1ec..7d578c2 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -5139,7 +5139,7 @@
           'x86-64',
         ],
         'test_suites': {
-          # TODO(crbug.com/1071693): Use the main 'linux_chromeos_gtests' suite
+          # TODO(crbug.com/40126889): Use the main 'linux_chromeos_gtests' suite
           # when OOBE tests no longer fail on MSAN.
           'gtest_tests': 'linux_chromeos_gtests_oobe',
         },
diff --git a/testing/libfuzzer/BUILD.gn b/testing/libfuzzer/BUILD.gn
index 4083f84..9899334 100644
--- a/testing/libfuzzer/BUILD.gn
+++ b/testing/libfuzzer/BUILD.gn
@@ -18,7 +18,7 @@
 # all to point to :fuzzing_engine_main instead.
 # TODO: remove this target once they've all migrated.
 source_set("libfuzzer_main") {
-  deps = [ ":fuzzing_engine" ]
+  deps = [ ":is_a_fuzz_target" ]
   testonly = true
   sources = []
   if (use_libfuzzer) {
@@ -44,12 +44,19 @@
   # Depend on this if you want to use LLVMFuzzerRunDriver from within an existing
   # executable
   group("fuzzing_engine_no_main") {
-    deps = [ ":fuzzing_engine" ]
+    testonly = true
+    deps = [
+      ":fuzzing_engine_no_main_core",
+      ":is_a_fuzz_target",
+    ]
+  }
+
+  group("fuzzing_engine_no_main_core") {
     testonly = true
     if (use_libfuzzer) {
-      deps += [ "//third_party/libFuzzer:libfuzzer" ]
+      deps = [ "//third_party/libFuzzer:libfuzzer" ]
     } else if (use_centipede) {
-      deps += [ "//third_party/fuzztest:centipede_runner_no_main" ]
+      deps = [ "//third_party/fuzztest:centipede_runner_no_main" ]
       data_deps = [
         # Centipede based fuzzers require the centipede runner in order to fuzz.
         "//third_party/fuzztest:centipede",
@@ -67,7 +74,13 @@
 
 # Any fuzzer using any fuzzing engine. This will be used by infra scripts
 # to identify fuzzers which should be built and made available to ClusterFuzz.
+group("is_a_fuzz_target") {
+  deps = [ ":fuzzing_engine" ]
+}
+
+# Named for legacy reasons for compatibility with recipes.
 group("fuzzing_engine") {
+  visibility = [ ":is_a_fuzz_target" ]
   if (use_clang_coverage) {
     # For purposes of code coverage calculation, fuzzer targets are run through
     # a wrapper script in this directory, which handles corpus retrieval and
@@ -133,10 +146,13 @@
 
 # A wrapper that knows how to execute a single fuzztest within a binary
 # containing many fuzztests.
+# Unlike fuzztests themselves, this depends on :is_a_fuzz_target
+# so that the build jobs know to build all these.
 source_set("individual_fuzztest_wrapper") {
   sources = [ "//testing/libfuzzer/fuzztest_wrapper.cpp" ]
   deps = [
     ":fuzztest_wrapper_buildflags",
+    ":is_a_fuzz_target",
     "//base",
   ]
 }
diff --git a/testing/scripts/check_static_initializers.py b/testing/scripts/check_static_initializers.py
index d2a6f9c..fb814c71 100755
--- a/testing/scripts/check_static_initializers.py
+++ b/testing/scripts/check_static_initializers.py
@@ -26,7 +26,7 @@
         'InstrProfilingRuntime\\.cpp : ' +
         '_GLOBAL__sub_I_InstrProfilingRuntime\\.cpp',
 
-        # TODO(crbug.com/973554): Remove.
+        # TODO(crbug.com/41464604): Remove.
         'iostream\\.cpp : _GLOBAL__I_000100',
 
         # TODO(crbug.com/40268361): Rust stdlib argv handling.
@@ -190,7 +190,7 @@
         allow_coverage_initializer = '--allow-coverage-initializer' in \
           args.args)
   elif sys.platform.startswith('linux'):
-    # TODO(crbug.com/1492865): Delete this assert if it's not seen to fail
+    # TODO(crbug.com/40285648): Delete this assert if it's not seen to fail
     # anywhere.
     assert not check_if_chromeos(args), (
         "This script is no longer supported for CrOS")
diff --git a/testing/test.gni b/testing/test.gni
index f8f763b2..d3f7908 100644
--- a/testing/test.gni
+++ b/testing/test.gni
@@ -314,9 +314,6 @@
           ":" + _fuzzer_target_name,
         ]
         deps = [
-          # Depend on fuzzing_engine so that our recipes know to build all
-          # these wrapper script targets.
-          "//testing/libfuzzer:fuzzing_engine",
           "//testing/libfuzzer:individual_fuzztest_wrapper",
           ":" + _fuzztest_generate_fuzzer + "_constants",
         ]
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 073beab3..894a332 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1249,6 +1249,27 @@
             ]
         }
     ],
+    "AutofillAssociateForms": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "chromeos_lacros",
+                "ios",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "AutofillAssociateForms"
+                    ]
+                }
+            ]
+        }
+    ],
     "AutofillContentEditableChangeEvents": [
         {
             "platforms": [
@@ -2890,6 +2911,10 @@
             "experiments": [
                 {
                     "name": "Enabled",
+                    "params": {
+                        "page_insights_alt_privacy_notice_url": "https://support.google.com/chrome?p=page_insights",
+                        "page_insights_send_context_metadata": "true"
+                    },
                     "enable_features": [
                         "CCTPageInsightsHub"
                     ]
@@ -5017,6 +5042,21 @@
             ]
         }
     ],
+    "CrOSLateBootAudioOffloadCrasDSPToSOF": [
+        {
+            "platforms": [
+                "chromeos"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled_20240421",
+                    "enable_features": [
+                        "CrOSLateBootAudioOffloadCrasDSPToSOF"
+                    ]
+                }
+            ]
+        }
+    ],
     "CrOSLateBootDynamicEPP": [
         {
             "platforms": [
@@ -8630,6 +8670,26 @@
             ]
         }
     ],
+    "HangoutExtensionV3": [
+        {
+            "platforms": [
+                "chromeos",
+                "chromeos_lacros",
+                "fuchsia",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "HangoutExtensionV3"
+                    ]
+                }
+            ]
+        }
+    ],
     "HappinessTrackingBorealisGames": [
         {
             "platforms": [
@@ -11141,7 +11201,7 @@
             ]
         }
     ],
-    "MagicStackRemoveGradientView": [
+    "MagicStackGradientView": [
         {
             "platforms": [
                 "ios"
@@ -16318,6 +16378,21 @@
             ]
         }
     ],
+    "RestoreSignedInAccountAndSettingsFromBackupAndroid": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "RestoreSignedInAccountAndSettingsFromBackup"
+                    ]
+                }
+            ]
+        }
+    ],
     "RetryGetVideoCaptureDeviceInfos": [
         {
             "platforms": [
@@ -19212,6 +19287,28 @@
             ]
         }
     ],
+    "ThirdPartyScriptDetection": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "chromeos_lacros",
+                "fuchsia",
+                "linux",
+                "mac",
+                "windows",
+                "android_webview"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "ThirdPartyScriptDetection"
+                    ]
+                }
+            ]
+        }
+    ],
     "ThreadCacheMinCachedMemoryForPurging": [
         {
             "platforms": [
diff --git a/testing/xvfb.py b/testing/xvfb.py
index d888f4ed..ba195ac 100755
--- a/testing/xvfb.py
+++ b/testing/xvfb.py
@@ -97,7 +97,7 @@
     print('Exception while running dbus_launch: %s' % e)
 
 
-# TODO(crbug.com/949194): Encourage setting flags to False.
+# TODO(crbug.com/40621504): Encourage setting flags to False.
 def run_executable(
     cmd, env, stdoutfile=None, use_openbox=True, use_xcompmgr=True,
     xvfb_whd=None, cwd=None):
diff --git a/third_party/angle b/third_party/angle
index 36ae4553..219f776 160000
--- a/third_party/angle
+++ b/third_party/angle
@@ -1 +1 @@
-Subproject commit 36ae4553287d44e82080c486adae52da7865daa8
+Subproject commit 219f7762e54ba3653d67a605dcba270f14f50467
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index 742726b..7855d81e 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -2313,6 +2313,11 @@
              "TextCodecCJKEnabled",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+// Enables third party script regex matching for detecting technologies.
+BASE_FEATURE(kThirdPartyScriptDetection,
+             "ThirdPartyScriptDetection",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 BASE_FEATURE(kThreadedBodyLoader,
              "ThreadedBodyLoader",
              base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index bd0e97d..fa752c0 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -1514,6 +1514,9 @@
 // If the flag is disabled TextCodecICU would be used instead.
 BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kTextCodecCJKEnabled);
 
+// If enabled, regex match on script source to detect third party technologies.
+BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kThirdPartyScriptDetection);
+
 // If enabled, reads and decodes navigation body data off the main thread.
 BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kThreadedBodyLoader);
 
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
index 26f43e68..b927bfcc4b 100644
--- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
+++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -4335,6 +4335,9 @@
 
   kIdentityDigitalCredentialsDeepLink = 4948,
 
+  kV8WebView_GetExperimentalMediaIntegrityTokenProvider_Method = 4949,
+  kV8MediaIntegrityTokenProvider_RequestToken_Method = 4950,
+
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
   // Also, run update_use_counter_feature_enum.py in
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index d0e0ed9..9f13461 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -334,6 +334,7 @@
     "//third_party/blink/renderer/core/xml:xpath_generated",
     "//third_party/blink/renderer/platform",
     "//third_party/blink/renderer/platform/wtf",
+    "//third_party/re2",
     "//ui/accessibility:ax_base",
     "//ui/base/cursor",
     "//ui/base/dragdrop/mojom:mojom_blink_headers",
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc
index a33fd24..84da736 100644
--- a/third_party/blink/renderer/core/animation/css/css_animations.cc
+++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -2655,6 +2655,9 @@
             transition_data->PropertyList()[transition_index];
         if (transition_property.unresolved_property == CSSPropertyID::kAll) {
           any_transition_had_transition_all = true;
+          // We don't need to build listed_properties (which is expensive for
+          // 'all').
+          state.listed_properties = nullptr;
         }
         CalculateTransitionUpdateForProperty(
             state, transition_property, transition_index, writing_direction);
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.h b/third_party/blink/renderer/core/animation/css/css_animations.h
index 4378833..1bf2c4ec 100644
--- a/third_party/blink/renderer/core/animation/css/css_animations.h
+++ b/third_party/blink/renderer/core/animation/css/css_animations.h
@@ -286,6 +286,8 @@
     const ComputedStyle& base_style;
     const ComputedStyle* before_change_style;
     const TransitionMap* active_transitions;
+    // If the performance of this HashSet shows up in profiles, we could
+    // convert any non-custom CSS properties in it to use CSSBitset instead.
     HashSet<PropertyHandle>* listed_properties;
     const CSSTransitionData* transition_data;
   };
diff --git a/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc b/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc
index d576a6f..bd738e5 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc
@@ -115,6 +115,13 @@
 void CustomProperty::ApplyValue(StyleResolverState& state,
                                 const CSSValue& value,
                                 ValueMode value_mode) const {
+  // Highlight Pseudos do not allow custom property definitions.
+  // Properties are copied from the originating element when the
+  // style is created.
+  if (state.UsesHighlightPseudoInheritance()) {
+    return;
+  }
+
   ComputedStyleBuilder& builder = state.StyleBuilder();
   DCHECK(!value.IsCSSWideKeyword());
 
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
index 0529341a..e938a971 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -1169,29 +1169,14 @@
     // if the element has no rules for this highlight pseudo, we skip resolution
     // entirely (leaving the scoped_refptr untouched). The bad news is that if
     // the element has rules but no matched properties, we currently clone.
-
     state.SetStyle(*parent_style);
 
-    // Custom Properties on highlight pseudos are taken from :root, due to the
-    // standard practice of putting document wide custom properties on :root.
-    // The highlight pseudo that requires the variables will have a non-pseudo
-    // parent style (as the root of the highlight inheritance chain).
-    bool parent_is_initial_style = parent_style->StyleType() == kPseudoIdNone;
-    DCHECK(parent_style->StyleType() == style_request.pseudo_id ||
-           parent_is_initial_style);
-
-    if (parent_is_initial_style) {
-      DCHECK(!parent_style->InheritedVariables());
-      DCHECK(!parent_style->NonInheritedVariables());
-      // Style on the root itself has no root element, so use the originating
-      // element which will be the root.
-      const ComputedStyle* source_style = state.RootElementStyle()
-                                              ? state.RootElementStyle()
-                                              : state.OriginatingElementStyle();
-      DCHECK(source_style);
-      state.StyleBuilder().CopyInheritedVariablesFrom(source_style);
-      state.StyleBuilder().CopyNonInheritedVariablesFrom(source_style);
-    }
+    // Highlight Pseudos do not support custom properties defined on the
+    // pseudo itself. They may use var() references but those must be resolved
+    // against the originating element. Share the variables from the originating
+    // style.
+    state.StyleBuilder().CopyInheritedVariablesFrom(state.OriginatingElementStyle());
+    state.StyleBuilder().CopyNonInheritedVariablesFrom(state.OriginatingElementStyle());
   } else {
     state.CreateNewStyle(
         source_for_noninherited, *parent_style,
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 6f285d1..86630ba 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -4945,9 +4945,16 @@
   // pseudo style.
   if (parent_style != nullptr &&
       parent_style->HighlightPseudoElementStylesDependOnRelativeUnits()) {
-    return HighlightRecalc::kRelativeUnits;
+    return HighlightRecalc::kOriginatingDependent;
   }
 
+  // If the parent style depends on custom properties we may need recalc
+  // in the event the originating element has changed the values for those
+  // properties.
+  if (parent_style != nullptr &&
+      parent_style->HighlightPseudoElementStylesHaveVariableReferences()) {
+    return HighlightRecalc::kOriginatingDependent;
+  }
   return HighlightRecalc::kNone;
 }
 
@@ -4959,7 +4966,17 @@
   if (highlight_recalc == HighlightRecalc::kFull) {
     return true;
   }
-  DCHECK(highlight_recalc == HighlightRecalc::kRelativeUnits);
+  DCHECK(highlight_recalc == HighlightRecalc::kOriginatingDependent);
+  // If the highlight depends on variables and the variables on the
+  // originating element have changed, we need to re-evaluate.
+  if (highlight_parent && highlight_parent->HasVariableReference() &&
+      (originating_style.InheritedVariables() !=
+           highlight_parent->InheritedVariables() ||
+       originating_style.NonInheritedVariables() !=
+           highlight_parent->NonInheritedVariables())) {
+    return true;
+  }
+  // Font relative units must be recomputed if the font size has changed.
   if (highlight_parent && highlight_parent->HasFontRelativeUnits() &&
       originating_style.SpecifiedFontSize() !=
           highlight_parent->SpecifiedFontSize()) {
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h
index f2f4f12..b44fa2f6 100644
--- a/third_party/blink/renderer/core/dom/element.h
+++ b/third_party/blink/renderer/core/dom/element.h
@@ -1577,7 +1577,7 @@
     // The HighlightData from the old style can be re-used.
     kReuse,
     // The HighlightData contains relative units and may need recalc.
-    kRelativeUnits,
+    kOriginatingDependent,
     // Highlights must be calculated in full.
     kFull,
   };
diff --git a/third_party/blink/renderer/core/frame/animation_frame_timing_monitor.cc b/third_party/blink/renderer/core/frame/animation_frame_timing_monitor.cc
index c28da57c..042c9cba 100644
--- a/third_party/blink/renderer/core/frame/animation_frame_timing_monitor.cc
+++ b/third_party/blink/renderer/core/frame/animation_frame_timing_monitor.cc
@@ -20,6 +20,7 @@
 #include "third_party/blink/renderer/core/script/script.h"
 #include "third_party/blink/renderer/core/timing/animation_frame_timing_info.h"
 #include "third_party/blink/renderer/core/timing/dom_window_performance.h"
+#include "third_party/blink/renderer/core/timing/third_party_script_detector.h"
 #include "third_party/blink/renderer/platform/bindings/source_location.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
 #include "third_party/blink/renderer/platform/heap/persistent.h"
@@ -295,6 +296,8 @@
   base::TimeDelta script_type_duration_event_listener;
   base::TimeDelta script_type_duration_promise_handler;
   base::TimeDelta script_type_duration_script_block;
+  int64_t third_party_script_callback_contributors = 0;
+  int64_t third_party_script_execution_contributors = 0;
   for (const Member<ScriptTimingInfo>& script : info.Scripts()) {
     total_compilation_duration +=
         (script->ExecutionStartTime() - script->StartTime());
@@ -303,20 +306,31 @@
     total_execution_duration += execution_duration;
     total_forced_style_and_layout_duration += script->StyleDuration();
     total_forced_style_and_layout_duration += script->LayoutDuration();
+    ThirdPartyScriptDetector::Technology third_party_technology =
+        ThirdPartyScriptDetector::From(*(script->Window()))
+            .Detect(script->GetSourceLocation().url);
     switch (script->GetInvokerType()) {
       case ScriptTimingInfo::InvokerType::kClassicScript:
       case ScriptTimingInfo::InvokerType::kModuleScript:
         script_type_duration_script_block += execution_duration;
+        third_party_script_execution_contributors |=
+            static_cast<int64_t>(third_party_technology);
         break;
       case ScriptTimingInfo::InvokerType::kEventHandler:
         script_type_duration_event_listener += execution_duration;
+        third_party_script_callback_contributors |=
+            static_cast<int64_t>(third_party_technology);
         break;
       case ScriptTimingInfo::InvokerType::kPromiseResolve:
       case ScriptTimingInfo::InvokerType::kPromiseReject:
         script_type_duration_promise_handler += execution_duration;
+        third_party_script_callback_contributors |=
+            static_cast<int64_t>(third_party_technology);
         break;
       case ScriptTimingInfo::InvokerType::kUserCallback:
         script_type_duration_user_callback += execution_duration;
+        third_party_script_callback_contributors |=
+            static_cast<int64_t>(third_party_technology);
         break;
     }
   }
@@ -335,6 +349,10 @@
   builder.SetDuration_StyleAndLayout_Forced(
       total_forced_style_and_layout_duration.InMilliseconds());
   builder.SetDidPause(info.DidPause());
+  builder.SetCategorized3PScriptLongAnimationFrameCallbackContributors(
+      third_party_script_callback_contributors);
+  builder.SetCategorized3PScriptLongAnimationFrameScriptExecutionContributors(
+      third_party_script_execution_contributors);
   builder.Record(recorder);
 }
 
diff --git a/third_party/blink/renderer/core/highlight/highlight_style_utils_test.cc b/third_party/blink/renderer/core/highlight/highlight_style_utils_test.cc
index 0163fafdd1..a00b5183 100644
--- a/third_party/blink/renderer/core/highlight/highlight_style_utils_test.cc
+++ b/third_party/blink/renderer/core/highlight/highlight_style_utils_test.cc
@@ -319,10 +319,13 @@
         --root-color: green;
       }
       ::selection {
+        /* This rule should not apply */
         --selection-color: blue;
       }
       div::selection {
+        /* Use the fallback */
         color: var(--selection-color, red);
+        /* Use the :root inherited via originating */
         background-color: var(--root-color, red);
       }
     </style>
@@ -347,7 +350,7 @@
                     paint_style, paint_info)
                     .style;
 
-  EXPECT_EQ(Color(0, 0, 255), paint_style.fill_color);
+  EXPECT_EQ(Color(255, 0, 0), paint_style.fill_color);
 
   Color background_color = HighlightStyleUtils::HighlightBackgroundColor(
       GetDocument(), div_style, div_node, previous_layer_color,
@@ -356,7 +359,8 @@
   EXPECT_EQ(Color(0, 128, 0), background_color);
 }
 
-TEST_F(HighlightStyleUtilsTest, CustomPropertyInheritanceNoRoot) {
+TEST_F(HighlightStyleUtilsTest,
+       CustomPropertyOriginatingInheritanceUniversal) {
   ScopedHighlightInheritanceForTest highlight_inheritance_enabled(true);
   SimRequest main_resource("https://example.com/test.html", "text/html");
 
@@ -366,13 +370,19 @@
     <!doctype html>
     <style>
       :root {
-        --background-color: green;
+        --selection-color: green;
       }
-      div::selection {
-        background-color: var(--background-color, red);
+      ::selection {
+        background-color: var(--selection-color);
+      }
+      .blue {
+        --selection-color: blue;
       }
     </style>
-    <div>Selected</div>
+    <div>
+      <p>Some <strong>green</strong> highlight</p>
+      <p class="blue">Some <strong>still blue</strong> highlight</p>
+    </div>
   )HTML");
 
   // Select some text.
@@ -383,11 +393,45 @@
 
   const ComputedStyle& div_style = div_node->ComputedStyleRef();
   std::optional<Color> previous_layer_color;
-  Color background_color = HighlightStyleUtils::HighlightBackgroundColor(
+  Color div_background_color = HighlightStyleUtils::HighlightBackgroundColor(
       GetDocument(), div_style, div_node, previous_layer_color,
       kPseudoIdSelection);
+  EXPECT_EQ(Color(0, 128, 0), div_background_color);
 
-  EXPECT_EQ(Color(0, 128, 0), background_color);
+  auto* div_inherited_vars = div_style.InheritedVariables();
+
+  auto* first_p_node = To<HTMLElement>(div_node->firstChild()->nextSibling());
+  const ComputedStyle& first_p_style = first_p_node->ComputedStyleRef();
+  Color first_p_background_color =
+      HighlightStyleUtils::HighlightBackgroundColor(
+          GetDocument(), first_p_style, first_p_node, previous_layer_color,
+          kPseudoIdSelection);
+  EXPECT_EQ(Color(0, 128, 0), first_p_background_color);
+  auto* first_p_inherited_vars = first_p_style.InheritedVariables();
+  EXPECT_EQ(div_inherited_vars, first_p_inherited_vars);
+
+  auto* second_p_node =
+      To<HTMLElement>(first_p_node->nextSibling()->nextSibling());
+  const ComputedStyle& second_p_style = second_p_node->ComputedStyleRef();
+  Color second_p_background_color =
+      HighlightStyleUtils::HighlightBackgroundColor(
+          GetDocument(), second_p_style, second_p_node, previous_layer_color,
+          kPseudoIdSelection);
+  EXPECT_EQ(Color(0, 0, 255), second_p_background_color);
+  auto* second_p_inherited_vars = second_p_style.InheritedVariables();
+  EXPECT_NE(second_p_inherited_vars, first_p_inherited_vars);
+
+  auto* second_strong_node =
+      To<HTMLElement>(second_p_node->firstChild()->nextSibling());
+  const ComputedStyle& second_strong_style =
+      second_strong_node->ComputedStyleRef();
+  Color second_strong_background_color =
+      HighlightStyleUtils::HighlightBackgroundColor(
+          GetDocument(), second_strong_style, second_strong_node,
+          previous_layer_color, kPseudoIdSelection);
+  EXPECT_EQ(Color(0, 0, 255), second_strong_background_color);
+  auto* second_strong_inherited_vars = second_strong_style.InheritedVariables();
+  EXPECT_EQ(second_p_inherited_vars, second_strong_inherited_vars);
 }
 
 TEST_F(HighlightStyleUtilsTest, FontMetricsFromOriginatingElement) {
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc
index 52b5994..749a9c9 100644
--- a/third_party/blink/renderer/core/style/computed_style.cc
+++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -704,6 +704,35 @@
   return false;
 }
 
+bool ComputedStyle::HighlightPseudoElementStylesHaveVariableReferences() const {
+  const StyleHighlightData& highlight_data = HighlightData();
+  if (highlight_data.Selection() &&
+      highlight_data.Selection()->HasVariableReference()) {
+    return true;
+  }
+  if (highlight_data.TargetText() &&
+      highlight_data.TargetText()->HasVariableReference()) {
+    return true;
+  }
+  if (highlight_data.SpellingError() &&
+      highlight_data.SpellingError()->HasVariableReference()) {
+    return true;
+  }
+  if (highlight_data.GrammarError() &&
+      highlight_data.GrammarError()->HasVariableReference()) {
+    return true;
+  }
+  const CustomHighlightsStyleMap& custom_highlights =
+      highlight_data.CustomHighlights();
+  for (auto custom_highlight : custom_highlights) {
+    if (custom_highlight.value->HasVariableReference()) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 const ComputedStyle* ComputedStyle::GetCachedPseudoElementStyle(
     PseudoId pseudo_id,
     const AtomicString& pseudo_argument) const {
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h
index 09657e5a..4eade8c 100644
--- a/third_party/blink/renderer/core/style/computed_style.h
+++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -837,6 +837,7 @@
   bool HighlightPseudoElementStylesDependOnRelativeUnits() const;
   bool HighlightPseudoElementStylesDependOnContainerUnits() const;
   bool HighlightPseudoElementStylesDependOnViewportUnits() const;
+  bool HighlightPseudoElementStylesHaveVariableReferences() const;
 
   // font-size
   int FontSize() const { return GetFontDescription().ComputedPixelSize(); }
diff --git a/third_party/blink/renderer/core/timing/build.gni b/third_party/blink/renderer/core/timing/build.gni
index ef212032..f183414 100644
--- a/third_party/blink/renderer/core/timing/build.gni
+++ b/third_party/blink/renderer/core/timing/build.gni
@@ -88,6 +88,8 @@
   "soft_navigation_entry.h",
   "task_attribution_timing.cc",
   "task_attribution_timing.h",
+  "third_party_script_detector.cc",
+  "third_party_script_detector.h",
   "time_clamper.cc",
   "time_clamper.h",
   "visibility_state_entry.cc",
diff --git a/third_party/blink/renderer/core/timing/third_party_script_detector.cc b/third_party/blink/renderer/core/timing/third_party_script_detector.cc
new file mode 100644
index 0000000..bbab964
--- /dev/null
+++ b/third_party/blink/renderer/core/timing/third_party_script_detector.cc
@@ -0,0 +1,111 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/timing/third_party_script_detector.h"
+
+#include <cmath>
+
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+namespace {
+// kThirdPartyTechnologiesSourceLocationRegexString has to strictly follow rules
+// below so the regex matching work as intended.
+//
+// 1. Each technology(eg. WordPress) contains exactly one capturing group in
+// order to identify technologies when a pattern is matched. Non-capturing
+// groups are free to use. (Ref:
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Groups_and_backreferences#types)
+// 2. Different technologies are separated by "|".
+// 3. If a technology has more than one regex pattern to be matched, use "|" to
+// concatenate them together within the same technology group.
+// 4. The order must be consistent with Technology enum value defined in
+// third_party_script_detector.h. That means i-th (0 based) group in regex
+// should have (1<<i) Technology.
+// 5. For better readability, please put each regex pattern on a single line
+// beginning with a "|".
+constexpr char kThirdPartyTechnologiesSourceLocationRegexString[] =
+    // WordPress
+    "(/wp-(?:content|includes)/"
+    "|wp-embed\\.min\\.js)"
+    // GoogleAnalytics
+    "|(google-analytics\\.com/(?:ga|urchin|analytics)\\.js"
+    "|googletagmanager\\.com/gtag/js)"
+    // GoogleFontApi
+    "|(googleapis\\.com/.+webfont)";
+constexpr int kTechnologyCount = std::bit_width(
+    static_cast<uint8_t>(ThirdPartyScriptDetector::Technology::kLast));
+}  // namespace
+
+// static
+const char ThirdPartyScriptDetector::kSupplementName[] =
+    "ThirdPartyScriptDetector";
+
+// static
+ThirdPartyScriptDetector& ThirdPartyScriptDetector::From(
+    LocalDOMWindow& window) {
+  ThirdPartyScriptDetector* supplement =
+      Supplement<LocalDOMWindow>::From<ThirdPartyScriptDetector>(window);
+  if (!supplement) {
+    supplement = MakeGarbageCollected<ThirdPartyScriptDetector>(window);
+    ProvideTo(window, supplement);
+  }
+  return *supplement;
+}
+
+ThirdPartyScriptDetector::ThirdPartyScriptDetector(LocalDOMWindow& window)
+    : Supplement<LocalDOMWindow>(window),
+      precompiled_detection_regex__(
+          kThirdPartyTechnologiesSourceLocationRegexString) {}
+
+void ThirdPartyScriptDetector::Trace(Visitor* visitor) const {
+  Supplement<LocalDOMWindow>::Trace(visitor);
+}
+
+ThirdPartyScriptDetector::Technology ThirdPartyScriptDetector::Detect(
+    const WTF::String url) {
+  if (!base::FeatureList::IsEnabled(features::kThirdPartyScriptDetection)) {
+    return Technology::kNone;
+  }
+
+  if (!url) {
+    // Early exit if the script is first party.
+    return Technology::kNone;
+  }
+
+  if (url_to_technology_cache_.Contains(url)) {
+    return url_to_technology_cache_.at(url);
+  }
+
+  // Create result vectors to get the matches for the capturing groups.
+  std::vector<std::string> results(kTechnologyCount);
+  std::vector<RE2::Arg> match_results(kTechnologyCount);
+  std::vector<RE2::Arg*> match_results_ptr(kTechnologyCount);
+
+  for (size_t i = 0; i < kTechnologyCount; ++i) {
+    match_results[i] = &results[i];
+    match_results_ptr[i] = &match_results[i];
+  }
+
+  Technology technology = Technology::kNone;
+  if (RE2::PartialMatchN(url.Utf8(), precompiled_detection_regex__,
+                         match_results_ptr.data(), kTechnologyCount)) {
+    for (int i = 0; i < kTechnologyCount; ++i) {
+      if (results[i] != "") {
+        // results[i] stores capturing subgroup match result. If not empty
+        // string, it means the subgroup has been matched, and the technology
+        // relates to that capturing group should be returned.
+        technology = static_cast<Technology>(1 << i);
+        break;
+      }
+    }
+  }
+
+  url_to_technology_cache_.Set(url, technology);
+  return technology;
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/timing/third_party_script_detector.h b/third_party/blink/renderer/core/timing/third_party_script_detector.h
new file mode 100644
index 0000000..0f4f954d
--- /dev/null
+++ b/third_party/blink/renderer/core/timing/third_party_script_detector.h
@@ -0,0 +1,52 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_THIRD_PARTY_SCRIPT_DETECTOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_THIRD_PARTY_SCRIPT_DETECTOR_H_
+
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+#include "third_party/blink/renderer/platform/wtf/hash_map.h"
+#include "third_party/re2/src/re2/re2.h"
+
+namespace blink {
+
+class LocalDOMWindow;
+
+class ThirdPartyScriptDetector final
+    : public GarbageCollected<ThirdPartyScriptDetector>,
+      public Supplement<LocalDOMWindow> {
+ public:
+  static const char kSupplementName[];
+
+  static ThirdPartyScriptDetector& From(LocalDOMWindow&);
+
+  explicit ThirdPartyScriptDetector(LocalDOMWindow&);
+  ThirdPartyScriptDetector(const ThirdPartyScriptDetector&) = delete;
+  ThirdPartyScriptDetector& operator=(const ThirdPartyScriptDetector&) = delete;
+
+  void Trace(Visitor*) const override;
+
+  // Enumerated list of top 3 third party technologies based on traffic, from
+  // httparchive July 2023 data.
+  enum class Technology {
+    kNone = 0,
+    kWordPress = 1 << 0,
+    kGoogleAnalytics = 1 << 1,
+    kGoogleFontApi = 1 << 2,
+    kLast = kGoogleFontApi
+    // If adding new technologies, add above kLast and shift kLast accordingly.
+    // Max value allowed: 1 << 63. Limited by UKM bitfield.
+  };
+
+  Technology Detect(const WTF::String url);
+
+ private:
+  RE2 precompiled_detection_regex__;
+  HashMap<WTF::String, Technology> url_to_technology_cache_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_TIMING_THIRD_PARTY_SCRIPT_DETECTOR_H_
diff --git a/third_party/blink/renderer/core/timing/window_performance.cc b/third_party/blink/renderer/core/timing/window_performance.cc
index 96c9f10..efb32fc 100644
--- a/third_party/blink/renderer/core/timing/window_performance.cc
+++ b/third_party/blink/renderer/core/timing/window_performance.cc
@@ -615,14 +615,16 @@
                       WebFeature::kEventTimingExplicitlyRequested);
     NotifyObserversOfEntry(*entry);
   }
+
   // TODO(npm): is 104 a reasonable buffering threshold or should it be
   // relaxed?
-  if (entry->duration() >= PerformanceObserver::kDefaultDurationThreshold &&
-      !IsEventTimingBufferFull()) {
+  if (entry->duration() >= PerformanceObserver::kDefaultDurationThreshold) {
     AddEventTimingBuffer(*entry);
   }
+
   bool tracing_enabled;
   TRACE_EVENT_CATEGORY_GROUP_ENABLED("devtools.timeline", &tracing_enabled);
+
   if (tracing_enabled) {
     base::TimeTicks unsafe_start_time =
         GetTimeOriginInternal() + base::Milliseconds(entry->startTime());
diff --git a/third_party/blink/renderer/extensions/webview/media_integrity/media_integrity_token_provider.idl b/third_party/blink/renderer/extensions/webview/media_integrity/media_integrity_token_provider.idl
index ae04fe5..9f98fac 100644
--- a/third_party/blink/renderer/extensions/webview/media_integrity/media_integrity_token_provider.idl
+++ b/third_party/blink/renderer/extensions/webview/media_integrity/media_integrity_token_provider.idl
@@ -15,5 +15,6 @@
     // device, which includes the pased-in contentBinding as a defense against
     // replay attacks.
     // Throws MediaIntegrityError.
-    [CallWith=ScriptState, HighEntropy, RaisesException] Promise<DOMString> requestToken(optional DOMString? contentBinding = null);
+    [CallWith=ScriptState, HighEntropy, RaisesException, Measure]
+    Promise<DOMString> requestToken(optional DOMString? contentBinding = null);
 };
diff --git a/third_party/blink/renderer/extensions/webview/web_view.idl b/third_party/blink/renderer/extensions/webview/web_view.idl
index 59cf965..3a137af5 100644
--- a/third_party/blink/renderer/extensions/webview/web_view.idl
+++ b/third_party/blink/renderer/extensions/webview/web_view.idl
@@ -20,5 +20,14 @@
     // time to resolve (> 1s).
     //
     // The promise may reject as a MediaIntegrityError.
-    [NewObject, CallWith=ScriptState, HighEntropy, RaisesException, RuntimeEnabled=BlinkExtensionWebViewMediaIntegrity, SecureContext] Promise<MediaIntegrityTokenProvider> getExperimentalMediaIntegrityTokenProvider(GetMediaIntegrityTokenProviderParams params);
+    [ NewObject,
+      CallWith=ScriptState,
+      HighEntropy,
+      RaisesException,
+      RuntimeEnabled=BlinkExtensionWebViewMediaIntegrity,
+      SecureContext,
+      Measure
+    ]
+    Promise<MediaIntegrityTokenProvider>
+    getExperimentalMediaIntegrityTokenProvider(GetMediaIntegrityTokenProviderParams params);
 };
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
index 128349c..18926ea 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -8,6 +8,7 @@
 #include <cmath>
 #include <cstring>
 #include <memory>
+#include <optional>
 #include <type_traits>
 
 #include "base/check_deref.h"
@@ -285,6 +286,28 @@
   setGlobalCompositeOperation("source-over");
 }
 
+class ScopedResetCtm {
+ public:
+  ScopedResetCtm(const CanvasRenderingContext2DState& state,
+                 cc::PaintCanvas& canvas) : canvas_(canvas) {
+    if (!state.GetTransform().IsIdentity()) {
+      ctm_to_restore_ = canvas_.getLocalToDevice();
+      ctm_to_restore_->dump();
+      canvas_.save();
+      canvas_.setMatrix(SkM44());
+    }
+  }
+  ~ScopedResetCtm() {
+    if (ctm_to_restore_.has_value()) {
+      canvas_.setMatrix(*ctm_to_restore_);
+    }
+  }
+
+ private:
+  cc::PaintCanvas& canvas_;
+  std::optional<SkM44> ctm_to_restore_;
+};
+
 CanvasRenderingContext2DState::SaveType
 BaseRenderingContext2D::SaveLayerForState(
     const CanvasRenderingContext2DState& state,
@@ -293,18 +316,34 @@
   const int initial_save_count = canvas.getSaveCount();
   bool needs_compositing = state.GlobalComposite() != SkBlendMode::kSrcOver;
 
-  // Global states must be applied on the result of the layer's filter.
-  // For alpha + shadows or compositing, we must use two nested layers. The
+  // The "copy" globalCompositeOperation replaces everything that was in the
+  // canvas. We therefore have to clear the canvas before proceeding. Since the
+  // shadow and foreground are composited one after the other, the foreground
+  // gets composited over the shadow itself. This means that in "copy"
+  // compositing mode, drawing the foreground will clear the shadow. There's
+  // therefore no need to draw the shadow at all.
+  //
+  // Global states must be applied on the result of the layer's filter, so the
+  // filter has to go in a nested layer.
+  //
+  // For alpha + (shadows or compositing), we must use two nested layers. The
   // inner one applies the alpha and the outer one applies the shadow and/or
   // compositing. This is needed to to get a transparent foreground, as the
   // alpha would otherwise be applied to the result of foreground+background.
-  if (state.ShouldDrawShadows() || BlendModeRequiresCompositedDraw(state)) {
+  if (state.GlobalComposite() == SkBlendMode::kSrc) {
+    canvas.clear(HasAlpha() ? SkColors::kTransparent : SkColors::kBlack);
+    needs_compositing = false;
+  } else if (state.ShouldDrawShadows()) {
+    ScopedResetCtm scoped_reset_ctm(state, canvas);
+    cc::PaintFlags flags;
+    flags.setImageFilter(state.ShadowAndForegroundImageFilter());
+    flags.setBlendMode(state.GlobalComposite());
+    needs_compositing = false;
+    canvas.saveLayer(flags);
+  } else if (BlendModeRequiresCompositedDraw(state)) {
     cc::PaintFlags flags;
     flags.setBlendMode(state.GlobalComposite());
     needs_compositing = false;
-    if (state.ShouldDrawShadows()) {
-      flags.setImageFilter(state.ShadowAndForegroundImageFilter());
-    }
     canvas.saveLayer(flags);
   }
 
@@ -322,10 +361,7 @@
   }
 
   const int save_diff = canvas.getSaveCount() - initial_save_count;
-  CHECK(save_diff == 1 || save_diff == 2);
-  using SaveType = CanvasRenderingContext2DState::SaveType;
-  return save_diff == 2 ? SaveType::kBeginEndLayerTwoSaves
-                        : SaveType::kBeginEndLayerOneSave;
+  return CanvasRenderingContext2DState::LayerSaveCountToSaveType(save_diff);
 }
 
 void BaseRenderingContext2D::endLayer(ExceptionState& exception_state) {
@@ -388,8 +424,8 @@
     GetModifiablePath().Transform(GetState().GetTransform());
   }
 
-  if (state_stack_.back()->GetSaveType() ==
-      CanvasRenderingContext2DState::SaveType::kBeginEndLayerTwoSaves) {
+  for (int i = 0, to_restore = state_stack_.back()->LayerSaveCount() - 1;
+       i < to_restore; ++i) {
     canvas.restore();
   }
 
@@ -424,9 +460,7 @@
 
     if (state_stack_[i]->IsLayerSaveType()) {
       ++actual_layer_count;
-    }
-    if (state_stack_[i]->GetSaveType() == SaveType::kBeginEndLayerTwoSaves) {
-      ++extra_layer_saves;
+      extra_layer_saves += state_stack_[i]->LayerSaveCount() - 1;
     }
   }
   DCHECK_EQ(layer_count_, actual_layer_count);
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d_test.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d_test.cc
index 1bb52b0..0b4eb57 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d_test.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d_test.cc
@@ -50,6 +50,7 @@
 using ::blink_testing::RecordedOpsView;
 using ::cc::ClipPathOp;
 using ::cc::ClipRectOp;
+using ::cc::DrawColorOp;
 using ::cc::DrawRecordOp;
 using ::cc::DrawRectOp;
 using ::cc::DrawVerticesOp;
@@ -995,6 +996,110 @@
                                             PaintOpEq<RestoreOp>())));
 }
 
+TEST(BaseRenderingContextLayerGlobalStateTests, TransformsWithoutShadow) {
+  test::TaskEnvironment task_environment;
+  ScopedCanvas2dLayersForTest layer_feature(/*enabled=*/true);
+  V8TestingScope scope;
+  auto* context = MakeGarbageCollected<TestRenderingContext2D>(scope);
+  NonThrowableExceptionState exception_state;
+
+  context->translate(4, 5);
+  context->beginLayer(
+      scope.GetScriptState(), BeginLayerOptions::Create(), exception_state);
+  context->endLayer(exception_state);
+
+  EXPECT_THAT(context->FlushRecorder(),
+              RecordedOpsAre(
+                PaintOpEq<TranslateOp>(4, 5),
+                DrawRecordOpEq(
+                  PaintOpEq<SaveLayerAlphaOp>(1.0f),
+                  PaintOpEq<RestoreOp>())));
+}
+
+TEST(BaseRenderingContextLayerGlobalStateTests, TransformsWithShadow) {
+  test::TaskEnvironment task_environment;
+  ScopedCanvas2dLayersForTest layer_feature(/*enabled=*/true);
+  V8TestingScope scope;
+  auto* context = MakeGarbageCollected<TestRenderingContext2D>(scope);
+  NonThrowableExceptionState exception_state;
+
+  context->translate(4, 5);
+  context->setShadowBlur(2.0);
+  context->setShadowColor("red");
+  context->beginLayer(
+      scope.GetScriptState(), BeginLayerOptions::Create(), exception_state);
+  context->endLayer(exception_state);
+
+  cc::PaintFlags shadow_flags;
+  shadow_flags.setImageFilter(sk_make_sp<DropShadowPaintFilter>(
+      0.0f, 0.0f, 1.0f, 1.0f, SkColors::kRed,
+      DropShadowPaintFilter::ShadowMode::kDrawShadowAndForeground, nullptr));
+
+  EXPECT_THAT(context->FlushRecorder(),
+              RecordedOpsAre(
+                PaintOpEq<TranslateOp>(4, 5),
+                DrawRecordOpEq(
+                  PaintOpEq<SaveOp>(),
+                  PaintOpEq<SetMatrixOp>(SkM44(1, 0, 0, 0,  //
+                                               0, 1, 0, 0,  //
+                                               0, 0, 1, 0,  //
+                                               0, 0, 0, 1)),
+                  PaintOpEq<SaveLayerOp>(shadow_flags),
+                  PaintOpEq<SetMatrixOp>(SkM44(1, 0, 0, 4,  //
+                                               0, 1, 0, 5,  //
+                                               0, 0, 1, 0,  //
+                                               0, 0, 0, 1)),
+                  PaintOpEq<RestoreOp>(), PaintOpEq<RestoreOp>())));
+}
+
+TEST(BaseRenderingContextLayerGlobalStateTests, CopyCompositeOp) {
+  test::TaskEnvironment task_environment;
+  ScopedCanvas2dLayersForTest layer_feature(/*enabled=*/true);
+  V8TestingScope scope;
+  auto* context = MakeGarbageCollected<TestRenderingContext2D>(scope);
+  NonThrowableExceptionState exception_state;
+
+  context->setGlobalCompositeOperation("copy");
+  context->beginLayer(scope.GetScriptState(), BeginLayerOptions::Create(),
+                      exception_state);
+  context->endLayer(exception_state);
+
+  EXPECT_THAT(context->FlushRecorder(),
+              RecordedOpsAre(DrawRecordOpEq(
+                  PaintOpEq<DrawColorOp>(SkColors::kBlack, SkBlendMode::kSrc),
+                  PaintOpEq<SaveLayerAlphaOp>(1.0f), PaintOpEq<RestoreOp>())));
+}
+
+TEST(BaseRenderingContextLayerGlobalStateTests,
+     CopyCompositeOpWithOtherStates) {
+  test::TaskEnvironment task_environment;
+  ScopedCanvas2dLayersForTest layer_feature(/*enabled=*/true);
+  V8TestingScope scope;
+  auto* context = MakeGarbageCollected<TestRenderingContext2D>(scope);
+  NonThrowableExceptionState exception_state;
+
+  context->setGlobalAlpha(0.4);
+  context->setGlobalCompositeOperation("copy");
+  context->setShadowBlur(2.0);
+  context->setShadowColor("red");
+  context->beginLayer(
+      scope.GetScriptState(),
+      FilterOption(scope, "({name: 'gaussianBlur', stdDeviation: 20})"),
+      exception_state);
+  context->endLayer(exception_state);
+
+  cc::PaintFlags filter_flags;
+  filter_flags.setAlphaf(0.4f);
+  filter_flags.setImageFilter(
+      sk_make_sp<BlurPaintFilter>(20.0f, 20.0f, SkTileMode::kDecal, nullptr));
+
+  EXPECT_THAT(context->FlushRecorder(),
+              RecordedOpsAre(DrawRecordOpEq(
+                  PaintOpEq<DrawColorOp>(SkColors::kBlack, SkBlendMode::kSrc),
+                  PaintOpEq<SaveLayerOp>(filter_flags),
+                  PaintOpEq<RestoreOp>())));
+}
+
 TEST(BaseRenderingContextRestoreStackTests, RestoresSaves) {
   test::TaskEnvironment task_environment;
   V8TestingScope scope;
@@ -1249,12 +1354,22 @@
                                        0, 0, 1, 0,  //
                                        0, 0, 0, 1)),
           DrawRecordOpEq(
+              PaintOpEq<SaveOp>(),
+              PaintOpEq<SetMatrixOp>(SkM44(1, 0, 0, 0,  //
+                                           0, 1, 0, 0,  //
+                                           0, 0, 1, 0,  //
+                                           0, 0, 0, 1)),
               PaintOpEq<SaveLayerOp>(shadow_flags),
+              PaintOpEq<SetMatrixOp>(SkM44(1, 0, 0, 4,  //
+                                           0, 1, 0, 6,  //
+                                           0, 0, 1, 0,  //
+                                           0, 0, 0, 1)),
               PaintOpEq<SaveLayerOp>(filter_flags),
               PaintOpEq<TranslateOp>(5.0f, 6.0f),
               PaintOpEq<DrawRectOp>(SkRect::MakeXYWH(2, 2, 6, 6), rect_flags),
               PaintOpEq<DrawRectOp>(SkRect::MakeXYWH(3, 3, 7, 7), rect_flags),
-              PaintOpEq<RestoreOp>(), PaintOpEq<RestoreOp>()),
+              PaintOpEq<RestoreOp>(), PaintOpEq<RestoreOp>(),
+              PaintOpEq<RestoreOp>()),
 
           PaintOpEq<RestoreOp>(), PaintOpEq<RestoreOp>()));
 }
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h
index 2e9af91f..c13a69f 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h
@@ -54,6 +54,7 @@
     kSaveRestore,
     kBeginEndLayerOneSave,
     kBeginEndLayerTwoSaves,
+    kBeginEndLayerThreeSaves,
     kInitial
   };
 
@@ -285,10 +286,26 @@
                                  ShadowMode,
                                  ImageType = kNoImage) const;
 
+  static_assert(static_cast<int>(SaveType::kBeginEndLayerOneSave) + 1 ==
+                static_cast<int>(SaveType::kBeginEndLayerTwoSaves));
+  static_assert(static_cast<int>(SaveType::kBeginEndLayerTwoSaves) + 1 ==
+                static_cast<int>(SaveType::kBeginEndLayerThreeSaves));
   SaveType GetSaveType() const { return save_type_; }
   bool IsLayerSaveType() const {
-    return save_type_ == SaveType::kBeginEndLayerOneSave ||
-           save_type_ == SaveType::kBeginEndLayerTwoSaves;
+    return save_type_ >= SaveType::kBeginEndLayerOneSave &&
+           save_type_ <= SaveType::kBeginEndLayerThreeSaves;
+  }
+  int LayerSaveCount() {
+    if (!IsLayerSaveType()) {
+      return 0;
+    }
+    return static_cast<int>(save_type_) -
+           static_cast<int>(SaveType::kBeginEndLayerOneSave) + 1;
+  }
+  static SaveType LayerSaveCountToSaveType(int save_count) {
+    CHECK(1 <= save_count && save_count <= 3);
+    return static_cast<SaveType>(
+        static_cast<int>(SaveType::kBeginEndLayerOneSave) + save_count - 1);
   }
 
   sk_sp<PaintFilter>& ShadowAndForegroundImageFilter() const;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index dc413541..2770d132 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1526,6 +1526,7 @@
     {
       // crbug.com/333630754
       name: "FasterMinContent",
+      status: "stable",
     },
     // Kill switch.
     {
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index dcc3dc43..3d2b117 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -370,20 +370,6 @@
 crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow.no-transform.html [ Failure ]
 crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.shadow.no-transform.w.html [ Failure ]
 crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow.no-transform.w.html [ Failure ]
-# Shadow + copy composite operation.
-crbug.com/1418141 external/wpt/html/canvas/element/layers/2d.layer.global-states.filter.copy.shadow.no-transform.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/element/layers/2d.layer.global-states.copy.shadow.no-transform.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.filter.copy.shadow.no-transform.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.copy.shadow.no-transform.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.filter.copy.shadow.no-transform.w.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.copy.shadow.no-transform.w.html [ Failure ]
-# Rotation + shadow.
-crbug.com/1418141 external/wpt/html/canvas/element/layers/2d.layer.global-states.filter.no-composite-op.shadow.rotation.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/element/layers/2d.layer.global-states.no-composite-op.shadow.rotation.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-composite-op.shadow.rotation.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.no-composite-op.shadow.rotation.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-composite-op.shadow.rotation.w.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.no-composite-op.shadow.rotation.w.html [ Failure ]
 # Rotation + shadow + composite operations.
 crbug.com/1418141 external/wpt/html/canvas/element/layers/2d.layer.global-states.filter.composite.shadow.rotation.html [ Failure ]
 crbug.com/1418141 external/wpt/html/canvas/element/layers/2d.layer.global-states.composite.shadow.rotation.html [ Failure ]
@@ -398,13 +384,6 @@
 crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow.rotation.html [ Failure ]
 crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.filter.blending.shadow.rotation.w.html [ Failure ]
 crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.blending.shadow.rotation.w.html [ Failure ]
-# Rotation + shadow + copy composite operations.
-crbug.com/1418141 external/wpt/html/canvas/element/layers/2d.layer.global-states.filter.copy.shadow.rotation.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/element/layers/2d.layer.global-states.copy.shadow.rotation.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.filter.copy.shadow.rotation.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.copy.shadow.rotation.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.filter.copy.shadow.rotation.w.html [ Failure ]
-crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.copy.shadow.rotation.w.html [ Failure ]
 # Composite operation grid
 crbug.com/1418141 external/wpt/html/canvas/element/layers/2d.layer.globalCompositeOperation.html [ Failure ]
 crbug.com/1418141 external/wpt/html/canvas/offscreen/layers/2d.layer.globalCompositeOperation.html [ Failure ]
@@ -1494,12 +1473,10 @@
 # css-pseudo
 crbug.com/1500288 external/wpt/css/css-pseudo/grammar-spelling-errors-001.html [ Failure ]
 crbug.com/1500288 external/wpt/css/css-pseudo/grammar-spelling-errors-002.html [ Failure ]
-crbug.com/1147859 external/wpt/css/css-pseudo/highlight-painting-001.html [ Failure ]
-crbug.com/1147859 external/wpt/css/css-pseudo/highlight-painting-002.html [ Failure ]
+crbug.com/40856519 external/wpt/css/css-pseudo/highlight-painting-001.html [ Failure ]
+crbug.com/40856519 external/wpt/css/css-pseudo/highlight-painting-002.html [ Failure ]
 crbug.com/1172333 external/wpt/css/css-pseudo/first-letter-hi-001.html [ Failure ]
 crbug.com/1172333 external/wpt/css/css-pseudo/first-letter-digraph.html [ Failure ]
-crbug.com/1147859 external/wpt/css/css-pseudo/target-text-004.html [ Failure ]
-crbug.com/1179938 external/wpt/css/css-pseudo/target-text-dynamic-004.html [ Failure ]
 crbug.com/1353352 [ Mac ] fast/css3-text/css3-text-decoration/text-decoration-line-grammar-error.html [ Failure ]
 crbug.com/1353352 [ Release Win11-arm64 ] fast/css3-text/css3-text-decoration/text-decoration-line-grammar-error.html [ Failure ]
 crbug.com/1353352 [ Release Win11-arm64 ] fast/css3-text/css3-text-decoration/text-decoration-line-spelling-error.html [ Failure ]
@@ -4806,7 +4783,6 @@
 # CSS Highlight API painting issues related to general CSS highlight
 # pseudo-elements painting
 crbug.com/1163437 external/wpt/css/css-highlight-api/painting/custom-highlight-painting-below-grammar.html [ Failure ]
-crbug.com/1147859 external/wpt/css/css-highlight-api/painting/custom-highlight-painting-below-target-text.html [ Failure ]
 crbug.com/1521187 external/wpt/css/css-highlight-api/painting/custom-highlight-painting-staticrange-005.html [ Failure Pass ]
 
 crbug.com/1455239 http/tests/security/drag-drop-different-origin.html [ Failure Pass ]
@@ -7237,29 +7213,6 @@
 crbug.com/324111880 virtual/ruby-lb/paint/invalidation/ruby-flipped-blocks.html [ Failure ]
 crbug.com/324111880 virtual/ruby-lb/virtual/text-antialias/emphasis-avoid-ruby.html [ Failure ]
 crbug.com/324111880 virtual/ruby-lb/virtual/text-antialias/whitespace/justification-expansion-crash.html [ Crash ]
-# RubyLineBreakable; NeedsRebaseline
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/after-doesnt-crash.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/before-doesnt-crash.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/float-object-doesnt-crash.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/modify-positioned-ruby-text-crash.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/nested-ruby.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/overhang-horizontal.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/overhang-vertical.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/percentage-height-child-crash.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/position-after.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-column-break.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-columns-spans.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-columns.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-empty-rt.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-first-letter.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-illegal-7.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-illegal-combined.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-length.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-position-modern-japanese-fonts.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-text-before-after-content.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-trailing.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/fast/ruby/split-ruby-column-percentage-height-descendant.html [ Failure ]
-crbug.com/324111880 virtual/ruby-lb/media/track/track-cue-rendering-ruby.html [ Failure ]
 # RubyLineBreakable; Passing in the virtual suite though failing in non-virtual
 crbug.com/324111880 virtual/ruby-lb/external/wpt/css/css-ruby/empty-ruby-text-container-float.html [ Pass ]
 crbug.com/324111880 virtual/ruby-lb/external/wpt/css/css-ruby/ruby-base-different-size.html [ Pass ]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-cascade-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-cascade-002-ref.html
deleted file mode 100644
index 17629a6d..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-cascade-002-ref.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!doctype html>
-<meta charset="utf-8">
-<link rel="author" title="Delan Azabani" href="mailto:dazabani@igalia.com">
-<script src="support/selections.js"></script>
-<link rel="stylesheet" href="support/highlights.css">
-<style>
-    main {
-        font-size: 7em;
-        margin: 0.5em;
-    }
-    main::selection {
-        color: black;
-        background-color: transparent;
-    }
-    main > .control > span::selection,
-    main > .bg > span::selection {
-        color: white;
-        background-color: green;
-    }
-    main > .fg > span::selection {
-        color: green;
-        background-color: white;
-    }
-</style>
-<p>Test passes if the words below are (respectively): white on green, green on white, white on green.
-<!--
-    The element tree below is intentionally the same shape as the
-    test, despite the fact that we might be able to simplify it. This
-    is because multiple impls (including Gecko and Blink) split the
-    background paints accordingly, which can obscure ink overflow in
-    some of the highlighted text (especially “f”).
--->
-<main class="highlight_reftest"
-    ><span class="control"><span>foo</span></span
-    > <span class="fg"><span>b</span></span
-    ><span class="fg"><span>a</span></span
-    ><span class="fg"><span>r</span></span
-    > <span class="bg"><span>b</span></span
-    ><span class="bg"><span>a</span></span
-    ><span class="bg"><span>z</span></span
-    ></main>
-<script>selectNodeContents(document.querySelector("main"));</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-cascade-002.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-cascade-002.html
deleted file mode 100644
index c01d3c7..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-cascade-002.html
+++ /dev/null
@@ -1,120 +0,0 @@
-<!doctype html>
-<meta charset="utf-8">
-<title>CSS Pseudo-Elements Test: highlight cascade: custom properties are inherited regardless of inherits flag or inheritedness of referencing property</title>
-<link rel="author" title="Delan Azabani" href="mailto:dazabani@igalia.com">
-<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#highlight-cascade">
-<link rel="match" href="highlight-cascade-002-ref.html">
-<meta name="assert" value="This test verifies that, given ::selection styles referencing custom properties, their substitution values are inherited from the parent ::selection styles, even if the property is registered with inherits set to false (--inherits-false) or the referencing property is not an inherited property (background-color). All custom properties are treated as inherited when used in highlight styles in any way.">
-<script src="support/selections.js"></script>
-<link rel="stylesheet" href="support/highlights.css">
-<style>
-    /*
-        Register the custom properties, other than --unregistered,
-        which would be an inherited property [css-variables-1].
-    */
-    @property --control {
-        syntax: "<color>";
-        initial-value: green;
-        inherits: false;
-    }
-    @property --inherits-false {
-        syntax: "<color>";
-        initial-value: red;
-        inherits: false;
-    }
-    @property --inherits-true {
-        syntax: "<color>";
-        initial-value: red;
-        inherits: true;
-    }
-
-    main {
-        font-size: 7em;
-        margin: 0.5em;
-    }
-    main::selection {
-        /*
-            Don’t visibly highlight the spaces between words.
-        */
-        color: black;
-        background-color: transparent;
-    }
-
-    /*
-        Non-highlight control: if this text is white on red (inherit)
-        rather than white on green (initial), then @property is not
-        supported well enough to make this test meaningful.
-    */
-    main > .control {
-        --control: red;
-    }
-    main > .control > span {
-        color: white;
-        background-color: var(--control);
-    }
-
-    main > *::selection {
-        --inherits-false: green;
-        --inherits-true: green;
-        --unregistered: green;
-    }
-
-    /*
-        Foreground tests: if the foreground of this text is red or
-        black (initial) rather than green (inherit), then custom
-        properties are not being inherited in highlight styles.
-
-        color is an inherited property, but that shouldn’t matter.
-    */
-    main > .fg > span::selection {
-        background-color: white;
-    }
-    main > .fg.inherits-false > span::selection {
-        color: var(--inherits-false);
-    }
-    main > .fg.inherits-true > span::selection {
-        color: var(--inherits-true);
-    }
-    main > .fg.unregistered > span::selection {
-        color: var(--unregistered);
-    }
-
-    /*
-        Background tests: if the background of this text is red or
-        black (initial) rather than green (inherit), then custom
-        properties are not being inherited in highlight styles.
-
-        background-color is not an inherited property, but that
-        shouldn’t matter.
-    */
-    main > .bg > span::selection {
-        color: white;
-    }
-    main > .bg.inherits-false > span::selection {
-        background-color: var(--inherits-false);
-    }
-    main > .bg.inherits-true > span::selection {
-        background-color: var(--inherits-true);
-    }
-    main > .bg.unregistered > span::selection {
-        background-color: var(--unregistered);
-    }
-</style>
-<p>Test passes if the words below are (respectively): white on green, green on white, white on green.
-<main class="highlight_reftest"
-    ><span class="control"><span>foo</span></span
-    > <span class="fg inherits-false"><span>b</span></span
-    ><span class="fg inherits-true"><span>a</span></span
-    ><span class="fg unregistered"><span>r</span></span
-    > <span class="bg inherits-false"><span>b</span></span
-    ><span class="bg inherits-true"><span>a</span></span
-    ><span class="bg unregistered"><span>z</span></span
-    ></main>
-<script>
-    const main = document.querySelector("main");
-    selectRangeWith(range => {
-        range.selectNodeContents(main);
-        range.setStart(main, 2);
-        range.setEnd(main, 9);
-    });
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-cascade-008.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-cascade-008.html
index 10ca924..d6f07439 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-cascade-008.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-cascade-008.html
@@ -1,18 +1,19 @@
 <!DOCTYPE html>
-<title>Custom property values from the root element</title>
+<title>Custom property values from the originating element</title>
 <link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
 <link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#highlight-cascade">
 <link rel="match" href="highlight-cascade-008-ref.html">
-<meta name="assert" value="This test verifies that when a custom property is not found in highlight cascade, its value is taken from the root element.">
+<meta name="assert" value="This test verifies that custom properties from the originating element are used to resolve var() on highlight pseudos.">
 <meta name="fuzzy" content="0-255;0-10">
 <script src="support/selections.js"></script>
 <style>
   :root {
     --background-color: green;
-    --decoration-color: purple;
+    --decoration-color: yellow;
   }
   ::selection {
-    --decoration-color: yellow;
+    --background-color: cyan;
+    --decoration-color: magenta;
   }
   div::selection {
     background-color: var(--background-color, red);
@@ -20,8 +21,11 @@
     text-decoration-style: line;
     text-decoration-color: var(--decoration-color, red);
   }
-  span::selection {
+  span {
     --background-color: blue;
+  }
+  span::selection {
+    --background-color: purple;
     background-color: var(--background-color, red);
   }
 </style>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-cascade-009.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-cascade-009.html
index acc48c7c3..ccc917b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-cascade-009.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-cascade-009.html
@@ -4,7 +4,7 @@
 <link rel="author" title="Stephen Chenney" href="mailto:schenney@chromium.org">
 <link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#highlight-cascade">
 <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/6641">
-<meta name="assert" content="This test verifies that custom properties used in highlight pseudos are taken from the ::root if not found in the highlight inheritance chain.">
+<meta name="assert" content="This test verifies that custom properties used in highlight pseudos are taken from the originating element.">
 <script src="support/selections.js"></script>
 <link rel="stylesheet" href="support/highlights.css">
 <script src="/resources/testharness.js"></script>
@@ -12,10 +12,10 @@
 <style>
   :root {
     --background-color: green;
-    --decoration-color: purple;
+    --decoration-color: green;
   }
   ::selection {
-    --decoration-color: green;
+    --decoration-color: purple;
   }
   div::selection {
     --background-color: blue;
@@ -31,11 +31,11 @@
     const body_selection = getComputedStyle(document.querySelector("body"), "::selection");
     const div_selection = getComputedStyle(document.querySelector("div"), "::selection");
     test(() => void assert_equals(body_selection.getPropertyValue("--background-color"), "green"),
-        "body ::selection has the root custom property");
+        "body ::selection uses the originating custom property");
     test(() => void assert_equals(body_selection.getPropertyValue("--decoration-color"), "green"),
-        "body ::selection uses its own custom property");
+        "body ::selection does not use its own custom property");
     test(() => void assert_equals(div_selection.getPropertyValue("--decoration-color"), "green"),
-        "div::selection inherits a custom property");
-    test(() => void assert_equals(div_selection.getPropertyValue("--background-color"), "blue"),
-        "div::selection uses its own custom property");
+        "div::selection uses the originating element custom property");
+    test(() => void assert_equals(div_selection.getPropertyValue("--background-color"), "green"),
+        "div::selection does not use its own custom property");
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-custom-properties-dynamic-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-custom-properties-dynamic-001-ref.html
new file mode 100644
index 0000000..836874df
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-custom-properties-dynamic-001-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Pseudo Test: Dynamic Custom Properties for Highlights</title>
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@igalia.com">
+<head>
+  <style>
+    ::selection {
+      background-color: green;
+    }
+  </style>
+</head>
+<body>Green background when selected</body>
+<script>
+  window.getSelection().selectAllChildren(document.body);
+</script>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-custom-properties-dynamic-001.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-custom-properties-dynamic-001.html
new file mode 100644
index 0000000..836ef54
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-custom-properties-dynamic-001.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>CSS Pseudo Test: Dynamic Custom Properties for Highlights</title>
+<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
+<link rel="match" href="highlight-custom-properties-dynamic-001-ref.html">
+<link rel="author" title="Stephen Chenney" href="mailto:schenney@igalia.com">
+<meta name="assert" value="Custom property values in highlights update correctly when the property is updated.">
+<head>
+  <style>
+    div {
+      --background-color: red;
+    }
+    ::selection {
+      background-color: var(--background-color, red);
+    }
+  </style>
+</head>
+<div id="originating">Green background when selected</div>
+<script>
+  window.getSelection().selectAllChildren(document.body);
+  requestAnimationFrame(() => {
+    requestAnimationFrame(() => {
+      originating.style.setProperty("--background-color", "green");
+      requestAnimationFrame(() => takeScreenshot());
+    });
+  });
+</script>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-001.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-001.html
index 63d8ee1e..7fe76d1 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-001.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-001.html
@@ -1,10 +1,10 @@
 <!doctype html>
 <meta charset="utf-8">
-<title>CSS Pseudo-Elements Test: highlight styling: custom properties are applicable properties in highlight pseudos</title>
+<title>CSS Pseudo-Elements Test: highlight styling: custom properties are not applicable properties in highlight pseudos</title>
 <link rel="author" title="Delan Azabani" href="mailto:dazabani@igalia.com">
 <link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#highlight-styling">
 <link rel="match" href="highlight-styling-001-ref.html">
-<meta name="assert" value="This test verifies that ::selection styles can set and reference custom properties.">
+<meta name="assert" value="This test verifies that ::selection styles cannot set custom properties.">
 <script src="support/selections.js"></script>
 <link rel="stylesheet" href="support/highlights.css">
 <style>
@@ -13,9 +13,9 @@
         margin: 0.5em;
     }
     main::selection {
-        --x: green;
+        --x: red;
         color: white;
-        background-color: var(--x);
+        background-color: var(--x, green);
     }
 </style>
 <p>Test passes if the text below is white on green.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-002.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-002.html
index 2f7cc29..351eacac 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-002.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-002.html
@@ -1,21 +1,21 @@
 <!doctype html>
 <meta charset="utf-8">
-<title>CSS Pseudo-Elements Test: highlight styling: originating custom property values do not affect highlight pseudos</title>
+<title>CSS Pseudo-Elements Test: highlight styling: originating custom property values are used for highlight pseudos</title>
 <link rel="author" title="Delan Azabani" href="mailto:dazabani@igalia.com">
 <link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#highlight-styling">
 <link rel="match" href="highlight-styling-002-ref.html">
-<meta name="assert" value="This test verifies that custom property values set in originating elements do not participate in the substitution of those properties in ::selection styles.">
+<meta name="assert" value="This test verifies that custom property values on the originating element are used for resolving var() in a selection pseudo.">
 <script src="support/selections.js"></script>
 <link rel="stylesheet" href="support/highlights.css">
 <style>
     main {
         font-size: 7em;
         margin: 0.5em;
-        --x: red;
+        --x: green;
     }
     main::selection {
         color: white;
-        background-color: var(--x, green);
+        background-color: var(--x, red);
     }
 </style>
 <p>Test passes if the text below is white on green.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/target-text-dynamic-004.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/target-text-dynamic-004.html
index 279ec67..35f2542 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/target-text-dynamic-004.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/target-text-dynamic-004.html
@@ -18,7 +18,7 @@
 </style>
 
 <p>The test passes if the following word has a magenta background.</p>
-<div>Example</div>
+<div><span>Example</span></div>
 
 <script>
   location.href = "#:~:text=Example";
diff --git a/third_party/blink/web_tests/fast/ruby/ruby-first-letter-expected.html b/third_party/blink/web_tests/fast/ruby/ruby-first-letter-expected.html
index d411004..c25ab42 100644
--- a/third_party/blink/web_tests/fast/ruby/ruby-first-letter-expected.html
+++ b/third_party/blink/web_tests/fast/ruby/ruby-first-letter-expected.html
@@ -8,13 +8,7 @@
 ruby tags works correctly.</div>
 
 <p>&lt;ruby&gt; is defined in the
-<ruby id='ruby'>
-  H<rt>Hyper</rt>
-  T<rt>Text</rt>
-  M<rt>Markup</rt>
-  L<rt>Language</rt>
-  5<rt>Level 5</rt>
-  T<rt>Test</rt>
+<ruby id='ruby'>H<rt>Hyper</rt>T<rt>Text</rt>M<rt>Markup</rt>L<rt>Language</rt>5<rt>Level 5</rt>T<rt>Test</rt>
 </ruby> specs.</p>
 
 <ruby xml:lang="ja">
diff --git a/third_party/blink/web_tests/platform/mac-mac11/virtual/ruby-lb/fast/ruby/nested-ruby-expected.png b/third_party/blink/web_tests/platform/mac-mac11/virtual/ruby-lb/fast/ruby/nested-ruby-expected.png
new file mode 100644
index 0000000..84f67365
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11/virtual/ruby-lb/fast/ruby/nested-ruby-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/tables/mozilla_expected_failures/bugs/bug18770-expected.png b/third_party/blink/web_tests/platform/mac/tables/mozilla_expected_failures/bugs/bug18770-expected.png
index a41cc665..eba579ee 100644
--- a/third_party/blink/web_tests/platform/mac/tables/mozilla_expected_failures/bugs/bug18770-expected.png
+++ b/third_party/blink/web_tests/platform/mac/tables/mozilla_expected_failures/bugs/bug18770-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/after-doesnt-crash-expected.txt b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/after-doesnt-crash-expected.txt
new file mode 100644
index 0000000..730ebf6
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/after-doesnt-crash-expected.txt
@@ -0,0 +1 @@
+This test passes if it doesn't crash.
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/before-doesnt-crash-expected.txt b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/before-doesnt-crash-expected.txt
new file mode 100644
index 0000000..730ebf6
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/before-doesnt-crash-expected.txt
@@ -0,0 +1 @@
+This test passes if it doesn't crash.
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/float-object-doesnt-crash-expected.txt b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/float-object-doesnt-crash-expected.txt
new file mode 100644
index 0000000..1c390fa3
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/float-object-doesnt-crash-expected.txt
@@ -0,0 +1,4 @@
+Test passes if it does not crash when run with memory checking for use-after-free.
+| 
+>
+ 
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/modify-positioned-ruby-text-crash-expected.txt b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/modify-positioned-ruby-text-crash-expected.txt
new file mode 100644
index 0000000..8c06dbf4
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/modify-positioned-ruby-text-crash-expected.txt
@@ -0,0 +1 @@
+PASS, if no assert or crash in debug
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/nested-ruby-expected.png b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/nested-ruby-expected.png
new file mode 100644
index 0000000..5b01734
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/nested-ruby-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/overhang-horizontal-expected.png b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/overhang-horizontal-expected.png
new file mode 100644
index 0000000..bac16b0
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/overhang-horizontal-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/overhang-vertical-expected.png b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/overhang-vertical-expected.png
new file mode 100644
index 0000000..45643a0a
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/overhang-vertical-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/percentage-height-child-crash-expected.txt b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/percentage-height-child-crash-expected.txt
new file mode 100644
index 0000000..144d68b
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/percentage-height-child-crash-expected.txt
@@ -0,0 +1,3 @@
+PASS if no crash or assertion failure.
+
+      
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/position-after-expected.png b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/position-after-expected.png
new file mode 100644
index 0000000..6809efd7e
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/position-after-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-column-break-expected.png b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-column-break-expected.png
new file mode 100644
index 0000000..e67855d8
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-column-break-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-columns-expected.png b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-columns-expected.png
new file mode 100644
index 0000000..e685ac9
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-columns-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-columns-spans-expected.png b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-columns-spans-expected.png
new file mode 100644
index 0000000..df8590f
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-columns-spans-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-empty-rt-expected.png b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-empty-rt-expected.png
new file mode 100644
index 0000000..04047169
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-empty-rt-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-illegal-7-expected.txt b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-illegal-7-expected.txt
new file mode 100644
index 0000000..362a9f4
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-illegal-7-expected.txt
@@ -0,0 +1,2 @@
+SUCCESS!
+> 
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-illegal-combined-expected.txt b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-illegal-combined-expected.txt
new file mode 100644
index 0000000..175f27b3
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-illegal-combined-expected.txt
@@ -0,0 +1,3 @@
+SUCCESS!
+\x0e
+\x0f    > 
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-length-expected.png b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-length-expected.png
new file mode 100644
index 0000000..5bef20de
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-length-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-position-modern-japanese-fonts-expected.png b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-position-modern-japanese-fonts-expected.png
new file mode 100644
index 0000000..af54254
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-position-modern-japanese-fonts-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-text-before-after-content-expected.png b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-text-before-after-content-expected.png
new file mode 100644
index 0000000..d106926
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-text-before-after-content-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-trailing-expected.png b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-trailing-expected.png
new file mode 100644
index 0000000..e3d18af
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/ruby-trailing-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/split-ruby-column-percentage-height-descendant-expected.txt b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/split-ruby-column-percentage-height-descendant-expected.txt
new file mode 100644
index 0000000..8ced764
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/ruby-lb/fast/ruby/split-ruby-column-percentage-height-descendant-expected.txt
@@ -0,0 +1,4 @@


+ This test checks that <ruby> doesn't leave any pointer in the percentage height descendant when it splits a ruby column, or merges ruby columns.
+For this test to pass it should not crash or ASSERT!
diff --git a/third_party/blink/web_tests/wpt_internal/third-party-script-detection/resources/fetch-fake-long-3p-script-callback-sw.js b/third_party/blink/web_tests/wpt_internal/third-party-script-detection/resources/fetch-fake-long-3p-script-callback-sw.js
new file mode 100644
index 0000000..c154905
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/third-party-script-detection/resources/fetch-fake-long-3p-script-callback-sw.js
@@ -0,0 +1,34 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+self.addEventListener('fetch', (event) => {
+    // Specify the URLs of scripts you want to replace
+    const targetScriptUrls = [
+        // Word Press
+        'https://c0.wp.com/c/6.4.2/wp-includes/js/dist/vendor/wp-polyfill.min.js',
+        // Google Analytics
+        'https://www.google-analytics.com/analytics.js',
+        // Google Font Api
+        'https://www.googleapis.com/example/webfont'
+    ];
+
+    // Check if the request is for one of the target 3p scripts
+    if (targetScriptUrls.includes(event.request.url)) {
+        // Fake long callback
+        const customScript = `
+        document.querySelector("#third-party-script-element-id").addEventListener('load', () => {
+            const before = performance.now();
+            const long_script_duration = 50;
+            while (performance.now() < (before + long_script_duration)) { }
+        });
+      `;
+
+        // send a response with the custom long script
+        event.respondWith(
+            new Response(customScript, {
+                headers: { 'Content-Type': 'text/javascript' }
+            })
+        );
+    }
+});
diff --git a/third_party/blink/web_tests/wpt_internal/third-party-script-detection/resources/fetch-fake-long-3p-script-execution-sw.js b/third_party/blink/web_tests/wpt_internal/third-party-script-detection/resources/fetch-fake-long-3p-script-execution-sw.js
new file mode 100644
index 0000000..a66bc1e
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/third-party-script-detection/resources/fetch-fake-long-3p-script-execution-sw.js
@@ -0,0 +1,32 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+self.addEventListener('fetch', (event) => {
+    // Specify the URLs of scripts you want to replace
+    const targetScriptUrls = [
+        // Word Press
+        'https://c0.wp.com/c/6.4.2/wp-includes/js/dist/vendor/wp-polyfill.min.js',
+        // Google Analytics
+        'https://www.google-analytics.com/analytics.js',
+        // Google Font Api
+        'https://www.googleapis.com/example/webfont'
+    ];
+
+    // Check if the request is for one of the target 3p scripts
+    if (targetScriptUrls.includes(event.request.url)) {
+        // Fake long script
+        const customScript = `
+        const before = performance.now();
+        const long_script_duration = 50;
+        while (performance.now() < (before + long_script_duration)) { }
+      `;
+
+        // send a response with the custom long script
+        event.respondWith(
+            new Response(customScript, {
+                headers: { 'Content-Type': 'text/javascript' }
+            })
+        );
+    }
+});
diff --git a/third_party/blink/web_tests/wpt_internal/third-party-script-detection/resources/third-party-script-test-utils.js b/third_party/blink/web_tests/wpt_internal/third-party-script-detection/resources/third-party-script-test-utils.js
new file mode 100644
index 0000000..736d45c0
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/third-party-script-detection/resources/third-party-script-test-utils.js
@@ -0,0 +1,73 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function third_party_script_test(test_type, url, expected_metric_value) {
+  return promise_test(async t => {
+    assert_implements(
+      window.navigator.serviceWorker,
+      'Service Worker is not supported.');
+    assert_true(
+      ['script-execution', 'script-callback'].includes(test_type),
+      "Third party script test type must be one of 'script-execution' or 'script-callback'.");
+    const script =
+      test_type == 'script-execution'
+        ? './resources/fetch-fake-long-3p-script-execution-sw.js'
+        : './resources/fetch-fake-long-3p-script-callback-sw.js';
+    const scope = './resources/fetch-fake-long-3p-script-frame.html';
+
+    // Add service worker to this 1P context. wait_for_state() and
+    // service_worker_unregister_and_register() are helper functions
+    // for creating test ServiceWorkers defined in:
+    // /service-workers/service-worker/resources/test-helpers.sub.js
+    const reg = await service_worker_unregister_and_register(t, script, scope);
+    t.add_cleanup(() => reg.unregister());
+    await wait_for_state(t, reg.installing, 'activated');
+
+    // Setup an iframe controlled by the service worker.
+    const frame = await with_iframe(scope);
+    t.add_cleanup(() => frame.remove());
+
+    // Create a script element
+    const scriptElement = frame.contentWindow.document.createElement('script');
+    scriptElement.src = url;
+    scriptElement.id = 'third-party-script-element-id';
+    scriptElement.async = false;
+
+    const scriptLoadPromise = new Promise(resolve => {
+      scriptElement.addEventListener('load', resolve);
+    });
+
+    const recorder = internals.initializeUKMRecorder();
+    // Add the script to the iframe's DOM
+    frame.contentWindow.document.body.appendChild(scriptElement);
+
+    await scriptLoadPromise
+    await new Promise(resolve => requestAnimationFrame(() => {
+      requestAnimationFrame(resolve);
+    }));
+
+    const entries = recorder.getMetrics(
+      "PerformanceAPI.LongAnimationFrame",
+      [
+        "Categorized3PScriptLongAnimationFrameCallbackContributors",
+        "Categorized3PScriptLongAnimationFrameScriptExecutionContributors"
+      ]);
+
+    // Entries usually have a length of 2, and the first entry will be an event
+    // handler callback added by test-helpers.sub.js. However, when running
+    // upstream on bots and repeating the test for times, starting from the
+    // second time, the callback from test-helpers.sub.js is no longer
+    // triggered, thus will get only 1 entry. As a result, we update this test
+    // to accept flexible number of entries and always check the last entry
+    // for the metric value.
+    assert_greater_than_equal(entries.length, 1);
+    const metrics = entries[entries.length - 1];
+    assert_equals(
+      metrics["Categorized3PScriptLongAnimationFrameCallbackContributors"],
+      test_type == 'script-callback' ? expected_metric_value : 0);
+    assert_equals(
+      metrics["Categorized3PScriptLongAnimationFrameScriptExecutionContributors"],
+      test_type == 'script-execution' ? expected_metric_value : 0);
+  }, `${url} should be reported as a third party ${test_type} contributor in LoAF UKM.`);
+}
\ No newline at end of file
diff --git a/third_party/blink/web_tests/wpt_internal/third-party-script-detection/third-party-script-callback-contributors-ukm-googleanalytics.https.html b/third_party/blink/web_tests/wpt_internal/third-party-script-detection/third-party-script-callback-contributors-ukm-googleanalytics.https.html
new file mode 100644
index 0000000..79bd137a
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/third-party-script-detection/third-party-script-callback-contributors-ukm-googleanalytics.https.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=resources/third-party-script-test-utils.js></script>
+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<script>
+  third_party_script_test(
+    'script-callback',
+    'https://www.google-analytics.com/analytics.js', 2);
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/wpt_internal/third-party-script-detection/third-party-script-callback-contributors-ukm-googlefontapi.https.html b/third_party/blink/web_tests/wpt_internal/third-party-script-detection/third-party-script-callback-contributors-ukm-googlefontapi.https.html
new file mode 100644
index 0000000..62ab557
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/third-party-script-detection/third-party-script-callback-contributors-ukm-googlefontapi.https.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=resources/third-party-script-test-utils.js></script>
+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<script>
+  third_party_script_test(
+    'script-callback',
+    'https://www.googleapis.com/example/webfont', 4);
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/wpt_internal/third-party-script-detection/third-party-script-execution-contributors-ukm-wordpress.https.html b/third_party/blink/web_tests/wpt_internal/third-party-script-detection/third-party-script-execution-contributors-ukm-wordpress.https.html
new file mode 100644
index 0000000..ecab354
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/third-party-script-detection/third-party-script-execution-contributors-ukm-wordpress.https.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=resources/third-party-script-test-utils.js></script>
+<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<script>
+  third_party_script_test(
+    'script-execution',
+    'https://c0.wp.com/c/6.4.2/wp-includes/js/dist/vendor/wp-polyfill.min.js',
+    1);
+</script>
\ No newline at end of file
diff --git a/third_party/dawn b/third_party/dawn
index 30d2bfb..b476146 160000
--- a/third_party/dawn
+++ b/third_party/dawn
@@ -1 +1 @@
-Subproject commit 30d2bfb2ecc261e55b1c329b039cb233678ae126
+Subproject commit b476146a257fbb8ee3b3a4982e16404fc335aa19
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal
index fac0637..5d8ddfd 160000
--- a/third_party/devtools-frontend-internal
+++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@
-Subproject commit fac063701741add8c5af364fb8cfbbf13e5bdc98
+Subproject commit 5d8ddfde5f0b4f9892d87404f14b3a7c48547020
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src
index 3586c71..c8712a9 160000
--- a/third_party/devtools-frontend/src
+++ b/third_party/devtools-frontend/src
@@ -1 +1 @@
-Subproject commit 3586c7113a54ede17dc840ba4213a90823e56756
+Subproject commit c8712a9d7df87cdcf0536f3aa3495b75cc6d707f
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index 652d0e0..edbb7ff 100644
--- a/third_party/freetype/README.chromium
+++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@
 Name: FreeType
 URL: http://www.freetype.org/
-Version: VER-2-13-2-117-g9a2d6d97b
-Revision: 9a2d6d97b2d8a5d22d02948b783df12b764afa2d
+Version: VER-2-13-2-120-g982bc8384
+Revision: 982bc83849966554f850fbc91405883a2a0de895
 CPEPrefix: cpe:/a:freetype:freetype:2.13.2
 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
          JPEG Group) licenses"
diff --git a/third_party/freetype/src b/third_party/freetype/src
index 9a2d6d97..982bc83 160000
--- a/third_party/freetype/src
+++ b/third_party/freetype/src
@@ -1 +1 @@
-Subproject commit 9a2d6d97b2d8a5d22d02948b783df12b764afa2d
+Subproject commit 982bc83849966554f850fbc91405883a2a0de895
diff --git a/third_party/fuzztest/BUILD.gn b/third_party/fuzztest/BUILD.gn
index 66818ede..8d903df 100644
--- a/third_party/fuzztest/BUILD.gn
+++ b/third_party/fuzztest/BUILD.gn
@@ -52,6 +52,7 @@
 
 if (use_centipede) {
   source_set("centipede_common") {
+    testonly = true
     sources = [
       "src/centipede/binary_info.cc",
       "src/centipede/binary_info.h",
@@ -92,6 +93,7 @@
   }
 
   source_set("centipede_runner_no_main") {
+    testonly = true
     sources = [
       "src/centipede/runner.cc",
       "src/centipede/runner.h",
@@ -115,6 +117,10 @@
     configs -= fuzztest_remove_configs
     configs += fuzztest_add_configs
 
+    # Ensure that the centipede driver executable is also built
+    # whenever we build any centipede-based fuzzer
+    data_deps = [ ":centipede" ]
+
     # sancov symbols need to be exported for centipede to work correctly with
     # multi-dso.
     configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]
@@ -122,6 +128,7 @@
   }
 
   source_set("centipede_runner_main") {
+    testonly = true
     deps = [
       ":centipede_runner_no_main",
       "//third_party/abseil-cpp:absl",
@@ -175,14 +182,6 @@
       "src/centipede/workdir.cc",
       "src/centipede/workdir.h",
     ]
-
-    if (build_with_chromium) {
-      deps += [
-        # Depend on fuzzing_engine so that we are automatically built in builds
-        # destined for ClusterFuzz.
-        "//testing/libfuzzer:fuzzing_engine",
-      ]
-    }
   }
 
   # The centipede out-of-process runner executable.
@@ -287,14 +286,6 @@
     "//third_party/abseil-cpp:absl_full",
   ]
 
-  if (build_with_chromium) {
-    deps += [
-      # Depends transitively on fuzzing_engine so that we are automatically
-      # built in builds destined for ClusterFuzz.
-      "//testing/libfuzzer:fuzzing_engine",
-    ]
-  }
-
   public_deps = [
     "//third_party/abseil-cpp:absl",
 
@@ -324,6 +315,12 @@
 #  centipede --binary=./mytest  # Allows the binary to be run using centipede
 #                               # out of process execution environment.
 #                               # Requires use_centipede gn argument.
+# Nothing in this target depends upon //testing/libfuzzer:is_a_fuzz_target,
+# so dependent binaries won't directly be built by the fuzzing build job.
+# However, any uses of the test("...") template which declare that they
+# have fuzztests will cause wrapper executables to be built (because they
+# will depend upon :is_a_fuzz_target). Such executables will have a data_dep
+# on the underlying fuzztest executable, so it will get built.
 source_set("fuzztest") {
   sources = [
     "src/fuzztest/init_fuzztest.cc",
@@ -343,7 +340,7 @@
     ]
   } else if (use_fuzzing_engine && fuzzing_engine_supports_custom_main) {
     # Typically, libfuzzer.
-    deps += [ "//testing/libfuzzer:fuzzing_engine_no_main" ]
+    deps += [ "//testing/libfuzzer:fuzzing_engine_no_main_core" ]
   }
   public_deps = [ ":fuzztest_internal" ]
   configs -= fuzztest_remove_configs
diff --git a/third_party/vulkan-deps b/third_party/vulkan-deps
index 36da75a..7e651e5 160000
--- a/third_party/vulkan-deps
+++ b/third_party/vulkan-deps
@@ -1 +1 @@
-Subproject commit 36da75a01950ce86a9525f7c080359710c0ee6b4
+Subproject commit 7e651e5917e3e8a7eadf8ee002291e4b85caaa56
diff --git a/third_party/webrtc b/third_party/webrtc
index cb3f740..6f170a0 160000
--- a/third_party/webrtc
+++ b/third_party/webrtc
@@ -1 +1 @@
-Subproject commit cb3f740525bca608b44fb2a5af2e8ee0190a789c
+Subproject commit 6f170a05dc27b0add7d9f351585b96e644382b1c
diff --git a/tools/checkbins/checkbins.py b/tools/checkbins/checkbins.py
index 6f4a9e9..ea15978 100755
--- a/tools/checkbins/checkbins.py
+++ b/tools/checkbins/checkbins.py
@@ -45,7 +45,7 @@
 CETCOMPAT_NOT_REQUIRED = [
     'chrome_proxy.exe',
     'chrome_pwa_launcher.exe',
-    'dxcompiler.dll',  # TODO(crbug.com/1473950)
+    'dxcompiler.dll',  # TODO(crbug.com/40927190)
     'elevation_service.exe',
     'nacl64.exe',
     'notification_helper.exe',
diff --git a/tools/cygprofile/orderfile_generator_backend.py b/tools/cygprofile/orderfile_generator_backend.py
index 1b8c3ea..8f69187 100755
--- a/tools/cygprofile/orderfile_generator_backend.py
+++ b/tools/cygprofile/orderfile_generator_backend.py
@@ -232,8 +232,7 @@
         'is_official_build=true',
         'symbol_level=1',  # to fit 30 GiB RAM on the bot when LLD is running
         'target_os="android"',
-        # TODO(b/236070141): remove goma config.
-        'use_goma=' + str(self._options.use_goma).lower(),
+        'enable_proguard_obfuscation=false',  # More debuggable stacktraces.
         'use_remoteexec=' + str(self._options.use_remoteexec).lower(),
         'use_order_profiling=' + str(instrumented).lower(),
         'devtools_instrumentation_dumping=' + str(instrumented).lower()
diff --git a/tools/mb/mb.py b/tools/mb/mb.py
index a111c8ee..b7e7c8ea 100755
--- a/tools/mb/mb.py
+++ b/tools/mb/mb.py
@@ -1759,7 +1759,7 @@
           # supported.
           # TODO(https://crbug.com/1320449): Enable on Mac inside asan once
           # things pass.
-          # TODO(https://crbug.com/974478): Enable on ChromeOS once things pass.
+          # TODO(crbug.com/40632267): Enable on ChromeOS once things pass.
           '--lsan=%d' % lsan
           or (asan and not is_mac and not is_win and not is_cros),
           '--msan=%d' % msan,
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 0fd5152..5b595b7 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -21449,6 +21449,15 @@
   </description>
 </action>
 
+<action name="MobileFullscreenExitedBottomReached">
+  <owner>ajuma@chromium.org</owner>
+  <owner>alionadangla@chromium.org</owner>
+  <description>
+    Reported when user reached the bottom of the page and fullscreen mode is
+    exited. iOS only.
+  </description>
+</action>
+
 <action name="MobileFullscreenExitedManually">
   <owner>ajuma@chromium.org</owner>
   <owner>alionadangla@chromium.org</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 756b5e4..534e706 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -11516,6 +11516,9 @@
   <int value="4946" label="V8Translation_CanTranslate_Method"/>
   <int value="4947" label="V8Translation_CreateTranslator_Method"/>
   <int value="4948" label="IdentityDigitalCredentialsDeepLink"/>
+  <int value="4949"
+      label="V8WebView_GetExperimentalMediaIntegrityTokenProvider_Method"/>
+  <int value="4950" label="V8MediaIntegrityTokenProvider_RequestToken_Method"/>
 </enum>
 
 <enum name="FeaturePolicyFeature">
diff --git a/tools/metrics/histograms/expand_owners.py b/tools/metrics/histograms/expand_owners.py
index 8b4f590..2bba9b4e 100644
--- a/tools/metrics/histograms/expand_owners.py
+++ b/tools/metrics/histograms/expand_owners.py
@@ -246,7 +246,7 @@
     A collection of DOM Elements made from owners in the given OWNERS file.
   """
   owner_elements = []
-  # TODO(crbug.com/987709): An OWNERS file API would be ideal.
+  # TODO(crbug.com/41472818): An OWNERS file API would be ideal.
   emails_from_owners_file = _ExtractEmailAddressesFromOWNERS(path)
   if not emails_from_owners_file:
     raise Error('No emails could be derived from {}.'.format(path))
diff --git a/tools/metrics/histograms/metadata/accessibility/histograms.xml b/tools/metrics/histograms/metadata/accessibility/histograms.xml
index ad6fba2..b57a696 100644
--- a/tools/metrics/histograms/metadata/accessibility/histograms.xml
+++ b/tools/metrics/histograms/metadata/accessibility/histograms.xml
@@ -611,6 +611,20 @@
   </summary>
 </histogram>
 
+<histogram name="Accessibility.CrosCaretBlinkInterval" units="ms"
+    expires_after="2024-08-18">
+  <owner>katie@chromium.org</owner>
+  <owner>chrome-a11y-core@google.com</owner>
+  <summary>
+    The caret blink interval rate, in milliseconds, chosen by the user, from 12
+    possible values in chrome os settings. 0ms means &quot;do not blink&quot;,
+    and the default value is 500ms. Logged once, 45 seconds after startup. For
+    how users adjust the setting from settings, see
+    ChromeOS.Settings.Accessibility.CaretBlinkInterval, which logs each time the
+    setting changes.
+  </summary>
+</histogram>
+
 <histogram name="Accessibility.CrosColorCorrection.FilterAmount" units="%"
     expires_after="2024-08-18">
   <owner>katie@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml
index 19ae97c..16199a5 100644
--- a/tools/metrics/histograms/metadata/chromeos/histograms.xml
+++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -2236,6 +2236,16 @@
   </summary>
 </histogram>
 
+<histogram name="ChromeOS.LockScreenReauth.LockScreenReauthReason"
+    enum="LoginReauthReasons" expires_after="2024-10-01">
+  <owner>ayag@chromium.org</owner>
+  <owner>cros-3pidp@google.com</owner>
+  <summary>
+    Record the reason(s) why a user is required to reauthenticate online on the
+    lock screen. Recorded after successful online authentication.
+  </summary>
+</histogram>
+
 <histogram name="ChromeOS.MachineIdRegen.AgeSeconds" units="seconds"
     expires_after="2022-02-02">
   <owner>ahassani@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml b/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml
index a12a2d8..8742d779 100644
--- a/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml
+++ b/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml
@@ -33,6 +33,18 @@
   </summary>
 </histogram>
 
+<histogram name="ChromeOS.Settings.Accessibility.CaretBlinkInterval" units="ms"
+    expires_after="2024-10-16">
+  <owner>katie@chromium.org</owner>
+  <owner>chrome-a11y-core@google.com</owner>
+  <summary>
+    The text caret blink interval in ms chosen by the user. Logged on change
+    from settings, from 12 possible values in a slider. The default value in
+    settings is 100% which corresponds to 500 ms. 0 ms means &quot;do not
+    blink&quot;.
+  </summary>
+</histogram>
+
 <histogram name="ChromeOS.Settings.Accessibility.ColorCorrection.FilterAmount"
     units="%" expires_after="2024-10-16">
   <owner>katie@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
index 40601b0..f7294d69 100644
--- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -2052,7 +2052,7 @@
   <affected-histogram name="NewTabPage.LogoShown"/>
 </histogram_suffixes>
 
-<!-- TODO(crbug.com/1309706): Migrate these histograms to use the patterned histograms instead. -->
+<!-- TODO(crbug.com/40829943): Migrate these histograms to use the patterned histograms instead. -->
 
 <histogram_suffixes name="NewTabPageModules" separator=".">
   <suffix name="chrome_cart" label="Module ID for Chrome Cart"/>
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml
index 1a40866c..f1a421b 100644
--- a/tools/metrics/histograms/metadata/ios/histograms.xml
+++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -1941,6 +1941,20 @@
   <summary>MultiWindow configuration sampled once per minute.</summary>
 </histogram>
 
+<histogram name="IOS.MultiWindow.ConnectedScenesCount" units="scenes"
+    expires_after="2025-03-03">
+  <owner>fedegermi@google.com</owner>
+  <owner>marq@chromium.org</owner>
+  <summary>Records the number of connected scenes.</summary>
+</histogram>
+
+<histogram name="IOS.MultiWindow.DisconnectedScenesCount" units="scenes"
+    expires_after="2025-03-03">
+  <owner>fedegermi@google.com</owner>
+  <owner>marq@chromium.org</owner>
+  <summary>Records the number of disconnected scenes.</summary>
+</histogram>
+
 <histogram name="IOS.MultiWindow.OpenInNewWindow" enum="WindowActivityOrigin"
     expires_after="2022-06-26">
   <owner>marq@chromium.org</owner>
@@ -3972,8 +3986,9 @@
   <owner>bling-team@google.com</owner>
   <summary>
     Tracks whether the user closed the incognito tab grid page without doing any
-    meaningful action. Meaningful actions are creating, moving, deleting or
-    switching tab. Recorded when the user closed the incognito tab grid page.
+    meaningful action on any tab grid pages. Meaningful actions are creating,
+    moving, deleting or switching tab. Recorded when the user closed the
+    incognito tab grid page.
   </summary>
 </histogram>
 
@@ -3984,8 +3999,9 @@
   <owner>bling-team@google.com</owner>
   <summary>
     Tracks whether the user closed the recent tabs page without doing any
-    meaningful action. Meaningful action is opening a tab. Recorded when the
-    user closed the recent tabs page or switched to a tab grid page.
+    meaningful action on any tab grid pages. Meaningful action is opening a tab.
+    Recorded when the user closed the recent tabs page or switched to a tab grid
+    page.
   </summary>
 </histogram>
 
@@ -3996,8 +4012,9 @@
   <owner>bling-team@google.com</owner>
   <summary>
     Tracks whether the user closed the regular tab grid page without doing any
-    meaningful action. Meaningful actions are creating, moving, deleting or
-    switching tab. Recorded when the user closed the regular tab grid page.
+    meaningful action on any tab grid pages. Meaningful actions are creating,
+    moving, deleting or switching tab. Recorded when the user closed the regular
+    tab grid page.
   </summary>
 </histogram>
 
diff --git a/tools/metrics/histograms/metadata/security/histograms.xml b/tools/metrics/histograms/metadata/security/histograms.xml
index db129c6..d76eb39 100644
--- a/tools/metrics/histograms/metadata/security/histograms.xml
+++ b/tools/metrics/histograms/metadata/security/histograms.xml
@@ -339,7 +339,7 @@
 </histogram>
 
 <histogram name="Security.JSONParser.ParsingTime" units="microseconds"
-    expires_after="M126">
+    expires_after="M127">
   <owner>djmitche@chromium.org</owner>
   <owner>chrome-platform-security@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/signin/histograms.xml b/tools/metrics/histograms/metadata/signin/histograms.xml
index 04803d8d..9fc0d4f 100644
--- a/tools/metrics/histograms/metadata/signin/histograms.xml
+++ b/tools/metrics/histograms/metadata/signin/histograms.xml
@@ -893,7 +893,7 @@
 </histogram>
 
 <histogram name="Signin.GetAccountsBackoffRetries" units="retries"
-    expires_after="2024-05-14">
+    expires_after="2024-09-14">
   <owner>samarchehade@google.com</owner>
   <owner>chrome-signin-team@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/web_rtc/histograms.xml b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
index 5a78016..b535aeb 100644
--- a/tools/metrics/histograms/metadata/web_rtc/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
@@ -128,7 +128,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.Agc2.EstimatedNoiseLevel" units="dBFS (negated)"
-    expires_after="2024-05-05">
+    expires_after="2024-09-15">
   <owner>alessiob@chromium.org</owner>
   <owner>silen@chromium.org</owner>
   <owner>webrtc-audio-uma@google.com</owner>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index ae82b2d..ecd2618 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -20022,6 +20022,9 @@
 </event>
 
 <event name="PartitionedCookiePresent">
+  <obsolete>
+    Deprecated as of 04/2024.
+  </obsolete>
   <owner>selya@chromium.org</owner>
   <owner>selya@google.com</owner>
   <summary>
@@ -20035,6 +20038,21 @@
   </metric>
 </event>
 
+<event name="PartitionedCookiePresentV2">
+  <owner>selya@chromium.org</owner>
+  <owner>dylancutler@google.com</owner>
+  <summary>
+    Recorded when a page has a partitioned cookie present and the cookie's name
+    is not receive-cookie-deprecation.
+  </summary>
+  <metric name="PartitionedCookiePresentV2" enum="Boolean">
+    <summary>
+      Records '1' if one or more partitioned cookies are present. This metric is
+      only logged for sites that have partitioned cookies.
+    </summary>
+  </metric>
+</event>
+
 <event name="PasswordForm">
   <owner>battre@chromium.org</owner>
   <summary>
@@ -20714,11 +20732,29 @@
 
 <event name="PerformanceAPI.LongAnimationFrame">
   <owner>nrosenthal@chromium.org</owner>
+  <owner>zuoaoyuan@chromium.org</owner>
   <summary>
     This event is associated with the LongAnimationFrame Web Platform API. The
     metrics are recorded when a long animation frame is detected and reported to
     the page. For more details see https://crbug.com/1392685.
   </summary>
+  <metric name="Categorized3PScriptLongAnimationFrameCallbackContributors">
+    <summary>
+      A bitfield representation of third party technologies who have contributed
+      at least one event/callback script that blocked the long animation frame
+      for more than 5ms. The bitwise fields are defined by ThirdPartyTechnology
+      enum in third_party/blink_renderer/core/timing/third_party_script_info.h.
+    </summary>
+  </metric>
+  <metric
+      name="Categorized3PScriptLongAnimationFrameScriptExecutionContributors">
+    <summary>
+      A bitfield representation of third party technologies who have contributed
+      at least one script execution block that blocked the long animation frame
+      for more than 5ms. The bitwise fields are defined by ThirdPartyTechnology
+      enum in third_party/blink_renderer/core/timing/third_party_script_info.h.
+    </summary>
+  </metric>
   <metric name="DidPause" enum="Boolean">
     <summary>
       True if there was a pause (sync XHR, dialog) during the long frame.
diff --git a/tools/perf/contrib/leak_detection/page_sets.py b/tools/perf/contrib/leak_detection/page_sets.py
index 385de47..eedcc508 100644
--- a/tools/perf/contrib/leak_detection/page_sets.py
+++ b/tools/perf/contrib/leak_detection/page_sets.py
@@ -49,215 +49,215 @@
       archive_data_file='data/leak_detection.json',
       cloud_storage_bucket=story_module.PARTNER_BUCKET)
     urls_list = [
-      # Alexa top websites
-      'https://www.google.com',
-      'https://www.youtube.com',
-      'https://www.facebook.com',
-      'https://www.baidu.com',
-      'https://www.wikipedia.org',
-      'https://world.taobao.com/',
-      'https://www.tmall.com/',
-      'http://www.amazon.com',
-      'http://www.twitter.com',
-      'https://www.instagram.com/',
-      'http://www.jd.com/',
-      'https://vk.com/',
-      'https://outlook.live.com',
-      'https://www.reddit.com/',
-      'https://weibo.com/',
-      'https://www.sina.com.cn/',
-      'https://www.360.cn/',
-      'https://yandex.ru/',
-      'https://www.blogger.com/',
-      'https://www.netflix.com/',
-      'https://www.pornhub.com/',
-      'https://www.linkedin.com/',
-      'https://www.yahoo.co.jp/',
-      'https://www.csdn.net/',
-      'https://www.alipay.com/',
-      'https://www.twitch.tv/',
-      # TODO(keishi): Memory dump fails flakily crbug.com/963273
-      #'https://www.ebay.com/',
-      # TODO(keishi): Memory dump fails flakily crbug.com/963273
-      #'https://www.microsoft.com/',
-      # TODO(keishi): Memory dump fails flakily crbug.com/963273
-      #'https://www.xvideos.com/',
-      'https://mail.ru/',
-      'https://www.bing.com/',
-      'http://www.wikia.com/',
-      'https://www.office.com/',
-      'https://www.imdb.com/',
-      'https://www.aliexpress.com/',
-      'https://www.msn.com/',
-      'https://news.google.com/',
-      'https://www.theguardian.com/',
-      'https://www.indiatimes.com/',
-      # TODO(keishi): Memory dump fails flakily crbug.com/963273
-      #'http://www.foxnews.com/',
-      'https://weather.com/',
-      'https://www.shutterstock.com/',
-      'https://docs.google.com/',
-      'https://wordpress.com/',
-      # TODO(yuzus): This test crashes.
-      # 'https://www.apple.com/',
-      'https://play.google.com/store',
-      'https://www.dropbox.com/',
-      'https://soundcloud.com/',
-      'https://vimeo.com/',
-      'https://www.slideshare.net/',
-      'https://www.mediafire.com/',
-      'https://www.etsy.com/',
-      'https://www.ikea.com/',
-      'https://www.bestbuy.com/',
-      'https://www.homedepot.com/',
-      # TODO(keishi): Memory dump fails flakily crbug.com/963273
-      #'https://www.target.com/',
-      'https://www.booking.com/',
-      'https://www.tripadvisor.com/',
-      'https://9gag.com/',
-      'https://www.expedia.com/',
-      'https://www.roblox.com/',
-      'https://www.gamespot.com/',
-      'https://www.blizzard.com',
-      # TODO(keishi): Memory dump fails flakily crbug.com/963273
-      #'https://ign.com/',
-      'https://www.yelp.com/',
-      # Times out waiting for HasReachedQuiescence - crbug.com/927427
-      # 'https://gizmodo.com/',
-      'https://www.gsmarena.com/',
-      'https://www.theverge.com/',
-      'https://www.nlm.nih.gov/',
-      'https://archive.org/',
-      'https://www.udemy.com/',
-      'https://answers.yahoo.com/',
-      # TODO(crbug.com/985552): Memory dump fails flakily.
-      # 'https://www.goodreads.com/',
-      'https://www.cricbuzz.com/',
-      'http://www.goal.com/',
-      'http://siteadvisor.com/',
-      'https://www.patreon.com/',
-      'https://www.jw.org/',
-      'http://europa.eu/',
-      'https://translate.google.com/',
-      'https://www.epicgames.com/',
-      'http://www.reverso.net/',
-      'https://play.na.leagueoflegends.com/',
-      'https://www.thesaurus.com/',
-      'https://www.weebly.com/',
-      'https://www.deviantart.com/',
-      'https://www.scribd.com/',
-      'https://www.hulu.com/',
-      'https://www.xfinity.com/',
-      # India Alexa top websites
-      'https://porn555.com/',
-      'https://www.onlinesbi.com/',
-      'https://www.flipkart.com/',
-      'https://www.hotstar.com/',
-      'https://www.incometaxindiaefiling.gov.in/',
-      'https://stackoverflow.com/',
-      # TODO(crbug.com/1005035) Memory dump fails flakily.
-      # 'https://www.irctc.co.in/nget/',
-      'https://www.hdfcbank.com/',
-      'https://www.whatsapp.com/',
-      'https://uidai.gov.in/',
-      'https://billdesk.com/',
-      'https://www.icicibank.com/',
-      # US Alexa top websites
-      'https://imgur.com/',
-      'https://www.craigslist.org/',
-      'https://www.chase.com/',
-      # TODO(892352): tumblr started timing out due to a catapult roll. See
-      # https://crbug.com/892352
-      # 'https://www.tumblr.com/',
-      'https://www.paypal.com/',
-      # TODO(yuzus): espn.com is flaky. https://crbug.com/959796
-      #'http://www.espn.com/',
-      'https://edition.cnn.com/',
-      'https://www.pinterest.com/',
-      # TODO(keishi): Memory dump fails flakily crbug.com/963273
-      #'https://www.nytimes.com/',
-      'https://github.com/',
-      'https://www.salesforce.com/',
-      # Japan Alexa top websites
-      'https://www.rakuten.co.jp/',
-      'http://www.nicovideo.jp/',
-      'https://fc2.com/',
-      'https://ameblo.jp/',
-      'http://kakaku.com/',
-      'https://www.goo.ne.jp/',
-      'https://www.pixiv.net/',
-      # websites which were found to be leaking in the past
-      'https://www.prezi.com',
-      # TODO(keishi): Memory dump fails flakily crbug.com/963273
-      #'http://www.time.com',
-      'http://www.cheapoair.com',
-      'http://www.onlinedown.net',
-      'http://www.dailypost.ng',
-      'http://www.aljazeera.net',
-      'http://www.googleapps.com',
-      'http://www.airbnb.ch',
-      'http://www.livedoor.jp',
-      'http://www.blu-ray.com',
-      # TODO(953195): Test times out.
-      # 'http://www.block.io',
-      'http://www.hockeybuzz.com',
-      'http://www.silverpop.com',
-      'http://www.ansa.it',
-      'http://www.gulfair.com',
-      'http://www.nusatrip.com',
-      'http://www.samsung-fun.ru',
-      'http://www.opentable.com',
-      'http://www.magnetmail.net',
-      'http://zzz.com.ua',
-      'http://a-rakumo.appspot.com',
-      'http://www.sakurafile.com',
-      'http://www.psiexams.com',
-      'http://www.contentful.com',
-      'http://www.estibot.com',
-      'http://www.mbs.de',
-      'http://www.zhengjie.com',
-      'http://www.sjp.pl',
-      'http://www.mastodon.social',
-      'http://www.horairetrain.net',
-      'http://www.torrentzeu.to',
-      'http://www.inbank.it',
-      'http://www.gradpoint.com',
-      'http://www.mail.bg',
-      'http://www.aaannunci.it',
-      'http://www.leandomainsearch.com',
-      'http://www.wpjam.com',
-      'http://www.nigma.ru',
-      'http://www.do-search.com',
-      'http://www.omniboxes.com',
-      'http://whu.edu.cn',
-      'http://support.wordpress.com',
-      'http://www.webwebweb.com',
-      'http://www.sick.com',
-      'http://www.iowacconline.com',
-      'http://hdu.edu.cn',
-      'http://www.register.com',
-      'http://www.careesma.in',
-      'http://www.bestdic.ir',
-      'http://www.privacyassistant.net',
-      'http://www.sklavenzentrale.com',
-      'http://www.podbay.fm',
-      'http://www.coco.fr',
-      'http://www.skipaas.com',
-      'http://www.chatword.org',
-      'http://www.ezcardinfo.com',
-      'http://www.daydao.com',
-      'http://www.expediapartnercentral.com',
-      'http://www.22find.com',
-      'http://www.e-shop.gr',
-      'http://www.indeed.com',
-      'http://www.highwaybus.com',
-      'http://www.pingpang.info',
-      'http://www.besgold.com',
-      'http://www.arabam.com',
-      'http://makfax.com.mk',
-      'http://game.co.za',
-      'http://www.savaari.com',
-      'http://www.railsguides.jp',
+        # Alexa top websites
+        'https://www.google.com',
+        'https://www.youtube.com',
+        'https://www.facebook.com',
+        'https://www.baidu.com',
+        'https://www.wikipedia.org',
+        'https://world.taobao.com/',
+        'https://www.tmall.com/',
+        'http://www.amazon.com',
+        'http://www.twitter.com',
+        'https://www.instagram.com/',
+        'http://www.jd.com/',
+        'https://vk.com/',
+        'https://outlook.live.com',
+        'https://www.reddit.com/',
+        'https://weibo.com/',
+        'https://www.sina.com.cn/',
+        'https://www.360.cn/',
+        'https://yandex.ru/',
+        'https://www.blogger.com/',
+        'https://www.netflix.com/',
+        'https://www.pornhub.com/',
+        'https://www.linkedin.com/',
+        'https://www.yahoo.co.jp/',
+        'https://www.csdn.net/',
+        'https://www.alipay.com/',
+        'https://www.twitch.tv/',
+        # TODO(keishi): Memory dump fails flakily crbug.com/963273
+        #'https://www.ebay.com/',
+        # TODO(keishi): Memory dump fails flakily crbug.com/963273
+        #'https://www.microsoft.com/',
+        # TODO(keishi): Memory dump fails flakily crbug.com/963273
+        #'https://www.xvideos.com/',
+        'https://mail.ru/',
+        'https://www.bing.com/',
+        'http://www.wikia.com/',
+        'https://www.office.com/',
+        'https://www.imdb.com/',
+        'https://www.aliexpress.com/',
+        'https://www.msn.com/',
+        'https://news.google.com/',
+        'https://www.theguardian.com/',
+        'https://www.indiatimes.com/',
+        # TODO(keishi): Memory dump fails flakily crbug.com/963273
+        #'http://www.foxnews.com/',
+        'https://weather.com/',
+        'https://www.shutterstock.com/',
+        'https://docs.google.com/',
+        'https://wordpress.com/',
+        # TODO(yuzus): This test crashes.
+        # 'https://www.apple.com/',
+        'https://play.google.com/store',
+        'https://www.dropbox.com/',
+        'https://soundcloud.com/',
+        'https://vimeo.com/',
+        'https://www.slideshare.net/',
+        'https://www.mediafire.com/',
+        'https://www.etsy.com/',
+        'https://www.ikea.com/',
+        'https://www.bestbuy.com/',
+        'https://www.homedepot.com/',
+        # TODO(keishi): Memory dump fails flakily crbug.com/963273
+        #'https://www.target.com/',
+        'https://www.booking.com/',
+        'https://www.tripadvisor.com/',
+        'https://9gag.com/',
+        'https://www.expedia.com/',
+        'https://www.roblox.com/',
+        'https://www.gamespot.com/',
+        'https://www.blizzard.com',
+        # TODO(keishi): Memory dump fails flakily crbug.com/963273
+        #'https://ign.com/',
+        'https://www.yelp.com/',
+        # Times out waiting for HasReachedQuiescence - crbug.com/927427
+        # 'https://gizmodo.com/',
+        'https://www.gsmarena.com/',
+        'https://www.theverge.com/',
+        'https://www.nlm.nih.gov/',
+        'https://archive.org/',
+        'https://www.udemy.com/',
+        'https://answers.yahoo.com/',
+        # TODO(crbug.com/985552): Memory dump fails flakily.
+        # 'https://www.goodreads.com/',
+        'https://www.cricbuzz.com/',
+        'http://www.goal.com/',
+        'http://siteadvisor.com/',
+        'https://www.patreon.com/',
+        'https://www.jw.org/',
+        'http://europa.eu/',
+        'https://translate.google.com/',
+        'https://www.epicgames.com/',
+        'http://www.reverso.net/',
+        'https://play.na.leagueoflegends.com/',
+        'https://www.thesaurus.com/',
+        'https://www.weebly.com/',
+        'https://www.deviantart.com/',
+        'https://www.scribd.com/',
+        'https://www.hulu.com/',
+        'https://www.xfinity.com/',
+        # India Alexa top websites
+        'https://porn555.com/',
+        'https://www.onlinesbi.com/',
+        'https://www.flipkart.com/',
+        'https://www.hotstar.com/',
+        'https://www.incometaxindiaefiling.gov.in/',
+        'https://stackoverflow.com/',
+        # TODO(crbug.com/1005035) Memory dump fails flakily.
+        # 'https://www.irctc.co.in/nget/',
+        'https://www.hdfcbank.com/',
+        'https://www.whatsapp.com/',
+        'https://uidai.gov.in/',
+        'https://billdesk.com/',
+        'https://www.icicibank.com/',
+        # US Alexa top websites
+        'https://imgur.com/',
+        'https://www.craigslist.org/',
+        'https://www.chase.com/',
+        # TODO(crbug.com/41419049): tumblr started timing out due to a catapult
+        # roll. See https://crbug.com/892352
+        # 'https://www.tumblr.com/',
+        'https://www.paypal.com/',
+        # TODO(yuzus): espn.com is flaky. https://crbug.com/959796
+        #'http://www.espn.com/',
+        'https://edition.cnn.com/',
+        'https://www.pinterest.com/',
+        # TODO(keishi): Memory dump fails flakily crbug.com/963273
+        #'https://www.nytimes.com/',
+        'https://github.com/',
+        'https://www.salesforce.com/',
+        # Japan Alexa top websites
+        'https://www.rakuten.co.jp/',
+        'http://www.nicovideo.jp/',
+        'https://fc2.com/',
+        'https://ameblo.jp/',
+        'http://kakaku.com/',
+        'https://www.goo.ne.jp/',
+        'https://www.pixiv.net/',
+        # websites which were found to be leaking in the past
+        'https://www.prezi.com',
+        # TODO(keishi): Memory dump fails flakily crbug.com/963273
+        #'http://www.time.com',
+        'http://www.cheapoair.com',
+        'http://www.onlinedown.net',
+        'http://www.dailypost.ng',
+        'http://www.aljazeera.net',
+        'http://www.googleapps.com',
+        'http://www.airbnb.ch',
+        'http://www.livedoor.jp',
+        'http://www.blu-ray.com',
+        # TODO(953195): Test times out.
+        # 'http://www.block.io',
+        'http://www.hockeybuzz.com',
+        'http://www.silverpop.com',
+        'http://www.ansa.it',
+        'http://www.gulfair.com',
+        'http://www.nusatrip.com',
+        'http://www.samsung-fun.ru',
+        'http://www.opentable.com',
+        'http://www.magnetmail.net',
+        'http://zzz.com.ua',
+        'http://a-rakumo.appspot.com',
+        'http://www.sakurafile.com',
+        'http://www.psiexams.com',
+        'http://www.contentful.com',
+        'http://www.estibot.com',
+        'http://www.mbs.de',
+        'http://www.zhengjie.com',
+        'http://www.sjp.pl',
+        'http://www.mastodon.social',
+        'http://www.horairetrain.net',
+        'http://www.torrentzeu.to',
+        'http://www.inbank.it',
+        'http://www.gradpoint.com',
+        'http://www.mail.bg',
+        'http://www.aaannunci.it',
+        'http://www.leandomainsearch.com',
+        'http://www.wpjam.com',
+        'http://www.nigma.ru',
+        'http://www.do-search.com',
+        'http://www.omniboxes.com',
+        'http://whu.edu.cn',
+        'http://support.wordpress.com',
+        'http://www.webwebweb.com',
+        'http://www.sick.com',
+        'http://www.iowacconline.com',
+        'http://hdu.edu.cn',
+        'http://www.register.com',
+        'http://www.careesma.in',
+        'http://www.bestdic.ir',
+        'http://www.privacyassistant.net',
+        'http://www.sklavenzentrale.com',
+        'http://www.podbay.fm',
+        'http://www.coco.fr',
+        'http://www.skipaas.com',
+        'http://www.chatword.org',
+        'http://www.ezcardinfo.com',
+        'http://www.daydao.com',
+        'http://www.expediapartnercentral.com',
+        'http://www.22find.com',
+        'http://www.e-shop.gr',
+        'http://www.indeed.com',
+        'http://www.highwaybus.com',
+        'http://www.pingpang.info',
+        'http://www.besgold.com',
+        'http://www.arabam.com',
+        'http://makfax.com.mk',
+        'http://game.co.za',
+        'http://www.savaari.com',
+        'http://www.railsguides.jp',
     ]
     resource_loading_urls_list = [
       'https://www.hotels.com/',
diff --git a/tools/perf/page_sets/press_story.py b/tools/perf/page_sets/press_story.py
index 3622298..1d7dfda 100644
--- a/tools/perf/page_sets/press_story.py
+++ b/tools/perf/page_sets/press_story.py
@@ -67,7 +67,7 @@
       description: An optional string with a short human readable description
         of the measurement.
     """
-    # TODO(crbug.com/999484): Ideally, these should be recorded directly into
+    # TODO(crbug.com/40642835): Ideally, these should be recorded directly into
     # the results object, rather than held on this temporary list. That needs,
     # however, another slight refactor to make the results object available at
     # this point.
diff --git a/tools/perf/process_perf_results.py b/tools/perf/process_perf_results.py
index a04e192..41cdaba 100755
--- a/tools/perf/process_perf_results.py
+++ b/tools/perf/process_perf_results.py
@@ -529,7 +529,7 @@
     if log:
       logging.warning(
           'Failed to get a CPU count for this bot. See crbug.com/947035.')
-    # TODO(crbug.com/948281): This is currently set to 4 since the mac masters
+    # TODO(crbug.com/41450490): This is currently set to 4 since the mac masters
     # only have 4 cores. Once we move to all-linux, this can be increased or
     # we can even delete this whole function and use multiprocessing.cpu_count()
     # directly.
diff --git a/tools/pgo/generate_profile.py b/tools/pgo/generate_profile.py
index daf1b10ad..7df9f05 100755
--- a/tools/pgo/generate_profile.py
+++ b/tools/pgo/generate_profile.py
@@ -80,6 +80,14 @@
         help='Only run benchmarks that do not require any special access. See '
         'https://www.chromium.org/developers/telemetry/upload_to_cloud_storage/#request-access-for-google-partners '
         'for more information.')
+    parser.add_argument('--skip-jetstream',
+                        action='store_true',
+                        help='Jetstream2 is very flaky (60% pass rate), so it '
+                        'is helpful to skip it when iterating fast locally.')
+    parser.add_argument(
+        '--temporal-trace-length',
+        type=int,
+        help='Add flags necessary for temporal PGO (experimental).')
     parser.add_argument('-v',
                         '--verbose',
                         action='count',
@@ -165,7 +173,9 @@
 
     # Run the shortest benchmarks first to fail early if anything is wrong.
     run_benchmark(['speedometer3'])
-    run_benchmark(['jetstream2'])
+
+    if not args.skip_jetstream:
+        run_benchmark(['jetstream2'])
 
     # These benchmarks require special access permissions:
     # https://www.chromium.org/developers/telemetry/upload_to_cloud_storage/#request-access-for-google-partners
@@ -188,10 +198,24 @@
             ])
 
     if not args.skip_profdata:
-        subprocess.run(
-            [PROFDATA, 'merge', '-o', f'{builddir}/profile.profdata'] +
-            glob.glob(f'{profiledir}/*.profdata'),
-            check=True)
+        merge_cmd = [PROFDATA, 'merge']
+        if args.temporal_trace_length:
+            merge_cmd += [
+                '--temporal-profile-max-trace-length',
+                str(args.temporal_trace_length)
+            ]
+        profile_output_path = f'{builddir}/profile.profdata'
+        merge_cmd += ['-o', profile_output_path]
+        subprocess.run(merge_cmd + glob.glob(f'{profiledir}/*.profdata'),
+                       check=True)
+
+        if args.temporal_trace_length:
+            orderfile_cmd = [
+                PROFDATA, 'order', profile_output_path, '-o',
+                f'{builddir}/orderfile.txt'
+            ]
+            subprocess.run(orderfile_cmd, check=True)
+
 
     if not args.keep_temps:
         shutil.rmtree(profiledir)
diff --git a/tools/rust/build_rust.py b/tools/rust/build_rust.py
index 572b5bab..7999b06 100755
--- a/tools/rust/build_rust.py
+++ b/tools/rust/build_rust.py
@@ -71,9 +71,9 @@
     os.path.join('tests', 'codegen', 'issue-45222.rs'),
     # https://github.com/rust-lang/rust/issues/96497
     os.path.join('tests', 'codegen', 'issue-96497-slice-size-nowrap.rs'),
-    # TODO(https://crbug.com/1515111): remove after rolling rust with fix
+    # TODO(crbug.com/41487664): remove after rolling rust with fix
     os.path.join('tests', 'codegen', 'abi-main-signature-32bit-c-int.rs'),
-    # TODO(https://crbug.com/1513478): remove after rolling rust with fix
+    # TODO(crbug.com/41486049): remove after rolling rust with fix
     os.path.join('tests', 'ui', 'asm', 'inline-syntax.rs'),
     # TODO(https://crbug.com/324853415): benign failure; remove when fixed.
     os.path.join('tests', 'codegen', 'iter-repeat-n-trivial-drop.rs'),
diff --git a/tools/typescript/validate_tsconfig.py b/tools/typescript/validate_tsconfig.py
index 8846da1..eca3a83 100644
--- a/tools/typescript/validate_tsconfig.py
+++ b/tools/typescript/validate_tsconfig.py
@@ -143,7 +143,7 @@
       # remove exception.
       'chrome/browser/resources/bluetooth_internals',
       'chrome/browser/resources/chromeos/accessibility',
-      # TODO(crbug.com/1511758): Migrate to TypeScript.
+      # TODO(crbug.com/41484340): Migrate to TypeScript.
       'chrome/browser/resources/device_log',
       'chrome/test/data/webui',
       # TODO(crbug.com/1337318): Migrate bluetooth-internals to TypeScript and
diff --git a/ui/display/display_features.cc b/ui/display/display_features.cc
index accede1f..5eafd98 100644
--- a/ui/display/display_features.cc
+++ b/ui/display/display_features.cc
@@ -37,7 +37,14 @@
 BASE_FEATURE(kEnableExternalDisplayHDR10Mode,
              "EnableExternalDisplayHDR10Mode",
              base::FEATURE_DISABLED_BY_DEFAULT);
+#endif
 
+#if BUILDFLAG(IS_CHROMEOS)
+// Feature to control if the CTM is dynamically set to the primary transform
+// from plane color space to output color space.
+BASE_FEATURE(kCtmColorManagement,
+             "CtmColorManagement",
+             base::FEATURE_DISABLED_BY_DEFAULT);
 #endif
 
 // This features allows listing all display modes of external displays in the
diff --git a/ui/display/display_features.h b/ui/display/display_features.h
index c3c2b6e..5220be5 100644
--- a/ui/display/display_features.h
+++ b/ui/display/display_features.h
@@ -24,6 +24,11 @@
 BASE_DECLARE_FEATURE(kEnableExternalDisplayHDR10Mode);
 #endif
 
+#if BUILDFLAG(IS_CHROMEOS)
+COMPONENT_EXPORT(DISPLAY_FEATURES)
+BASE_DECLARE_FEATURE(kCtmColorManagement);
+#endif
+
 COMPONENT_EXPORT(DISPLAY_FEATURES) BASE_DECLARE_FEATURE(kListAllDisplayModes);
 
 COMPONENT_EXPORT(DISPLAY_FEATURES) bool IsListAllDisplayModesEnabled();
diff --git a/ui/ozone/platform/drm/gpu/drm_display.cc b/ui/ozone/platform/drm/gpu/drm_display.cc
index 04f1c5be..38eaae5 100644
--- a/ui/ozone/platform/drm/gpu/drm_display.cc
+++ b/ui/ozone/platform/drm/gpu/drm_display.cc
@@ -143,6 +143,9 @@
   hdr_static_metadata_ = display_snapshot.hdr_static_metadata();
   privacy_screen_property_ =
       std::make_unique<PrivacyScreenProperty>(drm_, connector_.get());
+
+  SkColorSpacePrimaries output_primaries =
+      display_snapshot.color_info().edid_primaries;
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   is_hdr_capable_ =
       is_hdr_capable_ &&
@@ -151,10 +154,12 @@
   if (is_hdr_capable_ &&
       base::FeatureList::IsEnabled(
           display::features::kEnableExternalDisplayHDR10Mode)) {
+    output_primaries = SkNamedPrimariesExt::kRec2020;
     SetColorspaceProperty(display_snapshot.color_space());
     SetHdrOutputMetadata(display_snapshot.color_space());
   }
 #endif
+  drm_->plane_manager()->SetOutputColorSpace(crtc_, output_primaries);
 }
 
 DrmDisplay::~DrmDisplay() = default;
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
index 86977bd..a1fd231 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
@@ -12,9 +12,12 @@
 #include <utility>
 
 #include "base/containers/flat_set.h"
+#include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/ranges/algorithm.h"
+#include "skia/ext/skia_utils_base.h"
 #include "third_party/perfetto/include/perfetto/tracing/traced_value.h"
+#include "ui/display/display_features.h"
 #include "ui/display/types/display_color_management.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_conversions.h"
@@ -39,6 +42,23 @@
                    crop_rect.width() << 16, crop_rect.height() << 16);
 }
 
+// TODO(b/335542790): The values that are written to the CTM blob are not
+// tested, and so the values written by this function are also not tested.
+// Add tests for these.
+skcms_Matrix3x3 PlaneToOutputMatrix(
+    const HardwareDisplayPlaneManager::CrtcState& crtc_state) {
+  skcms_Matrix3x3 plane_to_xyzd50;
+  crtc_state.planes_primaries.toXYZD50(&plane_to_xyzd50);
+
+  skcms_Matrix3x3 output_to_xyzd50;
+  crtc_state.output_primaries.toXYZD50(&output_to_xyzd50);
+
+  skcms_Matrix3x3 xyzd50_to_output;
+  skcms_Matrix3x3_invert(&output_to_xyzd50, &xyzd50_to_output);
+
+  return skcms_Matrix3x3_concat(&xyzd50_to_output, &plane_to_xyzd50);
+}
+
 }  // namespace
 
 HardwareDisplayPlaneList::HardwareDisplayPlaneList() {
@@ -241,6 +261,14 @@
       return false;
     }
 
+    // Set the color space for all planes based on the color space of the plane
+    // with z-index 0. This assumes that all planes have the same primaries.
+    // This assumption will need to be enforced in the compositor's overlay
+    // processor.
+    if (plane.z_order == 0 && plane.color_space.IsValid()) {
+      SetColorSpaceForAllPlanes(crtc_id, plane.color_space.GetPrimaries());
+    }
+
     plane_list->plane_list.push_back(hw_plane);
     hw_plane->set_owning_crtc(crtc_id);
     hw_plane->set_in_use(true);
@@ -309,6 +337,41 @@
   return valid_ids;
 }
 
+void HardwareDisplayPlaneManager::SetOutputColorSpace(
+    uint32_t crtc_id,
+    const SkColorSpacePrimaries& primaries) {
+  if (primaries == SkNamedPrimariesExt::kInvalid) {
+    LOG(ERROR) << "Invalid output primaries for CRTC " << crtc_id;
+    return;
+  }
+  CrtcState& crtc_state = CrtcStateForCrtcId(crtc_id);
+  if (crtc_state.output_primaries == primaries) {
+    return;
+  }
+  crtc_state.output_primaries = primaries;
+  if (base::FeatureList::IsEnabled(display::features::kCtmColorManagement)) {
+    UpdatePendingCrtcState(crtc_state);
+  }
+}
+
+void HardwareDisplayPlaneManager::SetColorSpaceForAllPlanes(
+    uint32_t crtc_id,
+    const SkColorSpacePrimaries& primaries) {
+  if (primaries == SkNamedPrimariesExt::kInvalid) {
+    LOG(ERROR) << "Invalid plane primaries for CRTC " << crtc_id;
+    return;
+  }
+  CrtcState& crtc_state = CrtcStateForCrtcId(crtc_id);
+  if (crtc_state.planes_primaries == primaries) {
+    return;
+  }
+  CHECK(primaries != SkNamedPrimariesExt::kInvalid);
+  crtc_state.planes_primaries = primaries;
+  if (base::FeatureList::IsEnabled(display::features::kCtmColorManagement)) {
+    UpdatePendingCrtcState(crtc_state);
+  }
+}
+
 void HardwareDisplayPlaneManager::SetColorTemperatureAdjustment(
     uint32_t crtc_id,
     const display::ColorTemperatureAdjustment& cta) {
@@ -534,12 +597,23 @@
     CrtcState& crtc_state) {
   const auto& crtc_props = crtc_state.properties;
 
-  // Set the CTM to the concatenation of the color profile matrix and the color
-  // temperature adjustment matrix.
-  // TODO(https://crbug.com/1505062): This is incorrect if the color profile
-  // DEGAMMA/GAMMA curves are ever not the identity.
+  // Set the CTM to convert from the planes' color space primaries to the
+  // output color space primaries, followed by application of the color
+  // temperature adjustment matrix. This is not the correct math to perform
+  // color conversion in the following ways:
+  //   * The primary conversion should be done in linear space. This can only
+  //     be done if both DEGAMMA and GAMMA are functional, but DEGAMMA is
+  //     very often broken.
+  //   * The color temperature adjustment matrix is computed to be applied in
+  //     sRGB space, not the output space.
+  // This is being done as a trade-off sacrificing precise correctness in
+  // color conversion for power savings.
+  const skcms_Matrix3x3 plane_to_device_matrix =
+      base::FeatureList::IsEnabled(display::features::kCtmColorManagement)
+          ? PlaneToOutputMatrix(crtc_state)
+          : crtc_state.color_calibration.srgb_to_device_matrix;
   const skcms_Matrix3x3 ctm = skcms_Matrix3x3_concat(
-      &crtc_state.color_calibration.srgb_to_device_matrix,
+      &plane_to_device_matrix,
       &crtc_state.color_temperature_adjustment.srgb_matrix);
   if (crtc_state.properties.ctm.id) {
     ScopedDrmColorCtmPtr ctm_blob_data =
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
index 4ef9767..5c38510 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
@@ -108,6 +108,16 @@
     display::ColorCalibration color_calibration;
     display::GammaAdjustment gamma_adjustment;
 
+    // The color space of all input planes. This assumes that all planes have
+    // the same color space, because all existing devices only support one
+    // color management configuration for all planes.
+    SkColorSpacePrimaries planes_primaries = SkNamedPrimariesExt::kSRGB;
+
+    // The color space of the output. All planes must be transformed to this
+    // space, using the hardware color management parameters (DEGAMMA, CTM,
+    // and GAMMA, where available).
+    SkColorSpacePrimaries output_primaries = SkNamedPrimariesExt::kSRGB;
+
     // Cached blobs for the properties to commit in CommitCrtcProperties.
     // * If a property is `std::nullopt`, then it should be left unchanged.
     // * If a property is `nullptr` then it should be set to 0.
@@ -146,6 +156,15 @@
   // calls.
   void BeginFrame(HardwareDisplayPlaneList* plane_list);
 
+  // Sets the input color space for all planes. This assumes that all planes on
+  // a CRTC have the same color space.
+  void SetColorSpaceForAllPlanes(uint32_t crtc_id,
+                                 const SkColorSpacePrimaries& primaries);
+
+  // Sets the output color space for the given CRTC.
+  void SetOutputColorSpace(uint32_t crtc_id,
+                           const SkColorSpacePrimaries& primaries);
+
   // Sets the color temperature adjustment for a given CRTC.
   void SetColorTemperatureAdjustment(
       uint32_t crtc_id,
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
index 9b3bb7a..20b7d29 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
@@ -245,9 +245,11 @@
   // should all be handled in Set{Crtc,Connector,Plane}Props() modulo some state
   // tracking changes that should be done post commit. Break it apart when both
   // Commit() are consolidated.
+  std::vector<ScopedDrmPropertyBlob> pending_blobs;
   for (HardwareDisplayPlaneList* list : enable_planes_lists) {
     SetAtomicPropsForCommit(atomic_request.get(), list,
-                            GetCrtcIdsOfPlanes(*list), is_testing);
+                            GetCrtcIdsOfPlanes(*list), pending_blobs,
+                            is_testing);
   }
 
   // TODO(markyacoub): failed |status|'s should be made as DCHECKs. The only
@@ -282,6 +284,7 @@
     drmModeAtomicReq* atomic_request,
     HardwareDisplayPlaneList* plane_list,
     const std::vector<uint32_t>& crtcs,
+    std::vector<ScopedDrmPropertyBlob>& pending_blobs,
     bool test_only) {
   for (HardwareDisplayPlane* plane : plane_list->plane_list) {
     HardwareDisplayPlaneAtomic* atomic_plane =
@@ -322,6 +325,10 @@
 
     AddPropertyIfValid(atomic_request, crtc,
                        crtc_state_[*idx].properties.background_color);
+    if (base::FeatureList::IsEnabled(display::features::kCtmColorManagement)) {
+      AddAllPendingCrtcProperties(atomic_request, crtc_state_[*idx],
+                                  pending_blobs);
+    }
   }
 
   if (test_only) {
@@ -342,8 +349,9 @@
 
   std::vector<uint32_t> crtcs = GetCrtcIdsOfPlanes(*plane_list);
 
+  std::vector<ScopedDrmPropertyBlob> pending_blobs;
   SetAtomicPropsForCommit(plane_list->atomic_property_set.get(), plane_list,
-                          crtcs, test_only);
+                          crtcs, pending_blobs, test_only);
 
   // After we perform the atomic commit, and if the caller has requested an
   // out-fence, the out_fence_fds vector will contain any provided out-fence
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h
index d7b7eb6f..142ff23 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h
@@ -50,10 +50,12 @@
  private:
   bool InitializePlanes() override;
   std::unique_ptr<HardwareDisplayPlane> CreatePlane(uint32_t plane_id) override;
-  void SetAtomicPropsForCommit(drmModeAtomicReq* atomic_request,
-                               HardwareDisplayPlaneList* plane_list,
-                               const std::vector<uint32_t>& crtcs,
-                               bool test_only);
+  void SetAtomicPropsForCommit(
+      drmModeAtomicReq* atomic_request,
+      HardwareDisplayPlaneList* plane_list,
+      const std::vector<uint32_t>& crtcs,
+      std::vector<ScopedDrmPropertyBlob>& pending_blobs,
+      bool test_only);
 
   bool SetCrtcProps(drmModeAtomicReq* atomic_request,
                     uint32_t crtc_id,
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
index f38132f..fea864483 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
@@ -16,10 +16,12 @@
 #include "base/notreached.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/test/gtest_util.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/time/time.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/display/display_features.h"
 #include "ui/display/types/display_color_management.h"
 #include "ui/gfx/gpu_fence.h"
 #include "ui/gfx/gpu_fence_handle.h"
@@ -1033,6 +1035,10 @@
       fake_drm_->crtc_property(0).id, cta);
 
   if (use_atomic_) {
+    // The color temperature adjustment will get its own commit.
+    EXPECT_EQ(1, fake_drm_->get_commit_count());
+    EXPECT_NE(0u, GetCrtcPropertyValue(fake_drm_->crtc_property(0).id, "CTM"));
+
     HardwareDisplayPlaneList state;
     PerformPageFlip(/*crtc_idx=*/0, &state);
     EXPECT_EQ(2, fake_drm_->get_commit_count());
@@ -1084,6 +1090,49 @@
   }
 }
 
+TEST_P(HardwareDisplayPlaneManagerTest, ColorManagement_CtmColorManagement) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitWithFeatures({display::features::kCtmColorManagement},
+                                       {});
+
+  auto drm_state = MockDrmDevice::MockDrmState::CreateStateWithDefaultObjects(
+      /*crtc_count=*/1, /*planes_per_crtc=*/1);
+
+  // This test has full CTM, DEGAMMA, and GAMMA.
+  drm_state.crtc_properties[0].properties.push_back(
+      {.id = kCtmPropId, .value = 0});
+  drm_state.crtc_properties[0].properties.push_back(
+      {.id = kDegammaLutSizePropId, .value = 1});
+  drm_state.crtc_properties[0].properties.push_back(
+      {.id = kDegammaLutPropId, .value = 0});
+  drm_state.crtc_properties[0].properties.push_back(
+      {.id = kGammaLutSizePropId, .value = 1});
+  drm_state.crtc_properties[0].properties.push_back(
+      {.id = kGammaLutPropId, .value = 0});
+
+  // Color profile change will set all properties.
+  fake_drm_->InitializeState(drm_state, use_atomic_);
+
+  fake_drm_->plane_manager()->SetOutputColorSpace(
+      fake_drm_->crtc_property(0).id, SkNamedPrimariesExt::kP3);
+  fake_drm_->plane_manager()->SetColorSpaceForAllPlanes(
+      fake_drm_->crtc_property(0).id, SkNamedPrimariesExt::kRec2020);
+
+  if (use_atomic_) {
+    // We should not have committed the CTM yet.
+    EXPECT_EQ(0, fake_drm_->get_commit_count());
+    EXPECT_EQ(0u, GetCrtcPropertyValue(fake_drm_->crtc_property(0).id, "CTM"));
+
+    // The CTM commit should happen at flip time.
+    HardwareDisplayPlaneList state;
+    PerformPageFlip(/*crtc_idx=*/0, &state);
+    EXPECT_EQ(1, fake_drm_->get_commit_count());
+    EXPECT_NE(0u, GetCrtcPropertyValue(fake_drm_->crtc_property(0).id, "CTM"));
+  } else {
+    EXPECT_EQ(0, fake_drm_->get_set_object_property_count());
+  }
+}
+
 TEST_P(HardwareDisplayPlaneManagerTest, ColorManagement_GammaAdjustment) {
   auto drm_state = FakeDrmDevice::MockDrmState::CreateStateWithDefaultObjects(
       /*crtc_count=*/1, /*planes_per_crtc=*/1);
@@ -1108,6 +1157,11 @@
                                                  gamma_adjustment);
 
   if (use_atomic_) {
+    // The gamma adjustment will get its own commit.
+    EXPECT_EQ(1, fake_drm_->get_commit_count());
+    EXPECT_NE(
+        0u, GetCrtcPropertyValue(fake_drm_->crtc_property(0).id, "GAMMA_LUT"));
+
     HardwareDisplayPlaneList state;
     PerformPageFlip(/*crtc_idx=*/0, &state);
     EXPECT_EQ(2, fake_drm_->get_commit_count());
diff --git a/url/android/java/src/org/chromium/url/GURL.java b/url/android/java/src/org/chromium/url/GURL.java
index 08811081..37f483d 100644
--- a/url/android/java/src/org/chromium/url/GURL.java
+++ b/url/android/java/src/org/chromium/url/GURL.java
@@ -61,7 +61,7 @@
     private static final int DEBUG_REPORT_PERCENTAGE = 10;
     private static ReportDebugThrowableCallback sReportCallback;
 
-    // TODO(https://crbug.com/1039841): Right now we return a new String with each request for a
+    // TODO(crbug.com/40113773): Right now we return a new String with each request for a
     //      GURL component other than the spec itself. Should we cache return Strings (as
     //      WeakReference?) so that callers can share String memory?
     private String mSpec;
diff --git a/v8 b/v8
index 2eaa4a2..0eb99a5 160000
--- a/v8
+++ b/v8
@@ -1 +1 @@
-Subproject commit 2eaa4a2641b0d19b79d02a83d1683e60894a6179
+Subproject commit 0eb99a5fd27ab7a29e4d8bc54b5f7bd97012c7c0