diff --git a/DEPS b/DEPS
index 8e642c3..d262971 100644
--- a/DEPS
+++ b/DEPS
@@ -308,11 +308,11 @@
   # 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': '080b67ed0ec069265a884682bbd2fef434e6e0ed',
+  'angle_revision': 'b43a004567b060a6c01eb546bc7b055f00288c14',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': 'ecba967ea71ff219de64131f774d7fdd37473ada',
+  'swiftshader_revision': '150bc8c1c215221b317d09ccb1dff0ba8e66fa63',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -327,7 +327,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Fuchsia sdk
   # and whatever else without interference from each other.
-  'fuchsia_version': 'version:9.20220830.2.1',
+  'fuchsia_version': 'version:9.20220831.2.1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling google-toolbox-for-mac
   # and whatever else without interference from each other.
@@ -415,7 +415,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': '969692ccf88dd4c7386af48c7e9665fff601e1ad',
+  'dawn_revision': '1862e83510aef598b427af3d3a5c18fbf17ac590',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -865,7 +865,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/linux-amd64',
-          'version': '6EL1sfM-iJz_iMek03HGmidELNtP-IqR7DkVz8QDbXcC',
+          'version': 'NGh_JKbMnMFhVhCCsloO5zPsQDaqdZ8hvVsnFjYUx5MC',
         },
       ],
       'dep_type': 'cipd',
@@ -876,7 +876,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/mac-amd64',
-          'version': 'NxesCWKiUlO-SWBq1kG43uB9CA3XEym3aM0-J95u_dEC',
+          'version': 'iExTBPA_m79_ZYKrJZlfUsyzwy72CFGu-dbvPt3HpZsC',
         },
       ],
       'dep_type': 'cipd',
@@ -887,7 +887,7 @@
       'packages': [
         {
           'package': 'chromium/rts/model/windows-amd64',
-          'version': '4QdTbHeCHJ5R0ET-bXJC6196hjJ5EBTfuwAKrZ8We2wC',
+          'version': 'YPq1S1cpQ2wTAeq8NnjmH3ziVOcKx1yq-hxE6ZGsYagC',
         },
       ],
       'dep_type': 'cipd',
@@ -955,7 +955,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'hKX0VX69NMeCLmcE5neFgOa7S9dQdcsR_dbFV9ZcFmoC',
+          'version': '7LibE0MLJMFS99X0RgfGxaihptFBes7DCeHNQU_qJGMC',
       },
     ],
     'condition': 'checkout_android',
@@ -1170,7 +1170,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'c22997cf5674ce1458ae237e9e57668489d11bde',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '5aa70a7a666f34ad1898d4975f69ce175fd93186',
       'condition': 'checkout_chromeos',
   },
 
@@ -1592,7 +1592,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'cfc11efaad09f07f28857a9fea242db5891a8c63',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '85910f22b620e71323e7681d8b3c6689aaf4aa1a',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1759,7 +1759,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '44e4c8770158c505b03ee7feafa4859d083b0912',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'e93c41b874d287df70b5d56e9d1aecf4a93f33e5',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '39f597ad35bd5e88af9c388c65582673922df63c',
 
   'src/third_party/webrtc':
     Var('webrtc_git') + '/src.git' + '@' + '74195b2b4450065f43f757f69fd5c474f2c687f4',
@@ -1835,7 +1835,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@b0ff7261ae2ab9732bf983fa0591e92f20282f15',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3e783163168353c34b8d0d19b43880dedd15b81b',
     'condition': 'checkout_src_internal',
   },
 
@@ -1865,7 +1865,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/help_app/app',
-        'version': 'ckVfvqVSbMrvV6keF6pSW0FLeu_5CNBXxPmIBJXK6X0C',
+        'version': '54sfvjv1VfCr1dzHwWy8VVflJwVBT1BbrIj1vUP02u8C',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -1876,7 +1876,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': '7Tr94VSUyKEBYS1T6-fXIfM5p1FnXIzXPOdGa-VArmwC',
+        'version': 'wEx9XSPm6DcLPtW6xRkwgYwXJCBflovreZA5zFfSuBkC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/system_webview_apk_tmpl.gni b/android_webview/system_webview_apk_tmpl.gni
index eaf2c5a..3a8057c 100644
--- a/android_webview/system_webview_apk_tmpl.gni
+++ b/android_webview/system_webview_apk_tmpl.gni
@@ -273,11 +273,8 @@
       if (!defined(proguard_configs)) {
         proguard_configs = []
       }
-      proguard_configs += [
-        "//android_webview/nonembedded/java/proguard.flags",
-        "//base/android/proguard/chromium_apk.flags",
-        "//base/android/proguard/chromium_code.flags",
-      ]
+      proguard_configs +=
+          [ "//android_webview/nonembedded/java/proguard.flags" ]
       png_to_webp = true
     }
 
diff --git a/apps/saved_files_service.cc b/apps/saved_files_service.cc
index 54af80b..e1d8e26b 100644
--- a/apps/saved_files_service.cc
+++ b/apps/saved_files_service.cc
@@ -131,13 +131,12 @@
       continue;
     bool is_directory =
         file_entry->FindBoolPath(kFileEntryIsDirectory).value_or(false);
-    int sequence_number = 0;
-    if (!file_entry->GetInteger(kFileEntrySequenceNumber, &sequence_number))
+    const absl::optional<int> sequence_number =
+        file_entry->GetDict().FindInt(kFileEntrySequenceNumber);
+    if (!sequence_number || sequence_number.value() == 0)
       continue;
-    if (!sequence_number)
-      continue;
-    result.push_back(
-        SavedFileEntry(it.key(), *file_path, is_directory, sequence_number));
+    result.emplace_back(it.key(), *file_path, is_directory,
+                        sequence_number.value());
   }
   return result;
 }
diff --git a/ash/README.md b/ash/README.md
index 3b5c8652..33863d5 100644
--- a/ash/README.md
+++ b/ash/README.md
@@ -30,6 +30,18 @@
 same directory as the class under test (e.g. //ash/foo rather than //ash/test).
 Test code uses namespace ash; there is no special "test" namespace.
 
+base::raw_ptr<>
+---------------
+Use of [base::raw_ptr<>](/base/memory/raw_ptr.md) is *allowed* but
+*not required* in //ash.
+
+Chromium's Windows and Android codebases were converted in mid-2022 to use
+base:raw_ptr<> for class and struct members as part of the "MiraclePtr" security
+project. ChromeOS code was not converted, hence //ash was not converted.
+
+Until //ash is bulk converted (no ETA yet), feel free to use traditional
+pointer members if that would be more consistent with surrounding code.
+
 Prefs
 -----
 Ash supports both per-user prefs and device-wide prefs. These are called
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc
index 1c59a32..91c598b 100644
--- a/ash/app_list/app_list_controller_impl.cc
+++ b/ash/app_list/app_list_controller_impl.cc
@@ -195,10 +195,6 @@
       return TabletModeAnimationTransition::kHideHomeLauncherForWindow;
     case HomeLauncherAnimationTrigger::kLauncherButton:
       return TabletModeAnimationTransition::kHomeButtonShow;
-    case HomeLauncherAnimationTrigger::kDragRelease:
-      return launcher_should_show
-                 ? TabletModeAnimationTransition::kDragReleaseShow
-                 : TabletModeAnimationTransition::kDragReleaseHide;
     case HomeLauncherAnimationTrigger::kOverviewModeFade:
       return launcher_should_show
                  ? TabletModeAnimationTransition::kFadeOutOverview
diff --git a/ash/app_list/app_list_metrics.h b/ash/app_list/app_list_metrics.h
index d0a9f51..bf44682 100644
--- a/ash/app_list/app_list_metrics.h
+++ b/ash/app_list/app_list_metrics.h
@@ -171,12 +171,6 @@
 
 // Different ways to trigger launcher animation in tablet mode.
 enum TabletModeAnimationTransition {
-  // Release drag to show the launcher (launcher animates the rest of the way).
-  kDragReleaseShow,
-
-  // Release drag to hide the launcher (launcher animates the rest of the way).
-  kDragReleaseHide,
-
   // Click the Home button in tablet mode.
   kHomeButtonShow,
 
diff --git a/ash/app_list/app_list_test_api.cc b/ash/app_list/app_list_test_api.cc
index 5dfbf6b3..4b9c3bd 100644
--- a/ash/app_list/app_list_test_api.cc
+++ b/ash/app_list/app_list_test_api.cc
@@ -39,6 +39,7 @@
 #include "ash/test/layer_animation_stopped_waiter.h"
 #include "base/callback.h"
 #include "base/run_loop.h"
+#include "components/services/app_service/public/cpp/features.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/aura/window_observer.h"
 #include "ui/compositor/layer.h"
@@ -186,7 +187,10 @@
       if (is_folder_item) {
         root_menu = item_view->context_menu_for_folder()->root_menu_item_view();
       } else {
-        WaitUntilItemMenuShown(item_view);
+        if (!base::FeatureList::IsEnabled(
+                apps::kAppServiceGetMenuWithoutMojom)) {
+          WaitUntilItemMenuShown(item_view);
+        }
         ash::AppListMenuModelAdapter* menu_model_adapter =
             item_view->item_menu_model_adapter();
         root_menu = menu_model_adapter->root_for_testing();
diff --git a/ash/app_list/home_launcher_animation_info.h b/ash/app_list/home_launcher_animation_info.h
index 73861578..2a0871ea 100644
--- a/ash/app_list/home_launcher_animation_info.h
+++ b/ash/app_list/home_launcher_animation_info.h
@@ -9,9 +9,6 @@
 
 // The reason a home launcher animation was triggered.
 enum class HomeLauncherAnimationTrigger {
-  // Launcher animation is triggered by drag release.
-  kDragRelease,
-
   // Launcher animation is triggered by pressing the AppList button.
   kLauncherButton,
 
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc
index 2abddf74..50a99772 100644
--- a/ash/app_list/views/app_list_view.cc
+++ b/ash/app_list/views/app_list_view.cc
@@ -257,17 +257,6 @@
   if (!tablet_transition)
     return;
   switch (*tablet_transition) {
-    case TabletModeAnimationTransition::kDragReleaseShow:
-      UMA_HISTOGRAM_PERCENTAGE(
-          "Apps.HomeLauncherTransition.AnimationSmoothness.DragReleaseShow",
-          value);
-      break;
-    case TabletModeAnimationTransition::kDragReleaseHide:
-      UMA_HISTOGRAM_PERCENTAGE(
-          "Apps.HomeLauncherTransition.AnimationSmoothness."
-          "DragReleaseHide",
-          value);
-      break;
     case TabletModeAnimationTransition::kHomeButtonShow:
       UMA_HISTOGRAM_PERCENTAGE(
           "Apps.HomeLauncherTransition.AnimationSmoothness."
diff --git a/ash/components/arc/compat_mode/overlay_dialog.cc b/ash/components/arc/compat_mode/overlay_dialog.cc
index d9f2d99..55814879 100644
--- a/ash/components/arc/compat_mode/overlay_dialog.cc
+++ b/ash/components/arc/compat_mode/overlay_dialog.cc
@@ -5,12 +5,16 @@
 #include "ash/components/arc/compat_mode/overlay_dialog.h"
 
 #include "ash/components/arc/compat_mode/style/arc_color_provider.h"
+#include "ash/constants/ash_features.h"
+#include "ash/style/ash_color_id.h"
 #include "base/bind.h"
 #include "components/exo/shell_surface_base.h"
 #include "components/exo/shell_surface_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
+#include "ui/color/color_id.h"
 #include "ui/views/accessibility/view_accessibility.h"
 #include "ui/views/background.h"
+#include "ui/views/view.h"
 
 namespace arc {
 
@@ -48,6 +52,14 @@
   view_ax.OverrideIsIgnored(true);
 }
 
+void OverlayDialog::OnThemeChanged() {
+  views::View::OnThemeChanged();
+  const ui::ColorId color_id = ash::features::IsDarkLightModeEnabled()
+                                   ? ash::kColorAshShieldAndBase60
+                                   : ash::kColorAshShieldAndBase60Light;
+  SetBackground(views::CreateThemedSolidBackground(color_id));
+}
+
 OverlayDialog::OverlayDialog(base::OnceClosure on_destroying,
                              std::unique_ptr<views::View> dialog_view)
     : has_dialog_view_(dialog_view),
@@ -63,8 +75,6 @@
 
     AddChildView(std::move(dialog_view));
   }
-  const SkColor kScrimColor = GetShieldLayerColor(ShieldLayerType::kShield60);
-  SetBackground(views::CreateSolidBackground(kScrimColor));
 }
 
 BEGIN_METADATA(OverlayDialog, views::FlexLayoutView)
diff --git a/ash/components/arc/compat_mode/overlay_dialog.h b/ash/components/arc/compat_mode/overlay_dialog.h
index 758b284..bc262ab 100644
--- a/ash/components/arc/compat_mode/overlay_dialog.h
+++ b/ash/components/arc/compat_mode/overlay_dialog.h
@@ -45,6 +45,7 @@
 
   // views::View:
   void AddedToWidget() override;
+  void OnThemeChanged() override;
 
  private:
   friend class OverlayDialogTest;
diff --git a/ash/components/arc/compat_mode/style/arc_color_provider.cc b/ash/components/arc/compat_mode/style/arc_color_provider.cc
index cfb5010..a60ff63 100644
--- a/ash/components/arc/compat_mode/style/arc_color_provider.cc
+++ b/ash/components/arc/compat_mode/style/arc_color_provider.cc
@@ -10,31 +10,11 @@
 
 namespace arc {
 
-// Default color
-constexpr SkColor kDefaultColor = SK_ColorWHITE;
 // Dialog background base color
 constexpr SkColor kDialogBackgroundBaseColorLight = SK_ColorWHITE;
 constexpr SkColor kDialogBackgroundBaseColorDark =
     SkColorSetRGB(0x32, 0x33, 0x36);
 
-SkColor GetShieldLayerColor(ShieldLayerType type) {
-  auto* provider = ash::ColorProvider::Get();
-  // |provider| may return null in unit testing
-  if (!provider)
-    return kDefaultColor;
-  ash::ScopedLightModeAsDefault scoped_light_mode_as_default;
-  return provider->GetShieldLayerColor(type);
-}
-
-SkColor GetContentLayerColor(ContentLayerType type) {
-  auto* provider = ash::ColorProvider::Get();
-  // |provider| may return null in unit testing
-  if (!provider)
-    return kDefaultColor;
-  ash::ScopedLightModeAsDefault scoped_light_mode_as_default;
-  return provider->GetContentLayerColor(type);
-}
-
 SkColor GetDialogBackgroundBaseColor() {
   return IsDarkModeEnabled() ? kDialogBackgroundBaseColorDark
                              : kDialogBackgroundBaseColorLight;
diff --git a/ash/components/arc/compat_mode/style/arc_color_provider.h b/ash/components/arc/compat_mode/style/arc_color_provider.h
index 81606cff..a7ddab4 100644
--- a/ash/components/arc/compat_mode/style/arc_color_provider.h
+++ b/ash/components/arc/compat_mode/style/arc_color_provider.h
@@ -13,12 +13,6 @@
 using ShieldLayerType = ash::ColorProvider::ShieldLayerType;
 using ContentLayerType = ash::ColorProvider::ContentLayerType;
 
-// Get the shield layer color
-SkColor GetShieldLayerColor(ShieldLayerType type);
-
-// Get the content layer color
-SkColor GetContentLayerColor(ContentLayerType type);
-
 // Get dialog background base color
 SkColor GetDialogBackgroundBaseColor();
 
diff --git a/ash/login/ui/views_utils.cc b/ash/login/ui/views_utils.cc
index fc4c6409..a8981ea42 100644
--- a/ash/login/ui/views_utils.cc
+++ b/ash/login/ui/views_utils.cc
@@ -10,11 +10,14 @@
 #include "ash/public/cpp/shelf_config.h"
 #include "ash/style/ash_color_provider.h"
 #include "base/ranges/algorithm.h"
+#include "ui/color/color_id.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
+#include "ui/gfx/text_constants.h"
 #include "ui/views/controls/focus_ring.h"
 #include "ui/views/controls/highlight_path_generator.h"
 #include "ui/views/layout/box_layout.h"
+#include "ui/views/metadata/view_factory_internal.h"
 #include "ui/views/view_targeter_delegate.h"
 #include "ui/views/widget/widget.h"
 
@@ -103,28 +106,51 @@
   return search == view;
 }
 
+std::unique_ptr<views::Label> CreateUnthemedBubbleLabel(
+    const std::u16string& message,
+    views::View* view_defining_max_width,
+    const gfx::FontList& font_list,
+    int line_height) {
+  auto builder = views::Builder<views::Label>()
+                     .SetText(message)
+                     .SetTextContext(views::style::CONTEXT_DIALOG_BODY_TEXT)
+                     .SetAutoColorReadabilityEnabled(false)
+                     .SetHorizontalAlignment(gfx::ALIGN_LEFT)
+                     .SetSubpixelRenderingEnabled(false)
+                     .SetFontList(font_list)
+                     .SetLineHeight(line_height);
+  if (view_defining_max_width != nullptr) {
+    builder.SetMultiLine(true)
+        .SetAllowCharacterBreak(true)
+        // Make sure to set a maximum label width, otherwise text wrapping will
+        // significantly increase width and layout may not work correctly if
+        // the input string is very long.
+        .SetMaximumWidth(view_defining_max_width->GetPreferredSize().width());
+  }
+  return std::move(builder).Build();
+}
+
 std::unique_ptr<views::Label> CreateBubbleLabel(
     const std::u16string& message,
     views::View* view_defining_max_width,
     SkColor color,
     const gfx::FontList& font_list,
     int line_height) {
-  auto label = std::make_unique<views::Label>(
-      message, views::style::CONTEXT_DIALOG_BODY_TEXT);
-  label->SetAutoColorReadabilityEnabled(false);
-  label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  auto label = CreateUnthemedBubbleLabel(message, view_defining_max_width,
+                                         font_list, line_height);
   label->SetEnabledColor(color);
-  label->SetSubpixelRenderingEnabled(false);
-  label->SetFontList(font_list);
-  label->SetLineHeight(line_height);
-  if (view_defining_max_width != nullptr) {
-    label->SetMultiLine(true);
-    label->SetAllowCharacterBreak(true);
-    // Make sure to set a maximum label width, otherwise text wrapping will
-    // significantly increase width and layout may not work correctly if
-    // the input string is very long.
-    label->SetMaximumWidth(view_defining_max_width->GetPreferredSize().width());
-  }
+  return label;
+}
+
+std::unique_ptr<views::Label> CreateThemedBubbleLabel(
+    const std::u16string& message,
+    views::View* view_defining_max_width,
+    ui::ColorId enabled_color_type,
+    const gfx::FontList& font_list,
+    int line_height) {
+  auto label = CreateUnthemedBubbleLabel(message, view_defining_max_width,
+                                         font_list, line_height);
+  label->SetEnabledColorId(enabled_color_type);
   return label;
 }
 
diff --git a/ash/login/ui/views_utils.h b/ash/login/ui/views_utils.h
index f134b5ce..795f7d779 100644
--- a/ash/login/ui/views_utils.h
+++ b/ash/login/ui/views_utils.h
@@ -8,6 +8,8 @@
 #include "ash/ash_export.h"
 #include "ash/style/ash_color_provider.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
+#include "ui/color/color_id.h"
 #include "ui/views/controls/label.h"
 
 namespace views {
@@ -60,6 +62,13 @@
     const gfx::FontList& font_list = GetLoginDefaultFontList(),
     int line_height = kDefaultLineHeight);
 
+ASH_EXPORT std::unique_ptr<views::Label> CreateThemedBubbleLabel(
+    const std::u16string& message,
+    views::View* view_defining_max_width = nullptr,
+    ui::ColorId enabled_color_type = cros_tokens::kTextColorPrimary,
+    const gfx::FontList& font_list = GetLoginDefaultFontList(),
+    int line_height = kDefaultLineHeight);
+
 // Get the bubble container for |view| to place a LoginBaseBubbleView.
 views::View* GetBubbleContainer(views::View* view);
 
diff --git a/ash/style/ash_color_id.h b/ash/style/ash_color_id.h
index f85efebe..11f20085 100644
--- a/ash/style/ash_color_id.h
+++ b/ash/style/ash_color_id.h
@@ -21,6 +21,14 @@
   E_CPONLY(kColorAshShieldAndBase90) \
   E_CPONLY(kColorAshShieldAndBase95) \
   E_CPONLY(kColorAshShieldAndBaseOpaque) \
+  E_CPONLY(kColorAshShieldAndBase20Light) \
+  E_CPONLY(kColorAshShieldAndBase40Light) \
+  E_CPONLY(kColorAshShieldAndBase60Light) \
+  E_CPONLY(kColorAshShieldAndBase80Light) \
+  E_CPONLY(kColorAshInvertedShieldAndBase80Light) \
+  E_CPONLY(kColorAshShieldAndBase90Light) \
+  E_CPONLY(kColorAshShieldAndBase95Light) \
+  E_CPONLY(kColorAshShieldAndBaseOpaqueLight) \
   /* Controls Layer colors. */ \
   E_CPONLY(kColorAshHairlineBorderColor) \
   E_CPONLY(kColorAshControlBackgroundColorActive) \
diff --git a/ash/style/ash_color_mixer.cc b/ash/style/ash_color_mixer.cc
index 08c1c8e..d0d9fe2a 100644
--- a/ash/style/ash_color_mixer.cc
+++ b/ash/style/ash_color_mixer.cc
@@ -85,6 +85,18 @@
   mixer[kColorAshShieldAndBase95] = {SkColorSetA(background_color, kAlpha95)};
   mixer[kColorAshShieldAndBaseOpaque] = {
       SkColorSetA(background_color, SK_AlphaOPAQUE)};
+
+  // TODO(conniekxu): Remove these colorIds when the DarkLightModeEnabled flag
+  // is removed.
+  mixer[kColorAshShieldAndBase20Light] = {SkColorSetA(SK_ColorWHITE, kAlpha20)};
+  mixer[kColorAshShieldAndBase40Light] = {SkColorSetA(SK_ColorWHITE, kAlpha40)};
+  mixer[kColorAshShieldAndBase60Light] = {SkColorSetA(SK_ColorWHITE, kAlpha60)};
+  mixer[kColorAshShieldAndBase80Light] = {SkColorSetA(SK_ColorWHITE, kAlpha80)};
+  mixer[kColorAshInvertedShieldAndBase80Light] = {
+      SkColorSetA(color_utils::InvertColor(SK_ColorWHITE), kAlpha80)};
+  mixer[kColorAshShieldAndBase95Light] = {SkColorSetA(SK_ColorWHITE, kAlpha95)};
+  mixer[kColorAshShieldAndBaseOpaqueLight] = {
+      SkColorSetA(SK_ColorWHITE, SK_AlphaOPAQUE)};
 }
 
 // Mappings of Controls Colors for Material 2.
diff --git a/ash/webui/diagnostics_ui/backend/system_data_provider.cc b/ash/webui/diagnostics_ui/backend/system_data_provider.cc
index 03363ac..e382740 100644
--- a/ash/webui/diagnostics_ui/backend/system_data_provider.cc
+++ b/ash/webui/diagnostics_ui/backend/system_data_provider.cc
@@ -10,6 +10,7 @@
 
 #include "ash/system/diagnostics/telemetry_log.h"
 #include "ash/webui/diagnostics_ui/backend/cros_healthd_helpers.h"
+#include "ash/webui/diagnostics_ui/backend/histogram_util.h"
 #include "ash/webui/diagnostics_ui/backend/power_manager_client_conversions.h"
 #include "base/bind.h"
 #include "base/callback.h"
@@ -60,6 +61,7 @@
   out_system_info.cpu_threads_count = cpu_info.num_total_threads;
 
   if (physical_cpus.empty()) {
+    EmitSystemDataError(metrics::DataError::kExpectationNotMet);
     LOG(ERROR) << "No physical cpus in SystemInfo response.";
     return;
   }
@@ -69,6 +71,7 @@
   out_system_info.cpu_model_name = physical_cpus[0]->model_name.value_or("");
 
   if (physical_cpus[0]->logical_cpus.empty()) {
+    EmitSystemDataError(metrics::DataError::kExpectationNotMet);
     LOG(ERROR) << "Device reported having 0 logical CPUs.";
     return;
   }
@@ -201,6 +204,7 @@
 
   const uint64_t total_delta = delta.GetTotalTime();
   if (total_delta == 0) {
+    EmitSystemDataError(metrics::DataError::kExpectationNotMet);
     return;
   }
 
diff --git a/ash/webui/diagnostics_ui/backend/system_data_provider_unittest.cc b/ash/webui/diagnostics_ui/backend/system_data_provider_unittest.cc
index 2e08c2c..87a7d2b 100644
--- a/ash/webui/diagnostics_ui/backend/system_data_provider_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/system_data_provider_unittest.cc
@@ -1246,5 +1246,122 @@
   run_loop.Run();
 }
 
+TEST_F(SystemDataProviderTest, RecordSystemDataError_NoPhysicalCpuInfo) {
+  base::HistogramTester histogram_tester;
+  VerifySystemDataErrorBucketCounts(histogram_tester,
+                                    /*expected_no_data_error=*/0,
+                                    /*expected_not_a_number_error=*/0,
+                                    /*expected_expectation_not_met_error=*/0);
+
+  // System info.
+  auto system_info = GetDefaultSystemInfoPtr();
+
+  // Battery info.
+  auto battery_info = healthd_mojom::BatteryInfo::New();
+
+  // Memory info.
+  auto memory_info = healthd_mojom::MemoryInfo::New();
+  memory_info->total_memory_kib = 1234;
+
+  // CPU info.
+  auto cpu_info = healthd_mojom::CpuInfo::New();
+  auto logical_cpu_info = healthd_mojom::LogicalCpuInfo::New();
+  logical_cpu_info->max_clock_speed_khz = 91011;
+  cpu_info->num_total_threads = 5678;
+
+  SetProbeTelemetryInfoResponse(std::move(battery_info), std::move(cpu_info),
+                                std::move(memory_info), std::move(system_info));
+
+  base::RunLoop run_loop;
+  system_data_provider_->GetSystemInfo(
+      base::BindLambdaForTesting([&](mojom::SystemInfoPtr ptr) {
+        EXPECT_TRUE(ptr);
+        VerifySystemDataErrorBucketCounts(
+            histogram_tester,
+            /*expected_no_data_error=*/0,
+            /*expected_not_a_number_error=*/0,
+            /*expected_expectation_not_met_error=*/1);
+        run_loop.Quit();
+      }));
+  run_loop.Run();
+}
+
+// Validate expected metric ExpectationNotMet error triggered when logical cpu
+// info is empty.
+TEST_F(SystemDataProviderTest, RecordSystemDataError_NoLogicalCpuInfo) {
+  base::HistogramTester histogram_tester;
+  VerifySystemDataErrorBucketCounts(histogram_tester,
+                                    /*expected_no_data_error=*/0,
+                                    /*expected_not_a_number_error=*/0,
+                                    /*expected_expectation_not_met_error=*/0);
+
+  // System info.
+  auto system_info = GetDefaultSystemInfoPtr();
+
+  // Battery info.
+  auto battery_info = healthd_mojom::BatteryInfo::New();
+
+  // Memory info.
+  auto memory_info = healthd_mojom::MemoryInfo::New();
+  memory_info->total_memory_kib = 1234;
+
+  // CPU info.
+  auto cpu_info = healthd_mojom::CpuInfo::New();
+  auto physical_cpu_info = healthd_mojom::PhysicalCpuInfo::New();
+  physical_cpu_info->model_name = "cpu_model";
+  cpu_info->num_total_threads = 5678;
+  cpu_info->physical_cpus.emplace_back(std::move(physical_cpu_info));
+
+  SetProbeTelemetryInfoResponse(std::move(battery_info), std::move(cpu_info),
+                                std::move(memory_info), std::move(system_info));
+
+  base::RunLoop run_loop;
+  system_data_provider_->GetSystemInfo(
+      base::BindLambdaForTesting([&](mojom::SystemInfoPtr ptr) {
+        EXPECT_TRUE(ptr);
+        VerifySystemDataErrorBucketCounts(
+            histogram_tester,
+            /*expected_no_data_error=*/0,
+            /*expected_not_a_number_error=*/0,
+            /*expected_expectation_not_met_error=*/1);
+        run_loop.Quit();
+      }));
+  run_loop.Run();
+}
+
+// Validate expected metric ExpectationNotMet error triggered when cpu usage
+// delta is zero.
+TEST_F(SystemDataProviderTest, RecordSystemDataError_DeltaZero) {
+  base::HistogramTester histogram_tester;
+  VerifySystemDataErrorBucketCounts(histogram_tester,
+                                    /*expected_no_data_error=*/0,
+                                    /*expected_not_a_number_error=*/0,
+                                    /*expected_expectation_not_met_error=*/0);
+
+  // Setup Timer
+  auto timer = std::make_unique<base::MockRepeatingTimer>();
+  auto* timer_ptr = timer.get();
+  system_data_provider_->SetCpuUsageTimerForTesting(std::move(timer));
+
+  // Setup initial data
+  CpuUsageData core_1(100, 1000, 1000);
+
+  SetCrosHealthdCpuUsageResponse({core_1});
+
+  // Registering as an observer should trigger one update.
+  FakeCpuUsageObserver cpu_usage_observer;
+  system_data_provider_->ObserveCpuUsage(
+      cpu_usage_observer.receiver.BindNewPipeAndPassRemote());
+  base::RunLoop().RunUntilIdle();
+
+  timer_ptr->Fire();
+  base::RunLoop().RunUntilIdle();
+
+  VerifySystemDataErrorBucketCounts(histogram_tester,
+                                    /*expected_no_data_error=*/0,
+                                    /*expected_not_a_number_error=*/0,
+                                    /*expected_expectation_not_met_error=*/1);
+}
+
 }  // namespace diagnostics
 }  // namespace ash
diff --git a/ash/wm/desks/templates/saved_desk_presenter.cc b/ash/wm/desks/templates/saved_desk_presenter.cc
index d11da0f..aa8d338 100644
--- a/ash/wm/desks/templates/saved_desk_presenter.cc
+++ b/ash/wm/desks/templates/saved_desk_presenter.cc
@@ -494,17 +494,8 @@
 }
 
 void SavedDeskPresenter::EntriesRemovedRemotely(
-    const std::vector<std::string>& uuids) {
-  // TODO(crbug.com/1352667): We want the backend to provide this as
-  // vector<base::GUID>. Until it does, we'll convert manually here.
-  std::vector<base::GUID> typed_uuids;
-  for (const std::string& uuid_str : uuids) {
-    base::GUID uuid = base::GUID::ParseCaseInsensitive(uuid_str);
-    if (uuid.is_valid())
-      typed_uuids.push_back(uuid);
-  }
-
-  RemoveUIEntries(typed_uuids);
+    const std::vector<base::GUID>& uuids) {
+  RemoveUIEntries(uuids);
 }
 
 void SavedDeskPresenter::GetAllEntries(const base::GUID& item_to_focus,
diff --git a/ash/wm/desks/templates/saved_desk_presenter.h b/ash/wm/desks/templates/saved_desk_presenter.h
index c4e7070..6de209a 100644
--- a/ash/wm/desks/templates/saved_desk_presenter.h
+++ b/ash/wm/desks/templates/saved_desk_presenter.h
@@ -88,10 +88,10 @@
   void OnDeskModelDestroying() override;
   void EntriesAddedOrUpdatedRemotely(
       const std::vector<const DeskTemplate*>& new_entries) override;
-  void EntriesRemovedRemotely(const std::vector<std::string>& uuids) override;
+  void EntriesRemovedRemotely(const std::vector<base::GUID>& uuids) override;
   void EntriesAddedOrUpdatedLocally(
       const std::vector<const DeskTemplate*>& new_entries) override {}
-  void EntriesRemovedLocally(const std::vector<std::string>& uuids) override {}
+  void EntriesRemovedLocally(const std::vector<base::GUID>& uuids) override {}
 
  private:
   friend class SavedDeskPresenterTestApi;
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 4f55836a..ac10b53 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -4315,6 +4315,11 @@
     annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
 
     resources_package = "org.chromium.base"
+
+    proguard_configs = [
+      "android/proguard/chromium_apk.flags",
+      "android/proguard/chromium_code.flags",
+    ]
   }
 
   android_aidl("base_java_aidl") {
diff --git a/base/android/proguard/chromium_apk.flags b/base/android/proguard/chromium_apk.flags
index 35bec08..47a0272 100644
--- a/base/android/proguard/chromium_apk.flags
+++ b/base/android/proguard/chromium_apk.flags
@@ -70,24 +70,6 @@
   static boolean isLoggable(...);
 }
 
--assumenosideeffects class java.util.logging.Logger {
-    void finest(...);
-    void finer(...);
-    void fine(...);
-    void info(...);
-    void warning(...);
-    void severe(...);
-    void throwing(...);
-    void log(...);
-    void logp(...);
-    static java.util.logging.Logger getLogger(...) return null;
-    boolean isLoggable(...) return false;
-}
-
--assumenosideeffects class java.util.logging.Level {
-  int intValue() return 0;
-}
-
 # Makes try-with-resources less inefficient. Saved 3.8kb when added.
 -assumenosideeffects class java.lang.Throwable {
   void addSuppressed(...);
diff --git a/base/tracing/protos/chrome_track_event.proto b/base/tracing/protos/chrome_track_event.proto
index a7e3544..23c6969 100644
--- a/base/tracing/protos/chrome_track_event.proto
+++ b/base/tracing/protos/chrome_track_event.proto
@@ -129,6 +129,7 @@
   SHOULD_SWAP_BROWSING_INSTANCE_NO_RELOAD = 18;
   SHOULD_SWAP_BROWSING_INSTANCE_NO_GUEST = 19;
   SHOULD_SWAP_BROWSING_INSTANCE_NO_HAS_NOT_COMMITTED_ANY_NAVIGATION = 20;
+  // The following reason was deprecated from https://crrev.com/c/3858766
   SHOULD_SWAP_BROWSING_INSTANCE_NO_UNLOAD_HANDLER_EXISTS_ON_SAME_SITE_NAVIGATION =
       21;
   SHOULD_SWAP_BROWSING_INSTANCE_NO_NOT_PRIMARY_MAIN_FRAME = 22;
diff --git a/build/android/pylib/local/device/local_device_gtest_run.py b/build/android/pylib/local/device/local_device_gtest_run.py
index 7949bfac..f47fc17 100644
--- a/build/android/pylib/local/device/local_device_gtest_run.py
+++ b/build/android/pylib/local/device/local_device_gtest_run.py
@@ -272,8 +272,8 @@
           reinstall=True,
           permissions=self._permissions)
 
-  def ResultsDirectory(self, device):
-    return device.GetApplicationDataDirectory(self._package)
+  def ResultsDirectory(self, device):  # pylint: disable=no-self-use
+    return device.GetExternalStoragePath()
 
   def Run(self, test, device, flags=None, **kwargs):
     extras = dict(self._extras)
@@ -546,15 +546,6 @@
       def bind_crash_handler(step, dev):
         return lambda: crash_handler.RetryOnSystemCrash(step, dev)
 
-      # Explicitly enable root to ensure that tests run under deterministic
-      # conditions. Without this explicit call, EnableRoot() is called from
-      # push_test_data() when PushChangedFiles() determines that it should use
-      # _PushChangedFilesZipped(), which is only most of the time.
-      # Root is required (amongst maybe other reasons) to pull the results file
-      # from the device, since it lives within the application's data directory
-      # (via GetApplicationDataDirectory()).
-      device.EnableRoot()
-
       steps = [
           bind_crash_handler(s, device)
           for s in (install_apk, push_test_data, init_tool_and_start_servers)]
diff --git a/build/config/chromecast_build.gni b/build/config/chromecast_build.gni
index 7e5711bd..51d7db0 100644
--- a/build/config/chromecast_build.gni
+++ b/build/config/chromecast_build.gni
@@ -35,8 +35,13 @@
   # Set this to true to build for Nest hardware running Linux (aka "CastOS").
   # Set this to false to use the defaults for Linux.
   is_castos = false
+
+  # Set this to true to build for Android-based Cast devices.
+  # Set this to false to use the defaults for Android.
+  is_cast_android = false
 }
 is_castos = is_castos && current_toolchain == default_toolchain
+is_cast_android = is_cast_android && current_toolchain == default_toolchain
 
 declare_args() {
   # Set this true for a Chromecast build. Chromecast builds are supported on
@@ -45,10 +50,6 @@
   # During the migration from is_chromecast, this must be set to the same value
   # as is_chromecast.
   enable_cast_receiver = is_chromecast
-
-  # Set this to true to build for Android-based Cast devices.
-  # Set this to false to use the defaults for the target OS/platform.
-  is_cast_android = is_chromecast && is_android
 }
 
 declare_args() {
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index a404791..5ecfd6dc 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-9.20220819.1.1
+9.20220830.1.1
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni
index b6b7a67..92778439 100644
--- a/chrome/android/chrome_public_apk_tmpl.gni
+++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -290,11 +290,7 @@
       if (!defined(proguard_configs)) {
         proguard_configs = []
       }
-      proguard_configs += [
-        "//chrome/android/proguard/main.flags",
-        "//base/android/proguard/chromium_apk.flags",
-        "//base/android/proguard/chromium_code.flags",
-      ]
+      proguard_configs += [ "//chrome/android/proguard/main.flags" ]
     }
 
     if (use_chromium_linker) {
diff --git a/chrome/android/expectations/monochrome_public_bundle.proguard_flags.expected b/chrome/android/expectations/monochrome_public_bundle.proguard_flags.expected
index d412301e..d59ec55 100644
--- a/chrome/android/expectations/monochrome_public_bundle.proguard_flags.expected
+++ b/chrome/android/expectations/monochrome_public_bundle.proguard_flags.expected
@@ -170,24 +170,6 @@
   static boolean isLoggable(...);
 }
 
--assumenosideeffects class java.util.logging.Logger {
-    void finest(...);
-    void finer(...);
-    void fine(...);
-    void info(...);
-    void warning(...);
-    void severe(...);
-    void throwing(...);
-    void log(...);
-    void logp(...);
-    static java.util.logging.Logger getLogger(...) return null;
-    boolean isLoggable(...) return false;
-}
-
--assumenosideeffects class java.util.logging.Level {
-  int intValue() return 0;
-}
-
 # Makes try-with-resources less inefficient. Saved 3.8kb when added.
 -assumenosideeffects class java.lang.Throwable {
   void addSuppressed(...);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/FullscreenVideoPictureInPictureController.java b/chrome/android/java/src/org/chromium/chrome/browser/media/FullscreenVideoPictureInPictureController.java
index 50ae695a..cb003f6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/FullscreenVideoPictureInPictureController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/FullscreenVideoPictureInPictureController.java
@@ -132,7 +132,11 @@
         mActivityTabProvider = activityTabProvider;
         mFullscreenManager = fullscreenManager;
 
-        mListenForAutoEnterability = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
+        // TODO(crbug.com/1345586): This should be >= rather than > .  However, it looks like
+        // auto-enter might be causing a very bad display issue on S, which local ToT builds don't
+        // replicate even though canary does.  Turning off temporarily to see if canary builds start
+        // working, or if auto-enter isn't actually the problem.
+        mListenForAutoEnterability = Build.VERSION.SDK_INT > Build.VERSION_CODES.S;
         if (mListenForAutoEnterability) addObserversIfNeeded();
     }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java
index 56a59d5..722fa6b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/UrlOverridingTest.java
@@ -946,11 +946,9 @@
     @LargeTest
     @Features.EnableFeatures({"BackForwardCache<Study"})
     @Features.DisableFeatures({"BackForwardCacheMemoryControls"})
-    @CommandLineFlags.Add({"force-fieldtrials=Study/Group",
-            "force-fieldtrial-params=Study.Group:enable_same_site/true"})
+    @CommandLineFlags.Add({"force-fieldtrials=Study/Group"})
     @Restriction(Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE)
-    public void
-    testNoRedirectWithBFCache() throws Exception {
+    public void testNoRedirectWithBFCache() throws Exception {
         final CallbackHelper finishCallback = new CallbackHelper();
         final CallbackHelper syncHelper = new CallbackHelper();
         AtomicReference<NavigationHandle> mLastNavigationHandle = new AtomicReference<>(null);
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 f3a3ba13..320507c 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
@@ -48,6 +48,7 @@
 
 import org.chromium.base.Promise;
 import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.IntentHandler;
@@ -543,6 +544,7 @@
 
     @Test
     @SmallTest
+    @DisabledTest(message = "https://crbug.com/1358628")
     public void testCopyLink() {
         final ClipboardManager clipboardManager =
                 (ClipboardManager) mActivity.getSystemService(Context.CLIPBOARD_SERVICE);
diff --git a/chrome/android/webapk/libs/runtime_library/BUILD.gn b/chrome/android/webapk/libs/runtime_library/BUILD.gn
index 74b9eede..4391302 100644
--- a/chrome/android/webapk/libs/runtime_library/BUILD.gn
+++ b/chrome/android/webapk/libs/runtime_library/BUILD.gn
@@ -52,11 +52,7 @@
 dist_dex("webapk_runtime_library") {
   deps = [ ":runtime_library_for_assets_java" ]
   proguard_enabled = true
-  proguard_configs = [
-    "runtime_library.proguard.flags",
-    "//base/android/proguard/chromium_code.flags",
-    "//base/android/proguard/chromium_apk.flags",
-  ]
+  proguard_configs = [ "runtime_library.proguard.flags" ]
   output = "$target_out_dir/$runtime_library_dex_asset_name"
 }
 
diff --git a/chrome/android/webapk/shell_apk/BUILD.gn b/chrome/android/webapk/shell_apk/BUILD.gn
index c32987c..e2c665d7 100644
--- a/chrome/android/webapk/shell_apk/BUILD.gn
+++ b/chrome/android/webapk/shell_apk/BUILD.gn
@@ -285,8 +285,6 @@
       proguard_configs = [
         "//chrome/android/webapk/shell_apk/proguard.flags",
         "//chrome/android/proguard/main.flags",
-        "//base/android/proguard/chromium_apk.flags",
-        "//base/android/proguard/chromium_code.flags",
       ]
     }
   }
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 9a4a83a2..493df84 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -7085,6 +7085,9 @@
       <message name="IDS_READ_LATER_CANT_ADD_CURRENT_TAB" desc="Label for button when the current tab cannot be added to read later">
         Can't add current tab
       </message>
+      <message name="IDS_READ_LATER_MARK_CURRENT_TAB_READ" desc="Label for button to mark the current tab as read in Read Later">
+        Mark current tab as read
+      </message>
       <message name="IDS_READ_LATER_REMOVE_CURRENT_TAB" desc="Label for button to remove the current tab from read later">
         Remove current tab
       </message>
diff --git a/chrome/app/generated_resources_grd/IDS_READ_LATER_MARK_CURRENT_TAB_READ.png.sha1 b/chrome/app/generated_resources_grd/IDS_READ_LATER_MARK_CURRENT_TAB_READ.png.sha1
new file mode 100644
index 0000000..09b7323
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_READ_LATER_MARK_CURRENT_TAB_READ.png.sha1
@@ -0,0 +1 @@
+109f0df6d018e433ac5be62eecca0fecffc2bbb7
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp
index 65607c29..86ffa05 100644
--- a/chrome/app/os_settings_strings.grdp
+++ b/chrome/app/os_settings_strings.grdp
@@ -3326,16 +3326,13 @@
     Connecting to your phone
   </message>
   <message name="IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_TITLE" desc="The title of the screen lock dialog containing the Phone Hub notification opt-in flow shown when the user has confirmed to enable the app stream that will stream phone to their Chromebook.">
-    Set a PIN or password
+    Use a password or PIN to unlock your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>
   </message>
   <message name="IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_SUBTITLE" desc="The subtitle of the screen lock dialog containing the Phone Hub notification opt-in flow shown when the user has confirmed to enable the app stream that will stream phone to their Chromebook.">
-    This PIN or password protects your data on this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>, including any information you access from your phone
-  </message>
-  <message name="IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_INSTRUCTION" desc="The instruction message of the screen lock dialog.">
-    Choose either one each time you sign in
+    This password or PIN protects your data on this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> and any information you access from your phone. You'll need to unlock each time your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> wakes from sleep.
   </message>
   <message name="IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_ICON_INSTRUCTION" desc="The icon instruction message of the screen lock dialog.">
-    If Smart Lock is turned on, you won't need to enter a PIN or password
+    If Smart Lock is turned on and your phone is unlocked, you don't need to enter a password or PIN
   </message>
   <message name="IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_INSTRUCTIONS" desc="The second paragraph of text shown in the dialog containing the Phone Hub notification opt-in flow. Alerts the user that to enable notifications, they need to have their phone unlocked, nearby, and with Bluetooth/Wi-Fi on to complete setup.">
     Make sure your phone is nearby, unlocked, and has Bluetooth and Wi-Fi turned on
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_ICON_INSTRUCTION.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_ICON_INSTRUCTION.png.sha1
index d0e52f6..8305a21 100644
--- a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_ICON_INSTRUCTION.png.sha1
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_ICON_INSTRUCTION.png.sha1
@@ -1 +1 @@
-3e3d33e0b435270f4a941039fc852011769d8e28
\ No newline at end of file
+45b576125e332568fa5bd3a05375f1e3ef8f3fdc
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_INSTRUCTION.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_INSTRUCTION.png.sha1
deleted file mode 100644
index 647bd57..0000000
--- a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_INSTRUCTION.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-377efb6d99c62d8ac1b0568870b168263ea0ebac
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_SUBTITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_SUBTITLE.png.sha1
index d0e52f6..8305a21 100644
--- a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_SUBTITLE.png.sha1
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_SUBTITLE.png.sha1
@@ -1 +1 @@
-3e3d33e0b435270f4a941039fc852011769d8e28
\ No newline at end of file
+45b576125e332568fa5bd3a05375f1e3ef8f3fdc
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_TITLE.png.sha1
index 647bd57..8305a21 100644
--- a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_TITLE.png.sha1
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_TITLE.png.sha1
@@ -1 +1 @@
-377efb6d99c62d8ac1b0568870b168263ea0ebac
\ No newline at end of file
+45b576125e332568fa5bd3a05375f1e3ef8f3fdc
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index ffd773b..4b51ad7 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -4408,6 +4408,7 @@
       "webauthn/cablev2_devices.h",
       "webauthn/chrome_authenticator_request_delegate.cc",
       "webauthn/chrome_authenticator_request_delegate.h",
+      "webauthn/local_credential_management.cc",
       "webauthn/local_credential_management.h",
       "webauthn/observable_authenticator_list.cc",
       "webauthn/observable_authenticator_list.h",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index ae812de..d0ed678 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -2393,21 +2393,13 @@
       std::size(kRequestDesktopSiteForTablets1920), nullptr}};
 #endif  // BUILDFLAG(IS_ANDROID)
 
-// TODO(crbug.com/991082,1015377): Remove after proper support for back-forward
+// TODO(crbug.com/991082,1015377): Remove after proper support for back/forward
 // cache is implemented.
 const FeatureEntry::FeatureParam kBackForwardCache_ForceCaching[] = {
     {"TimeToLiveInBackForwardCacheInSeconds", "300"},
-    {"should_ignore_blocklists", "true"},
-    {"enable_same_site", "true"}};
-
-// With this, back-forward cache will be enabled on eligible pages when doing
-// same-site navigations (instead of only cross-site navigations).
-const FeatureEntry::FeatureParam kBackForwardCache_SameSite[] = {
-    {"enable_same_site", "true"}};
+    {"should_ignore_blocklists", "true"}};
 
 const FeatureEntry::FeatureVariation kBackForwardCacheVariations[] = {
-    {"same-site support (experimental)", kBackForwardCache_SameSite,
-     std::size(kBackForwardCache_SameSite), nullptr},
     {"force caching all pages (experimental)", kBackForwardCache_ForceCaching,
      std::size(kBackForwardCache_ForceCaching), nullptr},
 };
@@ -4787,6 +4779,9 @@
      FEATURE_WITH_PARAMS_VALUE_TYPE(feed::kFeedCloseRefresh,
                                     kFeedCloseRefreshVariations,
                                     "FeedCloseRefresh")},
+    {"feed-discofeed-endpoint", flag_descriptions::kFeedDiscoFeedEndpointName,
+     flag_descriptions::kFeedDiscoFeedEndpointDescription, kOsAndroid,
+     FEATURE_VALUE_TYPE(feed::kDiscoFeedEndpoint)},
 #endif  // BUILDFLAG(IS_ANDROID)
 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
     BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA)
diff --git a/chrome/browser/app_controller_mac.h b/chrome/browser/app_controller_mac.h
index 88582b8..c8e8787 100644
--- a/chrome/browser/app_controller_mac.h
+++ b/chrome/browser/app_controller_mac.h
@@ -125,6 +125,9 @@
   // This will be true after receiving a NSWorkspaceWillPowerOffNotification.
   BOOL _isPoweringOff;
 
+  // This will be true after receiving a |-applicationWillTerminate:| event.
+  BOOL _isShuttingDown;
+
   // Request to keep the browser alive during that object's lifetime.
   std::unique_ptr<ScopedKeepAlive> _keep_alive;
 
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm
index 6c36ff7..b10a991 100644
--- a/chrome/browser/app_controller_mac.mm
+++ b/chrome/browser/app_controller_mac.mm
@@ -722,6 +722,8 @@
   // Reset local state watching, as this object outlives the prefs system.
   _localPrefRegistrar.RemoveAll();
 
+  _isShuttingDown = true;
+
   // It's safe to delete |_lastProfile| now.
   [self setLastProfile:nullptr];
 
@@ -1729,9 +1731,13 @@
 
   // Before tearing down the menu controller bridges, return the history menu to
   // its initial state.
-  if (_historyMenuBridge)
-    _historyMenuBridge->ResetMenu();
-  _historyMenuBridge.reset();
+  if (profile != nullptr) {
+    if (_historyMenuBridge)
+      _historyMenuBridge->ResetMenu();
+    _historyMenuBridge.reset();
+  } else if (_historyMenuBridge && !_isShuttingDown) {
+    _historyMenuBridge->OnProfileWillBeDestroyed();
+  }
 
   _profilePrefRegistrar.reset();
 
diff --git a/chrome/browser/app_controller_mac_browsertest.mm b/chrome/browser/app_controller_mac_browsertest.mm
index 115d24aa..1d7a8d0e 100644
--- a/chrome/browser/app_controller_mac_browsertest.mm
+++ b/chrome/browser/app_controller_mac_browsertest.mm
@@ -836,40 +836,6 @@
                                            ServiceAccessType::EXPLICIT_ACCESS));
 }
 
-IN_PROC_BROWSER_TEST_F(AppControllerMainMenuBrowserTest,
-                       HistoryAndBookmarksMenusResetAfterAllProfilesDestroyed) {
-  AppController* ac =
-      base::mac::ObjCCastStrict<AppController>([NSApp delegate]);
-  ASSERT_TRUE(ac);
-
-  Profile* profile = browser()->profile();
-
-  // Load profile's History Service backend so it will be assigned to the
-  // HistoryMenuBridge when setLastProfile is called, or else this test will
-  // fail flaky.
-  ui_test_utils::WaitForHistoryToLoad(HistoryServiceFactory::GetForProfile(
-      profile, ServiceAccessType::EXPLICIT_ACCESS));
-  // Ditto for the Bookmark Model.
-  bookmarks::test::WaitForBookmarkModelToLoad(
-      BookmarkModelFactory::GetForBrowserContext(profile));
-  // Switch the controller to |profile|.
-  [ac setLastProfile:profile];
-  base::RunLoop().RunUntilIdle();
-
-  // Verify there are History and Bookmarks menus controllers.
-  EXPECT_NE(nullptr, [ac historyMenuBridge]);
-  EXPECT_NE(nullptr, [ac bookmarkMenuBridge]);
-
-  // Trigger Profile* destruction. Note that this event (destruction from
-  // memory) is a separate event from profile deletion (from disk).
-  chrome::CloseAllBrowsers();
-  ProfileDestructionWaiter(profile).Wait();
-
-  // Verify the History and Bookmarks menus' controllers have been reset.
-  EXPECT_EQ(nullptr, [ac historyMenuBridge]);
-  EXPECT_EQ(nullptr, [ac bookmarkMenuBridge]);
-}
-
 // Disabled because of flakiness. See crbug.com/1278031.
 IN_PROC_BROWSER_TEST_F(AppControllerMainMenuBrowserTest,
                        DISABLED_ReloadingDestroyedProfileDoesNotCrash) {
diff --git a/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc b/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc
index c7ff72c..07c0bb25 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ash/arc/input_overlay/ui/educational_view.h"
 
 #include "ash/components/arc/compat_mode/style/arc_color_provider.h"
+#include "ash/constants/ash_features.h"
 #include "ash/login/ui/views_utils.h"
 #include "ash/public/cpp/style/color_provider.h"
 #include "ash/style/ash_color_provider.h"
@@ -17,6 +18,7 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/chromeos/styles/cros_styles.h"
+#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
 #include "ui/color/color_id.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/geometry/insets.h"
@@ -178,23 +180,27 @@
         .SetMainAxisAlignment(views::LayoutAlignment::kCenter)
         .SetCrossAxisAlignment(views::LayoutAlignment::kCenter);
     // Game controls.
-    container_view->AddChildView(ash::login_views_utils::CreateBubbleLabel(
-        l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_GAME_CONTROLS_ALPHA),
-        /*view_defining_max_width=*/nullptr,
-        /*color=*/
-        GetContentLayerColor(
-            ash::AshColorProvider::ContentLayerType::kTextColorPrimary),
-        /*font_list=*/
-        gfx::FontList({ash::login_views_utils::kGoogleSansFont},
-                      gfx::Font::FontStyle::NORMAL,
-                      GetTitleFontSize(portrait_mode_),
-                      gfx::Font::Weight::MEDIUM)));
+    container_view->AddChildView(
+        ash::login_views_utils::CreateThemedBubbleLabel(
+            l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_GAME_CONTROLS_ALPHA),
+            /*view_defining_max_width=*/nullptr,
+            /*enabled_color_type=*/
+            ash::features::IsDarkLightModeEnabled()
+                ? cros_tokens::kTextColorPrimary
+                : cros_tokens::kTextColorPrimaryLight,
+            /*font_list=*/
+            gfx::FontList({ash::login_views_utils::kGoogleSansFont},
+                          gfx::Font::FontStyle::NORMAL,
+                          GetTitleFontSize(portrait_mode_),
+                          gfx::Font::Weight::MEDIUM)));
 
-    auto* alpha_label =
-        container_view->AddChildView(ash::login_views_utils::CreateBubbleLabel(
+    auto* alpha_label = container_view->AddChildView(
+        ash::login_views_utils::CreateThemedBubbleLabel(
             l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_RELEASE_ALPHA),
-            /*view_defining_max_width=*/nullptr, /*color=*/
-            arc::GetCrOSColor(cros_styles::ColorName::kTextColorSelection),
+            /*view_defining_max_width=*/nullptr, /*enabled_color_type=*/
+            ash::features::IsDarkLightModeEnabled()
+                ? cros_tokens::kColorSelection
+                : cros_tokens::kColorSelectionLight,
             /*font_list=*/
             gfx::FontList({ash::login_views_utils::kGoogleSansFont},
                           gfx::Font::FontStyle::NORMAL, kAlphaFontSize,
@@ -217,13 +223,14 @@
   {
     // Feature's description text.
     auto* description_label =
-        AddChildView(ash::login_views_utils::CreateBubbleLabel(
+        AddChildView(ash::login_views_utils::CreateThemedBubbleLabel(
             l10n_util::GetStringUTF16(
                 IDS_INPUT_OVERLAY_EDUCATIONAL_DESCRIPTION_ALPHA),
             /*view_defining_max_width=*/nullptr,
-            /*color=*/
-            GetContentLayerColor(
-                ash::AshColorProvider::ContentLayerType::kTextColorSecondary),
+            /*enabled_color_type=*/
+            ash::features::IsDarkLightModeEnabled()
+                ? cros_tokens::kTextColorPrimary
+                : cros_tokens::kTextColorPrimaryLight,
             /*font_list=*/
             gfx::FontList({ash::login_views_utils::kGoogleSansFont},
                           gfx::Font::FontStyle::NORMAL, kDescriptionFontSize,
diff --git a/chrome/browser/ash/login/session/user_session_manager.cc b/chrome/browser/ash/login/session/user_session_manager.cc
index fa5fb31..c4973e3 100644
--- a/chrome/browser/ash/login/session/user_session_manager.cc
+++ b/chrome/browser/ash/login/session/user_session_manager.cc
@@ -2330,13 +2330,13 @@
   }
 
   base::OnceClosure login_host_finalized_callback = base::BindOnce(
-      [](void* trace_id) {
+      [](uint64_t trace_id) {
         session_manager::SessionManager::Get()->SessionStarted();
         TRACE_EVENT_NESTABLE_ASYNC_END0(kEventCategoryChromeOS,
                                         kEventStartSession,
                                         TRACE_ID_LOCAL(trace_id));
       },
-      this);
+      static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this)));
 
   // Mark login host for deletion after browser starts.  This
   // guarantees that the message loop will be referenced by the
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc
index de81e5c..03505b1 100644
--- a/chrome/browser/banners/app_banner_manager_browsertest.cc
+++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -747,8 +747,6 @@
     EnableFeatureAndSetParams(::features::kBackForwardCache,
                               "ignore_outstanding_network_request_for_testing",
                               "true");
-    EnableFeatureAndSetParams(::features::kBackForwardCache, "enable_same_site",
-                              "true");
     // Allow BackForwardCache for all devices regardless of their memory.
     DisableFeature(::features::kBackForwardCacheMemoryControls);
 
diff --git a/chrome/browser/bookmarks/bookmark_model_factory.cc b/chrome/browser/bookmarks/bookmark_model_factory.cc
index 2899ffa..85b757a9 100644
--- a/chrome/browser/bookmarks/bookmark_model_factory.cc
+++ b/chrome/browser/bookmarks/bookmark_model_factory.cc
@@ -8,9 +8,11 @@
 #include "base/memory/singleton.h"
 #include "base/values.h"
 #include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/bookmarks/chrome_bookmark_client.h"
 #include "chrome/browser/bookmarks/managed_bookmark_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_selections.h"
 #include "chrome/browser/sync/bookmark_sync_service_factory.h"
 #include "chrome/browser/ui/webui/bookmarks/bookmarks_ui.h"
 #include "chrome/browser/undo/bookmark_undo_service_factory.h"
@@ -23,6 +25,10 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "chrome/browser/ash/profiles/profile_helper.h"
+#endif
+
 namespace {
 
 using bookmarks::BookmarkModel;
@@ -70,7 +76,7 @@
 BookmarkModelFactory::BookmarkModelFactory()
     : ProfileKeyedServiceFactory(
           "BookmarkModel",
-          ProfileSelections::BuildRedirectedInIncognito()) {
+          ProfileSelections::BuildRedirectedInIncognitoNonExperimental()) {
   DependsOn(BookmarkUndoServiceFactory::GetInstance());
   DependsOn(ManagedBookmarkServiceFactory::GetInstance());
   DependsOn(BookmarkSyncServiceFactory::GetInstance());
@@ -81,6 +87,13 @@
 
 KeyedService* BookmarkModelFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // ChromeOS creates various profiles (login, lock screen...) that do
+  // not have/need access to bookmarks.
+  Profile* profile = Profile::FromBrowserContext(context);
+  if (!chromeos::ProfileHelper::IsRegularProfile(profile))
+    return nullptr;
+#endif
   return BuildBookmarkModel(context).release();
 }
 
diff --git a/chrome/browser/chrome_back_forward_cache_browsertest.cc b/chrome/browser/chrome_back_forward_cache_browsertest.cc
index f07291b..837340d 100644
--- a/chrome/browser/chrome_back_forward_cache_browsertest.cc
+++ b/chrome/browser/chrome_back_forward_cache_browsertest.cc
@@ -108,8 +108,6 @@
     EnableFeatureAndSetParams(features::kBackForwardCache,
                               "ignore_outstanding_network_request_for_testing",
                               "true");
-    EnableFeatureAndSetParams(features::kBackForwardCache, "enable_same_site",
-                              "true");
     // Allow BackForwardCache for all devices regardless of their memory.
     DisableFeature(features::kBackForwardCacheMemoryControls);
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
index 4fa98145..7dd7b9e6 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
@@ -596,10 +596,14 @@
           DCHECK(url.is_string());
           files_rule.add_source_urls(url.GetString());
         }
-        for (const auto& url : destinations_urls->GetList()) {
-          DCHECK(url.is_string());
-          files_rule.add_destination_urls(url.GetString());
+
+        if (rule_has_destinations) {
+          for (const auto& url : destinations_urls->GetList()) {
+            DCHECK(url.is_string());
+            files_rule.add_destination_urls(url.GetString());
+          }
         }
+
         // TODO(crbug.com/1321088): Add components to SetDlpFilesPolicyRequest.
 
         files_rule.set_level(GetLevelProtoEnum(rule_level));
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
index fca7bc7..8fc8bc43 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
@@ -1194,4 +1194,38 @@
   chromeos::DlpClient::Shutdown();
 }
 
+// This is a test for the crash on the login screen for files policy rule with
+// no url destinations crbug.com/1358504.
+TEST_F(DlpRulesManagerImplTest, SetFilesPolicyWithOnlyComponents) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(
+      features::kDataLeakPreventionFilesRestriction);
+  chromeos::DlpClient::InitializeFake();
+
+  base::Value rules(base::Value::Type::LIST);
+
+  base::Value src_urls(base::Value::Type::LIST);
+  src_urls.Append(kExampleUrl);
+  base::Value dst_components(base::Value::Type::LIST);
+  dst_components.Append("ARC");
+  dst_components.Append("CROSTINI");
+  base::Value restrictions(base::Value::Type::LIST);
+  restrictions.Append(dlp_test_util::CreateRestrictionWithLevel(
+      dlp::kFilesRestriction, dlp::kBlockLevel));
+  rules.Append(dlp_test_util::CreateRule(
+      "rule #1", "Block Files", std::move(src_urls), absl::nullopt,
+      std::move(dst_components), std::move(restrictions)));
+
+  UpdatePolicyPref(std::move(rules));
+
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(dlp_rules_manager_.IsFilesPolicyEnabled());
+  EXPECT_EQ(chromeos::DlpClient::Get()
+                ->GetTestInterface()
+                ->GetSetDlpFilesPolicyCount(),
+            1);
+
+  chromeos::DlpClient::Shutdown();
+}
+
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.cc
index ec63cee..d62f5fd 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.cc
@@ -32,10 +32,17 @@
   return srcs;
 }
 
-base::Value CreateDestinations(base::Value urls, base::Value components) {
+base::Value CreateDestinations(absl::optional<base::Value> urls,
+                               absl::optional<base::Value> components) {
   base::Value dsts(base::Value::Type::DICTIONARY);
-  dsts.SetKey(kUrls, std::move(urls));
-  dsts.SetKey(kComponents, std::move(components));
+  if (urls.has_value()) {
+    DCHECK(urls->is_list());
+    dsts.SetKey(kUrls, std::move(urls.value()));
+  }
+  if (components.has_value()) {
+    DCHECK(components->is_list());
+    dsts.SetKey(kComponents, std::move(components.value()));
+  }
   return dsts;
 }
 
@@ -50,16 +57,14 @@
 base::Value CreateRule(const std::string& name,
                        const std::string& desc,
                        base::Value src_urls,
-                       base::Value dst_urls,
-                       base::Value dst_components,
+                       absl::optional<base::Value> dst_urls,
+                       absl::optional<base::Value> dst_components,
                        base::Value restrictions) {
   base::Value rule(base::Value::Type::DICTIONARY);
   rule.SetStringKey(kName, name);
   rule.SetStringKey(kDescription, desc);
   DCHECK(src_urls.is_list());
   rule.SetKey(kSources, CreateSources(std::move(src_urls)));
-  DCHECK(dst_urls.is_list());
-  DCHECK(dst_components.is_list());
   rule.SetKey(kDestinations, CreateDestinations(std::move(dst_urls),
                                                 std::move(dst_components)));
   DCHECK(restrictions.is_list());
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h
index 207c01e..e2304ed0 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_test_utils.h
@@ -25,8 +25,8 @@
 base::Value CreateRule(const std::string& name,
                        const std::string& desc,
                        base::Value src_urls,
-                       base::Value dst_urls,
-                       base::Value dst_components,
+                       absl::optional<base::Value> dst_urls,
+                       absl::optional<base::Value> dst_components,
                        base::Value restrictions);
 
 }  // namespace dlp_test_util
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.cc b/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.cc
index e5f73173..58fb0bdc 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.cc
@@ -9,6 +9,20 @@
 
 namespace policy {
 
+namespace {
+
+dlp::RequestFileAccessRequest PrepareBaseRequestFileAccessRequest(
+    const std::vector<base::FilePath>& files) {
+  dlp::RequestFileAccessRequest request;
+  for (const auto& file : files)
+    request.add_files_paths(file.value());
+
+  request.set_process_id(base::GetCurrentProcId());
+  return request;
+}
+
+}  // namespace
+
 // static
 void DlpScopedFileAccessDelegate::Initialize(chromeos::DlpClient* client) {
   if (!HasInstance()) {
@@ -29,12 +43,31 @@
     return;
   }
 
-  dlp::RequestFileAccessRequest request;
-  for (const auto& file : files)
-    request.add_files_paths(file.value());
-
+  dlp::RequestFileAccessRequest request =
+      PrepareBaseRequestFileAccessRequest(files);
   request.set_destination_url(destination_url.spec());
-  request.set_process_id(base::GetCurrentProcId());
+
+  PostRequestFileAccessToDaemon(request, std::move(callback));
+}
+
+void DlpScopedFileAccessDelegate::RequestFilesAccessForSystem(
+    const std::vector<base::FilePath>& files,
+    base::OnceCallback<void(file_access::ScopedFileAccess)> callback) {
+  if (!client_->IsAlive()) {
+    std::move(callback).Run(file_access::ScopedFileAccess::Allowed());
+    return;
+  }
+
+  dlp::RequestFileAccessRequest request =
+      PrepareBaseRequestFileAccessRequest(files);
+  request.set_destination_component(dlp::DlpComponent::SYSTEM);
+
+  PostRequestFileAccessToDaemon(request, std::move(callback));
+}
+
+void DlpScopedFileAccessDelegate::PostRequestFileAccessToDaemon(
+    const ::dlp::RequestFileAccessRequest request,
+    base::OnceCallback<void(file_access::ScopedFileAccess)> callback) {
   client_->RequestFileAccess(
       request, base::BindOnce(&DlpScopedFileAccessDelegate::OnResponse,
                               base::Unretained(this), std::move(callback)));
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h b/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h
index 5b29a8a6..a6ff6ea 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h
@@ -33,20 +33,28 @@
   // Initializes the singleton instance.
   static void Initialize(chromeos::DlpClient* client);
 
-  // Requests access to |files| in order to be sent to |destination_url|.
-  // |continuation_callback| is called with a token that should be hold until
-  // `open()` operation on the files finished.
+  // file_access::ScopedFileAccessDelegate:
   void RequestFilesAccess(
       const std::vector<base::FilePath>& files,
       const GURL& destination_url,
       base::OnceCallback<void(file_access::ScopedFileAccess)> callback)
       override;
+  void RequestFilesAccessForSystem(
+      const std::vector<base::FilePath>& files,
+      base::OnceCallback<void(file_access::ScopedFileAccess)> callback)
+      override;
 
  protected:
   explicit DlpScopedFileAccessDelegate(chromeos::DlpClient* client);
 
  private:
   friend class DlpScopedFileAccessDelegateTest;
+
+  // Starts a RequestFileAccess request to the daemon.
+  void PostRequestFileAccessToDaemon(
+      const ::dlp::RequestFileAccessRequest request,
+      base::OnceCallback<void(file_access::ScopedFileAccess)> callback);
+
   // Handles D-Bus response to access files.
   void OnResponse(
       base::OnceCallback<void(file_access::ScopedFileAccess)> callback,
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate_unittest.cc
index 42a2736..9dfad77 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/test/test_future.h"
 #include "chromeos/dbus/dlp/fake_dlp_client.h"
 #include "components/file_access/scoped_file_access_delegate.h"
+#include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace policy {
@@ -25,12 +26,12 @@
       const DlpScopedFileAccessDelegateTest&) = delete;
 
  protected:
-  base::test::SingleThreadTaskEnvironment task_environment_;
+  content::BrowserTaskEnvironment task_environment_;
   chromeos::FakeDlpClient fake_dlp_client_;
   DlpScopedFileAccessDelegate delegate_{&fake_dlp_client_};
 };
 
-TEST_F(DlpScopedFileAccessDelegateTest, Test) {
+TEST_F(DlpScopedFileAccessDelegateTest, TestNoSingleton) {
   base::FilePath file_path;
   base::CreateTemporaryFile(&file_path);
 
@@ -46,7 +47,7 @@
   EXPECT_FALSE(future2.Get<0>().is_allowed());
 }
 
-TEST_F(DlpScopedFileAccessDelegateTest, TestFileAccessSingleton) {
+TEST_F(DlpScopedFileAccessDelegateTest, TestFileAccessSingletonForUrl) {
   base::FilePath file_path;
   base::CreateTemporaryFile(&file_path);
 
@@ -65,6 +66,19 @@
   EXPECT_FALSE(future2.Get<0>().is_allowed());
 }
 
+TEST_F(DlpScopedFileAccessDelegateTest,
+       TestFileAccessSingletonForSystemComponent) {
+  base::FilePath file_path;
+  base::CreateTemporaryFile(&file_path);
+
+  DlpScopedFileAccessDelegate::Initialize(&fake_dlp_client_);
+
+  base::test::TestFuture<file_access::ScopedFileAccess> future1;
+  auto* delegate = file_access::ScopedFileAccessDelegate::Get();
+  delegate->RequestFilesAccessForSystem({file_path}, future1.GetCallback());
+  EXPECT_TRUE(future1.Get<0>().is_allowed());
+}
+
 TEST_F(DlpScopedFileAccessDelegateTest, TestMultipleInstances) {
   DlpScopedFileAccessDelegate::Initialize(nullptr);
   EXPECT_NO_FATAL_FAILURE(DlpScopedFileAccessDelegate::Initialize(nullptr));
diff --git a/chrome/browser/dips/cookie_access_filter.h b/chrome/browser/dips/cookie_access_filter.h
index ad464e01..13f5fc6 100644
--- a/chrome/browser/dips/cookie_access_filter.h
+++ b/chrome/browser/dips/cookie_access_filter.h
@@ -28,7 +28,9 @@
   // Clear `result` and fill it with the the type of cookie access for each URL.
   // `result` will have the same length as `urls`. Returns true iff every
   // previously-recorded cookie access was successfully matched to a URL in
-  // `urls`. (Note: this depends on the order of previous calls to AddAccess()).
+  // `urls`. Otherwise returns false, and `result` is filled entirely with
+  // kUnknown. (Note: this depends on the order of previous calls to
+  // AddAccess()).
   [[nodiscard]] bool Filter(const std::vector<GURL>& urls,
                             std::vector<CookieAccessType>* result) const;
 
diff --git a/chrome/browser/dips/dips_bounce_detector.cc b/chrome/browser/dips/dips_bounce_detector.cc
index dc19a9d..b6b0a1c 100644
--- a/chrome/browser/dips/dips_bounce_detector.cc
+++ b/chrome/browser/dips/dips_bounce_detector.cc
@@ -40,9 +40,7 @@
 class ServerBounceDetectionState
     : public content::NavigationHandleUserData<ServerBounceDetectionState> {
  public:
-  // The WebContents' previously committed URL at the time the navigation
-  // started. Needed in case a parallel navigation commits.
-  GURL initial_url;
+  DIPSNavigationStart navigation_start;
   CookieAccessFilter filter;
 
  private:
@@ -126,13 +124,20 @@
       dips_service_(DIPSService::Get(web_contents->GetBrowserContext())),
       site_engagement_service_(site_engagement::SiteEngagementService::Get(
           web_contents->GetBrowserContext())),
-      // It's safe to use unretained because the callback is owned by this.
-      redirect_handler_(base::BindRepeating(&DIPSBounceDetector::HandleRedirect,
-                                            base::Unretained(this))),
-      clock_(g_clock ? g_clock : base::DefaultTickClock::GetInstance()) {}
+      clock_(g_clock ? g_clock : base::DefaultTickClock::GetInstance()),
+      // It's safe to use unretained because the callback is owned by the
+      // DIPSRedirectContext which is owned by this.
+      redirect_context_(base::BindRepeating(&DIPSBounceDetector::HandleRedirect,
+                                            base::Unretained(this)),
+                        /*initial_url=*/GURL::EmptyGURL()) {}
 
 DIPSBounceDetector::~DIPSBounceDetector() = default;
 
+void DIPSBounceDetector::SetRedirectHandlerForTesting(
+    DIPSRedirectHandler handler) {
+  redirect_context_.SetRedirectHandlerForTesting(handler);  // IN-TEST
+}
+
 /*static*/
 base::TickClock* DIPSBounceDetector::SetTickClockForTesting(
     base::TickClock* clock) {
@@ -199,6 +204,68 @@
 
 DIPSRedirectInfo::~DIPSRedirectInfo() = default;
 
+DIPSRedirectContext::DIPSRedirectContext(DIPSRedirectHandler handler,
+                                         const GURL& initial_url)
+    : handler_(handler), initial_url_(initial_url) {}
+
+DIPSRedirectContext::~DIPSRedirectContext() = default;
+
+void DIPSRedirectContext::Append(
+    bool committed,
+    DIPSNavigationStart navigation_start,
+    std::vector<DIPSRedirectInfoPtr>&& server_redirects,
+    GURL final_url) {
+  if (committed) {
+    Append(std::move(navigation_start), std::move(server_redirects));
+  } else {
+    DIPSRedirectContext temp_context(handler_, initial_url_);
+    temp_context.Append(std::move(navigation_start),
+                        std::move(server_redirects));
+    temp_context.EndChain(std::move(final_url));
+  }
+}
+
+void DIPSRedirectContext::Append(
+    DIPSNavigationStart navigation_start,
+    std::vector<DIPSRedirectInfoPtr>&& server_redirects) {
+  // If there was a client-side redirect, grow the chain. Otherwise, end it.
+  if (absl::holds_alternative<DIPSRedirectInfoPtr>(navigation_start)) {
+    auto& client_redirect = absl::get<DIPSRedirectInfoPtr>(navigation_start);
+    DCHECK_EQ(client_redirect->redirect_type, DIPSRedirectType::kClient);
+    redirects_.push_back(std::move(client_redirect));
+  } else {
+    auto& client_url = absl::get<GURL>(navigation_start);
+    // This is the most common reason for redirect chains
+    // to terminate. Other reasons include: (1) navigations
+    // that don't commit and (2) the user closing the tab
+    // (i.e., WCO::WebContentsDestroyed())
+    EndChain(std::move(client_url));
+  }
+
+  // Server-side redirects always grow the chain.
+  for (auto& redirect : server_redirects) {
+    DCHECK_EQ(redirect->redirect_type, DIPSRedirectType::kServer);
+    redirects_.push_back(std::move(redirect));
+  }
+}
+
+void DIPSRedirectContext::EndChain(GURL url) {
+  if (!redirects_.empty()) {
+    // Uncommitted chains may omit earlier (committed) redirects in the chain,
+    // so |redirects_.size()| may not tell us the correct chain length. Instead,
+    // use the index of the last item in the chain (since it was generated based
+    // on the committed chain length).
+    DIPSRedirectChainInfo chain(initial_url_, url,
+                                redirects_.back()->index + 1);
+    for (const auto& redirect : redirects_) {
+      handler_.Run(*redirect, chain);
+    }
+    redirects_.clear();
+  }
+
+  initial_url_ = std::move(url);
+}
+
 void DIPSBounceDetector::HandleRedirect(const DIPSRedirectInfo& redirect,
                                         const DIPSRedirectChainInfo& chain) {
   const std::string site = GetSite(redirect.url);
@@ -242,6 +309,7 @@
     return;
   }
 
+  DIPSRedirectInfoPtr client_redirect;
   if (client_detection_state_.has_value()) {
     base::TimeDelta bounce_time = now - client_detection_state_->page_load_time;
 
@@ -254,28 +322,35 @@
       if (client_detection_state_->cookie_access_type > CookieAccessType::kNone)
         UmaHistogramTimeToBounce(bounce_time);
 
-      DIPSRedirectChainInfo chain(
-          /*initial_url=*/client_detection_state_->previous_url,
-          /*final_url=*/navigation_handle->GetURL(),
-          /*length=*/1);
-      DIPSRedirectInfo redirect(
+      client_redirect = std::make_unique<DIPSRedirectInfo>(
           /*url=*/web_contents()->GetLastCommittedURL(),
           /*redirect_type=*/DIPSRedirectType::kClient,
           /*access_type=*/client_detection_state_->cookie_access_type,
-          /*index=*/0,
+          /*index=*/redirect_context_.size(),
           /*source_id=*/
           web_contents()->GetPrimaryMainFrame()->GetPageUkmSourceId(),
           /*client_bounce_delay=*/bounce_time,
           /*has_sticky_activation=*/
           client_detection_state_->received_user_activation);
-      redirect_handler_.Run(redirect, chain);
+      // We cannot append |client_redirect| to |redirect_context_| immediately,
+      // because we don't know if the navigation will commit. We must wait until
+      // DidFinishNavigation().
     }
+    // Similarly, we can't call redirect_context_->EndChain() yet even if this
+    // navigation isn't a redirect. (Technically, if more than
+    // kBounceThresholdSeconds time has passed, we can be certain that the chain
+    // has ended; but for code simplicity, we ignore that.)
   }
 
   auto* server_state =
       ServerBounceDetectionState::GetOrCreateForNavigationHandle(
           *navigation_handle);
-  server_state->initial_url = web_contents()->GetLastCommittedURL();
+
+  if (client_redirect) {
+    server_state->navigation_start = std::move(client_redirect);
+  } else {
+    server_state->navigation_start = web_contents()->GetLastCommittedURL();
+  }
 }
 
 void DIPSBounceDetector::OnCookiesAccessed(
@@ -330,35 +405,41 @@
   auto* server_state =
       ServerBounceDetectionState::GetForNavigationHandle(*navigation_handle);
 
-  if (server_state) {
-    std::vector<CookieAccessType> access_types;
-    bool filter_success = server_state->filter.Filter(
-        navigation_handle->GetRedirectChain(), &access_types);
-    UmaHistogramCookieAccessFilterResult(filter_success, GetCookieMode());
-    DIPSRedirectChainInfo chain(/*initial_url=*/server_state->initial_url,
-                                /*final_url=*/navigation_handle->GetURL(),
-                                /*length=*/access_types.size() - 1);
+  if (!server_state) {
+    return;
+  }
 
-    for (size_t i = 0; i < access_types.size() - 1; i++) {
-      DIPSRedirectInfo redirect(
-          /*url=*/navigation_handle->GetRedirectChain()[i],
-          /*redirect_type=*/DIPSRedirectType::kServer,
-          /*access_type=*/access_types[i],
-          /*index=*/i,
-          /*source_id=*/GetRedirectSourceId(navigation_handle, i));
-      redirect_handler_.Run(redirect, chain);
-    }
+  std::vector<DIPSRedirectInfoPtr> redirects;
+  std::vector<CookieAccessType> access_types;
+  bool filter_success = server_state->filter.Filter(
+      navigation_handle->GetRedirectChain(), &access_types);
+  UmaHistogramCookieAccessFilterResult(filter_success, GetCookieMode());
 
-    if (navigation_handle->HasCommitted()) {
-      // The last entry in navigation_handle->GetRedirectChain() is actually the
-      // page being committed (i.e., not a redirect). If its HTTP request or
-      // response accessed cookies, record this in our client detection state.
-      //
-      // Note that we do this even if !filter_success, because it might still
-      // provide information on the committed page -- it annotates every URL it
-      // can.
-      client_detection_state_->cookie_access_type = access_types.back();
-    }
+  for (size_t i = 0; i < access_types.size() - 1; i++) {
+    redirects.push_back(std::make_unique<DIPSRedirectInfo>(
+        /*url=*/navigation_handle->GetRedirectChain()[i],
+        /*redirect_type=*/DIPSRedirectType::kServer,
+        /*access_type=*/access_types[i],
+        /*index=*/
+        absl::holds_alternative<DIPSRedirectInfoPtr>(
+            server_state->navigation_start)
+            ? redirect_context_.size() + i + 1
+            : i,
+        /*source_id=*/GetRedirectSourceId(navigation_handle, i)));
+  }
+
+  // This call handles all the logic for terminating the redirect chain when
+  // applicable, and using a temporary redirect context if the navigation didn't
+  // commit.
+  redirect_context_.Append(navigation_handle->HasCommitted(),
+                           std::move(server_state->navigation_start),
+                           std::move(redirects), navigation_handle->GetURL());
+
+  if (navigation_handle->HasCommitted()) {
+    // The last entry in navigation_handle->GetRedirectChain() is actually the
+    // page being committed (i.e., not a redirect). If its HTTP request or
+    // response accessed cookies, record this in our client detection state.
+    client_detection_state_->cookie_access_type = access_types.back();
   }
 }
 
@@ -368,4 +449,9 @@
     client_detection_state_->received_user_activation = true;
 }
 
+void DIPSBounceDetector::WebContentsDestroyed() {
+  // Handle the current chain before the tab closes and the state is lost.
+  redirect_context_.EndChain(web_contents()->GetLastCommittedURL());
+}
+
 WEB_CONTENTS_USER_DATA_KEY_IMPL(DIPSBounceDetector);
diff --git a/chrome/browser/dips/dips_bounce_detector.h b/chrome/browser/dips/dips_bounce_detector.h
index 3a8c559..d1f5f9d 100644
--- a/chrome/browser/dips/dips_bounce_detector.h
+++ b/chrome/browser/dips/dips_bounce_detector.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_DIPS_DIPS_BOUNCE_DETECTOR_H_
 
 #include <string>
+#include <variant>
 
 #include "base/callback.h"
 #include "base/memory/raw_ptr.h"
@@ -103,6 +104,51 @@
   const bool has_sticky_activation;
 };
 
+using DIPSRedirectHandler =
+    base::RepeatingCallback<void(const DIPSRedirectInfo&,
+                                 const DIPSRedirectChainInfo&)>;
+
+// a movable DIPSRedirectInfo, essentially
+using DIPSRedirectInfoPtr = std::unique_ptr<DIPSRedirectInfo>;
+
+// Either the URL navigated away from (starting a new chain), or the client-side
+// redirect connecting the navigation to the currently-committed chain.
+using DIPSNavigationStart = absl::variant<GURL, DIPSRedirectInfoPtr>;
+
+// A redirect-chain-in-progress. It grows by calls to Append() and restarts by
+// calls to EndChain().
+class DIPSRedirectContext {
+ public:
+  DIPSRedirectContext(DIPSRedirectHandler handler, const GURL& initial_url);
+  ~DIPSRedirectContext();
+
+  // If committed=true, appends the client and server redirects to the current
+  // chain. Otherwise, creates a temporary DIPSRedirectContext, appends the
+  // redirects, and immediately calls EndChain() on it.
+  void Append(bool committed,
+              DIPSNavigationStart navigation_start,
+              std::vector<DIPSRedirectInfoPtr>&& server_redirects,
+              GURL final_url);
+  // Terminates the current redirect chain and calls the DIPSRedirectHandler for
+  // each entry. Starts a new chain for later calls to Append() to add to.
+  void EndChain(GURL url);
+
+  size_t size() const { return redirects_.size(); }
+
+  void SetRedirectHandlerForTesting(DIPSRedirectHandler handler) {
+    handler_ = handler;
+  }
+
+ private:
+  // Appends the client and server redirects to the current chain.
+  void Append(DIPSNavigationStart navigation_start,
+              std::vector<DIPSRedirectInfoPtr>&& server_redirects);
+
+  DIPSRedirectHandler handler_;
+  GURL initial_url_;
+  std::vector<DIPSRedirectInfoPtr> redirects_;
+};
+
 class DIPSBounceDetector
     : public content::WebContentsObserver,
       public content::WebContentsUserData<DIPSBounceDetector> {
@@ -111,13 +157,7 @@
   DIPSBounceDetector(const DIPSBounceDetector&) = delete;
   DIPSBounceDetector& operator=(const DIPSBounceDetector&) = delete;
 
-  using RedirectHandler =
-      base::RepeatingCallback<void(const DIPSRedirectInfo&,
-                                   const DIPSRedirectChainInfo&)>;
-
-  void SetRedirectHandlerForTesting(RedirectHandler handler) {
-    redirect_handler_ = handler;
-  }
+  void SetRedirectHandlerForTesting(DIPSRedirectHandler handler);
 
   // This must be called prior to the DIPSBounceDetector being constructed.
   static base::TickClock* SetTickClockForTesting(base::TickClock* clock);
@@ -146,6 +186,7 @@
       content::NavigationHandle* navigation_handle) override;
   void FrameReceivedUserActivation(
       content::RenderFrameHost* render_frame_host) override;
+  void WebContentsDestroyed() override;
 
   // raw_ptr<> is safe here DIPSService is a KeyedService, associated with the
   // BrowserContext/Profile which will outlive the WebContents that
@@ -154,10 +195,8 @@
   // raw_ptr<> is safe here for the same reasons as above.
   raw_ptr<site_engagement::SiteEngagementService> site_engagement_service_;
   absl::optional<ClientBounceDetectionState> client_detection_state_;
-  // By default, this just calls this->HandleRedirect(), but it
-  // can be overridden for tests.
-  RedirectHandler redirect_handler_;
   raw_ptr<const base::TickClock> clock_;
+  DIPSRedirectContext redirect_context_;
 
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 };
diff --git a/chrome/browser/dips/dips_bounce_detector_browsertest.cc b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
index 2928ca1..8047a146 100644
--- a/chrome/browser/dips/dips_bounce_detector_browsertest.cc
+++ b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
@@ -19,6 +19,7 @@
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/hit_test_region_observer.h"
+#include "content/public/test/test_utils.h"
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
@@ -194,6 +195,9 @@
     host_resolver()->AddRule("sub.b.test", "127.0.0.1");
     host_resolver()->AddRule("c.test", "127.0.0.1");
     host_resolver()->AddRule("d.test", "127.0.0.1");
+    host_resolver()->AddRule("e.test", "127.0.0.1");
+    host_resolver()->AddRule("f.test", "127.0.0.1");
+    host_resolver()->AddRule("g.test", "127.0.0.1");
     bounce_detector_ =
         DIPSBounceDetector::FromWebContents(GetActiveWebContents());
   }
@@ -228,6 +232,15 @@
     observer.Wait();
   }
 
+  // Perform a browser-based navigation to terminate the current redirect chain.
+  // (NOTE: tests using WCOCallbackLogger must call this *after* checking the
+  // log, since this navigation will be logged.)
+  void EndRedirectChain() {
+    ASSERT_TRUE(content::NavigateToURL(
+        GetActiveWebContents(),
+        embedded_test_server()->GetURL("a.test", "/title1.html")));
+  }
+
  private:
   base::SimpleTestTickClock test_clock_;
   raw_ptr<DIPSBounceDetector> bounce_detector_ = nullptr;
@@ -346,6 +359,7 @@
 
   // Visit the redirect.
   ASSERT_TRUE(content::NavigateToURL(web_contents, redirect_url, final_url));
+  EndRedirectChain();
 
   // a.test and b.test are stateful redirects. c.test had no cookies, and d.test
   // was not a redirect.
@@ -419,6 +433,7 @@
   ASSERT_TRUE(content::NavigateToURL(web_contents, root_url));
   ASSERT_TRUE(
       content::NavigateIframeToURL(web_contents, iframe_id, redirect_url));
+  EndRedirectChain();
 
   // b.test had a stateful redirect, but because it was in an iframe, we ignored
   // it.
@@ -496,6 +511,7 @@
                                   "Change: b.test/title1.html)"),
                                  ("DidStartNavigation(c.test/title1.html)"),
                                  ("DidFinishNavigation(c.test/title1.html)")));
+  EndRedirectChain();
 
   EXPECT_THAT(
       redirects,
@@ -531,6 +547,7 @@
   ASSERT_TRUE(content::NavigateToURL(web_contents, initial_url));
   // Visit the redirect.
   ASSERT_TRUE(content::NavigateToURL(web_contents, redirect_url, final_url));
+  EndRedirectChain();
 
   // a.test and b.test are stateful redirects. c.test had no cookies, and d.test
   // was not a redirect.
@@ -619,13 +636,14 @@
                                   "Change: c.test/cross-site-with-cookie/"
                                   "d.test/title1.html)"),
                                  ("DidFinishNavigation(d.test/title1.html)")));
+  EndRedirectChain();
 
   EXPECT_THAT(
       redirects,
       testing::ElementsAre(
           ("a.test/title1.html -> "
            "a.test/cross-site-with-cookie/b.test/title1.html -> "
-           "b.test/title1.html"),
+           "c.test/title1.html"),
           ("a.test/title1.html -> b.test/title1.html -> c.test/title1.html"),
           ("c.test/title1.html -> "
            "c.test/cross-site-with-cookie/d.test/title1.html -> "
@@ -642,6 +660,9 @@
   content::WebContents* web_contents = GetActiveWebContents();
   content::RenderFrameHost* frame;
 
+  // a.test  -(click)-> b.test -(UA-redir)-> c.test -(redir)-> d.test -(redir)->
+  // a.test
+
   std::vector<std::string> redirects;
   bounce_detector()->SetRedirectHandlerForTesting(
       base::BindRepeating(&AppendRedirect, &redirects));
@@ -715,14 +736,15 @@
 
   // Wait for navigation to finish to final page (a.test).
   EXPECT_TRUE(content::WaitForLoadStop(web_contents));
+  EndRedirectChain();
 
   // c.test and d.test are stateful bounces, but b.test is not counted as a
   // bounce because it received user activation shortly before redirecting away.
   EXPECT_THAT(
       redirects,
       testing::ElementsAre(
-          ("b.test/title1.html -> c.test/title1.html -> d.test/title1.html"),
-          ("c.test/title1.html -> d.test/title1.html -> a.test/title1.html")));
+          ("b.test/title1.html -> c.test/title1.html -> a.test/title1.html"),
+          ("b.test/title1.html -> d.test/title1.html -> a.test/title1.html")));
 }
 
 IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
@@ -754,6 +776,7 @@
   // Visit the redirect (note that the user ends up back at initial_url).
   ASSERT_TRUE(content::NavigateToURL(web_contents, redirect_url,
                                      /*expected_commit_url=*/initial_url));
+  EndRedirectChain();
 
   // a.test and b.test are stateful redirects. c.test had no cookies, and d.test
   // was not a redirect.
@@ -796,6 +819,7 @@
   ASSERT_FALSE(content::NavigateToURL(web_contents, redirect_url));
   ASSERT_TRUE(content::IsLastCommittedEntryOfPageType(
       web_contents, content::PAGE_TYPE_ERROR));
+  EndRedirectChain();
 
   // a.test and b.test are stateful redirects. c.test had no cookies, and d.test
   // was not a redirect.
@@ -845,6 +869,8 @@
       web_contents->GetPrimaryMainFrame(),
       embedded_test_server()->GetURL("c.test", "/set-cookie?name=value")));
 
+  // a.test -(click) -> b.test -(redir)-> c.test -(redir) -> d.test
+
   // Visit initial page.
   ASSERT_TRUE(content::NavigateToURL(web_contents, initial_url));
   // Wait for navigation to finish to initial page.
@@ -892,6 +918,7 @@
 
   // Wait for navigation to finish to final page (d.test).
   EXPECT_TRUE(content::WaitForLoadStop(web_contents));
+  EndRedirectChain();
 
   // Verify the correct histogram was used for all samples.
   base::HistogramTester::CountsMap expected_counts;
@@ -934,7 +961,7 @@
                   Pair("InitialAndFinalSitesSame", false),
                   Pair("RedirectAndFinalSiteSame", false),
                   Pair("RedirectAndInitialSiteSame", false),
-                  Pair("RedirectChainIndex", 0), Pair("RedirectChainLength", 1),
+                  Pair("RedirectChainIndex", 0), Pair("RedirectChainLength", 2),
                   Pair("RedirectType", (int)DIPSRedirectType::kClient),
                   Pair("SiteEngagementLevel", Gt((int)EngagementLevel::NONE))));
 
@@ -952,7 +979,7 @@
                   Pair("InitialAndFinalSitesSame", false),
                   Pair("RedirectAndFinalSiteSame", false),
                   Pair("RedirectAndInitialSiteSame", false),
-                  Pair("RedirectChainIndex", 0), Pair("RedirectChainLength", 1),
+                  Pair("RedirectChainIndex", 1), Pair("RedirectChainLength", 2),
                   Pair("RedirectType", (int)DIPSRedirectType::kClient),
                   Pair("SiteEngagementLevel", (int)EngagementLevel::NONE)));
 }
@@ -983,6 +1010,7 @@
   ukm::TestAutoSetUkmRecorder ukm_recorder;
   ASSERT_TRUE(content::NavigateToURLFromRenderer(web_contents, redirect_url,
                                                  final_url));
+  EndRedirectChain();
 
   // Verify the correct histogram was used for all samples.
   base::HistogramTester::CountsMap expected_counts;
@@ -1125,6 +1153,7 @@
                   // Land on c.test
                   ("DidStartNavigation(c.test/title1.html)"),
                   ("DidFinishNavigation(c.test/title1.html)")));
+  EndRedirectChain();
 
   // b.test is not considered a stateful bounce.
   EXPECT_THAT(redirects, testing::IsEmpty());
@@ -1185,6 +1214,7 @@
                   // Land on c.test
                   ("DidStartNavigation(c.test/title1.html)"),
                   ("DidFinishNavigation(c.test/title1.html)")));
+  EndRedirectChain();
 
   // b.test IS considered a stateful bounce, even though the cookie was read by
   // an image hosted on sub.b.test.
@@ -1193,3 +1223,172 @@
       testing::ElementsAre(
           ("a.test/title1.html -> b.test/title1.html -> c.test/title1.html")));
 }
+
+void AppendAnyRedirect(std::vector<std::string>* redirects,
+                       const DIPSRedirectInfo& redirect,
+                       const DIPSRedirectChainInfo& chain) {
+  redirects->push_back(base::StringPrintf(
+      "[%d/%d] %s -> %s (%s) -> %s", redirect.index + 1, chain.length,
+      FormatURL(chain.initial_url).c_str(), FormatURL(redirect.url).c_str(),
+      CookieAccessTypeToString(redirect.access_type).data(),
+      FormatURL(chain.final_url).c_str()));
+}
+
+// This test verifies that consecutive redirect chains are combined into one.
+IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
+                       DetectStatefulRedirect_ServerClientClientServer) {
+  WebContents* web_contents = GetActiveWebContents();
+
+  std::vector<std::string> redirects;
+  bounce_detector()->SetRedirectHandlerForTesting(
+      base::BindRepeating(&AppendAnyRedirect, &redirects));
+
+  // Visit initial page on a.test
+  ASSERT_TRUE(content::NavigateToURL(
+      web_contents, embedded_test_server()->GetURL("a.test", "/title1.html")));
+
+  // Navigate with a click (not a redirect) to b.test, which S-redirects to
+  // c.test
+  ASSERT_TRUE(content::NavigateToURLFromRenderer(
+      web_contents,
+      embedded_test_server()->GetURL("b.test",
+                                     "/cross-site/c.test/title1.html"),
+      embedded_test_server()->GetURL("c.test", "/title1.html")));
+
+  // Advance TimeTicks by 1 second
+  AdvanceDIPSTime(base::Seconds(1));
+  // Navigate without a click (i.e. by C-redirecting) to d.test
+  ASSERT_TRUE(content::NavigateToURLFromRendererWithoutUserGesture(
+      web_contents, embedded_test_server()->GetURL("d.test", "/title1.html")));
+
+  // Advance TimeTicks by 1 second
+  AdvanceDIPSTime(base::Seconds(1));
+  // Navigate without a click (i.e. by C-redirecting) to e.test, which
+  // S-redirects to f.test
+  ASSERT_TRUE(content::NavigateToURLFromRendererWithoutUserGesture(
+      web_contents,
+      embedded_test_server()->GetURL("e.test",
+                                     "/cross-site/f.test/title1.html"),
+      embedded_test_server()->GetURL("f.test", "/title1.html")));
+  EndRedirectChain();
+
+  EXPECT_THAT(redirects,
+              testing::ElementsAre(
+                  ("[1/4] a.test/title1.html -> "
+                   "b.test/cross-site/c.test/title1.html (None) -> "
+                   "f.test/title1.html"),
+                  ("[2/4] a.test/title1.html -> c.test/title1.html (None) -> "
+                   "f.test/title1.html"),
+                  ("[3/4] a.test/title1.html -> d.test/title1.html (None) -> "
+                   "f.test/title1.html"),
+                  ("[4/4] a.test/title1.html -> "
+                   "e.test/cross-site/f.test/title1.html (None) -> "
+                   "f.test/title1.html")));
+}
+
+IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
+                       DetectStatefulRedirect_UncommittedChain) {
+  WebContents* web_contents = GetActiveWebContents();
+
+  std::vector<std::string> redirects;
+  bounce_detector()->SetRedirectHandlerForTesting(
+      base::BindRepeating(&AppendAnyRedirect, &redirects));
+
+  // Visit initial page on a.test
+  ASSERT_TRUE(content::NavigateToURL(
+      web_contents, embedded_test_server()->GetURL("a.test", "/title1.html")));
+
+  // Navigate with a click (not a redirect) to b.test, which S-redirects to
+  // c.test
+  ASSERT_TRUE(content::NavigateToURLFromRenderer(
+      web_contents,
+      embedded_test_server()->GetURL("b.test",
+                                     "/cross-site/c.test/title1.html"),
+      embedded_test_server()->GetURL("c.test", "/title1.html")));
+
+  // Advance TimeTicks by 1 second
+  AdvanceDIPSTime(base::Seconds(1));
+  // Navigate without a click (i.e. by C-redirecting) to d.test which redirects
+  // to e.test but doesn't commit.
+  ASSERT_TRUE(content::NavigateToURLFromRendererWithoutUserGesture(
+      web_contents,
+      embedded_test_server()->GetURL("d.test", "/cross-site/e.test/nocontent"),
+      /* empty URL since the navigation doesn't commit: */ GURL::EmptyGURL()));
+  ASSERT_EQ("c.test/title1.html",
+            FormatURL(web_contents->GetLastCommittedURL()));
+
+  // Advance TimeTicks by 1 second
+  AdvanceDIPSTime(base::Seconds(1));
+  // Navigate with a click (not a redirect) to d.test which redirects
+  // to e.test but doesn't commit.
+  ASSERT_TRUE(content::NavigateToURLFromRenderer(
+      web_contents,
+      embedded_test_server()->GetURL("d.test", "/cross-site/e.test/nocontent"),
+      /* empty URL since the navigation doesn't commit: */ GURL::EmptyGURL()));
+  ASSERT_EQ("c.test/title1.html",
+            FormatURL(web_contents->GetLastCommittedURL()));
+
+  // Advance TimeTicks by 1 second
+  AdvanceDIPSTime(base::Seconds(1));
+  // Navigate without a click (i.e. by C-redirecting) to e.test, which
+  // S-redirects to f.test
+  ASSERT_TRUE(content::NavigateToURLFromRendererWithoutUserGesture(
+      web_contents,
+      embedded_test_server()->GetURL("e.test",
+                                     "/cross-site/f.test/title1.html"),
+      embedded_test_server()->GetURL("f.test", "/title1.html")));
+  EndRedirectChain();
+
+  EXPECT_THAT(redirects,
+              testing::ElementsAre(
+                  // First uncommitted chain (with client redirect):
+                  ("[2/3] a.test/title1.html -> "
+                   "c.test/title1.html (None) -> "
+                   "e.test/nocontent"),
+                  ("[3/3] a.test/title1.html -> "
+                   "d.test/cross-site/e.test/nocontent (None) -> "
+                   "e.test/nocontent"),
+                  // Second uncommitted chain (without client redirect):
+                  ("[1/1] c.test/title1.html -> "
+                   "d.test/cross-site/e.test/nocontent (None) -> "
+                   "e.test/nocontent"),
+                  // Finally the committed chain:
+                  ("[1/3] a.test/title1.html -> "
+                   "b.test/cross-site/c.test/title1.html (None) -> "
+                   "f.test/title1.html"),
+                  ("[2/3] a.test/title1.html -> c.test/title1.html (None) -> "
+                   "f.test/title1.html"),
+                  ("[3/3] a.test/title1.html -> "
+                   "e.test/cross-site/f.test/title1.html (None) -> "
+                   "f.test/title1.html")));
+}
+
+IN_PROC_BROWSER_TEST_F(DIPSBounceDetectorBrowserTest,
+                       DetectStatefulRedirect_ClosingTabEndsChain) {
+  WebContents* web_contents = GetActiveWebContents();
+
+  std::vector<std::string> redirects;
+  bounce_detector()->SetRedirectHandlerForTesting(
+      base::BindRepeating(&AppendAnyRedirect, &redirects));
+
+  // Visit initial page on a.test
+  ASSERT_TRUE(content::NavigateToURL(
+      web_contents, embedded_test_server()->GetURL("a.test", "/title1.html")));
+
+  // Navigate with a click (not a redirect) to b.test, which S-redirects to
+  // c.test
+  ASSERT_TRUE(content::NavigateToURLFromRenderer(
+      web_contents,
+      embedded_test_server()->GetURL("b.test",
+                                     "/cross-site/c.test/title1.html"),
+      embedded_test_server()->GetURL("c.test", "/title1.html")));
+
+  content::WebContentsDestroyedWatcher destruction_watcher(web_contents);
+  web_contents->Close();
+  destruction_watcher.Wait();
+
+  EXPECT_THAT(redirects, testing::ElementsAre(
+                             ("[1/1] a.test/title1.html -> "
+                              "b.test/cross-site/c.test/title1.html (None) -> "
+                              "c.test/title1.html")));
+}
diff --git a/chrome/browser/download/bubble/download_display_controller.cc b/chrome/browser/download/bubble/download_display_controller.cc
index ca3852d0..5695a9f 100644
--- a/chrome/browser/download/bubble/download_display_controller.cc
+++ b/chrome/browser/download/bubble/download_display_controller.cc
@@ -111,8 +111,9 @@
     // exclusive_access_context can be null in tests.
     if (exclusive_access_context) {
       exclusive_access_context->UpdateExclusiveAccessExitBubbleContent(
-          GURL(), EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED,
+          GURL(), EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE,
           ExclusiveAccessBubbleHideCallback(),
+          /*notify_download=*/true,
           /*force_update=*/true);
     }
   } else if (download::ShouldShowDetailsAutomatically(browser_->profile())) {
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/BUILD.gn b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/BUILD.gn
index 945166b..d39d586 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/BUILD.gn
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/BUILD.gn
@@ -4,10 +4,13 @@
 
 if (is_win) {
   source_set("fetcher") {
-    public = [ "win_network_fetcher.h" ]
+    public = [
+      "win_network_fetcher.h",
+      "win_network_fetcher_factory.h",
+    ]
 
     sources = [
-      "win_network_fetcher.cc",
+      "win_network_fetcher_factory.cc",
       "win_network_fetcher_impl.cc",
       "win_network_fetcher_impl.h",
     ]
@@ -23,9 +26,15 @@
 
   source_set("test_support") {
     testonly = true
-    public = [ "mock_win_network_fetcher.h" ]
+    public = [
+      "mock_win_network_fetcher.h",
+      "mock_win_network_fetcher_factory.h",
+    ]
 
-    sources = [ "mock_win_network_fetcher.cc" ]
+    sources = [
+      "mock_win_network_fetcher.cc",
+      "mock_win_network_fetcher_factory.cc",
+    ]
 
     public_deps = [
       ":fetcher",
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/mock_win_network_fetcher_factory.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/mock_win_network_fetcher_factory.cc
new file mode 100644
index 0000000..8475f3d
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/mock_win_network_fetcher_factory.cc
@@ -0,0 +1,14 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/mock_win_network_fetcher_factory.h"
+
+namespace enterprise_connectors {
+namespace test {
+
+MockWinNetworkFetcherFactory::MockWinNetworkFetcherFactory() = default;
+MockWinNetworkFetcherFactory::~MockWinNetworkFetcherFactory() = default;
+
+}  // namespace test
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/mock_win_network_fetcher_factory.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/mock_win_network_fetcher_factory.h
new file mode 100644
index 0000000..a0fcc4c7
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/mock_win_network_fetcher_factory.h
@@ -0,0 +1,32 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_FETCHER_MOCK_WIN_NETWORK_FETCHER_FACTORY_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_FETCHER_MOCK_WIN_NETWORK_FETCHER_FACTORY_H_
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher_factory.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace enterprise_connectors {
+namespace test {
+
+// Mocked implementation of the WinNetworkFetcherFactory interface.
+class MockWinNetworkFetcherFactory : public WinNetworkFetcherFactory {
+ public:
+  MockWinNetworkFetcherFactory();
+  ~MockWinNetworkFetcherFactory() override;
+
+  MOCK_METHOD(std::unique_ptr<WinNetworkFetcher>,
+              CreateNetworkFetcher,
+              (const GURL&,
+               const std::string&,
+               (base::flat_map<std::string, std::string>)),
+              (override));
+};
+
+}  // namespace test
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_FETCHER_MOCK_WIN_NETWORK_FETCHER_FACTORY_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher.cc
deleted file mode 100644
index 8b705c9..0000000
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher.h"
-
-#include <memory>
-#include <string>
-
-#include "base/containers/flat_map.h"
-#include "base/no_destructor.h"
-#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher_impl.h"
-
-namespace enterprise_connectors {
-
-namespace {
-
-std::unique_ptr<WinNetworkFetcher>* GetTestInstanceStorage() {
-  static base::NoDestructor<std::unique_ptr<WinNetworkFetcher>> storage;
-  return storage.get();
-}
-
-}  // namespace
-
-// static
-std::unique_ptr<WinNetworkFetcher> WinNetworkFetcher::Create(
-    const GURL& url,
-    const std::string& body,
-    base::flat_map<std::string, std::string>& headers) {
-  std::unique_ptr<WinNetworkFetcher>& test_instance = *GetTestInstanceStorage();
-  if (test_instance)
-    return std::move(test_instance);
-  return std::make_unique<WinNetworkFetcherImpl>(url, body, headers);
-}
-
-// static
-void WinNetworkFetcher::SetInstanceForTesting(
-    std::unique_ptr<WinNetworkFetcher> fetcher) {
-  DCHECK(fetcher);
-  *GetTestInstanceStorage() = std::move(fetcher);
-}
-
-}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher.h
index db2518c..eea9e3b 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher.h
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher.h
@@ -5,11 +5,7 @@
 #ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_FETCHER_WIN_NETWORK_FETCHER_H_
 #define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_FETCHER_WIN_NETWORK_FETCHER_H_
 
-#include <memory>
-#include <string>
-
 #include "base/callback.h"
-#include "base/containers/flat_map.h"
 
 class GURL;
 
@@ -25,13 +21,6 @@
 
   virtual ~WinNetworkFetcher() = default;
 
-  static std::unique_ptr<WinNetworkFetcher> Create(
-      const GURL& url,
-      const std::string& body,
-      base::flat_map<std::string, std::string>& headers);
-
-  static void SetInstanceForTesting(std::unique_ptr<WinNetworkFetcher> fetcher);
-
   // Sends a DeviceManagementRequest to the DM server and returns the HTTP
   // response to the `callback`.
   virtual void Fetch(FetchCompletedCallback callback) = 0;
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher_factory.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher_factory.cc
new file mode 100644
index 0000000..9c503f4
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher_factory.cc
@@ -0,0 +1,43 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher_factory.h"
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher_impl.h"
+
+namespace enterprise_connectors {
+
+namespace {
+
+// Implementation of the WinNetworkFetcherFactory interface.
+class WinNetworkFetcherFactoryImpl : public WinNetworkFetcherFactory {
+ public:
+  WinNetworkFetcherFactoryImpl();
+  ~WinNetworkFetcherFactoryImpl() override;
+
+  std::unique_ptr<WinNetworkFetcher> CreateNetworkFetcher(
+      const GURL& url,
+      const std::string& body,
+      base::flat_map<std::string, std::string> headers) override;
+};
+
+WinNetworkFetcherFactoryImpl::WinNetworkFetcherFactoryImpl() {}
+WinNetworkFetcherFactoryImpl::~WinNetworkFetcherFactoryImpl() = default;
+
+std::unique_ptr<WinNetworkFetcher>
+WinNetworkFetcherFactoryImpl::CreateNetworkFetcher(
+    const GURL& url,
+    const std::string& body,
+    base::flat_map<std::string, std::string> headers) {
+  return std::make_unique<WinNetworkFetcherImpl>(url, body, headers);
+}
+
+}  // namespace
+
+// static
+std::unique_ptr<WinNetworkFetcherFactory> WinNetworkFetcherFactory::Create() {
+  return std::make_unique<WinNetworkFetcherFactoryImpl>();
+}
+
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher_factory.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher_factory.h
new file mode 100644
index 0000000..c70168ba
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher_factory.h
@@ -0,0 +1,37 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_FETCHER_WIN_NETWORK_FETCHER_FACTORY_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_FETCHER_WIN_NETWORK_FETCHER_FACTORY_H_
+
+#include <memory>
+#include <string>
+
+#include "base/containers/flat_map.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher.h"
+
+class GURL;
+
+namespace enterprise_connectors {
+
+// Factory responsible for the creation of the WinNetworkFetcher object.
+class WinNetworkFetcherFactory {
+ public:
+  virtual ~WinNetworkFetcherFactory() = default;
+
+  // Creates a WinNetworkFetcherFactory instance.
+  static std::unique_ptr<WinNetworkFetcherFactory> Create();
+
+  // Creates the WinNetworkFetcher that is used to issue a
+  // DeviceManagementRequest to the DM server using the DM server `url`, HTTP
+  // `headers`, and `body`.
+  virtual std::unique_ptr<WinNetworkFetcher> CreateNetworkFetcher(
+      const GURL& url,
+      const std::string& body,
+      base::flat_map<std::string, std::string> headers) = 0;
+};
+
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_FETCHER_WIN_NETWORK_FETCHER_FACTORY_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.cc
index a348574..040edb9 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.cc
@@ -13,6 +13,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher_factory.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/util.h"
 #include "net/base/backoff_entry.h"
 #include "url/gurl.h"
@@ -34,8 +35,18 @@
 
 }  // namespace
 
+WinKeyNetworkDelegate::WinKeyNetworkDelegate(
+    std::unique_ptr<WinNetworkFetcherFactory> factory)
+    : win_network_fetcher_factory_(std::move(factory)),
+      backoff_entry_(&kBackoffPolicy) {
+  DCHECK(win_network_fetcher_factory_);
+}
+
 WinKeyNetworkDelegate::WinKeyNetworkDelegate()
-    : backoff_entry_(&kBackoffPolicy) {}
+    : win_network_fetcher_factory_(WinNetworkFetcherFactory::Create()),
+      backoff_entry_(&kBackoffPolicy) {
+  DCHECK(win_network_fetcher_factory_);
+}
 
 WinKeyNetworkDelegate::~WinKeyNetworkDelegate() = default;
 
@@ -48,7 +59,8 @@
   DCHECK_EQ(backoff_entry_.failure_count(), 0);
   base::flat_map<std::string, std::string> headers;
   headers.emplace("Authorization", "GoogleDMToken token=" + dm_token);
-  win_network_fetcher_ = WinNetworkFetcher::Create(url, body, headers);
+  win_network_fetcher_ =
+      win_network_fetcher_factory_->CreateNetworkFetcher(url, body, headers);
   UploadKey(std::move(upload_key_completed_callback));
 }
 
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h
index 317917b..de546f4 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h
@@ -17,6 +17,7 @@
 namespace enterprise_connectors {
 
 class WinNetworkFetcher;
+class WinNetworkFetcherFactory;
 
 // Windows implementation of the KeyNetworkDelegate interface.
 class WinKeyNetworkDelegate : public KeyNetworkDelegate {
@@ -34,6 +35,9 @@
  private:
   friend class WinKeyNetworkDelegateTest;
 
+  explicit WinKeyNetworkDelegate(
+      std::unique_ptr<WinNetworkFetcherFactory> factory);
+
   // Makes an upload key request to the windows network fetcher. The
   // `upload_key_completed_callback` will be invoked after the upload request,
   // in the FetchCompleted method.
@@ -43,6 +47,9 @@
   void FetchCompleted(UploadKeyCompletedCallback upload_key_completed_callback,
                       HttpResponseCode response_code);
 
+  // Used for creating the WinNetworkFetcher object.
+  std::unique_ptr<WinNetworkFetcherFactory> win_network_fetcher_factory_;
+
   // Used for issuing network requests via the winhttp network fetcher.
   std::unique_ptr<WinNetworkFetcher> win_network_fetcher_;
 
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate_unittest.cc
index 2e90cccd..b1840f5 100644
--- a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate_unittest.cc
@@ -14,6 +14,7 @@
 #include "base/test/task_environment.h"
 #include "base/test/test_future.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/mock_win_network_fetcher.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/mock_win_network_fetcher_factory.h"
 #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/fetcher/win_network_fetcher.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -24,17 +25,29 @@
 namespace enterprise_connectors {
 
 using test::MockWinNetworkFetcher;
+using test::MockWinNetworkFetcherFactory;
+
 using HttpResponseCode = KeyNetworkDelegate::HttpResponseCode;
 
 namespace {
 
-constexpr char kFakeBody[] = "fake-body";
-constexpr char kFakeDMServerUrl[] =
+constexpr char kFakeBody1[] = "fake-body-1";
+constexpr char kFakeBody2[] = "fake-body-2";
+
+constexpr char kFakeDMServerUrl1[] =
     "https://example.com/"
     "management_service?retry=false&agent=Chrome+1.2.3(456)&apptype=Chrome&"
     "critical=true&deviceid=fake-client-id&devicetype=2&platform=Test%7CUnit%"
     "7C1.2.3&request=browser_public_key_upload";
-constexpr char kFakeDMToken[] = "fake-browser-dm-token";
+constexpr char kFakeDMServerUrl2[] =
+    "https://google.com/"
+    "management_service?retry=false&agent=Chrome+1.2.3(456)&apptype=Chrome&"
+    "critical=true&deviceid=fake-client-id&devicetype=2&platform=Test%7CUnit%"
+    "7C1.2.3&request=browser_public_key_upload";
+
+constexpr char kFakeDMToken1[] = "fake-browser-dm-token-1";
+constexpr char kFakeDMToken2[] = "fake-browser-dm-token-2";
+
 constexpr char kUmaHistogramName[] =
     "Enterprise.DeviceTrust.RotateSigningKey.Tries";
 
@@ -46,43 +59,64 @@
 
 class WinKeyNetworkDelegateTest : public testing::Test {
  protected:
-  void SetNewTestFetcherInstance() {
-    auto mock_win_network_fetcher = std::make_unique<MockWinNetworkFetcher>();
-    mock_win_network_fetcher_ = mock_win_network_fetcher.get();
-    WinNetworkFetcher::SetInstanceForTesting(
-        std::move(mock_win_network_fetcher));
+  void SetUp() override {
+    auto mock_network_fetcher_factory =
+        std::make_unique<MockWinNetworkFetcherFactory>();
+    mock_network_fetcher_factory_ = mock_network_fetcher_factory.get();
+
+    network_delegate_ = absl::WrapUnique(
+        new WinKeyNetworkDelegate(std::move(mock_network_fetcher_factory)));
   }
 
-  // Calls the SendPublicKeyToDmServer function and triggers a number
-  // of retry attempts given by the param `max_retries`.
-  void TestRequest(const HttpResponseCode& response_code, int max_retries) {
-    SetNewTestFetcherInstance();
-
+  // Calls the SendPublicKeyToDmServer function using the test `body`,
+  // `dm_token`, and `dm_server_url`; and triggers a number of retry attempts
+  // given by the param `max_retries`.
+  void TestRequest(const HttpResponseCode& response_code,
+                   int max_retries,
+                   const std::string& test_body,
+                   const std::string& dm_token,
+                   const GURL& dm_server_url) {
     ::testing::InSequence sequence;
-    DCHECK(mock_win_network_fetcher_);
 
-    EXPECT_CALL(*mock_win_network_fetcher_, Fetch(_))
+    auto mock_win_network_fetcher = std::make_unique<MockWinNetworkFetcher>();
+
+    base::flat_map<std::string, std::string> test_headers;
+    test_headers.emplace("Authorization", "GoogleDMToken token=" + dm_token);
+
+    EXPECT_CALL(*mock_network_fetcher_factory_,
+                CreateNetworkFetcher(dm_server_url, test_body, _))
+        .WillOnce([&dm_server_url, &test_body, &test_headers,
+                   &mock_win_network_fetcher](
+                      const GURL& url, const std::string& body,
+                      base::flat_map<std::string, std::string> headers) {
+          EXPECT_EQ(dm_server_url, url);
+          EXPECT_EQ(test_body, body);
+          EXPECT_EQ(test_headers, headers);
+          return std::move(mock_win_network_fetcher);
+        });
+
+    EXPECT_CALL(*mock_win_network_fetcher, Fetch(_))
         .Times(max_retries)
         .WillRepeatedly(
             [this](WinNetworkFetcher::FetchCompletedCallback callback) {
               task_environment_.FastForwardBy(
-                  network_delegate_.backoff_entry_.GetTimeUntilRelease());
+                  network_delegate_->backoff_entry_.GetTimeUntilRelease());
               std::move(callback).Run(kTransientFailureCode);
             });
 
-    EXPECT_CALL(*mock_win_network_fetcher_, Fetch(_))
+    EXPECT_CALL(*mock_win_network_fetcher, Fetch(_))
         .WillOnce([response_code](
                       WinNetworkFetcher::FetchCompletedCallback callback) {
           std::move(callback).Run(response_code);
         });
     base::test::TestFuture<HttpResponseCode> future;
-    network_delegate_.SendPublicKeyToDmServer(
-        GURL(kFakeDMServerUrl), kFakeDMToken, kFakeBody, future.GetCallback());
+    network_delegate_->SendPublicKeyToDmServer(dm_server_url, dm_token,
+                                               test_body, future.GetCallback());
     EXPECT_EQ(response_code, future.Get());
   }
 
-  WinKeyNetworkDelegate network_delegate_;
-  MockWinNetworkFetcher* mock_win_network_fetcher_ = nullptr;
+  MockWinNetworkFetcherFactory* mock_network_fetcher_factory_ = nullptr;
+  std::unique_ptr<WinKeyNetworkDelegate> network_delegate_;
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
 };
@@ -91,7 +125,8 @@
 // before a success. 200 error codes are treated as success.
 TEST_F(WinKeyNetworkDelegateTest, SendPublicKeyRequest_Success) {
   base::HistogramTester histogram_tester;
-  TestRequest(kSuccessCode, 3);
+  TestRequest(kSuccessCode, 3, kFakeBody1, kFakeDMToken1,
+              GURL(kFakeDMServerUrl1));
   histogram_tester.ExpectUniqueSample(kUmaHistogramName, 3, 1);
 }
 
@@ -100,7 +135,8 @@
 // failures.
 TEST_F(WinKeyNetworkDelegateTest, SendPublicKeyRequest_PermanentFailure) {
   base::HistogramTester histogram_tester;
-  TestRequest(kHardFailureCode, 3);
+  TestRequest(kHardFailureCode, 3, kFakeBody1, kFakeDMToken1,
+              GURL(kFakeDMServerUrl1));
   histogram_tester.ExpectUniqueSample(kUmaHistogramName, 3, 1);
 }
 
@@ -108,7 +144,8 @@
 // 500 error codes are treated as transient failures.
 TEST_F(WinKeyNetworkDelegateTest, SendPublicKeyRequest_TransientFailure) {
   base::HistogramTester histogram_tester;
-  TestRequest(kTransientFailureCode, 10);
+  TestRequest(kTransientFailureCode, 10, kFakeBody1, kFakeDMToken1,
+              GURL(kFakeDMServerUrl1));
   histogram_tester.ExpectUniqueSample(kUmaHistogramName, 10, 1);
 }
 
@@ -116,11 +153,12 @@
 // instance is set per request.
 TEST_F(WinKeyNetworkDelegateTest, SendPublicKeyRequest_MulitpleRequests) {
   base::HistogramTester histogram_tester;
-
-  TestRequest(kSuccessCode, 1);
+  TestRequest(kSuccessCode, 1, kFakeBody1, kFakeDMToken1,
+              GURL(kFakeDMServerUrl1));
   histogram_tester.ExpectUniqueSample(kUmaHistogramName, 1, 1);
 
-  TestRequest(kHardFailureCode, 1);
+  TestRequest(kHardFailureCode, 1, kFakeBody2, kFakeDMToken2,
+              GURL(kFakeDMServerUrl2));
   histogram_tester.ExpectUniqueSample(kUmaHistogramName, 1, 2);
 }
 
diff --git a/chrome/browser/extensions/api/messaging/messaging_apitest.cc b/chrome/browser/extensions/api/messaging/messaging_apitest.cc
index 18ca5936..1a416eb 100644
--- a/chrome/browser/extensions/api/messaging/messaging_apitest.cc
+++ b/chrome/browser/extensions/api/messaging/messaging_apitest.cc
@@ -132,10 +132,7 @@
   explicit MessagingApiTest(bool enable_back_forward_cache) {
     if (enable_back_forward_cache) {
       feature_list_.InitWithFeaturesAndParameters(
-          {{features::kBackForwardCache,
-            // The tests does same-site navigation. So same site BFCache needs
-            // to be enabled.
-            {{"enable_same_site", "true"}}},
+          {{features::kBackForwardCache, {}},
            // Allow BackForwardCache for all devices regardless of their memory.
            {features::kBackForwardCacheMemoryControls, {}}},
           {});
diff --git a/chrome/browser/extensions/back_forward_cache_browsertest.cc b/chrome/browser/extensions/back_forward_cache_browsertest.cc
index f550599..3329bab 100644
--- a/chrome/browser/extensions/back_forward_cache_browsertest.cc
+++ b/chrome/browser/extensions/back_forward_cache_browsertest.cc
@@ -48,7 +48,6 @@
            {"extension_message_supported",
             extension_message_support ? "true" : "false"},
            {"TimeToLiveInBackForwardCacheInSeconds", "3600"},
-           {"enable_same_site", "true"},
            {"all_extensions_allowed",
             all_extensions_allowed ? "true" : "false"},
            {"blocked_extensions", blocked_extensions},
diff --git a/chrome/browser/extensions/extension_security_exploit_browsertest.cc b/chrome/browser/extensions/extension_security_exploit_browsertest.cc
index 7f8ed5f..5441a0d 100644
--- a/chrome/browser/extensions/extension_security_exploit_browsertest.cc
+++ b/chrome/browser/extensions/extension_security_exploit_browsertest.cc
@@ -581,30 +581,21 @@
             kill_waiter.Wait());
 }
 
-// Native messaging is not available on Fuchsia (i.e.
-// //chrome/browser/extensions/BUILD.gn excludes
-// api/messaging/native_messaging_test_util.h on Fuchsia).
-#if !(BUILDFLAG(IS_FUCHSIA))
-
-// Test suite for covering ExtensionHostMsg_OpenChannelToNativeApp IPC.
-class OpenChannelToNativeAppExploitTest
-    : public ExtensionSecurityExploitBrowserTest {
+// Test suite for covering a specific kind (TMsg) of IPCs from an extension tab.
+template <typename TMsg>
+class ExtensionTabIpcExploitTest : public ExtensionSecurityExploitBrowserTest {
  public:
-  OpenChannelToNativeAppExploitTest() = default;
+  ExtensionTabIpcExploitTest() = default;
 
-  using OpenChannelMessageWaiter =
-      ExtensionMessageWaiter<ExtensionHostMsg_OpenChannelToNativeApp>;
+  using MessageWaiter = ExtensionMessageWaiter<TMsg>;
   void SetUpOnMainThread() override {
     // Set up ExtensionMessageWaiter *before* installing the extensions (i.e.
     // *before* the corresponding RenderProcessHost objects are created).
-    ipc_message_waiter_ = std::make_unique<OpenChannelMessageWaiter>();
+    ipc_message_waiter_ = std::make_unique<MessageWaiter>();
 
     // SetUpOnMainThread in the base class will install the test extensions.
     ExtensionSecurityExploitBrowserTest::SetUpOnMainThread();
 
-    // Register a (fake, test-only) native messaging host.
-    test_native_messaging_host_.RegisterTestHost(/* user_level= */ false);
-
     // Navigate the test tab to an extension page.
     GURL test_page_url = active_extension().GetResourceURL("page.html");
     EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), test_page_url));
@@ -613,9 +604,8 @@
     int matching_process_id =
         active_web_contents()->GetPrimaryMainFrame()->GetProcess()->GetID();
     ipc_message_waiter_->SetIpcMatcher(base::BindLambdaForTesting(
-        [matching_process_id](
-            int captured_render_process_id,
-            const ExtensionHostMsg_OpenChannelToNativeApp::Param& param) {
+        [matching_process_id](int captured_render_process_id,
+                              const typename TMsg::Param& param) {
           if (captured_render_process_id != matching_process_id)
             return false;
 
@@ -625,13 +615,33 @@
 
   // Waits for ExtensionHostMsg_OpenChannelToNativeApp IPC and returns its
   // payload.
-  ExtensionHostMsg_OpenChannelToNativeApp::Param WaitForMessage() {
+  typename TMsg::Param WaitForMessage() {
     return ipc_message_waiter_->WaitForMessage();
   }
 
  private:
+  std::unique_ptr<MessageWaiter> ipc_message_waiter_;
+};
+
+// Native messaging is not available on Fuchsia (i.e.
+// //chrome/browser/extensions/BUILD.gn excludes
+// api/messaging/native_messaging_test_util.h on Fuchsia).
+#if !(BUILDFLAG(IS_FUCHSIA))
+
+// Test suite for covering ExtensionHostMsg_OpenChannelToNativeApp IPC.
+class OpenChannelToNativeAppExploitTest
+    : public ExtensionTabIpcExploitTest<
+          ExtensionHostMsg_OpenChannelToNativeApp> {
+ public:
+  OpenChannelToNativeAppExploitTest() = default;
+
+  void SetUpOnMainThread() override {
+    ExtensionTabIpcExploitTest::SetUpOnMainThread();
+    test_native_messaging_host_.RegisterTestHost(/* user_level= */ false);
+  }
+
+ private:
   ScopedTestNativeMessagingHost test_native_messaging_host_;
-  std::unique_ptr<OpenChannelMessageWaiter> ipc_message_waiter_;
 };
 
 IN_PROC_BROWSER_TEST_F(OpenChannelToNativeAppExploitTest,
@@ -675,6 +685,43 @@
 
 #endif  // !(BUILDFLAG(IS_FUCHSIA)) - native messaging is available
 
+using OpenChannelToTabExploitTest =
+    ExtensionTabIpcExploitTest<ExtensionHostMsg_OpenChannelToTab>;
+
+IN_PROC_BROWSER_TEST_F(OpenChannelToTabExploitTest, SpoofedExtensionId) {
+  // Trigger sending of a valid ExtensionHostMsg_OpenChannelToTab IPC
+  // from a frame of an `active_extension`.
+  const char kScript[] = R"(
+      const message = {text: 'Hello!'};
+      const tabId = 123;
+      chrome.tabs.sendMessage(tabId, message);
+  )";
+  ASSERT_EQ(
+      active_extension().origin(),
+      active_web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin());
+  ASSERT_TRUE(content::ExecuteScript(active_web_contents(), kScript));
+
+  // Capture the IPC.
+  auto [source_context, info, extension_id, channel_name, port_id] =
+      WaitForMessage();
+  EXPECT_EQ(extension_id, active_extension_id());
+
+  // Mutate the IPC payload.
+  extension_id = spoofed_extension_id();
+
+  // Inject the malformed/mutated IPC and verify that the renderer is terminated
+  // as expected.
+  content::RenderProcessHost* main_frame_process =
+      active_web_contents()->GetPrimaryMainFrame()->GetProcess();
+  RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame_process);
+  IPC::IpcSecurityTestUtil::PwnMessageReceived(
+      main_frame_process->GetChannel(),
+      ExtensionHostMsg_OpenChannelToTab(source_context, info, extension_id,
+                                        channel_name, port_id));
+  EXPECT_EQ(bad_message::EMF_INVALID_EXTENSION_ID_FOR_TAB_MSG,
+            kill_waiter.Wait());
+}
+
 IN_PROC_BROWSER_TEST_F(ExtensionSecurityExploitBrowserTest,
                        SpoofedExtensionId_ExtensionFunctionDispatcher) {
   // Navigate to a test page.
diff --git a/chrome/browser/extensions/lazy_background_page_apitest.cc b/chrome/browser/extensions/lazy_background_page_apitest.cc
index 029528d..73d7ddd 100644
--- a/chrome/browser/extensions/lazy_background_page_apitest.cc
+++ b/chrome/browser/extensions/lazy_background_page_apitest.cc
@@ -622,7 +622,7 @@
   LazyBackgroundPageApiWithBFCacheParamTest() {
     if (IsBackForwardCacheEnabled()) {
       feature_list_.InitWithFeaturesAndParameters(
-          {{features::kBackForwardCache, {{"enable_same_site", "true"}}},
+          {{features::kBackForwardCache, {}},
            // Allow BackForwardCache for all devices regardless of their memory.
            {features::kBackForwardCacheMemoryControls, {}}},
           {});
diff --git a/chrome/browser/fast_checkout/fast_checkout_client.h b/chrome/browser/fast_checkout/fast_checkout_client.h
index 906b7be..11eff53 100644
--- a/chrome/browser/fast_checkout/fast_checkout_client.h
+++ b/chrome/browser/fast_checkout/fast_checkout_client.h
@@ -5,8 +5,14 @@
 #ifndef CHROME_BROWSER_FAST_CHECKOUT_FAST_CHECKOUT_CLIENT_H_
 #define CHROME_BROWSER_FAST_CHECKOUT_FAST_CHECKOUT_CLIENT_H_
 
+#include "base/memory/weak_ptr.h"
+
 class GURL;
 
+namespace autofill {
+class FastCheckoutDelegate;
+}  // namespace autofill
+
 namespace content {
 class WebContents;
 }  // namespace content
@@ -22,7 +28,8 @@
       content::WebContents* web_contents);
 
   // Starts the fast checkout run. Returns true if the run was successful.
-  virtual bool Start(const GURL& url) = 0;
+  virtual bool Start(base::WeakPtr<autofill::FastCheckoutDelegate> delegate,
+                     const GURL& url) = 0;
 
   // Stops the fast checkout run.
   virtual void Stop() = 0;
diff --git a/chrome/browser/fast_checkout/fast_checkout_client_impl.cc b/chrome/browser/fast_checkout/fast_checkout_client_impl.cc
index d4dd31da9..3455840 100644
--- a/chrome/browser/fast_checkout/fast_checkout_client_impl.cc
+++ b/chrome/browser/fast_checkout/fast_checkout_client_impl.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/fast_checkout/fast_checkout_features.h"
 #include "components/autofill/core/browser/data_model/autofill_profile.h"
 #include "components/autofill/core/browser/data_model/credit_card.h"
+#include "components/autofill/core/browser/fast_checkout_delegate.h"
 #include "components/autofill_assistant/browser/public/autofill_assistant_factory.h"
 #include "components/autofill_assistant/browser/public/public_script_parameters.h"
 #include "content/public/browser/web_contents_user_data.h"
@@ -27,7 +28,9 @@
 
 FastCheckoutClientImpl::~FastCheckoutClientImpl() = default;
 
-bool FastCheckoutClientImpl::Start(const GURL& url) {
+bool FastCheckoutClientImpl::Start(
+    base::WeakPtr<autofill::FastCheckoutDelegate> delegate,
+    const GURL& url) {
   if (!base::FeatureList::IsEnabled(features::kFastCheckout))
     return false;
 
@@ -36,6 +39,7 @@
 
   is_running_ = true;
   url_ = url;
+  delegate_ = std::move(delegate);
 
   base::flat_map<std::string, std::string> params_map{
       {autofill_assistant::public_script_parameters::kIntentParameterName,
@@ -58,6 +62,9 @@
       CreateFastCheckoutExternalActionDelegate();
   external_script_controller_ = CreateHeadlessScriptController();
 
+  // TODO(crbug.com/1334642): Stop keyboard and autofill suggestions from
+  // showing.
+
   external_script_controller_->StartScript(
       params_map,
       base::BindOnce(&FastCheckoutClientImpl::OnRunComplete,
@@ -110,14 +117,24 @@
       &GetWebContents(), fast_checkout_external_action_delegate_.get());
 }
 
+void FastCheckoutClientImpl::OnHidden() {
+  // TODO(crbug.com/1334642): Allow keyboard and autofill suggestions from
+  // showing.
+  if (delegate_) {
+    delegate_->OnFastCheckoutUIHidden();
+  }
+}
+
 void FastCheckoutClientImpl::OnOptionsSelected(
     std::unique_ptr<autofill::AutofillProfile> selected_profile,
     std::unique_ptr<autofill::CreditCard> selected_credit_card) {
   fast_checkout_external_action_delegate_->SetOptionsSelected(
       *selected_profile, *selected_credit_card);
+  OnHidden();
 }
 
 void FastCheckoutClientImpl::OnDismiss() {
+  OnHidden();
   Stop();
 }
 
diff --git a/chrome/browser/fast_checkout/fast_checkout_client_impl.h b/chrome/browser/fast_checkout/fast_checkout_client_impl.h
index 508461f..05fe755 100644
--- a/chrome/browser/fast_checkout/fast_checkout_client_impl.h
+++ b/chrome/browser/fast_checkout/fast_checkout_client_impl.h
@@ -25,7 +25,8 @@
   FastCheckoutClientImpl& operator=(const FastCheckoutClientImpl&) = delete;
 
   // FastCheckoutClient:
-  bool Start(const GURL& url) override;
+  bool Start(base::WeakPtr<autofill::FastCheckoutDelegate> delegate,
+             const GURL& url) override;
   void Stop() override;
   bool IsRunning() const override;
 
@@ -53,6 +54,10 @@
  private:
   friend class content::WebContentsUserData<FastCheckoutClientImpl>;
 
+  // Called whenever the surface gets hidden (regardless of the cause). Informs
+  // the Delegate that the surface is now hidden.
+  void OnHidden();
+
   // Registers when a run is complete. Used in callbacks.
   void OnRunComplete(
       autofill_assistant::HeadlessScriptController::ScriptResult result);
@@ -61,6 +66,9 @@
   // ready to run.
   void OnOnboardingCompletedSuccessfully();
 
+  // Delegate for the surface being shown.
+  base::WeakPtr<autofill::FastCheckoutDelegate> delegate_;
+
   // The delegate is responsible for handling protos received from backend DSL
   // actions.
   std::unique_ptr<FastCheckoutExternalActionDelegate>
diff --git a/chrome/browser/fast_checkout/fast_checkout_client_impl_unittest.cc b/chrome/browser/fast_checkout/fast_checkout_client_impl_unittest.cc
index c0c92f4..ea5448d 100644
--- a/chrome/browser/fast_checkout/fast_checkout_client_impl_unittest.cc
+++ b/chrome/browser/fast_checkout/fast_checkout_client_impl_unittest.cc
@@ -12,6 +12,8 @@
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "components/autofill/core/browser/data_model/autofill_profile.h"
 #include "components/autofill/core/browser/data_model/credit_card.h"
+#include "components/autofill/core/browser/fast_checkout_delegate.h"
+#include "components/autofill/core/common/form_field_data.h"
 #include "components/autofill_assistant/browser/public/mock_headless_script_controller.h"
 #include "ui/gfx/native_widget_types.h"
 
@@ -38,6 +40,28 @@
   MOCK_METHOD(gfx::NativeView, GetNativeView, (), (override));
 };
 
+class MockFastCheckoutDelegate : public autofill::FastCheckoutDelegate {
+ public:
+  MockFastCheckoutDelegate() = default;
+  ~MockFastCheckoutDelegate() override = default;
+
+  MOCK_METHOD(bool,
+              TryToShowFastCheckout,
+              (const autofill::FormData&, const autofill::FormFieldData&),
+              (override));
+  MOCK_METHOD(bool, IsShowingFastCheckoutUI, (), (const, override));
+  MOCK_METHOD(void, HideFastCheckoutUI, (), (override));
+  MOCK_METHOD(void, OnFastCheckoutUIHidden, (), (override));
+  MOCK_METHOD(void, Reset, (), (override));
+
+  base::WeakPtr<MockFastCheckoutDelegate> GetWeakPtr() {
+    return weak_factory_.GetWeakPtr();
+  }
+
+ private:
+  base::WeakPtrFactory<MockFastCheckoutDelegate> weak_factory_{this};
+};
+
 class MockFastCheckoutExternalActionDelegate
     : public FastCheckoutExternalActionDelegate {
  public:
@@ -140,6 +164,9 @@
     external_action_delegate_ = external_action_delegate.get();
     test_client_->InjectFastCheckoutExternalActionDelegate(
         std::move(external_action_delegate));
+
+    // Prepare the FastCheckoutDelegate.
+    fast_checkout_delegate_ = std::make_unique<MockFastCheckoutDelegate>();
   }
 
   TestFastCheckoutClientImpl* fast_checkout_client() { return test_client_; }
@@ -153,11 +180,15 @@
     return fast_checkout_controller_;
   }
 
-  MockFastCheckoutExternalActionDelegate* delegate() {
+  MockFastCheckoutExternalActionDelegate* external_action_delegate() {
     return external_action_delegate_;
   }
 
- private:
+  base::WeakPtr<MockFastCheckoutDelegate> delegate() {
+    return fast_checkout_delegate_->GetWeakPtr();
+  }
+
+ protected:
   base::test::ScopedFeatureList feature_list_;
 
   raw_ptr<TestFastCheckoutClientImpl> test_client_;
@@ -165,6 +196,7 @@
       external_script_controller_;
   raw_ptr<MockFastCheckoutController> fast_checkout_controller_;
   raw_ptr<MockFastCheckoutExternalActionDelegate> external_action_delegate_;
+  std::unique_ptr<MockFastCheckoutDelegate> fast_checkout_delegate_;
 };
 
 TEST_F(
@@ -188,8 +220,10 @@
   // Do not expect bottomsheet to show up.
   EXPECT_CALL(*fast_checkout_controller(), Show).Times(0);
 
+  EXPECT_CALL(*delegate(), OnFastCheckoutUIHidden).Times(0);
+
   // Starting is not successful which is also represented by the internal state.
-  EXPECT_FALSE(fast_checkout_client()->Start(GURL(kUrl)));
+  EXPECT_FALSE(fast_checkout_client()->Start(delegate(), GURL(kUrl)));
   EXPECT_FALSE(fast_checkout_client()->IsRunning());
 }
 
@@ -222,13 +256,13 @@
   EXPECT_CALL(*fast_checkout_controller(), Show);
 
   // Starting the run successfully.
-  EXPECT_TRUE(fast_checkout_client()->Start(GURL(kUrl)));
+  EXPECT_TRUE(fast_checkout_client()->Start(delegate(), GURL(kUrl)));
 
   // `FastCheckoutClient` is running.
   EXPECT_TRUE(fast_checkout_client()->IsRunning());
 
   // Cannot start another run.
-  EXPECT_FALSE(fast_checkout_client()->Start(GURL(kUrl)));
+  EXPECT_FALSE(fast_checkout_client()->Start(delegate(), GURL(kUrl)));
 
   // Successful run.
   std::move(onboarding_successful_callback).Run();
@@ -258,13 +292,13 @@
   EXPECT_CALL(*fast_checkout_controller(), Show).Times(0);
 
   // Starting the run successfully.
-  EXPECT_TRUE(fast_checkout_client()->Start(GURL(kUrl)));
+  EXPECT_TRUE(fast_checkout_client()->Start(delegate(), GURL(kUrl)));
 
   // `FastCheckoutClient` is running.
   EXPECT_TRUE(fast_checkout_client()->IsRunning());
 
   // Cannot start another run.
-  EXPECT_FALSE(fast_checkout_client()->Start(GURL(kUrl)));
+  EXPECT_FALSE(fast_checkout_client()->Start(delegate(), GURL(kUrl)));
 
   // Failed run.
   autofill_assistant::HeadlessScriptController::ScriptResult script_result = {
@@ -280,7 +314,7 @@
   EXPECT_FALSE(fast_checkout_client()->IsRunning());
 
   // Starting the run successfully.
-  EXPECT_TRUE(fast_checkout_client()->Start(GURL(kUrl)));
+  EXPECT_TRUE(fast_checkout_client()->Start(delegate(), GURL(kUrl)));
 
   fast_checkout_client()->Stop();
 
@@ -293,7 +327,9 @@
   EXPECT_FALSE(fast_checkout_client()->IsRunning());
 
   // Starting the run successfully.
-  EXPECT_TRUE(fast_checkout_client()->Start(GURL(kUrl)));
+  EXPECT_TRUE(fast_checkout_client()->Start(delegate(), GURL(kUrl)));
+
+  EXPECT_CALL(*delegate(), OnFastCheckoutUIHidden);
 
   fast_checkout_client()->OnDismiss();
 
@@ -303,13 +339,28 @@
 
 TEST_F(FastCheckoutClientImplTest,
        OnOptionsSelected_MovesSelectionsToExternalActionDelegate) {
-  EXPECT_CALL(*delegate(), SetOptionsSelected);
+  EXPECT_CALL(*external_action_delegate(), SetOptionsSelected);
 
   // Starting the run successfully.
-  EXPECT_TRUE(fast_checkout_client()->Start(GURL(kUrl)));
+  EXPECT_TRUE(fast_checkout_client()->Start(delegate(), GURL(kUrl)));
+
+  EXPECT_CALL(*delegate(), OnFastCheckoutUIHidden);
 
   // User selected profile and card in bottomsheet.
   fast_checkout_client()->OnOptionsSelected(
       std::make_unique<autofill::AutofillProfile>(),
       std::make_unique<autofill::CreditCard>());
 }
+
+TEST_F(FastCheckoutClientImplTest, RunsSuccessfullyIfDelegateIsDestroyed) {
+  // `FastCheckoutClient` is not running initially.
+  EXPECT_FALSE(fast_checkout_client()->IsRunning());
+  // Starting the run successfully.
+  EXPECT_TRUE(fast_checkout_client()->Start(delegate(), GURL(kUrl)));
+
+  fast_checkout_delegate_.reset();
+  fast_checkout_client()->OnDismiss();
+
+  // `FastCheckoutClient` is not running anymore.
+  EXPECT_FALSE(fast_checkout_client()->IsRunning());
+}
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index db70994..99c1f875 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -3434,6 +3434,11 @@
     "expiry_milestone": 110
   },
   {
+    "name": "feed-discofeed-endpoint",
+    "owners": [ "//chrome/android/feed/OWNERS", "freedjm@chromium.org" ],
+    "expiry_milestone": 115
+  },
+  {
     "name": "feed-interactive-refresh",
     "owners": [ "//chrome/android/feed/OWNERS", "jianli@chromium.org" ],
     "expiry_milestone": 99
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index f9a4502..1a6b54c5 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -3524,6 +3524,11 @@
 const char kFeedVideoInlinePlaybackDescription[] =
     "Enable playing feed video in inline playback mode.";
 
+const char kFeedDiscoFeedEndpointName[] =
+    "Feed using the DiscoFeed backend endpoint";
+const char kFeedDiscoFeedEndpointDescription[] =
+    "Uses the DiscoFeed endpoint for serving the feed instead of GWS.";
+
 const char kGridTabSwitcherForTabletsName[] = "Grid tab switcher for tablets";
 const char kGridTabSwitcherForTabletsDescription[] =
     "Enable grid tab switcher for tablets, replacing the tab strip.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index a2e0c92a..ca97e6a 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1989,6 +1989,9 @@
 extern const char kFeedVideoInlinePlaybackName[];
 extern const char kFeedVideoInlinePlaybackDescription[];
 
+extern const char kFeedDiscoFeedEndpointName[];
+extern const char kFeedDiscoFeedEndpointDescription[];
+
 extern const char kGridTabSwitcherForTabletsName[];
 extern const char kGridTabSwitcherForTabletsDescription[];
 
diff --git a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
index 2f1785ca..51400174 100644
--- a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
+++ b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
@@ -904,10 +904,8 @@
   ~GetDisplayMediaChangeSourceBrowserTest() override = default;
 
   void SetUpInProcessBrowserTestFixture() override {
-    if (feature_enabled_) {
-      feature_list_.InitWithFeatures(
-          {media::kShareThisTabInsteadButtonGetDisplayMedia}, {});
-    }
+    feature_list_.InitWithFeatureState(
+        media::kShareThisTabInsteadButtonGetDisplayMedia, feature_enabled_);
 
     WebRtcTestBase::SetUpInProcessBrowserTestFixture();
 
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
index fe82aaf..286000db5 100644
--- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
+++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -3925,7 +3925,7 @@
     if (GetParam() == BackForwardCacheStatus::kEnabled) {
       // Enable BackForwardCache.
       feature_list_.InitWithFeaturesAndParameters(
-          {{features::kBackForwardCache, {{"enable_same_site", "true"}}}},
+          {{features::kBackForwardCache, {}}},
           // Allow BackForwardCache for all devices regardless of their memory.
           {features::kBackForwardCacheMemoryControls});
     } else {
diff --git a/chrome/browser/performance_manager/metrics/metrics_provider.h b/chrome/browser/performance_manager/metrics/metrics_provider.h
index ce54dd0..f4ffa00 100644
--- a/chrome/browser/performance_manager/metrics/metrics_provider.h
+++ b/chrome/browser/performance_manager/metrics/metrics_provider.h
@@ -56,12 +56,6 @@
 
   // UserPerformanceTuningManager::Observer:
   void OnBatterySaverModeChanged(bool is_active) override;
-  void OnExternalPowerConnectedChanged(bool external_power_connected) override {
-  }
-  void OnBatteryThresholdReached() override {}
-  void OnMemoryThresholdReached() override {}
-  void OnTabCountThresholdReached() override {}
-  void OnJankThresholdReached() override {}
 
   void OnTuningModesChanged();
   EfficiencyMode ComputeCurrentMode() const;
diff --git a/chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h b/chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h
index 0411967..cc5cf67 100644
--- a/chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h
+++ b/chrome/browser/performance_manager/public/user_tuning/user_performance_tuning_manager.h
@@ -47,7 +47,7 @@
    public:
     // Raised when the battery saver mode interventions are activated or
     // deactivated
-    virtual void OnBatterySaverModeChanged(bool is_active) = 0;
+    virtual void OnBatterySaverModeChanged(bool is_active) {}
 
     // Raised when the device is plugged in or unplugged
     // Can be used by the UI to show a promo if BSM isn't configured to be
@@ -56,24 +56,24 @@
     // enabled/disabled, the state of battery saver will not yet be updated when
     // this is invoked. `OnBatterySaverModeChanged` will be invoked after the
     // state is updated.
-    virtual void OnExternalPowerConnectedChanged(bool on_battery_power) = 0;
+    virtual void OnExternalPowerConnectedChanged(bool on_battery_power) {}
 
     // Raised when the battery has reached the X% threshold
     // Can be used by the UI to show a promo if BSM isn't configured to be
     // enabled when on battery power under a certain threshold.
-    virtual void OnBatteryThresholdReached() = 0;
+    virtual void OnBatteryThresholdReached() {}
 
     // Raised when the total memory footprint reaches X%.
     // Can be used by the UI to show a promo
-    virtual void OnMemoryThresholdReached() = 0;
+    virtual void OnMemoryThresholdReached() {}
 
     // Raised when the tab count reaches X.
     // Can be used by the UI to show a promo
-    virtual void OnTabCountThresholdReached() = 0;
+    virtual void OnTabCountThresholdReached() {}
 
     // Raised when the count of janky intervals reaches X.
     // Can be used by the UI to show a promo
-    virtual void OnJankThresholdReached() = 0;
+    virtual void OnJankThresholdReached() {}
   };
 
   static UserPerformanceTuningManager* GetInstance();
diff --git a/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager_unittest.cc b/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager_unittest.cc
index 7126ce5f..c208826f 100644
--- a/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager_unittest.cc
+++ b/chrome/browser/performance_manager/user_tuning/user_performance_tuning_manager_unittest.cc
@@ -30,14 +30,6 @@
 
   void Quit() { quit_closure_.Run(); }
 
-  // UserPeformanceTuningManager::Observer implementation:
-  void OnBatterySaverModeChanged(bool) override {}
-  void OnExternalPowerConnectedChanged(bool) override {}
-  void OnBatteryThresholdReached() override {}
-  void OnMemoryThresholdReached() override {}
-  void OnTabCountThresholdReached() override {}
-  void OnJankThresholdReached() override {}
-
  private:
   base::RepeatingClosure quit_closure_;
 };
diff --git a/chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service_browsertest.cc b/chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service_browsertest.cc
index 061ef81f..06dd111b 100644
--- a/chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service_browsertest.cc
+++ b/chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service_browsertest.cc
@@ -3005,8 +3005,7 @@
     feature_list_.InitWithFeaturesAndParameters(
         {{kSearchPrefetchServicePrefetching, {{"cache_size", "1"}}},
          {{features::kBackForwardCache},
-          {{"enable_same_site", "true"},
-           {"ignore_outstanding_network_request_for_testing", "true"}}}},
+          {{"ignore_outstanding_network_request_for_testing", "true"}}}},
         // Allow BackForwardCache for all devices regardless of their memory.
         {features::kBackForwardCacheMemoryControls});
   }
diff --git a/chrome/browser/profiles/keep_alive/profile_keep_alive_types.cc b/chrome/browser/profiles/keep_alive/profile_keep_alive_types.cc
index 59062d5..c3a1261f 100644
--- a/chrome/browser/profiles/keep_alive/profile_keep_alive_types.cc
+++ b/chrome/browser/profiles/keep_alive/profile_keep_alive_types.cc
@@ -61,6 +61,8 @@
       return out << "kCommanderFrontend";
     case ProfileKeepAliveOrigin::kDiceWebSigninInterceptionBubble:
       return out << "kDiceWebSigninInterceptionBubble";
+    case ProfileKeepAliveOrigin::kHistoryMenuBridge:
+      return out << "kHistoryMenuBridge";
   }
   NOTREACHED();
   return out << static_cast<int>(origin);
diff --git a/chrome/browser/profiles/keep_alive/profile_keep_alive_types.h b/chrome/browser/profiles/keep_alive/profile_keep_alive_types.h
index 21ff7d8..b5d4d67 100644
--- a/chrome/browser/profiles/keep_alive/profile_keep_alive_types.h
+++ b/chrome/browser/profiles/keep_alive/profile_keep_alive_types.h
@@ -118,7 +118,11 @@
   // UI bubble that may outlive the Browser, especially on Mac.
   kDiceWebSigninInterceptionBubble = 27,
 
-  kMaxValue = kDiceWebSigninInterceptionBubble,
+  // Waiting for History menu entries to populate, so we have
+  // something to show after the profile is destroyed. macOS-specific.
+  kHistoryMenuBridge = 28,
+
+  kMaxValue = kHistoryMenuBridge,
 };
 
 std::ostream& operator<<(std::ostream& out,
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index c0a48974..a9a32c2 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -771,9 +771,11 @@
 
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
   // Listen for bookmark model load, to bootstrap the sync service.
+  // Not necessary for profiles that don't have a BookmarkModel.
   // On CrOS sync service will be initialized after sign in.
   BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(this);
-  model->AddObserver(new BookmarkModelLoadedObserver(this));
+  if (model)
+    model->AddObserver(new BookmarkModelLoadedObserver(this));
 #endif
 
   HeavyAdServiceFactory::GetForBrowserContext(this)->Initialize(GetPath());
diff --git a/chrome/browser/profiles/profile_keyed_service_browsertest.cc b/chrome/browser/profiles/profile_keyed_service_browsertest.cc
index ae956d8..609a047 100644
--- a/chrome/browser/profiles/profile_keyed_service_browsertest.cc
+++ b/chrome/browser/profiles/profile_keyed_service_browsertest.cc
@@ -258,9 +258,7 @@
     "BluetoothPrivateAPI",
     "BluetoothSocketEventDispatcher",
     "BookmarkManagerPrivateAPI",
-    "BookmarkModel",
     "BookmarkSyncServiceFactory",
-    "BookmarkUndoService",
     "BookmarksAPI",
     "BookmarksApiWatcher",
     "BrailleDisplayPrivateAPI",
@@ -323,7 +321,6 @@
     "LiveCaptionController",
     "LoginUIServiceFactory",
     "MDnsAPI",
-    "ManagedBookmarkService",
     "ManagedConfigurationAPI",
     "ManagementAPI",
     "MediaRouter",
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.html
index b82d1b6..6cd90e0 100644
--- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.html
+++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_permissions_setup_dialog.html
@@ -169,7 +169,7 @@
   }
 
   #screen-lock-instruction {
-    align-items: flex-end;
+    align-items: flex-start;
     color: var(--cros-text-color-secondary);
     display: flex;
     flex-direction: row;
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_screen_lock_subpage.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_screen_lock_subpage.html
index 8af3e1e3..d33b0251 100644
--- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_screen_lock_subpage.html
+++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_screen_lock_subpage.html
@@ -87,9 +87,6 @@
         <cr-radio-button id="pinRadioButton" name="pin+password"
             label=$i18n{lockScreenPinOrPassword}>
         </cr-radio-button>
-        <div id="subtext">
-          $i18n{multideviceNotificationAccessSetupScreenLockInstruction}
-        </div>
       </cr-radio-group>
     </template>
   </div>
diff --git a/chrome/browser/resources/side_panel/bookmarks/commerce/icons.html b/chrome/browser/resources/side_panel/bookmarks/commerce/icons.html
index f84556e..50ff016 100644
--- a/chrome/browser/resources/side_panel/bookmarks/commerce/icons.html
+++ b/chrome/browser/resources/side_panel/bookmarks/commerce/icons.html
@@ -6,5 +6,13 @@
         <path d="M12 11.167v-4c0-2.047-1.087-3.76-3-4.214V2.5a1 1 0 1 0-2 0v.453c-1.907.454-3 2.16-3 4.214v4H2.666V12.5h10.667v-1.333H12Zm-1.334 0H5.333v-4c0-1.654 1.007-3 2.667-3s2.666 1.346 2.666 3v4Zm-4 2h2.667c0 .733-.6 1.333-1.333 1.333-.734 0-1.334-.6-1.334-1.333Zm8-6h-1.333c0-1.827-.82-3.46-2.107-4.56l.94-.94a7.313 7.313 0 0 1 2.5 5.5Zm-10.833-5.5.94.94a5.985 5.985 0 0 0-2.107 4.56H1.333c0-2.194.973-4.154 2.5-5.5Z">
         </path>
       </g>
+      <g id="shopping-list-track-icon">
+        <path d="M9.686 4.939C9.25 4.559 8.68 4.333 8 4.333c-1.66 0-2.666 1.346-2.666 3v4h5.333V8.666H12v2.667h1.334v1.333H2.667v-1.333H4v-4c0-2.054 1.094-3.76 3-4.214v-.453c0-.553.447-1 1-1 .554 0 1 .447 1 1v.453c.6.142 1.117.408 1.546.768l-.86 1.052Z"></path>
+        <path d="M9.334 13.333c0 .733-.6 1.333-1.334 1.333-.733 0-1.333-.6-1.333-1.333h2.667Z"></path>
+        <path d="M14 3.333h-1.333v2h-2v1.333h2v2H14v-2h2V5.333h-2v-2Z"></path>
+      </g>
+      <g id="shopping-list-untrack-icon">
+        <path d="M12 7.333v4h1.333v1.333H2.666v-1.333H4v-4c0-2.054 1.093-3.76 3-4.214v-.453c0-.553.446-1 1-1 .553 0 1 .447 1 1v.453c1.913.454 3 2.167 3 4.214Zm-4 7.333c.733 0 1.333-.6 1.333-1.333H6.666c0 .733.6 1.333 1.334 1.333Zm6.666-7.333h-1.333c0-1.827-.82-3.46-2.107-4.56l.94-.94c1.527 1.346 2.5 3.306 2.5 5.5Zm-9.893-4.56-.94-.94c-1.527 1.346-2.5 3.306-2.5 5.5h1.333c0-1.827.82-3.46 2.107-4.56Z"></path>
+      </g>
     </defs>
 </iron-iconset-svg>
\ No newline at end of file
diff --git a/chrome/browser/resources/side_panel/bookmarks/commerce/shopping_list.html b/chrome/browser/resources/side_panel/bookmarks/commerce/shopping_list.html
index 788cf09..88afe57 100644
--- a/chrome/browser/resources/side_panel/bookmarks/commerce/shopping_list.html
+++ b/chrome/browser/resources/side_panel/bookmarks/commerce/shopping_list.html
@@ -107,11 +107,13 @@
   }
 
   .product-item {
+    align-items: center;
     appearance: none;
     background: transparent;
     border: none;
     display: flex;
     height: 76px;
+    justify-content: center;
     padding: 10px 0;
     width: 100%;
   }
@@ -121,6 +123,7 @@
     display: flex;
     height: 100%;
     margin-inline-start: 16px;
+    min-width: 56px;
     width: 56px;
   }
 
@@ -146,6 +149,7 @@
   .product-title {
     color: var(--cr-primary-text-color);
     line-height: 20px;
+    max-width: 100%;
     overflow: hidden;
     text-overflow: ellipsis;
     white-space: nowrap;
@@ -180,6 +184,22 @@
     margin-inline-start: 4px;
     text-decoration: line-through;
   }
+
+  .action-button {
+    background: transparent;
+    margin-inline-end: 16px;
+    margin-inline-start: auto;
+    --cr-icon-button-fill-color: var(--icon-color);
+  }
+
+  .action-button:focus-visible {
+    background-color: var(--mwb-list-item-selected-background-color);
+    box-shadow: none;
+  }
+
+  .action-button:focus {
+    box-shadow: none;
+  }
 </style>
 
 <div id="container" role="treeitem" aria-expanded="[[open_]]">
@@ -224,6 +244,10 @@
             </div>
           </template>
         </div>
+        <cr-icon-button class="action-button" on-click="onActionButtonClick_"
+            iron-icon="[[getIconForItem_(item, untrackedItems_.*)]]"
+            title="[[getButtonDescriptionForItem_(item, untrackedItems_.*)]]">
+        </cr-icon-button>
       </button>
     </template>
   </template>
diff --git a/chrome/browser/resources/side_panel/bookmarks/commerce/shopping_list.ts b/chrome/browser/resources/side_panel/bookmarks/commerce/shopping_list.ts
index 302b81d4..f518887 100644
--- a/chrome/browser/resources/side_panel/bookmarks/commerce/shopping_list.ts
+++ b/chrome/browser/resources/side_panel/bookmarks/commerce/shopping_list.ts
@@ -9,6 +9,7 @@
 import './icons.html.js';
 
 import {getFaviconForPageURL} from 'chrome://resources/js/icon.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {DomRepeatEvent, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {ActionSource} from '../bookmarks.mojom-webui.js';
@@ -16,8 +17,13 @@
 
 import {getTemplate} from './shopping_list.html.js';
 import {BookmarkProductInfo} from './shopping_list.mojom-webui.js';
+import {ShoppingListApiProxy, ShoppingListApiProxyImpl} from './shopping_list_api_proxy.js';
 
 export const LOCAL_STORAGE_EXPAND_STATUS_KEY = 'shoppingListExpanded';
+export const ACTION_BUTTON_TRACK_IMAGE =
+    'shopping-list:shopping-list-track-icon';
+export const ACTION_BUTTON_UNTRACK_IMAGE =
+    'shopping-list:shopping-list-untrack-icon';
 
 export class ShoppingListElement extends PolymerElement {
   static get is() {
@@ -35,14 +41,22 @@
         value: true,
       },
 
+      untrackedItems_: {
+        type: Array,
+        value: [],
+      },
+
       productInfos: Array,
     };
   }
 
   productInfos: BookmarkProductInfo[];
+  private untrackedItems_: BookmarkProductInfo[];
   private open_: boolean;
   private bookmarksApi_: BookmarksApiProxy =
       BookmarksApiProxyImpl.getInstance();
+  private shoppingListApi_: ShoppingListApiProxy =
+      ShoppingListApiProxyImpl.getInstance();
 
   override connectedCallback() {
     super.connectedCallback();
@@ -110,6 +124,32 @@
         event.model.item.bookmarkId!.toString(), event.clientX, event.clientY,
         ActionSource.kPriceTracking);
   }
+
+  private onActionButtonClick_(
+      event: DomRepeatEvent<BookmarkProductInfo, MouseEvent>) {
+    event.preventDefault();
+    event.stopPropagation();
+    const bookmarkId = event.model.item.bookmarkId!;
+    if (this.untrackedItems_.includes(event.model.item)) {
+      const index = this.untrackedItems_.indexOf(event.model.item);
+      this.splice('untrackedItems_', index, 1);
+      this.shoppingListApi_.trackPriceForBookmark(bookmarkId);
+    } else {
+      this.push('untrackedItems_', event.model.item);
+      this.shoppingListApi_.untrackPriceForBookmark(bookmarkId);
+    }
+  }
+
+  private getIconForItem_(item: BookmarkProductInfo): string {
+    return this.untrackedItems_.includes(item) ? ACTION_BUTTON_TRACK_IMAGE :
+                                                 ACTION_BUTTON_UNTRACK_IMAGE;
+  }
+
+  private getButtonDescriptionForItem_(item: BookmarkProductInfo): string {
+    return this.untrackedItems_.includes(item) ?
+        loadTimeData.getString('shoppingListTrackPriceButtonDescription') :
+        loadTimeData.getString('shoppingListUntrackPriceButtonDescription');
+  }
 }
 
 declare global {
diff --git a/chrome/browser/resources/side_panel/bookmarks/commerce/shopping_list_api_proxy.ts b/chrome/browser/resources/side_panel/bookmarks/commerce/shopping_list_api_proxy.ts
index 9b97b8a..37fe6791 100644
--- a/chrome/browser/resources/side_panel/bookmarks/commerce/shopping_list_api_proxy.ts
+++ b/chrome/browser/resources/side_panel/bookmarks/commerce/shopping_list_api_proxy.ts
@@ -8,6 +8,8 @@
 
 export interface ShoppingListApiProxy {
   getAllBookmarkProductInfo(): Promise<{productInfos: BookmarkProductInfo[]}>;
+  trackPriceForBookmark(bookmarkId: bigint): void;
+  untrackPriceForBookmark(bookmarkId: bigint): void;
 }
 
 export class ShoppingListApiProxyImpl implements ShoppingListApiProxy {
@@ -25,6 +27,14 @@
     return this.handler.getAllBookmarkProductInfo();
   }
 
+  trackPriceForBookmark(bookmarkId: bigint) {
+    this.handler.trackPriceForBookmark(bookmarkId);
+  }
+
+  untrackPriceForBookmark(bookmarkId: bigint) {
+    this.handler.untrackPriceForBookmark(bookmarkId);
+  }
+
   static getInstance(): ShoppingListApiProxy {
     return instance || (instance = new ShoppingListApiProxyImpl());
   }
diff --git a/chrome/browser/resources/side_panel/reading_list/app.html b/chrome/browser/resources/side_panel/reading_list/app.html
index 8a37478..334c1ea 100644
--- a/chrome/browser/resources/side_panel/reading_list/app.html
+++ b/chrome/browser/resources/side_panel/reading_list/app.html
@@ -129,16 +129,17 @@
     <div id="empty-state-subheader">[[getEmptyStateSubheaderText_()]]</div>
   </div>
   <cr-button id="currentPageActionButton"
-      hidden$="[[!shouldShowCurrentPageActionButton_()]]"
-      aria-label="$i18n{addCurrentTab}"
+      aria-label="[[getCurrentPageActionButtonText_(
+          currentPageActionButtonState_)]]"
       on-click="onCurrentPageActionButtonClick_"
       disabled="[[getCurrentPageActionButtonDisabled_(
           currentPageActionButtonState_)]]">
     <iron-icon id="currentPageActionButtonIcon" aria-hidden="true"
-        icon="cr:add">
+      icon="[[getCurrentPageActionButtonIcon_(
+          currentPageActionButtonState_)]]">
     </iron-icon>
     <div id="currentPageActionButtonText" aria-hidden="true">
-      $i18n{addCurrentTab}
+      [[getCurrentPageActionButtonText_(currentPageActionButtonState_)]]
     </div>
   </cr-button>
   <div id="readingListList">
diff --git a/chrome/browser/resources/side_panel/reading_list/app.ts b/chrome/browser/resources/side_panel/reading_list/app.ts
index 0f5e9952..2745de2 100644
--- a/chrome/browser/resources/side_panel/reading_list/app.ts
+++ b/chrome/browser/resources/side_panel/reading_list/app.ts
@@ -182,6 +182,28 @@
   }
 
   /**
+   * @return The appropriate text for the current page action button
+   */
+  private getCurrentPageActionButtonText_(): string {
+    if (this.getCurrentPageActionButtonMarkAsRead_()) {
+      return loadTimeData.getString('markCurrentTabAsRead');
+    } else {
+      return loadTimeData.getString('addCurrentTab');
+    }
+  }
+
+  /**
+   * @return The appropriate cr icon for the current page action button
+   */
+  private getCurrentPageActionButtonIcon_(): string {
+    if (this.getCurrentPageActionButtonMarkAsRead_()) {
+      return 'cr:check';
+    } else {
+      return 'cr:add';
+    }
+  }
+
+  /**
    * @return Whether the current page action button should be disabled
    */
   private getCurrentPageActionButtonDisabled_(): boolean {
@@ -189,12 +211,25 @@
         CurrentPageActionButtonState.kDisabled;
   }
 
+  /**
+   * @return Whether the current page action button should be in its mark as
+   * read state
+   */
+  private getCurrentPageActionButtonMarkAsRead_(): boolean {
+    return this.currentPageActionButtonState_ ===
+        CurrentPageActionButtonState.kMarkAsRead;
+  }
+
   private isReadingListEmpty_(): boolean {
     return this.unreadItems_.length === 0 && this.readItems_.length === 0;
   }
 
   private onCurrentPageActionButtonClick_() {
-    this.apiProxy_.addCurrentTab();
+    if (this.getCurrentPageActionButtonMarkAsRead_()) {
+      this.apiProxy_.markCurrentTabAsRead();
+    } else {
+      this.apiProxy_.addCurrentTab();
+    }
   }
 
   private onItemKeyDown_(e: KeyboardEvent) {
diff --git a/chrome/browser/resources/side_panel/reading_list/reading_list_api_proxy.ts b/chrome/browser/resources/side_panel/reading_list/reading_list_api_proxy.ts
index cce54e1..3745407 100644
--- a/chrome/browser/resources/side_panel/reading_list/reading_list_api_proxy.ts
+++ b/chrome/browser/resources/side_panel/reading_list/reading_list_api_proxy.ts
@@ -15,6 +15,8 @@
 
   updateReadStatus(url: Url, read: boolean): void;
 
+  markCurrentTabAsRead(): void;
+
   addCurrentTab(): void;
 
   removeEntry(url: Url): void;
@@ -57,6 +59,10 @@
     this.handler.updateReadStatus(url, read);
   }
 
+  markCurrentTabAsRead() {
+    this.handler.markCurrentTabAsRead();
+  }
+
   addCurrentTab() {
     this.handler.addCurrentTab();
   }
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
index bb0ef2e..4a59064 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
@@ -1128,8 +1128,7 @@
                 GetWebContents,
             base::Unretained(this))) {
     std::vector<base::test::ScopedFeatureList::FeatureAndParams>
-        additional_features = {
-            {features::kBackForwardCache, {{"enable_same_site", "true"}}}};
+        additional_features = {{features::kBackForwardCache, {}}};
     scoped_feature_list_.InitWithFeaturesAndParameters(
         content::DefaultEnabledBackForwardCacheParametersForTests(
             additional_features),
diff --git a/chrome/browser/speech/on_device_speech_recognizer.cc b/chrome/browser/speech/on_device_speech_recognizer.cc
index efb436c0..5601df5 100644
--- a/chrome/browser/speech/on_device_speech_recognizer.cc
+++ b/chrome/browser/speech/on_device_speech_recognizer.cc
@@ -39,10 +39,10 @@
     int sample_rate = params->sample_rate();
     int frames_per_buffer = std::max(params->frames_per_buffer(),
                                      sample_rate / kPollingTimesPerSecond);
-    media::ChannelLayout channel_layout = is_multichannel_supported
-                                              ? params->channel_layout()
-                                              : media::CHANNEL_LAYOUT_MONO;
-    result.Reset(params->format(), channel_layout, sample_rate,
+    media::ChannelLayoutConfig channel_layout_config =
+        is_multichannel_supported ? params->channel_layout_config()
+                                  : media::ChannelLayoutConfig::Mono();
+    result.Reset(params->format(), channel_layout_config, sample_rate,
                  frames_per_buffer);
     return result;
   }
@@ -51,8 +51,8 @@
                 "Audio sample rate is not divisible by 100");
   return media::AudioParameters(
       media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-      is_multichannel_supported ? media::CHANNEL_LAYOUT_STEREO
-                                : media::CHANNEL_LAYOUT_MONO,
+      is_multichannel_supported ? media::ChannelLayoutConfig::Stereo()
+                                : media::ChannelLayoutConfig::Mono(),
       kAudioSampleRate, kAudioSampleRate / kPollingTimesPerSecond);
 }
 
diff --git a/chrome/browser/speech/on_device_speech_recognizer_browsertest.cc b/chrome/browser/speech/on_device_speech_recognizer_browsertest.cc
index 3c57417..3ebfd73 100644
--- a/chrome/browser/speech/on_device_speech_recognizer_browsertest.cc
+++ b/chrome/browser/speech/on_device_speech_recognizer_browsertest.cc
@@ -258,7 +258,7 @@
   int sample_rate = 10000;
   media::AudioParameters params(
       media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-      media::CHANNEL_LAYOUT_STEREO, sample_rate,
+      media::ChannelLayoutConfig::Stereo(), sample_rate,
       sample_rate / (kDefaultPollingTimesPerSecond / 2));
   ConstructRecognizerAndWaitForReady();
   StartListeningWithAudioParams(params);
@@ -275,7 +275,7 @@
   int sample_rate = 20000;
   media::AudioParameters params(
       media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-      media::CHANNEL_LAYOUT_STEREO, sample_rate,
+      media::ChannelLayoutConfig::Stereo(), sample_rate,
       sample_rate / (kDefaultPollingTimesPerSecond * 2));
   ConstructRecognizerAndWaitForReady();
   StartListeningWithAudioParams(params);
@@ -296,7 +296,8 @@
   fake_service_->set_multichannel_supported(false);
   int sample_rate = 20000;
   media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-                                media::CHANNEL_LAYOUT_STEREO, sample_rate,
+                                media::ChannelLayoutConfig::Stereo(),
+                                sample_rate,
                                 sample_rate / kDefaultPollingTimesPerSecond);
   ConstructRecognizerAndWaitForReady();
   StartListeningWithAudioParams(params);
diff --git a/chrome/browser/sync/test/integration/workspace_desk_helper.cc b/chrome/browser/sync/test/integration/workspace_desk_helper.cc
index ed7f8ed..fdfed78 100644
--- a/chrome/browser/sync/test/integration/workspace_desk_helper.cc
+++ b/chrome/browser/sync/test/integration/workspace_desk_helper.cc
@@ -48,7 +48,7 @@
 }
 
 void DeskUuidChecker::EntriesRemovedRemotely(
-    const std::vector<std::string>& uuids) {
+    const std::vector<base::GUID>& uuids) {
   CheckExitCondition();
 }
 
@@ -88,7 +88,7 @@
 }
 
 void DeskUuidDeletedChecker::EntriesRemovedRemotely(
-    const std::vector<std::string>& uuids) {
+    const std::vector<base::GUID>& uuids) {
   CheckExitCondition();
 }
 
@@ -119,7 +119,7 @@
 }
 
 void DeskModelReadyChecker::EntriesRemovedRemotely(
-    const std::vector<std::string>& uuids) {
+    const std::vector<base::GUID>& uuids) {
   CheckExitCondition();
 }
 
diff --git a/chrome/browser/sync/test/integration/workspace_desk_helper.h b/chrome/browser/sync/test/integration/workspace_desk_helper.h
index d6ebc37..aa39d17 100644
--- a/chrome/browser/sync/test/integration/workspace_desk_helper.h
+++ b/chrome/browser/sync/test/integration/workspace_desk_helper.h
@@ -5,7 +5,6 @@
 #ifndef CHROME_BROWSER_SYNC_TEST_INTEGRATION_WORKSPACE_DESK_HELPER_H_
 #define CHROME_BROWSER_SYNC_TEST_INTEGRATION_WORKSPACE_DESK_HELPER_H_
 
-#include <string>
 #include <vector>
 
 #include "base/guid.h"
@@ -38,10 +37,10 @@
   void DeskModelLoaded() override;
   void EntriesAddedOrUpdatedRemotely(
       const std::vector<const ash::DeskTemplate*>& new_entries) override;
-  void EntriesRemovedRemotely(const std::vector<std::string>& uuids) override;
+  void EntriesRemovedRemotely(const std::vector<base::GUID>& uuids) override;
   void EntriesAddedOrUpdatedLocally(
       const std::vector<const ash::DeskTemplate*>& new_entries) override {}
-  void EntriesRemovedLocally(const std::vector<std::string>& uuids) override {}
+  void EntriesRemovedLocally(const std::vector<base::GUID>& uuids) override {}
 
  private:
   const base::GUID uuid_;
@@ -68,10 +67,10 @@
   void DeskModelLoaded() override;
   void EntriesAddedOrUpdatedRemotely(
       const std::vector<const ash::DeskTemplate*>& new_entries) override;
-  void EntriesRemovedRemotely(const std::vector<std::string>& uuids) override;
+  void EntriesRemovedRemotely(const std::vector<base::GUID>& uuids) override;
   void EntriesAddedOrUpdatedLocally(
       const std::vector<const ash::DeskTemplate*>& new_entries) override {}
-  void EntriesRemovedLocally(const std::vector<std::string>& uuids) override {}
+  void EntriesRemovedLocally(const std::vector<base::GUID>& uuids) override {}
 
  private:
   const base::GUID uuid_;
@@ -96,10 +95,10 @@
   void DeskModelLoaded() override;
   void EntriesAddedOrUpdatedRemotely(
       const std::vector<const ash::DeskTemplate*>& new_entries) override;
-  void EntriesRemovedRemotely(const std::vector<std::string>& uuids) override;
+  void EntriesRemovedRemotely(const std::vector<base::GUID>& uuids) override;
   void EntriesAddedOrUpdatedLocally(
       const std::vector<const ash::DeskTemplate*>& new_entries) override {}
-  void EntriesRemovedLocally(const std::vector<std::string>& uuids) override {}
+  void EntriesRemovedLocally(const std::vector<base::GUID>& uuids) override {}
 
  private:
   desks_storage::DeskSyncService* const service_;
diff --git a/chrome/browser/sync_file_system/local/local_file_change_tracker.cc b/chrome/browser/sync_file_system/local/local_file_change_tracker.cc
index 867cbf1..f7a53b3 100644
--- a/chrome/browser/sync_file_system/local/local_file_change_tracker.cc
+++ b/chrome/browser/sync_file_system/local/local_file_change_tracker.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/sync_file_system/local/local_file_change_tracker.h"
 
 #include <stddef.h>
+#include <memory>
 #include <utility>
 
 #include "base/containers/circular_deque.h"
@@ -81,10 +82,9 @@
     base::SequencedTaskRunner* file_task_runner)
     : initialized_(false),
       file_task_runner_(file_task_runner),
-      tracker_db_(new TrackerDB(base_path, env_override)),
+      tracker_db_(std::make_unique<TrackerDB>(base_path, env_override)),
       current_change_seq_number_(0),
-      num_changes_(0) {
-}
+      num_changes_(0) {}
 
 LocalFileChangeTracker::~LocalFileChangeTracker() {
   DCHECK(file_task_runner_->RunsTasksInCurrentSequence());
@@ -279,7 +279,7 @@
 void LocalFileChangeTracker::ResetForFileSystem(const GURL& origin,
                                                 storage::FileSystemType type) {
   DCHECK(file_task_runner_->RunsTasksInCurrentSequence());
-  std::unique_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
+  auto batch = std::make_unique<leveldb::WriteBatch>();
   for (auto iter = changes_.begin(); iter != changes_.end();) {
     storage::FileSystemURL url = iter->first;
     int change_seq = iter->second.change_seq;
diff --git a/chrome/browser/task_manager/providers/web_contents/devtools_tag_browsertest.cc b/chrome/browser/task_manager/providers/web_contents/devtools_tag_browsertest.cc
index ddedbe5..9ad0824 100644
--- a/chrome/browser/task_manager/providers/web_contents/devtools_tag_browsertest.cc
+++ b/chrome/browser/task_manager/providers/web_contents/devtools_tag_browsertest.cc
@@ -128,12 +128,10 @@
   }
   EXPECT_NE(task_manager.tasks()[0]->title(),
             task_manager.tasks()[1]->title());
-  // If same-site back-forward cache is enabled, the task for the previous page
+  // If back/forward cache is enabled, the task for the previous page
   // will still be around.
   EXPECT_EQ(
-      content::BackForwardCache::IsSameSiteBackForwardCacheFeatureEnabled()
-          ? 3U
-          : 2U,
+      content::BackForwardCache::IsBackForwardCacheFeatureEnabled() ? 3U : 2U,
       task_manager.tasks().size());
 
   // Close the DevTools window.
@@ -141,9 +139,7 @@
   EXPECT_EQ(1U, tags_manager()->tracked_tags().size());
 
   EXPECT_EQ(
-      content::BackForwardCache::IsSameSiteBackForwardCacheFeatureEnabled()
-          ? 2U
-          : 1U,
+      content::BackForwardCache::IsBackForwardCacheFeatureEnabled() ? 2U : 1U,
       task_manager.tasks().size());
 }
 
diff --git a/chrome/browser/task_manager/providers/web_contents/subframe_task_browsertest.cc b/chrome/browser/task_manager/providers/web_contents/subframe_task_browsertest.cc
index 7eef369b..718eb54 100644
--- a/chrome/browser/task_manager/providers/web_contents/subframe_task_browsertest.cc
+++ b/chrome/browser/task_manager/providers/web_contents/subframe_task_browsertest.cc
@@ -137,14 +137,12 @@
   NavigateTo(kSimplePageUrl);
 
   ASSERT_EQ(
-      content::BackForwardCache::IsSameSiteBackForwardCacheFeatureEnabled()
-          ? 4U
-          : 1U,
+      content::BackForwardCache::IsBackForwardCacheFeatureEnabled() ? 4U : 1U,
       task_manager.tasks().size());
 
   const auto& tasks = task_manager.tasks();
   // Main page and two cross-origin iframes.
-  if (content::BackForwardCache::IsSameSiteBackForwardCacheFeatureEnabled()) {
+  if (content::BackForwardCache::IsBackForwardCacheFeatureEnabled()) {
     EXPECT_EQ(
         PrefixExpectedBFCacheTitle("http://a.com/", /*is_subframe=*/false),
         tasks[0]->title());
diff --git a/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc b/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc
index 500413a..800208a 100644
--- a/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc
+++ b/chrome/browser/task_manager/providers/web_contents/tab_contents_tag_browsertest.cc
@@ -330,8 +330,8 @@
     // When ProactivelySwapBrowsingInstance or RenderDocument is enabled on
     // same-site main frame navigations, we'll get a new task because we are
     // changing RenderFrameHosts. Note that the previous page's task might still
-    // be around if the previous page is saved in the back-forward cache.
-    if (content::BackForwardCache::IsSameSiteBackForwardCacheFeatureEnabled()) {
+    // be around if the previous page is saved in the back/forward cache.
+    if (content::BackForwardCache::IsBackForwardCacheFeatureEnabled()) {
       ASSERT_EQ(2U, task_manager.tasks().size());
       ASSERT_EQ(
           l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_BACK_FORWARD_CACHE_PREFIX,
diff --git a/chrome/browser/task_manager/task_manager_browsertest.cc b/chrome/browser/task_manager/task_manager_browsertest.cc
index 3414196..2ba63a3 100644
--- a/chrome/browser/task_manager/task_manager_browsertest.cc
+++ b/chrome/browser/task_manager/task_manager_browsertest.cc
@@ -1473,8 +1473,7 @@
         /*enabled_features=*/
         {
             {features::kBackForwardCache,
-             {{"enable_same_site", "true"},
-              {"TimeToLiveInBackForwardCacheInSeconds", "3600"}}},
+             {{"TimeToLiveInBackForwardCacheInSeconds", "3600"}}},
             {features::kOmniboxTriggerForPrerender2, {}},
         },
         /*disabled_features=*/{});
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index f55204d..c8980fd 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1800,6 +1800,7 @@
       "//components/commerce/content/browser:hint",
       "//components/commerce/core:cart_db_content_proto",
       "//components/commerce/core:feature_list",
+      "//components/commerce/core:shopping_service",
       "//components/commerce/core/mojom:mojo_bindings",
       "//components/commerce/core/webui",
       "//components/enterprise/common:download_item_reroute_info",
diff --git a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
index 7b879f5..2eee6c99 100644
--- a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
+++ b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
@@ -31,6 +31,7 @@
 #include "ash/wm/overview/overview_test_util.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/containers/contains.h"
 #include "base/guid.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
@@ -198,17 +199,10 @@
 // Search `desk_templates` for a template with `uuid` and returns true if found,
 // false if not.
 bool ContainUuidInTemplates(
-    const std::string& uuid,
+    const base::GUID& uuid,
     const std::vector<const ash::DeskTemplate*>& desk_templates) {
-  base::GUID guid = base::GUID::ParseCaseInsensitive(uuid);
-  DCHECK(guid.is_valid());
-
-  for (auto* desk_template : desk_templates) {
-    if (desk_template->uuid() == guid)
-      return true;
-  }
-
-  return false;
+  DCHECK(uuid.is_valid());
+  return base::Contains(desk_templates, uuid, &ash::DeskTemplate::uuid);
 }
 
 std::string GetTemplateJson(const base::GUID& uuid, Profile* profile) {
@@ -2887,19 +2881,20 @@
                        SetAndClearAdminTemplates) {
   EXPECT_TRUE(DesksClient::Get());
 
+  base::GUID admin_template_uuid =
+      base::GUID::ParseCaseInsensitive(kTestAdminTemplateUuid);
+
   // Set an admin template policy.
   DesksClient::Get()->SetPolicyPreconfiguredTemplate(
       account_id1_, std::make_unique<std::string>(base::StringPrintf(
                         kTestAdminTemplateFormat, kTestAdminTemplateUuid)));
 
   // Verify that the admin templates is present.
-  EXPECT_TRUE(
-      ContainUuidInTemplates(kTestAdminTemplateUuid, GetDeskTemplates()));
+  EXPECT_TRUE(ContainUuidInTemplates(admin_template_uuid, GetDeskTemplates()));
 
   // Clear admin templates.
   DesksClient::Get()->RemovePolicyPreconfiguredTemplate(account_id1_);
 
   // Verify that the admin templates is removed.
-  EXPECT_FALSE(
-      ContainUuidInTemplates(kTestAdminTemplateUuid, GetDeskTemplates()));
+  EXPECT_FALSE(ContainUuidInTemplates(admin_template_uuid, GetDeskTemplates()));
 }
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc
index 6dff77f..f1b32f6 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.cc
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -23,6 +23,9 @@
 #include "chrome/browser/autofill/risk_util.h"
 #include "chrome/browser/autofill/strike_database_factory.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher.h"
+#include "chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_factory.h"
+#include "chrome/browser/fast_checkout/fast_checkout_features.h"
 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
 #include "chrome/browser/password_manager/password_manager_settings_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
@@ -62,6 +65,7 @@
 #include "components/autofill/core/common/autofill_payments_features.h"
 #include "components/autofill/core/common/autofill_prefs.h"
 #include "components/autofill/core/common/autofill_switches.h"
+#include "components/autofill_assistant/browser/features.h"
 #include "components/autofill_assistant/browser/public/runtime_manager.h"
 #include "components/password_manager/content/browser/content_password_manager_driver.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
@@ -678,29 +682,68 @@
 }
 
 bool ChromeAutofillClient::IsFastCheckoutSupported() {
-  // TODO(crbug.com/1334642): Implement.
-  NOTIMPLEMENTED();
+#if BUILDFLAG(IS_ANDROID)
+  if (!base::FeatureList::IsEnabled(::features::kFastCheckout)) {
+    return false;
+  }
+
+  if (!GetPersonalDataManager()->IsAutofillProfileEnabled() ||
+      !GetPersonalDataManager()->IsAutofillCreditCardEnabled()) {
+    return false;
+  }
+
+  // TODO(crbug.com/1334642): Check that the assistant settings flag is on.
+
+  return base::FeatureList::IsEnabled(
+      autofill_assistant::features::kAutofillAssistant);
+
+#else
   return false;
+#endif
 }
 
 bool ChromeAutofillClient::IsFastCheckoutTriggerForm(
     const FormData& form,
     const FormFieldData& field) {
-  // TODO(crbug.com/1334642): Implement.
-  NOTIMPLEMENTED();
+#if BUILDFLAG(IS_ANDROID)
+  FastCheckoutCapabilitiesFetcher* fetcher =
+      FastCheckoutCapabilitiesFetcherFactory::GetForBrowserContext(
+          GetProfile());
+
+  // TODO(crbug.com/1356498): Stop calculating the signature once the form
+  // signature has been moved to `form_data`.
+  // Check browser form's signature and renderer form's signature.
+  return fetcher->IsTriggerFormSupported(form.main_frame_origin,
+                                         CalculateFormSignature(form)) ||
+         fetcher->IsTriggerFormSupported(form.main_frame_origin,
+                                         field.host_form_signature);
+#else
+  NOTREACHED();
   return false;
+#endif
 }
 
 bool ChromeAutofillClient::ShowFastCheckout(
     base::WeakPtr<FastCheckoutDelegate> delegate) {
-  // TODO(crbug.com/1334642): Implement.
-  NOTIMPLEMENTED();
+#if BUILDFLAG(IS_ANDROID)
+  if (delegate->IsShowingFastCheckoutUI()) {
+    return false;
+  }
+
+  return FastCheckoutClient::GetOrCreateForWebContents(web_contents())
+      ->Start(delegate, web_contents()->GetLastCommittedURL());
+#else
+  NOTREACHED();
   return false;
+#endif
 }
 
 void ChromeAutofillClient::HideFastCheckout() {
-  // TODO(crbug.com/1334642): Implement.
-  NOTIMPLEMENTED();
+#if BUILDFLAG(IS_ANDROID)
+  FastCheckoutClient::GetOrCreateForWebContents(web_contents())->Stop();
+#else
+  NOTREACHED();
+#endif
 }
 
 bool ChromeAutofillClient::IsTouchToFillCreditCardSupported() {
diff --git a/chrome/browser/ui/bookmarks/bookmark_browsertest.cc b/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
index 7f699eee..1a3c078 100644
--- a/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
+++ b/chrome/browser/ui/bookmarks/bookmark_browsertest.cc
@@ -595,40 +595,40 @@
   // The total number of bookmarks is 7, but it gets rounded down due to
   // bucketing.
   ASSERT_THAT(
-      histogram_tester()->GetAllSamples("Bookmarks.Count.OnProfileLoad"),
+      histogram_tester()->GetAllSamples("Bookmarks.Count.OnProfileLoad3"),
       testing::ElementsAre(base::Bucket(/*min=*/6, /*count=*/1)));
 
   // 2 bookmarks have URL http://b.com and 4 have http://c.com. This counts as 4
   // duplicates.
   EXPECT_THAT(histogram_tester()->GetAllSamples(
-                  "Bookmarks.Count.OnProfileLoad.DuplicateUrl2"),
+                  "Bookmarks.Count.OnProfileLoad.DuplicateUrl3"),
               testing::ElementsAre(base::Bucket(/*min=*/4, /*count=*/1)));
   // 3 bookmarks have the pair (http://c.com, title5). This counts as 2
   // duplicates when considering URLs and titles.
   EXPECT_THAT(histogram_tester()->GetAllSamples(
-                  "Bookmarks.Count.OnProfileLoad.DuplicateUrlAndTitle"),
+                  "Bookmarks.Count.OnProfileLoad.DuplicateUrlAndTitle3"),
               testing::ElementsAre(base::Bucket(/*min=*/2, /*count=*/1)));
   // Among the three above, only two have the same parent. This means only one
   // counts as duplicate when considering all three attributes.
   EXPECT_THAT(
       histogram_tester()->GetAllSamples(
-          "Bookmarks.Count.OnProfileLoad.DuplicateUrlAndTitleAndParent"),
+          "Bookmarks.Count.OnProfileLoad.DuplicateUrlAndTitleAndParent3"),
       testing::ElementsAre(base::Bucket(/*min=*/1, /*count=*/1)));
 
   // The remaining histograms are the result of substracting the number of
   // duplicates from the total, which is 7 despite the bucket for the first
   // histogram above suggesting 6.
   EXPECT_THAT(histogram_tester()->GetAllSamples(
-                  "Bookmarks.Count.OnProfileLoad.UniqueUrl"),
+                  "Bookmarks.Count.OnProfileLoad.UniqueUrl3"),
               testing::ElementsAre(base::Bucket(/*min=*/3, /*count=*/1)));
   EXPECT_THAT(histogram_tester()->GetAllSamples(
-                  "Bookmarks.Count.OnProfileLoad.UniqueUrlAndTitle"),
+                  "Bookmarks.Count.OnProfileLoad.UniqueUrlAndTitle3"),
               testing::ElementsAre(base::Bucket(/*min=*/5, /*count=*/1)));
   EXPECT_THAT(histogram_tester()->GetAllSamples(
-                  "Bookmarks.Count.OnProfileLoad.UniqueUrlAndTitleAndParent"),
+                  "Bookmarks.Count.OnProfileLoad.UniqueUrlAndTitleAndParent3"),
               testing::ElementsAre(base::Bucket(/*min=*/6, /*count=*/1)));
   EXPECT_THAT(histogram_tester()->GetAllSamples(
-                  "Bookmarks.Times.OnProfileLoad.TimeSinceAdded"),
+                  "Bookmarks.Times.OnProfileLoad.TimeSinceAdded3"),
               testing::ElementsAre(base::Bucket(/*min=*/0, /*count=*/1)));
 }
 
diff --git a/chrome/browser/ui/browser_command_controller_unittest.cc b/chrome/browser/ui/browser_command_controller_unittest.cc
index 62e795d..1b87d4318 100644
--- a/chrome/browser/ui/browser_command_controller_unittest.cc
+++ b/chrome/browser/ui/browser_command_controller_unittest.cc
@@ -291,6 +291,7 @@
       const GURL& url,
       ExclusiveAccessBubbleType bubble_type,
       ExclusiveAccessBubbleHideCallback bubble_first_hide_callback,
+      bool notify_download,
       bool force_update) override {}
   bool IsExclusiveAccessBubbleDisplayed() const override { return false; }
   void OnExclusiveAccessUserInput() override {}
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm
index 85b9b1cb..5cee6f10 100644
--- a/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm
+++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.mm
@@ -58,7 +58,6 @@
   DCHECK(![menu_root_ delegate]);
   [menu_root_ setDelegate:controller_];
 
-  DCHECK(GetBookmarkModel());
   ObserveBookmarkModel();
 }
 
@@ -66,7 +65,6 @@
   ClearBookmarkMenu();
   [menu_root_ setDelegate:nil];
   BookmarkModel* model = GetBookmarkModel();
-  DCHECK(model);
   if (model)
     model->RemoveObserver(this);
 }
@@ -201,6 +199,11 @@
 // Watch for changes.
 void BookmarkMenuBridge::ObserveBookmarkModel() {
   BookmarkModel* model = GetBookmarkModel();
+
+  // In Guest mode, there is no bookmark model.
+  if (!model)
+    return;
+
   model->AddObserver(this);
   if (model->loaded())
     BookmarkModelLoaded(model, false);
diff --git a/chrome/browser/ui/cocoa/history_menu_bridge.h b/chrome/browser/ui/cocoa/history_menu_bridge.h
index 45a99927..f7cf810 100644
--- a/chrome/browser/ui/cocoa/history_menu_bridge.h
+++ b/chrome/browser/ui/cocoa/history_menu_bridge.h
@@ -5,17 +5,19 @@
 #ifndef CHROME_BROWSER_UI_COCOA_HISTORY_MENU_BRIDGE_H_
 #define CHROME_BROWSER_UI_COCOA_HISTORY_MENU_BRIDGE_H_
 
-#include "base/memory/raw_ptr.h"
-
 #import <Cocoa/Cocoa.h>
 #include <map>
 #include <memory>
 #include <vector>
 
 #include "base/mac/scoped_nsobject.h"
+#include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
 #include "base/task/cancelable_task_tracker.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/profiles/profile_manager_observer.h"
 #import "chrome/browser/ui/cocoa/main_menu_item.h"
 #import "components/favicon/core/favicon_service.h"
 #include "components/history/core/browser/history_service.h"
@@ -25,10 +27,12 @@
 #include "components/sessions/core/tab_restore_service_observer.h"
 
 class Profile;
+class ScopedProfileKeepAlive;
 @class HistoryMenuCocoaController;
 
 namespace {
 class HistoryMenuBridgeTest;
+class HistoryMenuBridgeLifetimeTest;
 }
 
 namespace favicon_base {
@@ -59,7 +63,8 @@
 // class does the bulk of the work.
 class HistoryMenuBridge : public sessions::TabRestoreServiceObserver,
                           public MainMenuItem,
-                          public history::HistoryServiceObserver {
+                          public history::HistoryServiceObserver,
+                          public ProfileManagerObserver {
  public:
   // This is a generalization of the data we store in the history menu because
   // we pull things from different sources with different data types.
@@ -140,6 +145,9 @@
   void ResetMenu() override;
   void BuildMenu() override;
 
+  // ProfileManagerObserver:
+  void OnProfileMarkedForPermanentDeletion(Profile* profile) override;
+
   // Looks up an NSMenuItem in the |menu_item_map_| and returns the
   // corresponding HistoryItem.
   HistoryItem* HistoryItemForMenuItem(NSMenuItem* item);
@@ -152,6 +160,12 @@
   // to access model information when responding to actions.
   history::HistoryService* service();
   Profile* profile();
+  const base::FilePath& profile_dir() const;
+
+  // Resets |profile_| to nullptr. Called before the Profile is destroyed, when
+  // this bridge is still needed. Also performs some internal cleanup, like
+  // resetting observers and pointers to the Profile and KeyedServices.
+  void OnProfileWillBeDestroyed();
 
  protected:
   // Return the History menu.
@@ -232,6 +246,7 @@
 
  private:
   friend class ::HistoryMenuBridgeTest;
+  friend class ::HistoryMenuBridgeLifetimeTest;
   friend class HistoryMenuCocoaControllerTest;
 
   // history::HistoryServiceObserver:
@@ -254,9 +269,15 @@
 
   base::scoped_nsobject<HistoryMenuCocoaController> controller_;  // strong
 
-  const raw_ptr<Profile> profile_;                                      // weak
+  raw_ptr<Profile> profile_;                                            // weak
   raw_ptr<history::HistoryService> history_service_ = nullptr;          // weak
   raw_ptr<sessions::TabRestoreService> tab_restore_service_ = nullptr;  // weak
+  base::FilePath profile_dir_;  // Remembered after OnProfileWillBeDestroyed().
+
+  // Inhibit Profile destruction until the HistoryService and TabRestoreService
+  // are finished loading.
+  std::unique_ptr<ScopedProfileKeepAlive> history_service_keep_alive_;
+  std::unique_ptr<ScopedProfileKeepAlive> tab_restore_service_keep_alive_;
 
   base::CancelableTaskTracker cancelable_task_tracker_;
 
@@ -283,6 +304,10 @@
   base::ScopedObservation<sessions::TabRestoreService,
                           sessions::TabRestoreServiceObserver>
       tab_restore_service_observation_{this};
+  base::ScopedObservation<ProfileManager, ProfileManagerObserver>
+      profile_manager_observation_{this};
+
+  base::WeakPtrFactory<HistoryMenuBridge> weak_factory_{this};
 };
 
 #endif  // CHROME_BROWSER_UI_COCOA_HISTORY_MENU_BRIDGE_H_
diff --git a/chrome/browser/ui/cocoa/history_menu_bridge.mm b/chrome/browser/ui/cocoa/history_menu_bridge.mm
index 3013795..ce5828ef 100644
--- a/chrome/browser/ui/cocoa/history_menu_bridge.mm
+++ b/chrome/browser/ui/cocoa/history_menu_bridge.mm
@@ -16,8 +16,11 @@
 #include "chrome/app/chrome_command_ids.h"  // IDC_HISTORY_MENU
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/app_controller_mac.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/favicon/favicon_service_factory.h"
 #include "chrome/browser/history/history_service_factory.h"
+#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
+#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sessions/tab_restore_service_factory.h"
 #include "chrome/browser/themes/theme_service.h"
@@ -71,6 +74,11 @@
     : controller_([[HistoryMenuCocoaController alloc] initWithBridge:this]),
       profile_(profile) {
   DCHECK(profile_);
+  profile_dir_ = profile_->GetPath();
+
+  if (auto* profile_manager = g_browser_process->profile_manager())
+    profile_manager_observation_.Observe(profile_manager);
+
   // Set the static icons in the menu.
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
   NSMenuItem* full_history_item = [HistoryMenu() itemWithTag:IDC_SHOW_HISTORY];
@@ -95,6 +103,8 @@
       profile_, ServiceAccessType::EXPLICIT_ACCESS);
   if (hs) {
     history_service_observation_.Observe(hs);
+    history_service_keep_alive_ = std::make_unique<ScopedProfileKeepAlive>(
+        profile_, ProfileKeepAliveOrigin::kHistoryMenuBridge);
     if (hs->BackendLoaded()) {
       history_service_ = hs;
       Init();
@@ -107,10 +117,14 @@
     // If the tab entries are already loaded, invoke the observer method to
     // build the "Recently Closed" section. Otherwise it will be when the
     // backend loads.
-    if (!tab_restore_service_->IsLoaded())
+    if (!tab_restore_service_->IsLoaded()) {
+      tab_restore_service_keep_alive_ =
+          std::make_unique<ScopedProfileKeepAlive>(
+              profile_, ProfileKeepAliveOrigin::kHistoryMenuBridge);
       tab_restore_service_->LoadTabsFromLastSession();
-    else
+    } else {
       TabRestoreServiceChanged(tab_restore_service_);
+    }
   }
 
   default_favicon_.reset(
@@ -164,6 +178,8 @@
       }
     }
   }
+
+  tab_restore_service_keep_alive_.reset();
 }
 
 void HistoryMenuBridge::TabRestoreServiceDestroyed(
@@ -200,8 +216,8 @@
   is_menu_open_ = flag;
   if (!is_menu_open_ && need_recreate_) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE,
-        base::BindOnce(&HistoryMenuBridge::CreateMenu, base::Unretained(this)));
+        FROM_HERE, base::BindOnce(&HistoryMenuBridge::CreateMenu,
+                                  weak_factory_.GetWeakPtr()));
   }
 }
 
@@ -213,6 +229,10 @@
   return profile_;
 }
 
+const base::FilePath& HistoryMenuBridge::profile_dir() const {
+  return profile_dir_;
+}
+
 NSMenu* HistoryMenuBridge::HistoryMenu() {
   NSMenu* history_menu = [[[NSApp mainMenu] itemWithTag:IDC_HISTORY_MENU]
                             submenu];
@@ -409,6 +429,8 @@
 
 void HistoryMenuBridge::Init() {
   DCHECK(history_service_);
+  need_recreate_ = true;
+  CreateMenu();
 }
 
 void HistoryMenuBridge::CreateMenu() {
@@ -475,6 +497,8 @@
   // We are already invalid by the time we finished, darn.
   if (need_recreate_)
     CreateMenu();
+  else
+    history_service_keep_alive_.reset();
 
   create_in_progress_ = false;
 }
@@ -601,3 +625,17 @@
   NOTREACHED();
   return false;
 }
+
+void HistoryMenuBridge::OnProfileMarkedForPermanentDeletion(Profile* profile) {
+  if (profile != profile_)
+    return;
+  ResetMenu();
+}
+
+void HistoryMenuBridge::OnProfileWillBeDestroyed() {
+  profile_ = nullptr;
+  history_service_observation_.Reset();
+  history_service_ = nullptr;
+  tab_restore_service_observation_.Reset();
+  tab_restore_service_ = nullptr;
+}
diff --git a/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm b/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm
index 55e367c1..8de5f59d 100644
--- a/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm
+++ b/chrome/browser/ui/cocoa/history_menu_bridge_unittest.mm
@@ -47,6 +47,56 @@
   MOCK_CONST_METHOD0(entries, const sessions::TabRestoreService::Entries&());
 };
 
+MockTRS::Tab* CreateSessionTab(SessionID::id_type id,
+                               const std::string& url,
+                               const std::string& title) {
+  auto* tab = new MockTRS::Tab;
+  tab->id = SessionID::FromSerializedValue(id);
+  tab->current_navigation_index = 0;
+  tab->navigations.push_back(
+      sessions::ContentTestHelper::CreateNavigation(url, title));
+  return tab;
+}
+
+MockTRS::Entries CreateSessionEntries(
+    std::initializer_list<MockTRS::Entry*> entries) {
+  MockTRS::Entries ret;
+  for (auto* entry : entries)
+    ret.emplace_back(entry);
+  return ret;
+}
+
+MockTRS::Window* CreateSessionWindow(
+    SessionID::id_type id,
+    std::initializer_list<MockTRS::Tab*> tabs) {
+  auto* window = new MockTRS::Window;
+  window->id = SessionID::FromSerializedValue(id);
+  window->tabs.reserve(tabs.size());
+  for (auto* tab : tabs)
+    window->tabs.emplace_back(std::move(tab));
+  return window;
+}
+
+MockTRS::Group* CreateSessionGroup(SessionID::id_type id,
+                                   tab_groups::TabGroupVisualData visual_data,
+                                   std::initializer_list<MockTRS::Tab*> tabs) {
+  auto* group = new MockTRS::Group;
+  group->id = SessionID::FromSerializedValue(id);
+  group->visual_data = visual_data;
+  group->tabs.reserve(tabs.size());
+  for (auto* tab : tabs)
+    group->tabs.emplace_back(std::move(tab));
+  return group;
+}
+
+std::unique_ptr<HistoryMenuBridge::HistoryItem> CreateItem(
+    const std::u16string& title) {
+  auto item = std::make_unique<HistoryMenuBridge::HistoryItem>();
+  item->title = title;
+  item->url = GURL(title);
+  return item;
+}
+
 class MockBridge : public HistoryMenuBridge {
  public:
   MockBridge(Profile* profile)
@@ -120,57 +170,6 @@
     return item;
   }
 
-  std::unique_ptr<HistoryMenuBridge::HistoryItem> CreateItem(
-      const std::u16string& title) {
-    auto item = std::make_unique<HistoryMenuBridge::HistoryItem>();
-    item->title = title;
-    item->url = GURL(title);
-    return item;
-  }
-
-  MockTRS::Entries CreateSessionEntries(
-      std::initializer_list<MockTRS::Entry*> entries) {
-    MockTRS::Entries ret;
-    for (auto* entry : entries)
-      ret.emplace_back(entry);
-    return ret;
-  }
-
-  MockTRS::Tab* CreateSessionTab(SessionID::id_type id,
-                                 const std::string& url,
-                                 const std::string& title) {
-    auto* tab = new MockTRS::Tab;
-    tab->id = SessionID::FromSerializedValue(id);
-    tab->current_navigation_index = 0;
-    tab->navigations.push_back(
-        sessions::ContentTestHelper::CreateNavigation(url, title));
-    return tab;
-  }
-
-  MockTRS::Window* CreateSessionWindow(
-      SessionID::id_type id,
-      std::initializer_list<MockTRS::Tab*> tabs) {
-    auto* window = new MockTRS::Window;
-    window->id = SessionID::FromSerializedValue(id);
-    window->tabs.reserve(tabs.size());
-    for (auto* tab : tabs)
-      window->tabs.emplace_back(std::move(tab));
-    return window;
-  }
-
-  MockTRS::Group* CreateSessionGroup(
-      SessionID::id_type id,
-      tab_groups::TabGroupVisualData visual_data,
-      std::initializer_list<MockTRS::Tab*> tabs) {
-    auto* group = new MockTRS::Group;
-    group->id = SessionID::FromSerializedValue(id);
-    group->visual_data = visual_data;
-    group->tabs.reserve(tabs.size());
-    for (auto* tab : tabs)
-      group->tabs.emplace_back(std::move(tab));
-    return group;
-  }
-
   void GetFaviconForHistoryItem(HistoryMenuBridge::HistoryItem* item) {
     bridge_->GetFaviconForHistoryItem(item);
   }
@@ -200,6 +199,26 @@
   id<NSApplicationDelegate> previousApplicationDelegate_;
 };
 
+class HistoryMenuBridgeLifetimeTest : public testing::Test {
+ public:
+  NSMenu* HistoryMenu(HistoryMenuBridge* bridge) {
+    return bridge->HistoryMenu();
+  }
+
+  const std::map<NSMenuItem*, std::unique_ptr<HistoryMenuBridge::HistoryItem>>&
+  menu_item_map(HistoryMenuBridge* bridge) {
+    return bridge->menu_item_map_;
+  }
+
+  void AddItemToBridgeMenu(HistoryMenuBridge* bridge,
+                           std::unique_ptr<HistoryMenuBridge::HistoryItem> item,
+                           NSMenu* menu,
+                           NSInteger tag,
+                           NSInteger index) {
+    bridge->AddItemToMenu(std::move(item), menu, tag, index);
+  }
+};
+
 void CheckMenuItemVisibility(HistoryMenuBridgeTest* test, bool is_incognito) {
   // Make sure the items belong to both original and incognito mode are visible.
   NSInteger always_visible_items[] = {IDC_HOME, IDC_BACK, IDC_FORWARD};
@@ -557,7 +576,7 @@
 }
 
 // Does a full setup and tear down of the bridge.
-TEST(HistoryMenuBridgeLifetimeTest, ShutdownAfterProfile) {
+TEST_F(HistoryMenuBridgeLifetimeTest, ShutdownAfterProfile) {
   content::BrowserTaskEnvironment task_environment;
   TestingProfile::Builder profile_builder;
   profile_builder.AddTestingFactory(
@@ -574,7 +593,7 @@
 }
 
 // Does a full setup and tear down of the bridge.
-TEST(HistoryMenuBridgeLifetimeTest, ShutdownBeforeProfile) {
+TEST_F(HistoryMenuBridgeLifetimeTest, ShutdownBeforeProfile) {
   content::BrowserTaskEnvironment task_environment;
   TestingProfile::Builder profile_builder;
   profile_builder.AddTestingFactory(
@@ -588,4 +607,78 @@
   bridge.reset();
 }
 
+// Initializes the menu, then destroys the Profile but keeps the
+// HistoryMenuBridge around.
+TEST_F(HistoryMenuBridgeLifetimeTest, StillValidAfterProfileShutdown) {
+  content::BrowserTaskEnvironment task_environment;
+  TestingProfile::Builder profile_builder;
+  profile_builder.AddTestingFactory(FaviconServiceFactory::GetInstance(),
+                                    FaviconServiceFactory::GetDefaultFactory());
+  profile_builder.AddTestingFactory(
+      TabRestoreServiceFactory::GetInstance(),
+      TabRestoreServiceFactory::GetDefaultFactory());
+  profile_builder.AddTestingFactory(HistoryServiceFactory::GetInstance(),
+                                    HistoryServiceFactory::GetDefaultFactory());
+  std::unique_ptr<TestingProfile> profile = profile_builder.Build();
+  base::FilePath profile_dir = profile->GetPath();
+  base::scoped_nsobject<AppController> appController(
+      [[AppController alloc] init]);
+  [NSApp setDelegate:appController];
+
+  auto bridge = std::make_unique<MockBridge>(profile.get());
+  std::unique_ptr<MockTRS> trs(new MockTRS(profile.get()));
+  auto entries{CreateSessionEntries({
+      CreateSessionTab(24, "http://google.com", "Google"),
+      CreateSessionTab(42, "http://apple.com", "Apple"),
+  })};
+
+  using ::testing::ReturnRef;
+  EXPECT_CALL(*trs.get(), entries()).WillOnce(ReturnRef(entries));
+
+  bridge->TabRestoreServiceChanged(trs.get());
+
+  NSMenu* menu = HistoryMenu(bridge.get());
+  AddItemToBridgeMenu(bridge.get(), CreateItem(u"http://example.com/"), menu,
+                      100, 2);
+  AddItemToBridgeMenu(bridge.get(), CreateItem(u"http://example.org/"), menu,
+                      101, 3);
+
+  // Destroy the Profile.
+  bridge->OnProfileWillBeDestroyed();
+  trs.reset();
+  profile.reset();
+  ASSERT_EQ(nullptr, bridge->profile());
+  EXPECT_EQ(profile_dir, bridge->profile_dir());
+
+  // The menu should still contain items after Profile destruction.
+  ASSERT_EQ(4u, [[menu itemArray] count]);
+
+  NSMenuItem* item1 = [menu itemAtIndex:0];
+  MockBridge::HistoryItem* hist1 = bridge->HistoryItemForMenuItem(item1);
+  EXPECT_TRUE(hist1);
+  EXPECT_EQ(24, hist1->session_id.id());
+  EXPECT_NSEQ(@"Google", [item1 title]);
+
+  NSMenuItem* item2 = [menu itemAtIndex:1];
+  MockBridge::HistoryItem* hist2 = bridge->HistoryItemForMenuItem(item2);
+  EXPECT_TRUE(hist2);
+  EXPECT_EQ(42, hist2->session_id.id());
+  EXPECT_NSEQ(@"Apple", [item2 title]);
+
+  NSMenuItem* item3 = [menu itemAtIndex:2];
+  MockBridge::HistoryItem* hist3 = bridge->HistoryItemForMenuItem(item2);
+  EXPECT_TRUE(hist3);
+  EXPECT_NSEQ(@"http://example.com/", [item3 title]);
+
+  NSMenuItem* item4 = [menu itemAtIndex:3];
+  MockBridge::HistoryItem* hist4 = bridge->HistoryItemForMenuItem(item2);
+  EXPECT_TRUE(hist4);
+  EXPECT_NSEQ(@"http://example.org/", [item4 title]);
+
+  EXPECT_EQ(4u, menu_item_map(bridge.get()).size());
+
+  bridge.reset();
+  [NSApp setDelegate:nil];
+}
+
 }  // namespace
diff --git a/chrome/browser/ui/cocoa/history_menu_cocoa_controller.mm b/chrome/browser/ui/cocoa/history_menu_cocoa_controller.mm
index e0759fa..e1bcb941 100644
--- a/chrome/browser/ui/cocoa/history_menu_cocoa_controller.mm
+++ b/chrome/browser/ui/cocoa/history_menu_cocoa_controller.mm
@@ -17,6 +17,7 @@
 #include "chrome/browser/ui/browser_navigator_params.h"
 #include "components/history/core/browser/history_service.h"
 #include "components/history/core/browser/history_types.h"
+#include "components/sessions/core/session_id.h"
 #include "components/sessions/core/tab_restore_service.h"
 #import "ui/base/cocoa/cocoa_base_utils.h"
 #include "ui/base/window_open_disposition.h"
@@ -24,6 +25,44 @@
 using content::OpenURLParams;
 using content::Referrer;
 
+namespace {
+
+// TODO(crbug.com/1334721): Single-tab windows get restored as tabs instead of
+// windows, which is confusing.
+//
+// NB: Takes |node| by value, because the HistoryMenuBridge could be destroyed
+// before RunInSafeProfileHelper finishes.
+void OpenURLForItem(HistoryMenuBridge::HistoryItem node,
+                    WindowOpenDisposition disposition,
+                    Profile* profile) {
+  if (!profile)
+    return;  // Failed to load profile, ignore.
+  // If this item can be restored using TabRestoreService, do so. Otherwise,
+  // just load the URL.
+  if (node.session_id.is_valid()) {
+    app_controller_mac::TabRestorer::RestoreByID(profile, node.session_id);
+  } else {
+    DCHECK(node.url.is_valid());
+    Profile* target_profile = profile;
+
+    // Allow a history menu item to open in an active incognito window.
+    // Specifically, if the active window has the same root profile as the
+    // bridge, target the active profile. Without this, history menu items open
+    // in the nearest non-incognito window, or create one.
+    if (auto* active_browser = chrome::FindBrowserWithActiveWindow()) {
+      if (active_browser->profile()->GetOriginalProfile() == target_profile)
+        target_profile = active_browser->profile();
+    }
+
+    NavigateParams params(target_profile, node.url,
+                          ui::PAGE_TRANSITION_AUTO_BOOKMARK);
+    params.disposition = disposition;
+    Navigate(&params);
+  }
+}
+
+};  // namespace
+
 @implementation HistoryMenuCocoaController
 
 - (instancetype)initWithBridge:(HistoryMenuBridge*)bridge {
@@ -42,35 +81,18 @@
 
 // Open the URL of the given history item in the current tab.
 - (void)openURLForItem:(const HistoryMenuBridge::HistoryItem*)node {
-  // If this item can be restored using TabRestoreService, do so. Otherwise,
-  // just load the URL.
-  sessions::TabRestoreService* service =
-      TabRestoreServiceFactory::GetForProfile(_bridge->profile());
-  if (node->session_id.is_valid() && service) {
-    Browser* browser = chrome::FindTabbedBrowser(_bridge->profile(), false);
-    BrowserLiveTabContext* context =
-        browser ? browser->live_tab_context() : NULL;
-    service->RestoreEntryById(context, node->session_id,
-                              WindowOpenDisposition::UNKNOWN);
+  WindowOpenDisposition disposition =
+      ui::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
+  if (Profile* profile = _bridge->profile()) {
+    OpenURLForItem(*node, disposition, profile);
   } else {
-    DCHECK(node->url.is_valid());
-    WindowOpenDisposition disposition =
-        ui::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
-    Profile* target_profile = _bridge->profile();
-
-    // Allow a history menu item to open in an active incognito window.
-    // Specifically, if the active window has the same root profile as the
-    // bridge, target the active profile. Without this, history menu items open
-    // in the nearest non-incognito window, or create one.
-    if (auto* active_browser = chrome::FindBrowserWithActiveWindow()) {
-      if (active_browser->profile()->GetOriginalProfile() == target_profile)
-        target_profile = active_browser->profile();
-    }
-
-    NavigateParams params(target_profile, node->url,
-                          ui::PAGE_TRANSITION_AUTO_BOOKMARK);
-    params.disposition = disposition;
-    Navigate(&params);
+    // Both HistoryMenuBridge and HistoryMenuCocoaController could get destroyed
+    // before RunInSafeProfileHelper finishes. The callback needs to be
+    // self-contained.
+    app_controller_mac::RunInProfileSafely(
+        _bridge->profile_dir(),
+        base::BindOnce(&OpenURLForItem, *node, disposition),
+        app_controller_mac::kIgnoreOnFailure);
   }
 }
 
diff --git a/chrome/browser/ui/cocoa/history_menu_cocoa_controller_unittest.mm b/chrome/browser/ui/cocoa/history_menu_cocoa_controller_unittest.mm
index 7cc11e3..5185a92f 100644
--- a/chrome/browser/ui/cocoa/history_menu_cocoa_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/history_menu_cocoa_controller_unittest.mm
@@ -50,6 +50,8 @@
     [controller() initTest];
   }
 
+  void TearDown() override { bridge_.reset(); }
+
   void CreateItems(NSMenu* menu) {
     auto item = std::make_unique<HistoryMenuBridge::HistoryItem>();
     item->url = GURL("http://google.com");
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_bubble.cc b/chrome/browser/ui/exclusive_access/exclusive_access_bubble.cc
index ff75fba..a6a6e0868 100644
--- a/chrome/browser/ui/exclusive_access/exclusive_access_bubble.cc
+++ b/chrome/browser/ui/exclusive_access/exclusive_access_bubble.cc
@@ -119,8 +119,8 @@
 
 std::u16string ExclusiveAccessBubble::GetInstructionText(
     const std::u16string& accelerator) const {
-  return exclusive_access_bubble::GetInstructionTextForType(bubble_type_,
-                                                            accelerator);
+  return exclusive_access_bubble::GetInstructionTextForType(
+      bubble_type_, accelerator, notify_download_, notify_overridden_);
 }
 
 bool ExclusiveAccessBubble::IsHideTimeoutRunning() const {
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_bubble.h b/chrome/browser/ui/exclusive_access/exclusive_access_bubble.h
index fb15c6e6..e7edaea9 100644
--- a/chrome/browser/ui/exclusive_access/exclusive_access_bubble.h
+++ b/chrome/browser/ui/exclusive_access/exclusive_access_bubble.h
@@ -110,6 +110,12 @@
   // The type of the bubble; controls e.g. which buttons to show.
   ExclusiveAccessBubbleType bubble_type_;
 
+  // The bubble should notify about downloads
+  bool notify_download_ = false;
+
+  // The bubble should notify about overriding another ExclusiveAccessBubble
+  bool notify_overridden_ = false;
+
  private:
   friend class ExclusiveAccessTest;
 
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.cc b/chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.cc
index 72ca4f8..f95275f7 100644
--- a/chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.cc
+++ b/chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.cc
@@ -47,8 +47,6 @@
       case EXCLUSIVE_ACCESS_BUBBLE_TYPE_EXTENSION_FULLSCREEN_EXIT_INSTRUCTION:
         return l10n_util::GetStringUTF16(
             IDS_FULLSCREEN_UNKNOWN_EXTENSION_TRIGGERED_FULLSCREEN);
-      case EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED:
-      case EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED_AND_EXIT:
       case EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE:
         NOTREACHED();
         return std::u16string();
@@ -72,8 +70,6 @@
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_EXTENSION_FULLSCREEN_EXIT_INSTRUCTION:
       return l10n_util::GetStringFUTF16(
           IDS_FULLSCREEN_EXTENSION_TRIGGERED_FULLSCREEN, host);
-    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED:
-    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED_AND_EXIT:
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE:
       NOTREACHED();
       return std::u16string();
@@ -90,8 +86,6 @@
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_MOUSELOCK_EXIT_INSTRUCTION:
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION:
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_EXTENSION_FULLSCREEN_EXIT_INSTRUCTION:
-    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED:
-    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED_AND_EXIT:
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE:
       NOTREACHED();  // No button in this case.
       return std::u16string();
@@ -109,8 +103,6 @@
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_MOUSELOCK_EXIT_INSTRUCTION:
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION:
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_EXTENSION_FULLSCREEN_EXIT_INSTRUCTION:
-    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED:
-    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED_AND_EXIT:
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE:
       NOTREACHED();  // No button in this case.
       return std::u16string();
@@ -120,7 +112,18 @@
 }
 
 std::u16string GetInstructionTextForType(ExclusiveAccessBubbleType type,
-                                         const std::u16string& accelerator) {
+                                         const std::u16string& accelerator,
+                                         bool notify_download,
+                                         bool notify_overridden) {
+  if (notify_download) {
+    return notify_overridden
+               ? l10n_util::GetStringFUTF16(
+                     IDS_FULLSCREEN_PRESS_TO_SEE_DOWNLOADS_AND_EXIT,
+                     accelerator)
+               : l10n_util::GetStringFUTF16(
+                     IDS_FULLSCREEN_PRESS_TO_SEE_DOWNLOADS, accelerator);
+  }
+
   switch (type) {
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_EXIT_INSTRUCTION:
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_MOUSELOCK_EXIT_INSTRUCTION:
@@ -137,12 +140,6 @@
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_MOUSELOCK_EXIT_INSTRUCTION:
       return l10n_util::GetStringFUTF16(
           IDS_FULLSCREEN_PRESS_ESC_TO_EXIT_MOUSELOCK, accelerator);
-    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED:
-      return l10n_util::GetStringFUTF16(IDS_FULLSCREEN_PRESS_TO_SEE_DOWNLOADS,
-                                        accelerator);
-    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED_AND_EXIT:
-      return l10n_util::GetStringFUTF16(
-          IDS_FULLSCREEN_PRESS_TO_SEE_DOWNLOADS_AND_EXIT, accelerator);
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE:
       NOTREACHED();
       return std::u16string();
@@ -151,4 +148,22 @@
   return std::u16string();
 }
 
+bool IsExclusiveAccessModeBrowserFullscreen(ExclusiveAccessBubbleType type) {
+  switch (type) {
+    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION:
+    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_EXTENSION_FULLSCREEN_EXIT_INSTRUCTION:
+      return true;
+    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_EXIT_INSTRUCTION:
+    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_KEYBOARD_LOCK_EXIT_INSTRUCTION:
+    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_MOUSELOCK_EXIT_INSTRUCTION:
+    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_MOUSELOCK_EXIT_INSTRUCTION:
+      return false;
+    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE:
+      NOTREACHED();
+      return false;
+  }
+  NOTREACHED();
+  return false;
+}
+
 }  // namespace exclusive_access_bubble
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.h b/chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.h
index ee76df6..6549142 100644
--- a/chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.h
+++ b/chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.h
@@ -31,10 +31,6 @@
   // For browser fullscreen mode.
   EXCLUSIVE_ACCESS_BUBBLE_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION,
   EXCLUSIVE_ACCESS_BUBBLE_TYPE_EXTENSION_FULLSCREEN_EXIT_INSTRUCTION,
-
-  // To notify user that a download has started.
-  EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED,
-  EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED_AND_EXIT
 };
 
 namespace exclusive_access_bubble {
@@ -54,7 +50,12 @@
 // Gets the text instructing the user how to exit an exclusive access mode.
 // |accelerator| is the name of the key to exit fullscreen mode.
 std::u16string GetInstructionTextForType(ExclusiveAccessBubbleType type,
-                                         const std::u16string& accelerator);
+                                         const std::u16string& accelerator,
+                                         bool notify_download,
+                                         bool notify_overridden);
+
+// Helpers to categorize different types of ExclusiveAccessBubbleType.
+bool IsExclusiveAccessModeBrowserFullscreen(ExclusiveAccessBubbleType type);
 
 }  // namespace exclusive_access_bubble
 
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_context.h b/chrome/browser/ui/exclusive_access/exclusive_access_context.h
index 02b58048..893d2c6 100644
--- a/chrome/browser/ui/exclusive_access/exclusive_access_context.h
+++ b/chrome/browser/ui/exclusive_access/exclusive_access_context.h
@@ -53,6 +53,7 @@
       const GURL& url,
       ExclusiveAccessBubbleType bubble_type,
       ExclusiveAccessBubbleHideCallback bubble_first_hide_callback,
+      bool notify_download,
       bool force_update) = 0;
 
   virtual bool IsExclusiveAccessBubbleDisplayed() const = 0;
diff --git a/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc b/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc
index 1c6115d..c58d84b 100644
--- a/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc
+++ b/chrome/browser/ui/exclusive_access/exclusive_access_manager.cc
@@ -78,7 +78,8 @@
   GURL url = GetExclusiveAccessBubbleURL();
   ExclusiveAccessBubbleType bubble_type = GetExclusiveAccessExitBubbleType();
   exclusive_access_context_->UpdateExclusiveAccessExitBubbleContent(
-      url, bubble_type, std::move(bubble_first_hide_callback), force_update);
+      url, bubble_type, std::move(bubble_first_hide_callback),
+      /*notify_download=*/false, force_update);
 }
 
 GURL ExclusiveAccessManager::GetExclusiveAccessBubbleURL() const {
@@ -150,8 +151,6 @@
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_EXIT_INSTRUCTION:
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION:
     case EXCLUSIVE_ACCESS_BUBBLE_TYPE_EXTENSION_FULLSCREEN_EXIT_INSTRUCTION:
-    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED:
-    case EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED_AND_EXIT:
       // Only fullscreen in effect.
       fullscreen = true;
       break;
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
index 645fbb1..cbfb8ba 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
@@ -958,14 +958,14 @@
 
 // TODO(crbug.com/1034772): Disabled on Windows, where views::FullscreenHandler
 // implements fullscreen by directly obtaining MONITORINFO, ignoring the mocked
-// display::Screen configuration used in this test. Disabled on Mac and Linux,
-// where the window server's async handling of the fullscreen window state may
-// transition the window into fullscreen on the actual (non-mocked) display
-// bounds before or after the window bounds checks, yielding flaky results.
-#if !BUILDFLAG(IS_CHROMEOS_ASH)
-#define MAYBE_SameDisplayAndSwap DISABLED_SameDisplayAndSwap
-#else
+// display::Screen configuration used in this test. Disabled on Linux, where the
+// window server's async handling of the fullscreen window state may transition
+// the window into fullscreen on the actual (non-mocked) display bounds before
+// or after the window bounds checks, yielding flaky results.
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_MAC)
 #define MAYBE_SameDisplayAndSwap SameDisplayAndSwap
+#else
+#define MAYBE_SameDisplayAndSwap DISABLED_SameDisplayAndSwap
 #endif
 // Test requesting fullscreen on the current display and then swapping displays.
 IN_PROC_BROWSER_TEST_F(MultiScreenFullscreenControllerInteractiveTest,
@@ -975,11 +975,14 @@
 
   // Execute JS to request fullscreen on the current display (on the left).
   RequestContentFullscreen();
-  EXPECT_EQ(gfx::Rect(0, 0, 800, 800), browser()->window()->GetBounds());
+  const display::Screen* screen = display::Screen::GetScreen();
+  const auto first_display = screen->GetAllDisplays()[0];
+  EXPECT_EQ(first_display.bounds(), browser()->window()->GetBounds());
 
   // Execute JS to request fullscreen on the other display (on the right).
   RequestContentFullscreenOnScreen(1);
-  EXPECT_EQ(gfx::Rect(800, 0, 800, 800), browser()->window()->GetBounds());
+  const auto second_display = screen->GetAllDisplays()[1];
+  EXPECT_EQ(second_display.bounds(), browser()->window()->GetBounds());
 
   ExitContentFullscreen();
   EXPECT_EQ(original_bounds, browser()->window()->GetBounds());
@@ -1128,7 +1131,7 @@
       ->UpdateExclusiveAccessExitBubbleContent(
           browser()->exclusive_access_manager()->GetExclusiveAccessBubbleURL(),
           EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE, std::move(callback),
-          /*force_update=*/false);
+          /*notify_download=*/false, /*force_update=*/false);
   run_loop.Run();
   EXPECT_FALSE(IsExclusiveAccessBubbleDisplayed());
 
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_state_unittest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_state_unittest.cc
index 96c14b5..4f829a0 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_state_unittest.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_state_unittest.cc
@@ -68,6 +68,7 @@
       const GURL& url,
       ExclusiveAccessBubbleType bubble_type,
       ExclusiveAccessBubbleHideCallback bubble_first_hide_callback,
+      bool notify_download,
       bool force_update) override;
   bool IsExclusiveAccessBubbleDisplayed() const override;
   void OnExclusiveAccessUserInput() override;
@@ -189,6 +190,7 @@
     const GURL& url,
     ExclusiveAccessBubbleType bubble_type,
     ExclusiveAccessBubbleHideCallback bubble_first_hide_callback,
+    bool notify_download,
     bool force_update) {}
 
 bool FullscreenControllerTestWindow::IsExclusiveAccessBubbleDisplayed() const {
diff --git a/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc b/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc
index ea6aa50..a9d4126 100644
--- a/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc
+++ b/chrome/browser/ui/toolbar/back_forward_menu_model_unittest.cc
@@ -476,9 +476,9 @@
   EXPECT_EQ(32u, back_model->GetIndexOfNextChapterStop(31, true));
   EXPECT_FALSE(back_model->GetIndexOfNextChapterStop(32, true).has_value());
 
-  if (content::BackForwardCache::IsSameSiteBackForwardCacheFeatureEnabled()) {
+  if (content::BackForwardCache::IsBackForwardCacheFeatureEnabled()) {
     // The case below currently fails on the linux-bfcache-rel bot with
-    // same-site bfcache enabled, so return early.
+    // back/forward cache enabled, so return early.
     // TODO(https://crbug.com/1232883): re-enable this test.
     return;
   }
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
index 36f72b7..fcba673 100644
--- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
+++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
@@ -289,6 +289,7 @@
             ? EXCLUSIVE_ACCESS_BUBBLE_TYPE_FULLSCREEN_EXIT_INSTRUCTION
             : EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE,
         ExclusiveAccessBubbleHideCallback(),
+        /*notify_download=*/false,
         /*force_update=*/false);
   }
 
@@ -361,8 +362,10 @@
     const GURL& url,
     ExclusiveAccessBubbleType bubble_type,
     ExclusiveAccessBubbleHideCallback bubble_first_hide_callback,
+    bool notify_download,
     bool force_update) {
-  if (bubble_type == EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE) {
+  DCHECK(!notify_download || exclusive_access_bubble_);
+  if (bubble_type == EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE && !notify_download) {
     exclusive_access_bubble_.reset();
     if (bubble_first_hide_callback) {
       std::move(bubble_first_hide_callback)
@@ -373,7 +376,8 @@
 
   if (exclusive_access_bubble_) {
     exclusive_access_bubble_->UpdateContent(
-        url, bubble_type, std::move(bubble_first_hide_callback), force_update);
+        url, bubble_type, std::move(bubble_first_hide_callback),
+        notify_download, force_update);
     return;
   }
 
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h
index 6ab4d81..2fd6daf 100644
--- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h
+++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h
@@ -113,6 +113,7 @@
       const GURL& url,
       ExclusiveAccessBubbleType bubble_type,
       ExclusiveAccessBubbleHideCallback bubble_first_hide_callback,
+      bool notify_download,
       bool force_update) override;
   bool IsExclusiveAccessBubbleDisplayed() const override;
   void OnExclusiveAccessUserInput() override;
diff --git a/chrome/browser/ui/views/exclusive_access_bubble_views.cc b/chrome/browser/ui/views/exclusive_access_bubble_views.cc
index b495de6..65964be6 100644
--- a/chrome/browser/ui/views/exclusive_access_bubble_views.cc
+++ b/chrome/browser/ui/views/exclusive_access_bubble_views.cc
@@ -128,19 +128,19 @@
     const GURL& url,
     ExclusiveAccessBubbleType bubble_type,
     ExclusiveAccessBubbleHideCallback bubble_first_hide_callback,
+    bool notify_download,
     bool force_update) {
-  DCHECK_NE(EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE, bubble_type);
+  DCHECK(EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE != bubble_type || notify_download);
   if (bubble_type_ == bubble_type && url_ == url && !force_update)
     return;
 
-  // Show the exit and download notification only if a notification that was
-  // informing about the exit directions was visible, and a download
-  // notification was laid on top.
-  if (IsVisible() &&
-      bubble_type_ != EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED &&
-      bubble_type == EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED) {
-    bubble_type = EXCLUSIVE_ACCESS_BUBBLE_TYPE_DOWNLOAD_STARTED_AND_EXIT;
-  }
+  // Show the notification about overriding only if requesting a download
+  // notification, a notification was visible earlier, and the earlier
+  // notification was either a non-download one, or was one about an override
+  // itself.
+  notify_overridden_ = notify_download && IsVisible() &&
+                       (!notify_download_ || notify_overridden_);
+  notify_download_ = notify_download;
 
   // Bubble maybe be re-used after timeout.
   RunHideCallbackIfNeeded(ExclusiveAccessBubbleHideReason::kInterrupted);
@@ -148,7 +148,11 @@
   bubble_first_hide_callback_ = std::move(bubble_first_hide_callback);
 
   url_ = url;
-  bubble_type_ = bubble_type;
+  // When a request to notify about a download is made, the bubble type
+  // should be preserved from the old value, and not be updated.
+  if (!notify_download) {
+    bubble_type_ = bubble_type;
+  }
   UpdateViewContent(bubble_type_);
 
   gfx::Size size = GetPopupRect(true).size();
@@ -212,10 +216,8 @@
   DCHECK_NE(EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE, bubble_type);
 
   std::u16string accelerator;
-  if (bubble_type ==
-          EXCLUSIVE_ACCESS_BUBBLE_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION ||
-      bubble_type ==
-          EXCLUSIVE_ACCESS_BUBBLE_TYPE_EXTENSION_FULLSCREEN_EXIT_INSTRUCTION) {
+  if (exclusive_access_bubble::IsExclusiveAccessModeBrowserFullscreen(
+          bubble_type)) {
     accelerator = browser_fullscreen_exit_accelerator_;
   } else {
     accelerator = l10n_util::GetStringUTF16(IDS_APP_ESC_KEY);
diff --git a/chrome/browser/ui/views/exclusive_access_bubble_views.h b/chrome/browser/ui/views/exclusive_access_bubble_views.h
index 6e9a4b4..8896cf3 100644
--- a/chrome/browser/ui/views/exclusive_access_bubble_views.h
+++ b/chrome/browser/ui/views/exclusive_access_bubble_views.h
@@ -48,11 +48,15 @@
   ~ExclusiveAccessBubbleViews() override;
 
   // |force_update| indicates the caller wishes to show the bubble contents
-  // regardless of whether the contents have changed.
+  // regardless of whether the contents have changed. |notify_download|
+  // indicates if the notification should be about a new download. Note that
+  // bubble_type may be an invalid one for notify_download, as we want to
+  // preserve the current type.
   void UpdateContent(
       const GURL& url,
       ExclusiveAccessBubbleType bubble_type,
       ExclusiveAccessBubbleHideCallback bubble_first_hide_callback,
+      bool notify_download,
       bool force_update);
 
   // Repositions |popup_| if it is visible.
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 1cb1dc3..408250b 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1784,7 +1784,9 @@
     const GURL& url,
     ExclusiveAccessBubbleType bubble_type,
     ExclusiveAccessBubbleHideCallback bubble_first_hide_callback,
+    bool notify_download,
     bool force_update) {
+  DCHECK(!notify_download || exclusive_access_bubble_);
   // Trusted pinned mode does not allow to escape. So do not show the bubble.
   bool is_trusted_pinned =
       platform_util::IsBrowserLockedFullscreen(browser_.get());
@@ -1793,7 +1795,8 @@
   // top that gives the user a hover target. In a public session we show the
   // bubble.
   // TODO(jamescook): Figure out what to do with mouse-lock.
-  if (is_trusted_pinned || bubble_type == EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE ||
+  if (is_trusted_pinned ||
+      (!notify_download && bubble_type == EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE) ||
       (ShouldUseImmersiveFullscreenForUrl(url) &&
        !profiles::IsPublicSession())) {
     // |exclusive_access_bubble_.reset()| will trigger callback for current
@@ -1808,10 +1811,13 @@
 
   if (exclusive_access_bubble_) {
     exclusive_access_bubble_->UpdateContent(
-        url, bubble_type, std::move(bubble_first_hide_callback), force_update);
+        url, bubble_type, std::move(bubble_first_hide_callback),
+        notify_download, force_update);
     return;
   }
 
+  // Notification about download should only be considered for a bubble that
+  // exists already.
   exclusive_access_bubble_ = std::make_unique<ExclusiveAccessBubbleViews>(
       this, url, bubble_type, std::move(bubble_first_hide_callback));
 }
@@ -4277,6 +4283,7 @@
   if (fullscreen && !chrome::IsRunningInAppMode()) {
     UpdateExclusiveAccessExitBubbleContent(
         url, bubble_type, ExclusiveAccessBubbleHideCallback(),
+        /*notify_download=*/false,
         /*force_update=*/swapping_screens_during_fullscreen);
   }
 
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index 8b969d1b..73a06ce 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -481,6 +481,7 @@
       const GURL& url,
       ExclusiveAccessBubbleType bubble_type,
       ExclusiveAccessBubbleHideCallback bubble_first_hide_callback,
+      bool notify_download,
       bool force_update) override;
   bool IsExclusiveAccessBubbleDisplayed() const override;
   void OnExclusiveAccessUserInput() override;
diff --git a/chrome/browser/ui/views/frame/webui_tab_strip_interactive_uitest.cc b/chrome/browser/ui/views/frame/webui_tab_strip_interactive_uitest.cc
index 08868c1..fe3f3fa 100644
--- a/chrome/browser/ui/views/frame/webui_tab_strip_interactive_uitest.cc
+++ b/chrome/browser/ui/views/frame/webui_tab_strip_interactive_uitest.cc
@@ -472,6 +472,7 @@
                        .SetStartCallback(base::BindLambdaForTesting(
                            [&](ui::InteractionSequence*,
                                ui::TrackedElement* element) {
+                             LOG(WARNING) << "Drag test: mouse move completed.";
                              // For WebUI tab drag, the tab isn't actually
                              // removed from the tabstrip until the drag
                              // completes.
@@ -480,6 +481,8 @@
 
                              // Close the new tab.
                              second_tab->Execute("() => window.close()");
+                             LOG(WARNING)
+                                 << "Drag test: waiting for window to close.";
                            })))
 
           // Wait for the dragged tab to be closed, verify it is closed, and
@@ -495,6 +498,8 @@
                        .SetStartCallback(base::BindLambdaForTesting(
                            [&](ui::InteractionSequence*,
                                ui::TrackedElement* element) {
+                             LOG(WARNING)
+                                 << "Drag test: window successfully closed.";
                              // The tab should now be removed from the tabstrip
                              // because it was closed; the drag has not yet
                              // finished.
diff --git a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc
index 525d6611..ad9a94a 100644
--- a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc
+++ b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc
@@ -310,6 +310,7 @@
 #endif
   UpdateExclusiveAccessExitBubbleContent(url, bubble_type,
                                          ExclusiveAccessBubbleHideCallback(),
+                                         /*notify_download=*/false,
                                          /*force_update=*/false);
 }
 
@@ -324,15 +325,18 @@
     const GURL& url,
     ExclusiveAccessBubbleType bubble_type,
     ExclusiveAccessBubbleHideCallback bubble_first_hide_callback,
+    bool notify_download,
     bool force_update) {
+  DCHECK(!notify_download || exclusive_access_bubble_);
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // On Chrome OS, we will not show the toast for the normal browser fullscreen
   // mode.  The 'F11' text is confusing since how to access F11 on a Chromebook
   // is not common knowledge and there is also a dedicated fullscreen toggle
   // button available.
-  if (bubble_type == EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE || url.is_empty()) {
+  if ((!notify_download && bubble_type == EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE) ||
+      url.is_empty()) {
 #else
-  if (bubble_type == EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE) {
+  if (!notify_download && bubble_type == EXCLUSIVE_ACCESS_BUBBLE_TYPE_NONE) {
 #endif
     // |exclusive_access_bubble_.reset()| will trigger callback for current
     // bubble with |ExclusiveAccessBubbleHideReason::kInterrupted| if available.
@@ -346,7 +350,8 @@
 
   if (exclusive_access_bubble_) {
     exclusive_access_bubble_->UpdateContent(
-        url, bubble_type, std::move(bubble_first_hide_callback), force_update);
+        url, bubble_type, std::move(bubble_first_hide_callback),
+        notify_download, force_update);
     return;
   }
 
diff --git a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.h b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.h
index 6db9051..d39a57a 100644
--- a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.h
+++ b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.h
@@ -97,6 +97,7 @@
       const GURL& url,
       ExclusiveAccessBubbleType bubble_type,
       ExclusiveAccessBubbleHideCallback bubble_first_hide_callback,
+      bool notify_download,
       bool force_update) final;
   bool IsExclusiveAccessBubbleDisplayed() const final;
   void OnExclusiveAccessUserInput() final;
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index 535e4b4..04426ca 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -1561,6 +1561,7 @@
       GURL(chrome::kOsUIAppDisabledURL),
       GURL(chrome::kOsUIAppServiceInternalsURL),
       GURL(chrome::kOsUIBluetoothInternalsURL),
+      GURL(chrome::kChromeUIBluetoothInternalsURL),
       GURL(chrome::kChromeUIArcGraphicsTracingURL),
       GURL(chrome::kChromeUIArcOverviewTracingURL),
       GURL(chrome::kChromeUIArcPowerControlURL),
diff --git a/chrome/browser/ui/webui/settings/ash/multidevice_section.cc b/chrome/browser/ui/webui/settings/ash/multidevice_section.cc
index 11f9280..89ea998 100644
--- a/chrome/browser/ui/webui/settings/ash/multidevice_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/multidevice_section.cc
@@ -402,10 +402,6 @@
        IDS_SETTINGS_MULTIDEVICE_WIFI_SYNC_LEARN_MORE_LABEL},
       {"multideviceNotificationAccessSetupConnectingTitle",
        IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_CONNECTING_TITLE},
-      {"multideviceNotificationAccessSetupScreenLockTitle",
-       IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_TITLE},
-      {"multideviceNotificationAccessSetupScreenLockInstruction",
-       IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_INSTRUCTION},
       {"multideviceNotificationAccessSetupScreenLockIconInstruction",
        IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_ICON_INSTRUCTION},
       {"multideviceNotificationAccessSetupAwaitingResponseTitle",
@@ -514,6 +510,10 @@
       chromeos::multidevice_setup::AreAnyMultiDeviceFeaturesAllowed(
           profile()->GetPrefs()));
   html_source->AddString(
+      "multideviceNotificationAccessSetupScreenLockTitle",
+      ui::SubstituteChromeOSDeviceType(
+          IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_SCREEN_LOCK_TITLE));
+  html_source->AddString(
       "multideviceNotificationAccessSetupAckSummary",
       ui::SubstituteChromeOSDeviceType(
           IDS_SETTINGS_MULTIDEVICE_NOTIFICATION_ACCESS_SETUP_DIALOG_ACK_SUMMARY));
diff --git a/chrome/browser/ui/webui/settings/settings_security_key_handler.cc b/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
index 6c31c22b..3ec5faa 100644
--- a/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
@@ -1136,13 +1136,11 @@
 
   AllowJavascript();
   std::unique_ptr<LocalCredentialManagement> local_cred_man =
-      LocalCredentialManagement::Create();
-  local_cred_man->HasCredentials(
-      Profile::FromBrowserContext(
-          web_ui()->GetWebContents()->GetBrowserContext()),
-      base::BindOnce(&PasskeysHandler::OnHasPasskeysComplete,
-                     weak_factory_.GetWeakPtr(), args[0].GetString(),
-                     std::move(local_cred_man)));
+      LocalCredentialManagement::Create(Profile::FromBrowserContext(
+          web_ui()->GetWebContents()->GetBrowserContext()));
+  local_cred_man->HasCredentials(base::BindOnce(
+      &PasskeysHandler::OnHasPasskeysComplete, weak_factory_.GetWeakPtr(),
+      args[0].GetString(), std::move(local_cred_man)));
 }
 
 void PasskeysHandler::OnHasPasskeysComplete(
@@ -1163,13 +1161,11 @@
 
 void PasskeysHandler::DoEnumerate(std::string callback_id) {
   std::unique_ptr<LocalCredentialManagement> local_cred_man =
-      LocalCredentialManagement::Create();
-  local_cred_man->Enumerate(
-      Profile::FromBrowserContext(
-          web_ui()->GetWebContents()->GetBrowserContext()),
-      base::BindOnce(&PasskeysHandler::OnEnumerateComplete,
-                     weak_factory_.GetWeakPtr(), std::move(callback_id),
-                     std::move(local_cred_man)));
+      LocalCredentialManagement::Create(Profile::FromBrowserContext(
+          web_ui()->GetWebContents()->GetBrowserContext()));
+  local_cred_man->Enumerate(base::BindOnce(
+      &PasskeysHandler::OnEnumerateComplete, weak_factory_.GetWeakPtr(),
+      std::move(callback_id), std::move(local_cred_man)));
 }
 
 void PasskeysHandler::OnEnumerateComplete(
@@ -1212,10 +1208,9 @@
   DCHECK(ok);
 
   std::unique_ptr<LocalCredentialManagement> local_cred_man =
-      LocalCredentialManagement::Create();
+      LocalCredentialManagement::Create(Profile::FromBrowserContext(
+          web_ui()->GetWebContents()->GetBrowserContext()));
   local_cred_man->Delete(
-      Profile::FromBrowserContext(
-          web_ui()->GetWebContents()->GetBrowserContext()),
       credential_id,
       base::BindOnce(&PasskeysHandler::OnDeleteComplete,
                      weak_factory_.GetWeakPtr(), args[0].GetString(),
diff --git a/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_side_panel_ui.cc b/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_side_panel_ui.cc
index 2627b80..b9e93410 100644
--- a/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_side_panel_ui.cc
+++ b/chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_side_panel_ui.cc
@@ -7,6 +7,8 @@
 #include <string>
 #include <utility>
 
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/commerce/shopping_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/webui/favicon_source.h"
@@ -16,7 +18,9 @@
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/side_panel_resources.h"
 #include "chrome/grit/side_panel_resources_map.h"
+#include "components/bookmarks/browser/bookmark_model.h"
 #include "components/bookmarks/common/bookmark_pref_names.h"
+#include "components/commerce/core/shopping_service.h"
 #include "components/commerce/core/webui/shopping_list_handler.h"
 #include "components/favicon_base/favicon_url_parser.h"
 #include "components/prefs/pref_service.h"
@@ -43,6 +47,10 @@
       {"tooltipClose", IDS_CLOSE},
       {"tooltipDelete", IDS_DELETE},
       {"shoppingListFolderTitle", IDS_SIDE_PANEL_TRACKED_PRODUCTS},
+      {"shoppingListTrackPriceButtonDescription",
+       IDS_PRICE_TRACKING_TRACK_PRODUCT_ACCESSIBILITY},
+      {"shoppingListUntrackPriceButtonDescription",
+       IDS_PRICE_TRACKING_UNTRACK_PRODUCT_ACCESSIBILITY},
   };
   for (const auto& str : kLocalizedStrings)
     webui::AddLocalizedString(source, str.name, str.id);
@@ -95,6 +103,11 @@
 
 void BookmarksSidePanelUI::CreateShoppingListHandler(
     mojo::PendingReceiver<shopping_list::mojom::ShoppingListHandler> receiver) {
-  shopping_list_handler_ =
-      std::make_unique<commerce::ShoppingListHandler>(std::move(receiver));
+  Profile* const profile = Profile::FromWebUI(web_ui());
+  bookmarks::BookmarkModel* bookmark_model =
+      BookmarkModelFactory::GetForBrowserContext(profile);
+  commerce::ShoppingService* shopping_service =
+      commerce::ShoppingServiceFactory::GetForBrowserContext(profile);
+  shopping_list_handler_ = std::make_unique<commerce::ShoppingListHandler>(
+      std::move(receiver), bookmark_model, shopping_service);
 }
diff --git a/chrome/browser/ui/webui/side_panel/reading_list/reading_list.mojom b/chrome/browser/ui/webui/side_panel/reading_list/reading_list.mojom
index 3a34905..f058e95 100644
--- a/chrome/browser/ui/webui/side_panel/reading_list/reading_list.mojom
+++ b/chrome/browser/ui/webui/side_panel/reading_list/reading_list.mojom
@@ -45,6 +45,9 @@
   // Updates a read later entry's read status.
   UpdateReadStatus(url.mojom.Url url, bool read);
 
+  // Marks the current tab as read in the reading list.
+  MarkCurrentTabAsRead();
+
   // Adds the current tab to the reading list.
   AddCurrentTab();
 
@@ -67,6 +70,7 @@
 enum CurrentPageActionButtonState {
   kAdd,
   kDisabled,
+  kMarkAsRead,
 };
 
 // WebUI-side handler for requests from the browser.
diff --git a/chrome/browser/ui/webui/side_panel/reading_list/reading_list_page_handler.cc b/chrome/browser/ui/webui/side_panel/reading_list/reading_list_page_handler.cc
index d143e28..53e07190 100644
--- a/chrome/browser/ui/webui/side_panel/reading_list/reading_list_page_handler.cc
+++ b/chrome/browser/ui/webui/side_panel/reading_list/reading_list_page_handler.cc
@@ -202,6 +202,15 @@
                                    : "DesktopReadingList.MarkAsUnread"));
 }
 
+void ReadingListPageHandler::MarkCurrentTabAsRead() {
+  Browser* browser = chrome::FindLastActive();
+  if (!browser)
+    return;
+
+  chrome::MarkCurrentTabAsReadInReadLater(browser);
+  base::RecordAction(base::UserMetricsAction("DesktopReadingList.MarkAsRead"));
+}
+
 void ReadingListPageHandler::AddCurrentTab() {
   Browser* browser = chrome::FindLastActive();
   if (!browser)
@@ -362,10 +371,11 @@
     return;
 
   reading_list::mojom::CurrentPageActionButtonState new_state;
-  if (!reading_list_model_->IsUrlSupported(url.value()) ||
-      (reading_list_model_->GetEntryByURL(url.value()) &&
-       !reading_list_model_->GetEntryByURL(url.value())->IsRead())) {
+  if (!reading_list_model_->IsUrlSupported(url.value())) {
     new_state = reading_list::mojom::CurrentPageActionButtonState::kDisabled;
+  } else if ((reading_list_model_->GetEntryByURL(url.value()) &&
+              !reading_list_model_->GetEntryByURL(url.value())->IsRead())) {
+    new_state = reading_list::mojom::CurrentPageActionButtonState::kMarkAsRead;
   } else {
     new_state = reading_list::mojom::CurrentPageActionButtonState::kAdd;
   }
diff --git a/chrome/browser/ui/webui/side_panel/reading_list/reading_list_page_handler.h b/chrome/browser/ui/webui/side_panel/reading_list/reading_list_page_handler.h
index 89ec9d8..f54e0b1b 100644
--- a/chrome/browser/ui/webui/side_panel/reading_list/reading_list_page_handler.h
+++ b/chrome/browser/ui/webui/side_panel/reading_list/reading_list_page_handler.h
@@ -48,6 +48,7 @@
                bool mark_as_read,
                ui::mojom::ClickModifiersPtr click_modifiers) override;
   void UpdateReadStatus(const GURL& url, bool read) override;
+  void MarkCurrentTabAsRead() override;
   void AddCurrentTab() override;
   void RemoveEntry(const GURL& url) override;
   void ShowContextMenuForURL(const GURL& url, int32_t x, int32_t y) override;
diff --git a/chrome/browser/ui/webui/side_panel/reading_list/reading_list_page_handler_unittest.cc b/chrome/browser/ui/webui/side_panel/reading_list/reading_list_page_handler_unittest.cc
index 14779f6..38ef490 100644
--- a/chrome/browser/ui/webui/side_panel/reading_list/reading_list_page_handler_unittest.cc
+++ b/chrome/browser/ui/webui/side_panel/reading_list/reading_list_page_handler_unittest.cc
@@ -346,9 +346,17 @@
   EXPECT_EQ(browser()->tab_strip_model()->count(), 4);
   handler()->OpenURL(GURL(kTabUrl3), true, GetClickModifiers());
   EXPECT_EQ(browser()->tab_strip_model()->count(), 4);
+  // Expect CurrentPageActionButtonState to be add, due to the current
+  // tab not being on the reading list.
+  EXPECT_EQ(handler()->GetCurrentPageActionButtonStateForTesting(),
+            reading_list::mojom::CurrentPageActionButtonState::kAdd);
   model()->AddEntry(GURL(kTabUrl3), kTabName3,
                     reading_list::EntrySource::ADDED_VIA_CURRENT_APP);
 
+  // Expect CurrentPageActionButtonState to be mark as read, due to the current
+  // tab being unread on the reading list.
+  EXPECT_EQ(handler()->GetCurrentPageActionButtonStateForTesting(),
+            reading_list::mojom::CurrentPageActionButtonState::kMarkAsRead);
   // Expect ItemsChanged to be called 6 times.
   // Four times for the two AddEntry calls in SetUp().
   // Twice for the AddEntry call above.
diff --git a/chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.cc b/chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.cc
index 45022891..140d101 100644
--- a/chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.cc
+++ b/chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.cc
@@ -7,6 +7,8 @@
 #include <string>
 #include <utility>
 
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/commerce/shopping_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/read_later/reading_list_model_factory.h"
 #include "chrome/browser/ui/ui_features.h"
@@ -19,7 +21,9 @@
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/side_panel_resources.h"
 #include "chrome/grit/side_panel_resources_map.h"
+#include "components/bookmarks/browser/bookmark_model.h"
 #include "components/bookmarks/common/bookmark_pref_names.h"
+#include "components/commerce/core/shopping_service.h"
 #include "components/commerce/core/webui/shopping_list_handler.h"
 #include "components/favicon_base/favicon_url_parser.h"
 #include "components/prefs/pref_service.h"
@@ -51,6 +55,7 @@
        IDS_READ_LATER_MENU_EMPTY_STATE_ADD_FROM_DIALOG_SUBHEADER},
       {"emptyStateHeader", IDS_READ_LATER_MENU_EMPTY_STATE_HEADER},
       {"emptyStateSubheader", IDS_READ_LATER_MENU_EMPTY_STATE_SUBHEADER},
+      {"markCurrentTabAsRead", IDS_READ_LATER_MARK_CURRENT_TAB_READ},
       {"readAnythingTabTitle", IDS_READ_ANYTHING_TITLE},
       {"readHeader", IDS_READ_LATER_MENU_READ_HEADER},
       {"title", IDS_READ_LATER_TITLE},
@@ -61,6 +66,10 @@
       {"tooltipMarkAsUnread", IDS_READ_LATER_MENU_TOOLTIP_MARK_AS_UNREAD},
       {"unreadHeader", IDS_READ_LATER_MENU_UNREAD_HEADER},
       {"shoppingListFolderTitle", IDS_SIDE_PANEL_TRACKED_PRODUCTS},
+      {"shoppingListTrackPriceButtonDescription",
+       IDS_PRICE_TRACKING_TRACK_PRODUCT_ACCESSIBILITY},
+      {"shoppingListUntrackPriceButtonDescription",
+       IDS_PRICE_TRACKING_UNTRACK_PRODUCT_ACCESSIBILITY},
   };
   for (const auto& str : kLocalizedStrings)
     webui::AddLocalizedString(source, str.name, str.id);
@@ -151,8 +160,13 @@
 
 void ReadingListUI::CreateShoppingListHandler(
     mojo::PendingReceiver<shopping_list::mojom::ShoppingListHandler> receiver) {
-  shopping_list_handler_ =
-      std::make_unique<commerce::ShoppingListHandler>(std::move(receiver));
+  Profile* const profile = Profile::FromWebUI(web_ui());
+  bookmarks::BookmarkModel* bookmark_model =
+      BookmarkModelFactory::GetForBrowserContext(profile);
+  commerce::ShoppingService* shopping_service =
+      commerce::ShoppingServiceFactory::GetForBrowserContext(profile);
+  shopping_list_handler_ = std::make_unique<commerce::ShoppingListHandler>(
+      std::move(receiver), bookmark_model, shopping_service);
 }
 
 void ReadingListUI::SetActiveTabURL(const GURL& url) {
diff --git a/chrome/browser/web_applications/commands/install_isolated_app_command.cc b/chrome/browser/web_applications/commands/install_isolated_app_command.cc
index 0aeda09..75d3fa80 100644
--- a/chrome/browser/web_applications/commands/install_isolated_app_command.cc
+++ b/chrome/browser/web_applications/commands/install_isolated_app_command.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/web_applications/commands/install_isolated_app_command.h"
 
 #include <memory>
+#include <sstream>
 #include <string>
 #include <utility>
 
@@ -14,11 +15,14 @@
 #include "base/check.h"
 #include "base/containers/flat_set.h"
 #include "base/sequence_checker.h"
+#include "base/strings/strcat.h"
 #include "base/strings/string_piece_forward.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/types/expected.h"
 #include "base/values.h"
 #include "chrome/browser/web_applications/commands/web_app_command.h"
 #include "chrome/browser/web_applications/locks/shared_web_contents_with_app_lock.h"
+#include "chrome/browser/web_applications/os_integration/os_integration_manager.h"
 #include "chrome/browser/web_applications/web_app_data_retriever.h"
 #include "chrome/browser/web_applications/web_app_helpers.h"
 #include "chrome/browser/web_applications/web_app_id.h"
@@ -55,9 +59,11 @@
     base::StringPiece url,
     WebAppUrlLoader& url_loader,
     WebAppInstallFinalizer& install_finalizer,
-    base::OnceCallback<void(InstallIsolatedAppCommandResult)> callback)
+    base::OnceCallback<void(base::expected<InstallIsolatedAppCommandSuccess,
+                                           InstallIsolatedAppCommandError>)>
+        callback)
     : lock_(std::make_unique<SharedWebContentsWithAppLock>(
-          base::flat_set<AppId>{GenerateAppId("/", GURL{url})})),
+          base::flat_set<AppId>{GenerateAppId("", GURL{url})})),
       url_(url),
       url_loader_(url_loader),
       install_finalizer_(install_finalizer),
@@ -66,11 +72,12 @@
 
   DCHECK(!callback.is_null());
 
-  callback_ = base::BindOnce([](InstallIsolatedAppCommandResult result) {
-                webapps::InstallableMetrics::TrackInstallResult(
-                    result == InstallIsolatedAppCommandResult::kOk);
-                return result;
-              }).Then(std::move(callback));
+  callback_ =
+      base::BindOnce([](base::expected<InstallIsolatedAppCommandSuccess,
+                                       InstallIsolatedAppCommandError> result) {
+        webapps::InstallableMetrics::TrackInstallResult(result.has_value());
+        return result;
+      }).Then(std::move(callback));
 }
 
 void InstallIsolatedAppCommand::SetDataRetrieverForTesting(
@@ -109,7 +116,8 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (!IsUrlLoadingResultSuccess(result)) {
-    ReportFailure();
+    ReportFailure(base::StrCat({"Error during URL loading: ",
+                                ConvertUrlLoaderResultToString(result)}));
     return;
   }
 
@@ -152,11 +160,11 @@
     return absl::nullopt;
   }
 
-  if (*encoded_id != "/") {
+  if (!encoded_id->empty()) {
     return absl::nullopt;
   }
 
-  info.manifest_id = *encoded_id;
+  info.manifest_id = "";
 
   if (manifest.scope != GURL{url_}.Resolve("/")) {
     return absl::nullopt;
@@ -173,7 +181,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (!is_installable) {
-    ReportFailure();
+    ReportFailure("App is not installable.");
     return;
   }
 
@@ -183,7 +191,7 @@
       << "must be true when |is_installable| is true.";
 
   if (!opt_manifest) {
-    ReportFailure();
+    ReportFailure("Manifest is null.");
     return;
   }
 
@@ -207,23 +215,27 @@
 }
 
 void InstallIsolatedAppCommand::FinalizeInstall(const WebAppInstallInfo& info) {
-  auto is_finalize_install_success =
-      [](const AppId& unused_app_id,
-         webapps::InstallResultCode install_result_code,
-         OsHooksErrors unused_os_hooks_errors) {
-        return install_result_code ==
-               webapps::InstallResultCode::kSuccessNewInstall;
-      };
-
   install_finalizer_.FinalizeInstall(
       info,
       WebAppInstallFinalizer::FinalizeOptions{
           /*install_surface=*/webapps::WebappInstallSource::
               ISOLATED_APP_DEV_INSTALL,
       },
-      base::BindOnce(is_finalize_install_success)
-          .Then(base::BindOnce(&InstallIsolatedAppCommand::Report,
-                               weak_factory_.GetWeakPtr())));
+      base::BindOnce(&InstallIsolatedAppCommand::OnFinalizeInstall,
+                     weak_factory_.GetWeakPtr()));
+}
+
+void InstallIsolatedAppCommand::OnFinalizeInstall(
+    const AppId& unused_app_id,
+    webapps::InstallResultCode install_result_code,
+    OsHooksErrors unused_os_hooks_errors) {
+  if (install_result_code == webapps::InstallResultCode::kSuccessNewInstall) {
+    ReportSuccess();
+  } else {
+    std::stringstream os;
+    os << install_result_code;
+    ReportFailure(base::StrCat({"Error during finalization: ", os.str()}));
+  }
 }
 
 void InstallIsolatedAppCommand::DownloadIcons(WebAppInstallInfo install_info) {
@@ -240,23 +252,26 @@
   ReportFailure();
 }
 
-void InstallIsolatedAppCommand::ReportFailure() {
-  Report(/*success=*/false);
-}
-
-void InstallIsolatedAppCommand::ReportSuccess() {
-  Report(/*success=*/true);
-}
-
-void InstallIsolatedAppCommand::Report(bool success) {
+void InstallIsolatedAppCommand::ReportFailure(
+    absl::optional<std::string> message) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!callback_.is_null());
 
   SignalCompletionAndSelfDestruct(
-      success ? CommandResult::kSuccess : CommandResult::kFailure,
+      CommandResult::kFailure,
       base::BindOnce(std::move(callback_),
-                     success ? InstallIsolatedAppCommandResult::kOk
-                             : InstallIsolatedAppCommandResult::kUnknownError));
+                     base::unexpected{InstallIsolatedAppCommandError{
+                         .message = message.value_or("<no error message>"),
+                     }}));
+}
+
+void InstallIsolatedAppCommand::ReportSuccess() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(!callback_.is_null());
+
+  SignalCompletionAndSelfDestruct(
+      CommandResult::kSuccess,
+      base::BindOnce(std::move(callback_), InstallIsolatedAppCommandSuccess{}));
 }
 
 base::Value InstallIsolatedAppCommand::ToDebugValue() const {
diff --git a/chrome/browser/web_applications/commands/install_isolated_app_command.h b/chrome/browser/web_applications/commands/install_isolated_app_command.h
index 72cd931a..cd2e7c2 100644
--- a/chrome/browser/web_applications/commands/install_isolated_app_command.h
+++ b/chrome/browser/web_applications/commands/install_isolated_app_command.h
@@ -12,9 +12,13 @@
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
 #include "base/strings/string_piece_forward.h"
+#include "base/types/expected.h"
 #include "base/values.h"
 #include "chrome/browser/web_applications/commands/web_app_command.h"
+#include "chrome/browser/web_applications/os_integration/os_integration_manager.h"
+#include "chrome/browser/web_applications/web_app_id.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
+#include "components/webapps/browser/install_result_code.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/mojom/manifest/manifest.mojom-forward.h"
 
@@ -34,6 +38,11 @@
   kUnknownError,
 };
 
+struct InstallIsolatedAppCommandSuccess {};
+struct InstallIsolatedAppCommandError {
+  std::string message;
+};
+
 class InstallIsolatedAppCommand : public WebAppCommand {
  public:
   // TODO(kuragin): Consider to create an instance of |GURL| instead of passing
@@ -49,7 +58,9 @@
       base::StringPiece application_url,
       WebAppUrlLoader& url_loader,
       WebAppInstallFinalizer& install_finalizer,
-      base::OnceCallback<void(InstallIsolatedAppCommandResult)> callback);
+      base::OnceCallback<void(base::expected<InstallIsolatedAppCommandSuccess,
+                                             InstallIsolatedAppCommandError>)>
+          callback);
   ~InstallIsolatedAppCommand() override;
 
   Lock& lock() const override;
@@ -64,9 +75,8 @@
       std::unique_ptr<WebAppDataRetriever> data_retriever);
 
  private:
-  void ReportFailure();
+  void ReportFailure(absl::optional<std::string> message = absl::nullopt);
   void ReportSuccess();
-  void Report(bool success);
 
   void DownloadIcons(WebAppInstallInfo install_info);
 
@@ -83,6 +93,9 @@
       const blink::mojom::Manifest& manifest,
       const GURL& manifest_url);
   void FinalizeInstall(const WebAppInstallInfo& info);
+  void OnFinalizeInstall(const AppId& unused_app_id,
+                         webapps::InstallResultCode install_result_code,
+                         OsHooksErrors unused_os_hooks_errors);
 
   SEQUENCE_CHECKER(sequence_checker_);
 
@@ -95,7 +108,9 @@
 
   std::unique_ptr<WebAppDataRetriever> data_retriever_;
 
-  base::OnceCallback<void(InstallIsolatedAppCommandResult)> callback_;
+  base::OnceCallback<void(base::expected<InstallIsolatedAppCommandSuccess,
+                                         InstallIsolatedAppCommandError>)>
+      callback_;
 
   base::WeakPtrFactory<InstallIsolatedAppCommand> weak_factory_{this};
 };
diff --git a/chrome/browser/web_applications/commands/install_isolated_app_command_unittest.cc b/chrome/browser/web_applications/commands/install_isolated_app_command_unittest.cc
index d16d872..b307006 100644
--- a/chrome/browser/web_applications/commands/install_isolated_app_command_unittest.cc
+++ b/chrome/browser/web_applications/commands/install_isolated_app_command_unittest.cc
@@ -7,6 +7,8 @@
 #include <map>
 #include <memory>
 #include <sstream>
+#include <type_traits>
+#include <utility>
 #include <vector>
 
 #include "base/bind.h"
@@ -52,6 +54,7 @@
 using ::testing::AllOf;
 using ::testing::Eq;
 using ::testing::Field;
+using ::testing::HasSubstr;
 using ::testing::IsEmpty;
 using ::testing::IsFalse;
 using ::testing::IsNull;
@@ -62,12 +65,13 @@
 using ::testing::Pair;
 using ::testing::Pointee;
 using ::testing::Property;
+using ::testing::ResultOf;
 using ::testing::UnorderedElementsAre;
 
 blink::mojom::ManifestPtr CreateDefaultManifest(
     base::StringPiece application_url) {
   auto manifest = blink::mojom::Manifest::New();
-  manifest->id = u"/";
+  manifest->id = u"";
   manifest->scope = GURL{application_url}.Resolve("/");
   manifest->start_url =
       GURL{application_url}.Resolve("/testing-start-url.html");
@@ -121,7 +125,9 @@
 
   std::unique_ptr<InstallIsolatedAppCommand> CreateCommand(
       base::StringPiece url,
-      base::OnceCallback<void(InstallIsolatedAppCommandResult)> callback) {
+      base::OnceCallback<void(base::expected<InstallIsolatedAppCommandSuccess,
+                                             InstallIsolatedAppCommandError>)>
+          callback) {
     return std::make_unique<InstallIsolatedAppCommand>(
         url, *url_loader_, *install_finalizer_, std::move(callback));
   }
@@ -143,6 +149,12 @@
         GURL{url}, WebAppUrlLoader::Result::kFailedErrorPageLoaded);
   }
 
+  void ExpectFailureForURL(base::StringPiece url,
+                           WebAppUrlLoader::Result result) {
+    DCHECK(GURL{url}.is_valid());
+    url_loader_->SetNextLoadUrlResult(GURL{url}, result);
+  }
+
   WebAppUrlLoader::UrlComparison last_call_url_comparison() const {
     absl::optional<TestWebAppUrlLoader::LoadUrlCall> last_url_load_call =
         url_loader_->last_load_url_call();
@@ -150,10 +162,14 @@
     return last_url_load_call->url_comparison;
   }
 
-  InstallIsolatedAppCommandResult ExecuteCommand(
+  base::expected<InstallIsolatedAppCommandSuccess,
+                 InstallIsolatedAppCommandError>
+  ExecuteCommand(
       base::StringPiece url,
       std::unique_ptr<WebAppDataRetriever> data_retriever = nullptr) {
-    base::test::TestFuture<InstallIsolatedAppCommandResult> test_future;
+    base::test::TestFuture<base::expected<InstallIsolatedAppCommandSuccess,
+                                          InstallIsolatedAppCommandError>>
+        test_future;
     auto command = CreateCommand(url, test_future.GetCallback());
     command->SetDataRetrieverForTesting(data_retriever != nullptr
                                             ? std::move(data_retriever)
@@ -162,9 +178,10 @@
     return test_future.Get();
   }
 
-  InstallIsolatedAppCommandResult ExecuteCommandWithManifest(
-      base::StringPiece application_url,
-      const blink::mojom::ManifestPtr& manifest) {
+  base::expected<InstallIsolatedAppCommandSuccess,
+                 InstallIsolatedAppCommandError>
+  ExecuteCommandWithManifest(base::StringPiece application_url,
+                             const blink::mojom::ManifestPtr& manifest) {
     SetPrepareForLoadResultLoaded();
 
     ExpectLoadedForURL(application_url);
@@ -208,9 +225,41 @@
   }();
 };
 
+MATCHER_P(IsExpectedValue, value_matcher, "") {
+  if (!arg.has_value()) {
+    *result_listener << "which is not engaged";
+    return false;
+  }
+
+  return ExplainMatchResult(value_matcher, arg.value(), result_listener);
+}
+
+MATCHER_P(IsUnexpectedValue, error_matcher, "") {
+  if (arg.has_value()) {
+    *result_listener << "which is not engaged";
+    return false;
+  }
+
+  return ExplainMatchResult(error_matcher, arg.error(), result_listener);
+}
+
 MATCHER(IsInstallationOk, "") {
-  return ExplainMatchResult(Eq(InstallIsolatedAppCommandResult::kOk), arg,
-                            result_listener);
+  return ExplainMatchResult(IsExpectedValue(_), arg, result_listener);
+}
+
+MATCHER_P(IsInstallationError, message_matcher, "") {
+  return ExplainMatchResult(
+      IsUnexpectedValue(ResultOf(
+          "error.message",
+          [](const InstallIsolatedAppCommandError& error) {
+            return error.message;
+          },
+          message_matcher)),
+      arg, result_listener);
+}
+
+MATCHER(IsInstallationError, "") {
+  return ExplainMatchResult(IsUnexpectedValue(_), arg, result_listener);
 }
 
 TEST_F(InstallIsolatedAppCommandTest, CommandCanBeExecutedSuccesfully) {
@@ -228,7 +277,19 @@
   ExpectFailureForURL("http://test-url-example.com");
 
   EXPECT_THAT(ExecuteCommand("http://test-url-example.com"),
-              Not(IsInstallationOk()));
+              IsInstallationError(HasSubstr("Error during URL loading: ")));
+}
+
+TEST_F(InstallIsolatedAppCommandTest,
+       PropagateErrorWhenURLLoaderFailsWithDestroyedWebContentsError) {
+  SetPrepareForLoadResultLoaded();
+
+  ExpectFailureForURL("http://test-url-example.com",
+                      WebAppUrlLoader::Result::kFailedWebContentsDestroyed);
+
+  EXPECT_THAT(ExecuteCommand("http://test-url-example.com"),
+              IsInstallationError(HasSubstr(
+                  "Error during URL loading: FailedWebContentsDestroyed")));
 }
 
 TEST_F(InstallIsolatedAppCommandTest,
@@ -248,7 +309,7 @@
   SetPrepareForLoadResultLoaded();
 
   EXPECT_THAT(ExecuteCommand("some definetely invalid url"),
-              Not(IsInstallationOk()));
+              IsInstallationError());
 }
 
 TEST_F(InstallIsolatedAppCommandTest, URLLoaderIgnoresQueryParameters) {
@@ -274,7 +335,8 @@
       webapps::InstallResultCode::kNotInstallable);
 
   EXPECT_THAT(ExecuteCommand("http://test-url-example.com"),
-              Not(IsInstallationOk()));
+              IsInstallationError(
+                  HasSubstr("Error during finalization: kNotInstallable")));
 }
 
 TEST_F(InstallIsolatedAppCommandTest,
@@ -335,18 +397,20 @@
 
   EXPECT_THAT(ExecuteCommand("http://test-url-example.com",
                              std::move(fake_data_retriever)),
-              Not(IsInstallationOk()));
+              IsInstallationError(HasSubstr("App is not installable")));
 }
 
 TEST_F(InstallIsolatedAppCommandTest, CommandLocksOnAppIdAndWebContents) {
-  base::test::TestFuture<InstallIsolatedAppCommandResult> test_future;
+  base::test::TestFuture<base::expected<InstallIsolatedAppCommandSuccess,
+                                        InstallIsolatedAppCommandError>>
+      test_future;
   auto command =
       CreateCommand("http://test-app-id.com/", test_future.GetCallback());
   EXPECT_THAT(command->lock(),
               AllOf(Property(&Lock::type, Eq(Lock::Type::kAppAndWebContents)),
                     Property(&Lock::app_ids,
                              UnorderedElementsAre(GenerateAppIdFromUnhashed(
-                                 "http://test-app-id.com//")))));
+                                 "http://test-app-id.com/")))));
 }
 
 TEST_F(InstallIsolatedAppCommandTest,
@@ -369,7 +433,7 @@
 
   EXPECT_THAT(ExecuteCommand("http://test-url-example.com",
                              std::move(fake_data_retriever)),
-              Not(IsInstallationOk()));
+              IsInstallationError(HasSubstr("Manifest is null")));
 }
 
 using InstallIsolatedAppCommandManifestTest = InstallIsolatedAppCommandTest;
@@ -382,7 +446,7 @@
 
   EXPECT_THAT(ExecuteCommandWithManifest("http://manifest-test-url.com",
                                          manifest.Clone()),
-              Not(IsInstallationOk()));
+              IsInstallationError());
 
   EXPECT_THAT(install_finalizer().web_app_info(), IsNull());
 }
@@ -396,14 +460,14 @@
 
   EXPECT_THAT(ExecuteCommandWithManifest("http://manifest-test-url.com",
                                          manifest.Clone()),
-              Not(IsInstallationOk()));
+              IsInstallationError());
 }
 
 TEST_F(InstallIsolatedAppCommandManifestTest,
-       PassesManifestIdToFinalizerWhenManifestIdIsSlash) {
+       PassesManifestIdToFinalizerWhenManifestIdIsEmpty) {
   blink::mojom::ManifestPtr manifest =
       CreateDefaultManifest("http://manifest-test-url.com");
-  manifest->id = u"/";
+  manifest->id = u"";
 
   EXPECT_THAT(ExecuteCommandWithManifest("http://manifest-test-url.com",
                                          manifest.Clone()),
@@ -411,17 +475,17 @@
 
   EXPECT_THAT(install_finalizer().web_app_info(),
               Pointee(Field(&WebAppInstallInfo::manifest_id,
-                            Optional(std::string{"/"}))));
+                            Optional(std::string{""}))));
 }
 
-TEST_F(InstallIsolatedAppCommandManifestTest, FailsWhenManifestIdIsNotSlash) {
+TEST_F(InstallIsolatedAppCommandManifestTest, FailsWhenManifestIdIsNotEmpty) {
   blink::mojom::ManifestPtr manifest =
       CreateDefaultManifest("http://manifest-test-url.com");
   manifest->id = u"test-manifest-id";
 
   EXPECT_THAT(ExecuteCommandWithManifest("http://manifest-test-url.com",
                                          manifest.Clone()),
-              Not(IsInstallationOk()));
+              IsInstallationError());
   EXPECT_THAT(install_finalizer().web_app_info(), IsNull());
 }
 
@@ -434,7 +498,7 @@
 
   EXPECT_THAT(ExecuteCommandWithManifest("http://manifest-test-url.com",
                                          manifest.Clone()),
-              Not(IsInstallationOk()));
+              IsInstallationError());
   EXPECT_THAT(install_finalizer().web_app_info(), IsNull());
 }
 
@@ -540,7 +604,7 @@
   base::HistogramTester histogram_tester;
 
   EXPECT_THAT(ExecuteCommand("some definetely invalid url"),
-              Not(IsInstallationOk()));
+              IsInstallationError());
 
   EXPECT_THAT(histogram_tester.GetAllSamples("WebApp.Install.Result"),
               BucketsAre(base::Bucket(false, 1)));
@@ -554,7 +618,7 @@
   base::HistogramTester histogram_tester;
 
   EXPECT_THAT(ExecuteCommand("http://test-url-example.com"),
-              Not(IsInstallationOk()));
+              IsInstallationError());
 
   EXPECT_THAT(histogram_tester.GetAllSamples("WebApp.Install.Result"),
               BucketsAre(base::Bucket(false, 1)));
@@ -582,7 +646,7 @@
 
   EXPECT_THAT(ExecuteCommand("http://test-url-example.com",
                              std::move(fake_data_retriever)),
-              Not(IsInstallationOk()));
+              IsInstallationError());
 
   EXPECT_THAT(histogram_tester.GetAllSamples("WebApp.Install.Result"),
               BucketsAre(base::Bucket(false, 1)));
@@ -609,14 +673,14 @@
 
   EXPECT_THAT(ExecuteCommand("http://test-url-example.com",
                              std::move(fake_data_retriever)),
-              Not(IsInstallationOk()));
+              IsInstallationError());
 
   EXPECT_THAT(histogram_tester.GetAllSamples("WebApp.Install.Result"),
               BucketsAre(base::Bucket(false, 1)));
 }
 
 TEST_F(InstallIsolatedAppCommandMetricsTest,
-       ReportFailureWhenManifestIdIsNotSlash) {
+       ReportFailureWhenManifestIdIsNotEmpty) {
   blink::mojom::ManifestPtr manifest =
       CreateDefaultManifest("http://manifest-test-url.com");
   manifest->id = u"test manifest id";
@@ -625,7 +689,7 @@
 
   EXPECT_THAT(ExecuteCommandWithManifest("http://manifest-test-url.com",
                                          manifest.Clone()),
-              Not(IsInstallationOk()));
+              IsInstallationError());
   EXPECT_THAT(histogram_tester.GetAllSamples("WebApp.Install.Result"),
               BucketsAre(base::Bucket(false, 1)));
 }
diff --git a/chrome/browser/web_applications/isolated_web_apps/install_isolated_app_from_command_line.cc b/chrome/browser/web_applications/isolated_web_apps/install_isolated_app_from_command_line.cc
index 9b4cc0b..5f63eae 100644
--- a/chrome/browser/web_applications/isolated_web_apps/install_isolated_app_from_command_line.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/install_isolated_app_from_command_line.cc
@@ -47,16 +47,17 @@
 
                   WebAppUrlLoader& url_loader_ref = *url_loader;
 
-                  base::OnceCallback<void(InstallIsolatedAppCommandResult)>
+                  base::OnceCallback<void(
+                      base::expected<InstallIsolatedAppCommandSuccess,
+                                     InstallIsolatedAppCommandError>)>
                       callback = base::BindOnce(
                           [](std::unique_ptr<WebAppUrlLoader> url_loader,
-                             InstallIsolatedAppCommandResult result) {
-                            switch (result) {
-                              case InstallIsolatedAppCommandResult::kOk:
-                                break;
-                              default:
-                                LOG(ERROR) << "Isolated app auto installation "
-                                              "is failed.";
+                             base::expected<InstallIsolatedAppCommandSuccess,
+                                            InstallIsolatedAppCommandError>
+                                 result) {
+                            if (!result.has_value()) {
+                              LOG(ERROR) << "Isolated app auto installation "
+                                            "is failed.";
                             }
                           },
                           std::move(url_loader));
diff --git a/chrome/browser/webauthn/local_credential_management.cc b/chrome/browser/webauthn/local_credential_management.cc
new file mode 100644
index 0000000..1d5431a
--- /dev/null
+++ b/chrome/browser/webauthn/local_credential_management.cc
@@ -0,0 +1,61 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/webauthn/local_credential_management.h"
+
+#include "base/i18n/string_compare.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/prefs/pref_service.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+
+CredentialComparator::CredentialComparator() {
+  UErrorCode error = U_ZERO_ERROR;
+  collator_.reset(
+      icu::Collator::createInstance(icu::Locale::getDefault(), error));
+}
+
+CredentialComparator::~CredentialComparator() = default;
+
+bool CredentialComparator::operator()(
+    const device::DiscoverableCredentialMetadata& a,
+    const device::DiscoverableCredentialMetadata& b) {
+  UCollationResult relation = base::i18n::CompareString16WithCollator(
+      *collator_, ETLDPlus1(a.rp_id), ETLDPlus1(b.rp_id));
+  if (relation != UCOL_EQUAL) {
+    return relation == UCOL_LESS;
+  }
+
+  relation = base::i18n::CompareString16WithCollator(
+      *collator_, LabelReverse(a.rp_id), LabelReverse(b.rp_id));
+  if (relation != UCOL_EQUAL) {
+    return relation == UCOL_LESS;
+  }
+
+  relation = base::i18n::CompareString16WithCollator(
+      *collator_, base::UTF8ToUTF16(a.user.name.value_or("")),
+      base::UTF8ToUTF16(b.user.name.value_or("")));
+  if (relation != UCOL_EQUAL) {
+    return relation == UCOL_LESS;
+  }
+  return a.cred_id < b.cred_id;
+}
+
+std::u16string CredentialComparator::ETLDPlus1(const std::string& rp_id) {
+  std::string domain = net::registry_controlled_domains::GetDomainAndRegistry(
+      rp_id, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+  if (domain.empty()) {
+    domain = rp_id;
+  }
+  return base::UTF8ToUTF16(domain);
+}
+
+std::u16string CredentialComparator::LabelReverse(const std::string& rp_id) {
+  std::vector<base::StringPiece> parts = base::SplitStringPiece(
+      rp_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+  std::reverse(parts.begin(), parts.end());
+  return base::UTF8ToUTF16(base::JoinString(parts, "."));
+}
diff --git a/chrome/browser/webauthn/local_credential_management.h b/chrome/browser/webauthn/local_credential_management.h
index 0459651..55f2892 100644
--- a/chrome/browser/webauthn/local_credential_management.h
+++ b/chrome/browser/webauthn/local_credential_management.h
@@ -8,10 +8,32 @@
 #include <vector>
 
 #include "base/callback.h"
+#include "chrome/browser/profiles/profile_observer.h"
 #include "device/fido/discoverable_credential_metadata.h"
+#include "third_party/icu/source/i18n/unicode/coll.h"
 
 class Profile;
 
+// CredentialComparator compares two credentials based on their RP ID's eTLD +
+// 1, then on the label-reversed RP ID, then on user.name, and finally on
+// credential ID if the previous values are equal.
+class CredentialComparator {
+ public:
+  CredentialComparator();
+
+  ~CredentialComparator();
+
+  bool operator()(const device::DiscoverableCredentialMetadata& a,
+                  const device::DiscoverableCredentialMetadata& b);
+
+ private:
+  static std::u16string ETLDPlus1(const std::string& rp_id);
+
+  static std::u16string LabelReverse(const std::string& rp_id);
+
+  std::unique_ptr<icu::Collator> collator_;
+};
+
 // LocalCredentialManagement provides functions for managing local WebAuthn
 // credentials, i.e. those kept in a platform authenticator like Windows Hello
 // or Chrome's TouchId authenticator. This is in contrast to the classes in
@@ -24,14 +46,13 @@
   // Returns an instance of LocalCredentialManagement depending on the
   // underlying operating system. It is incorrect to call this on an unsupported
   // OS.
-  static std::unique_ptr<LocalCredentialManagement> Create();
+  static std::unique_ptr<LocalCredentialManagement> Create(Profile* profile);
 
   // HasCredentials resolves whether a non-zero number of credentials exists on
   // the platform authenticator. This may be significantly more efficient than
   // calling `Enumerate`. The callback will never be invoked before the
   // function returns.
-  virtual void HasCredentials(Profile* profile,
-                              base::OnceCallback<void(bool)> callback) = 0;
+  virtual void HasCredentials(base::OnceCallback<void(bool)> callback) = 0;
 
   // Enumerate returns the metadata for all credentials on the platform. The
   // callback will never be invoked before the function returns.
@@ -39,7 +60,6 @@
   // If enumeration isn't supported on this version of Windows the callback will
   // be run with `absl::nullopt`.
   virtual void Enumerate(
-      Profile* profile,
       base::OnceCallback<void(
           absl::optional<std::vector<device::DiscoverableCredentialMetadata>>)>
           callback) = 0;
@@ -47,8 +67,7 @@
   // Delete removes a credentail from the platform authenticator. The
   // callback will never be invoked before the function returns. It is run with
   // the value `true` if the deletion was successful.
-  virtual void Delete(Profile* profile,
-                      base::span<const uint8_t> credential_id,
+  virtual void Delete(base::span<const uint8_t> credential_id,
                       base::OnceCallback<void(bool)> callback) = 0;
 };
 
diff --git a/chrome/browser/webauthn/local_credential_management_mac.cc b/chrome/browser/webauthn/local_credential_management_mac.cc
index 70009a9..ad4eb8fd 100644
--- a/chrome/browser/webauthn/local_credential_management_mac.cc
+++ b/chrome/browser/webauthn/local_credential_management_mac.cc
@@ -1,28 +1,34 @@
 // Copyright 2022 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
+
 #include "chrome/browser/webauthn/local_credential_management_mac.h"
 #include "chrome/browser/webauthn/local_credential_management.h"
 
 #include "base/bind.h"
 #include "base/feature_list.h"
 #include "content/public/common/content_features.h"
+#include "device/fido/mac/credential_store.h"
 
-LocalCredentialManagementMac::LocalCredentialManagementMac() = default;
+LocalCredentialManagementMac::LocalCredentialManagementMac(
+    device::fido::mac::AuthenticatorConfig config)
+    : config_(config) {}
 
-std::unique_ptr<LocalCredentialManagement> LocalCredentialManagement::Create() {
-  return std::make_unique<LocalCredentialManagementMac>();
+std::unique_ptr<LocalCredentialManagement> LocalCredentialManagement::Create(
+    Profile* profile) {
+  auto config =
+      ChromeWebAuthenticationDelegate::TouchIdAuthenticatorConfigForProfile(
+          profile);
+  return std::make_unique<LocalCredentialManagementMac>(config);
 }
 
 void LocalCredentialManagementMac::HasCredentials(
-    Profile* profile,
     base::OnceCallback<void(bool)> callback) {
   if (!base::FeatureList::IsEnabled(features::kWebAuthConditionalUI)) {
     std::move(callback).Run(false);
     return;
   }
   Enumerate(
-      profile,
       base::BindOnce(
           [](absl::optional<std::vector<device::DiscoverableCredentialMetadata>>
                  metadata) { return !metadata->empty(); })
@@ -30,26 +36,32 @@
 }
 
 void LocalCredentialManagementMac::Enumerate(
-    Profile* profile,
     base::OnceCallback<void(
         absl::optional<std::vector<device::DiscoverableCredentialMetadata>>)>
         callback) {
-  // TODO(crbug.com/1349854): wire up the real keychain implementation.
-  device::DiscoverableCredentialMetadata cred_1(
-      "a.com", {0}, device::PublicKeyCredentialUserEntity({1, 2, 3, 4}));
-  device::DiscoverableCredentialMetadata cred_2(
-      "b.com", {1}, device::PublicKeyCredentialUserEntity({5, 6, 7, 8}));
+  device::fido::mac::TouchIdCredentialStore credential_store(config_);
+  absl::optional<std::list<device::fido::mac::Credential>> credentials =
+      credential_store.FindResidentCredentials(/*rp_id=*/absl::nullopt);
+
+  if (!credentials) {
+    std::move(callback).Run(/*credentials=*/{});
+    return;
+  }
   std::vector<device::DiscoverableCredentialMetadata> credential_metadata;
-
-  credential_metadata.push_back(cred_1);
-  credential_metadata.push_back(cred_2);
-
+  credential_metadata.reserve(credentials->size());
+  for (auto& credential : *credentials) {
+    credential_metadata.emplace_back(
+        credential.rp_id, credential.credential_id,
+        credential.metadata.ToPublicKeyCredentialUserEntity());
+  }
+  std::sort(credential_metadata.begin(), credential_metadata.end(),
+            CredentialComparator());
   std::move(callback).Run(std::move(credential_metadata));
 }
 
 void LocalCredentialManagementMac::Delete(
-    Profile* profile,
     base::span<const uint8_t> credential_id,
     base::OnceCallback<void(bool)> callback) {
-  NOTIMPLEMENTED();
+  device::fido::mac::TouchIdCredentialStore credential_store(config_);
+  std::move(callback).Run(credential_store.DeleteCredentialById(credential_id));
 }
diff --git a/chrome/browser/webauthn/local_credential_management_mac.h b/chrome/browser/webauthn/local_credential_management_mac.h
index b682c0f..2b94a36 100644
--- a/chrome/browser/webauthn/local_credential_management_mac.h
+++ b/chrome/browser/webauthn/local_credential_management_mac.h
@@ -7,6 +7,7 @@
 
 #include <vector>
 
+#include "chrome/browser/webauthn/chrome_authenticator_request_delegate.h"
 #include "chrome/browser/webauthn/local_credential_management.h"
 
 class Profile;
@@ -15,19 +16,20 @@
 // LocalCredentialManagement.
 class LocalCredentialManagementMac : public LocalCredentialManagement {
  public:
-  LocalCredentialManagementMac();
+  explicit LocalCredentialManagementMac(
+      device::fido::mac::AuthenticatorConfig config);
 
   // LocalCredentialManagement:
-  void HasCredentials(Profile* profile,
-                      base::OnceCallback<void(bool)> callback) override;
+  void HasCredentials(base::OnceCallback<void(bool)> callback) override;
   void Enumerate(
-      Profile* profile,
       base::OnceCallback<void(
           absl::optional<std::vector<device::DiscoverableCredentialMetadata>>)>
           callback) override;
-  void Delete(Profile* profile,
-              base::span<const uint8_t> credential_id,
+  void Delete(base::span<const uint8_t> credential_id,
               base::OnceCallback<void(bool)> callback) override;
+
+ private:
+  device::fido::mac::AuthenticatorConfig config_;
 };
 
 #endif  // CHROME_BROWSER_WEBAUTHN_LOCAL_CREDENTIAL_MANAGEMENT_MAC_H_
\ No newline at end of file
diff --git a/chrome/browser/webauthn/local_credential_management_mac_unittest.mm b/chrome/browser/webauthn/local_credential_management_mac_unittest.mm
new file mode 100644
index 0000000..bcfe88c0
--- /dev/null
+++ b/chrome/browser/webauthn/local_credential_management_mac_unittest.mm
@@ -0,0 +1,121 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <tuple>
+
+#include "chrome/browser/webauthn/local_credential_management_mac.h"
+
+#include "base/test/scoped_feature_list.h"
+#include "build/build_config.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/common/content_features.h"
+#include "content/public/test/browser_task_environment.h"
+#include "device/fido/mac/authenticator_config.h"
+#include "device/fido/mac/credential_store.h"
+#include "device/fido/mac/fake_keychain.h"
+#include "device/fido/public_key_credential_user_entity.h"
+#include "device/fido/test_callback_receiver.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace {
+
+static const device::PublicKeyCredentialUserEntity kUser({1, 2, 3},
+                                                         "doe@example.com",
+                                                         "John Doe");
+constexpr char kRpId[] = "example.com";
+
+class LocalCredentialManagementTest : public testing::Test {
+ protected:
+  LocalCredentialManagementTest() = default;
+
+  content::BrowserTaskEnvironment task_environment_;
+  TestingProfile profile_;
+  device::fido::mac::AuthenticatorConfig config_{
+      .keychain_access_group = "test-keychain-access-group",
+      .metadata_secret = "TestMetadataSecret"};
+  LocalCredentialManagementMac local_cred_man_{config_};
+  device::fido::mac::ScopedFakeKeychain keychain_{
+      config_.keychain_access_group};
+  device::fido::mac::TouchIdCredentialStore store_{config_};
+  base::test::ScopedFeatureList scoped_feature_list_{
+      features::kWebAuthConditionalUI};
+};
+
+class WebAuthConditionalUIFlagOffTest : public LocalCredentialManagementTest {
+ protected:
+  WebAuthConditionalUIFlagOffTest() {
+    scoped_feature_list_.Reset();
+    scoped_feature_list_.InitAndDisableFeature(features::kWebAuthConditionalUI);
+  }
+};
+
+TEST_F(WebAuthConditionalUIFlagOffTest, FeatureFlagOff) {
+  device::test::TestCallbackReceiver<bool> callback;
+  auto credential = store_.CreateCredential(
+      kRpId, kUser, device::fido::mac::TouchIdCredentialStore::kDiscoverable);
+  EXPECT_TRUE(credential);
+  local_cred_man_.HasCredentials(callback.callback());
+  callback.WaitForCallback();
+  EXPECT_FALSE(std::get<0>(callback.TakeResult()));
+}
+
+TEST_F(LocalCredentialManagementTest, NoCredentials) {
+  device::test::TestCallbackReceiver<bool> callback;
+  local_cred_man_.HasCredentials(callback.callback());
+  callback.WaitForCallback();
+  EXPECT_FALSE(std::get<0>(callback.TakeResult()));
+
+  device::test::TestCallbackReceiver<
+      absl::optional<std::vector<device::DiscoverableCredentialMetadata>>>
+      enumerate_callback;
+  local_cred_man_.Enumerate(enumerate_callback.callback());
+  enumerate_callback.WaitForCallback();
+  auto result = std::get<0>(enumerate_callback.TakeResult());
+  ASSERT_TRUE(result.has_value());
+  EXPECT_TRUE(result->empty());
+}
+
+TEST_F(LocalCredentialManagementTest, OneCredential) {
+  device::test::TestCallbackReceiver<bool> callback;
+  auto credential = store_.CreateCredential(
+      kRpId, kUser, device::fido::mac::TouchIdCredentialStore::kDiscoverable);
+  EXPECT_TRUE(credential);
+  local_cred_man_.HasCredentials(callback.callback());
+  callback.WaitForCallback();
+  EXPECT_TRUE(std::get<0>(callback.TakeResult()));
+
+  device::test::TestCallbackReceiver<
+      absl::optional<std::vector<device::DiscoverableCredentialMetadata>>>
+      enumerate_callback;
+  local_cred_man_.Enumerate(enumerate_callback.callback());
+  enumerate_callback.WaitForCallback();
+  const absl::optional<std::vector<device::DiscoverableCredentialMetadata>>
+      result = std::get<0>(enumerate_callback.TakeResult());
+  ASSERT_TRUE(result.has_value());
+  ASSERT_EQ(result->size(), 1u);
+  EXPECT_EQ(result->at(0).rp_id, kRpId);
+}
+
+TEST_F(LocalCredentialManagementTest, DeleteCredential) {
+  device::test::TestCallbackReceiver<bool> callback;
+  auto credential = store_.CreateCredential(
+      kRpId, kUser, device::fido::mac::TouchIdCredentialStore::kDiscoverable);
+  ASSERT_TRUE(credential);
+  auto credentials = store_.FindResidentCredentials(kRpId);
+  ASSERT_TRUE(credentials);
+  EXPECT_EQ(credentials->size(), 1u);
+  local_cred_man_.Delete(credential->first.credential_id, callback.callback());
+  callback.WaitForCallback();
+  EXPECT_TRUE(std::get<0>(callback.TakeResult()));
+  credentials = store_.FindResidentCredentials(kRpId);
+  ASSERT_TRUE(credentials);
+  EXPECT_EQ(store_.FindResidentCredentials(kRpId)->size(), 0u);
+
+  local_cred_man_.Delete(std::vector<uint8_t>{8}, callback.callback());
+  callback.WaitForCallback();
+  EXPECT_FALSE(std::get<0>(callback.TakeResult()));
+}
+
+}  // namespace
diff --git a/chrome/browser/webauthn/local_credential_management_win.cc b/chrome/browser/webauthn/local_credential_management_win.cc
index 32cf4a10..35e3fe5 100644
--- a/chrome/browser/webauthn/local_credential_management_win.cc
+++ b/chrome/browser/webauthn/local_credential_management_win.cc
@@ -7,11 +7,6 @@
 
 #include "base/bind.h"
 #include "base/feature_list.h"
-#include "base/i18n/string_compare.h"
-#include "base/ranges/algorithm.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "build/build_config.h"
 #include "chrome/browser/profiles/profile.h"
@@ -22,67 +17,9 @@
 #include "content/public/common/content_features.h"
 #include "device/fido/win/authenticator.h"
 #include "device/fido/win/webauthn_api.h"
-#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
-#include "third_party/icu/source/common/unicode/locid.h"
-#include "third_party/icu/source/i18n/unicode/coll.h"
 
 namespace {
 
-// CredentialComparator compares two credentials based on their RP ID's eTLD +
-// 1, then on the label-reversed RP ID, then on user.name, and finally on
-// credential ID if the previous values are equal.
-class CredentialComparator {
- public:
-  CredentialComparator() {
-    UErrorCode error = U_ZERO_ERROR;
-    collator_.reset(
-        icu::Collator::createInstance(icu::Locale::getDefault(), error));
-  }
-
-  bool operator()(const device::DiscoverableCredentialMetadata& a,
-                  const device::DiscoverableCredentialMetadata& b) {
-    UCollationResult relation = base::i18n::CompareString16WithCollator(
-        *collator_, ETLDPlus1(a.rp_id), ETLDPlus1(b.rp_id));
-    if (relation != UCOL_EQUAL) {
-      return relation == UCOL_LESS;
-    }
-
-    relation = base::i18n::CompareString16WithCollator(
-        *collator_, LabelReverse(a.rp_id), LabelReverse(b.rp_id));
-    if (relation != UCOL_EQUAL) {
-      return relation == UCOL_LESS;
-    }
-
-    relation = base::i18n::CompareString16WithCollator(
-        *collator_, base::UTF8ToUTF16(a.user.name.value_or("")),
-        base::UTF8ToUTF16(b.user.name.value_or("")));
-    if (relation != UCOL_EQUAL) {
-      return relation == UCOL_LESS;
-    }
-
-    return a.cred_id < b.cred_id;
-  }
-
- private:
-  static std::u16string ETLDPlus1(const std::string& rp_id) {
-    std::string domain = net::registry_controlled_domains::GetDomainAndRegistry(
-        rp_id, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
-    if (domain.empty()) {
-      domain = rp_id;
-    }
-    return base::UTF8ToUTF16(domain);
-  }
-
-  static std::u16string LabelReverse(const std::string& rp_id) {
-    std::vector<base::StringPiece> parts = base::SplitStringPiece(
-        rp_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
-    std::reverse(parts.begin(), parts.end());
-    return base::UTF8ToUTF16(base::JoinString(parts, "."));
-  }
-
-  std::unique_ptr<icu::Collator> collator_;
-};
-
 bool ContainsUserCreatedCredential(
     const std::vector<device::DiscoverableCredentialMetadata>& credentials) {
   return base::ranges::any_of(
@@ -165,8 +102,9 @@
 }  // namespace
 
 LocalCredentialManagementWin::LocalCredentialManagementWin(
-    device::WinWebAuthnApi* api)
-    : api_(api) {}
+    device::WinWebAuthnApi* api,
+    Profile* profile)
+    : api_(api), profile_(profile) {}
 
 // static
 void LocalCredentialManagementWin::RegisterProfilePrefs(
@@ -174,20 +112,20 @@
   registry->RegisterBooleanPref(kHasPlatformCredentialsPref, false);
 }
 
-std::unique_ptr<LocalCredentialManagement> LocalCredentialManagement::Create() {
+std::unique_ptr<LocalCredentialManagement> LocalCredentialManagement::Create(
+    Profile* profile) {
   return std::make_unique<LocalCredentialManagementWin>(
-      device::WinWebAuthnApi::GetDefault());
+      device::WinWebAuthnApi::GetDefault(), profile);
 }
 
 void LocalCredentialManagementWin::HasCredentials(
-    Profile* profile,
     base::OnceCallback<void(bool)> callback) {
   absl::optional<bool> result;
 
   if (!api_->IsAvailable() || !api_->SupportsSilentDiscovery() ||
       !base::FeatureList::IsEnabled(features::kWebAuthConditionalUI)) {
     result = false;
-  } else if (profile->GetPrefs()->GetBoolean(kHasPlatformCredentialsPref)) {
+  } else if (profile_->GetPrefs()->GetBoolean(kHasPlatformCredentialsPref)) {
     result = true;
   }
 
@@ -198,14 +136,13 @@
   }
 
   auto cacher = std::make_unique<CredentialPresenceCacher>(
-      profile, base::BindOnce(EnumerateResultToBool, std::move(callback)));
+      profile_, base::BindOnce(EnumerateResultToBool, std::move(callback)));
   device::WinWebAuthnApiAuthenticator::EnumeratePlatformCredentials(
       api_, base::BindOnce(&CredentialPresenceCacher::OnEnumerateResult,
                            std::move(cacher)));
 }
 
 void LocalCredentialManagementWin::Enumerate(
-    Profile* profile,
     base::OnceCallback<void(
         absl::optional<std::vector<device::DiscoverableCredentialMetadata>>)>
         callback) {
@@ -216,14 +153,13 @@
   }
 
   auto cacher =
-      std::make_unique<CredentialPresenceCacher>(profile, std::move(callback));
+      std::make_unique<CredentialPresenceCacher>(profile_, std::move(callback));
   device::WinWebAuthnApiAuthenticator::EnumeratePlatformCredentials(
       api_, base::BindOnce(&CredentialPresenceCacher::OnEnumerateResult,
                            std::move(cacher)));
 }
 
 void LocalCredentialManagementWin::Delete(
-    Profile* profile,
     base::span<const uint8_t> credential_id,
     base::OnceCallback<void(bool)> callback) {
   device::WinWebAuthnApiAuthenticator::DeletePlatformCredential(
diff --git a/chrome/browser/webauthn/local_credential_management_win.h b/chrome/browser/webauthn/local_credential_management_win.h
index 7a30c50e..582631e 100644
--- a/chrome/browser/webauthn/local_credential_management_win.h
+++ b/chrome/browser/webauthn/local_credential_management_win.h
@@ -26,26 +26,25 @@
 // LocalCredentialManagement.
 class LocalCredentialManagementWin : public LocalCredentialManagement {
  public:
-  explicit LocalCredentialManagementWin(device::WinWebAuthnApi* api);
+  explicit LocalCredentialManagementWin(device::WinWebAuthnApi* api,
+                                        Profile* profile);
 
   // RegisterProfilePrefs registers preference values that are used for caching
   // whether local credentials exist.
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
 
   // LocalCredentialManagement:
-  void HasCredentials(Profile* profile,
-                      base::OnceCallback<void(bool)> callback) override;
+  void HasCredentials(base::OnceCallback<void(bool)> callback) override;
   void Enumerate(
-      Profile* profile,
       base::OnceCallback<void(
           absl::optional<std::vector<device::DiscoverableCredentialMetadata>>)>
           callback) override;
-  void Delete(Profile* profile,
-              base::span<const uint8_t> credential_id,
+  void Delete(base::span<const uint8_t> credential_id,
               base::OnceCallback<void(bool)> callback) override;
 
  private:
   device::WinWebAuthnApi* const api_;
+  Profile* profile_;
 };
 
 #endif  // CHROME_BROWSER_WEBAUTHN_LOCAL_CREDENTIAL_MANAGEMENT_WIN_H_
diff --git a/chrome/browser/webauthn/local_credential_management_unittest.cc b/chrome/browser/webauthn/local_credential_management_win_unittest.cc
similarity index 92%
rename from chrome/browser/webauthn/local_credential_management_unittest.cc
rename to chrome/browser/webauthn/local_credential_management_win_unittest.cc
index 1098230..82cbacbb 100644
--- a/chrome/browser/webauthn/local_credential_management_unittest.cc
+++ b/chrome/browser/webauthn/local_credential_management_win_unittest.cc
@@ -4,15 +4,11 @@
 
 #include <tuple>
 
-#include "build/build_config.h"
-
-// This class is only supported on Windows so far.
-#if BUILDFLAG(IS_WIN)
+#include "chrome/browser/webauthn/local_credential_management_win.h"
 
 #include "base/run_loop.h"
 #include "base/test/scoped_feature_list.h"
-#include "chrome/browser/webauthn/local_credential_management.h"
-#include "chrome/browser/webauthn/local_credential_management_win.h"
+#include "build/build_config.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/prefs/pref_service.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
@@ -38,11 +34,9 @@
 
   bool HasCredentials() {
     device::test::TestCallbackReceiver<bool> callback;
-    local_cred_man_.HasCredentials(&profile_, callback.callback());
+    local_cred_man_.HasCredentials(callback.callback());
 
-    while (!callback.was_called()) {
-      base::RunLoop().RunUntilIdle();
-    }
+    callback.WaitForCallback();
     return std::get<0>(callback.TakeResult());
   }
 
@@ -51,11 +45,9 @@
     device::test::TestCallbackReceiver<
         absl::optional<std::vector<device::DiscoverableCredentialMetadata>>>
         callback;
-    local_cred_man_.Enumerate(&profile_, callback.callback());
+    local_cred_man_.Enumerate(callback.callback());
 
-    while (!callback.was_called()) {
-      base::RunLoop().RunUntilIdle();
-    }
+    callback.WaitForCallback();
     return std::get<0>(callback.TakeResult());
   }
 
@@ -64,7 +56,7 @@
   content::BrowserTaskEnvironment task_environment_;
   TestingProfile profile_;
   device::FakeWinWebAuthnApi api_;
-  LocalCredentialManagementWin local_cred_man_{&api_};
+  LocalCredentialManagementWin local_cred_man_{&api_, &profile_};
   const base::test::ScopedFeatureList scoped_feature_list_;
 };
 
@@ -171,5 +163,3 @@
 }
 
 }  // namespace
-
-#endif
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index fa6bc0cc..769b29e 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1661947159-549299e6da42efd09f96a15146e14154c35be413.profdata
+chrome-win32-main-1661957766-14109ed98e96cd465250e4742133f746282dae66.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index bc781a8..06aba2fa 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1661947159-cd94e3a6610b5069eea540ff58f57755f3b38dfa.profdata
+chrome-win64-main-1661957766-624932beb329b06d076c9f4e41626cf2ce1dc33f.profdata
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc
index 44b10b24..cf94f8cf 100644
--- a/chrome/common/webui_url_constants.cc
+++ b/chrome/common/webui_url_constants.cc
@@ -39,6 +39,7 @@
     "chrome://apps?showForceInstallDialog=";
 const char kChromeUIAutofillInternalsHost[] = "autofill-internals";
 const char kChromeUIBluetoothInternalsHost[] = "bluetooth-internals";
+const char kChromeUIBluetoothInternalsURL[] = "chrome://bluetooth-internals";
 const char kChromeUIBookmarksHost[] = "bookmarks";
 const char kChromeUIBookmarksURL[] = "chrome://bookmarks/";
 const char kChromeUIBrowsingTopicsInternalsHost[] = "topics-internals";
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h
index a4f46cd8..0fa1474e 100644
--- a/chrome/common/webui_url_constants.h
+++ b/chrome/common/webui_url_constants.h
@@ -41,6 +41,7 @@
 extern const char kChromeUIAppsWithForceInstalledDeprecationDialogURL[];
 extern const char kChromeUIAutofillInternalsHost[];
 extern const char kChromeUIBluetoothInternalsHost[];
+extern const char kChromeUIBluetoothInternalsURL[];
 extern const char kChromeUIBookmarksHost[];
 extern const char kChromeUIBookmarksURL[];
 extern const char kChromeUIBrowsingTopicsInternalsHost[];
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 8bda121a..d282d3d 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -6876,7 +6876,6 @@
       "../browser/webauthn/authenticator_request_scheduler_unittest.cc",
       "../browser/webauthn/cablev2_devices_unittest.cc",
       "../browser/webauthn/chrome_authenticator_request_delegate_unittest.cc",
-      "../browser/webauthn/local_credential_management_unittest.cc",
       "../common/importer/mock_importer_bridge.cc",
       "../common/importer/mock_importer_bridge.h",
       "../renderer/media/webrtc_logging_agent_impl_unittest.cc",
@@ -6886,6 +6885,16 @@
       "interaction/webui_interaction_test_util_unittest.cc",
     ]
 
+    if (is_mac) {
+      sources +=
+          [ "../browser/webauthn/local_credential_management_mac_unittest.mm" ]
+    }
+
+    if (is_win) {
+      sources +=
+          [ "../browser/webauthn/local_credential_management_win_unittest.cc" ]
+    }
+
     sources += [
       # Badging isn't supported on Android.
       "../browser/badging/badge_manager_unittest.cc",
diff --git a/chrome/test/data/webui/side_panel/bookmarks/commerce/shopping_list_test.ts b/chrome/test/data/webui/side_panel/bookmarks/commerce/shopping_list_test.ts
index 1b4c97f..8a8fa574 100644
--- a/chrome/test/data/webui/side_panel/bookmarks/commerce/shopping_list_test.ts
+++ b/chrome/test/data/webui/side_panel/bookmarks/commerce/shopping_list_test.ts
@@ -4,19 +4,25 @@
 
 import 'chrome://webui-test/mojo_webui_test_support.js';
 import 'chrome://read-later.top-chrome/bookmarks/commerce/shopping_list.js';
+import 'chrome://read-later.top-chrome/bookmarks/bookmarks_list.js';
 
 import {ActionSource} from 'chrome://read-later.top-chrome/bookmarks/bookmarks.mojom-webui.js';
 import {BookmarksApiProxyImpl} from 'chrome://read-later.top-chrome/bookmarks/bookmarks_api_proxy.js';
-import {LOCAL_STORAGE_EXPAND_STATUS_KEY, ShoppingListElement} from 'chrome://read-later.top-chrome/bookmarks/commerce/shopping_list.js';
+import {ACTION_BUTTON_TRACK_IMAGE, ACTION_BUTTON_UNTRACK_IMAGE, LOCAL_STORAGE_EXPAND_STATUS_KEY, ShoppingListElement} from 'chrome://read-later.top-chrome/bookmarks/commerce/shopping_list.js';
 import {BookmarkProductInfo} from 'chrome://read-later.top-chrome/bookmarks/commerce/shopping_list.mojom-webui.js';
+import {ShoppingListApiProxyImpl} from 'chrome://read-later.top-chrome/bookmarks/commerce/shopping_list_api_proxy.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks, isVisible} from 'chrome://webui-test/test_util.js';
 
 import {TestBookmarksApiProxy} from '../test_bookmarks_api_proxy.js';
 
+import {TestShoppingListApiProxy} from './test_shopping_list_api_proxy.js';
+
 suite('SidePanelShoppingListTest', () => {
   let shoppingList: ShoppingListElement;
   let bookmarksApi: TestBookmarksApiProxy;
+  let shoppingListApi: TestShoppingListApiProxy;
 
   const products: BookmarkProductInfo[] = [
     {
@@ -77,6 +83,12 @@
       assertEquals(priceElements[0]!.textContent, product.info.currentPrice);
       assertEquals(priceElements[1]!.textContent, product.info.previousPrice);
     }
+    const actionButton = element.querySelector('.action-button') as HTMLElement;
+    assertEquals(
+        actionButton.getAttribute('iron-icon'), ACTION_BUTTON_UNTRACK_IMAGE);
+    assertEquals(
+        actionButton.getAttribute('title'),
+        loadTimeData.getString('shoppingListUntrackPriceButtonDescription'));
   }
 
   setup(async () => {
@@ -85,6 +97,9 @@
     bookmarksApi = new TestBookmarksApiProxy();
     BookmarksApiProxyImpl.setInstance(bookmarksApi);
 
+    shoppingListApi = new TestShoppingListApiProxy();
+    ShoppingListApiProxyImpl.setInstance(shoppingListApi);
+
     shoppingList = document.createElement('shopping-list');
     shoppingList.productInfos = products;
     document.body.appendChild(shoppingList);
@@ -177,4 +192,26 @@
         shoppingListClosed.shadowRoot!.getElementById(
                                           'arrowIcon')!.hasAttribute('open'));
   });
+
+  test('TracksAndUntracksPrice', async () => {
+    const actionButton = getProductElements(shoppingList)[0]!.querySelector(
+                             '.action-button')! as HTMLElement;
+    actionButton.click();
+    let id = await shoppingListApi.whenCalled('untrackPriceForBookmark');
+    assertEquals(id, products[0]!.bookmarkId);
+    assertEquals(
+        actionButton.getAttribute('iron-icon'), ACTION_BUTTON_TRACK_IMAGE);
+    assertEquals(
+        actionButton.getAttribute('title'),
+        loadTimeData.getString('shoppingListTrackPriceButtonDescription'));
+
+    actionButton.click();
+    id = await shoppingListApi.whenCalled('trackPriceForBookmark');
+    assertEquals(id, products[0]!.bookmarkId);
+    assertEquals(
+        actionButton.getAttribute('iron-icon'), ACTION_BUTTON_UNTRACK_IMAGE);
+    assertEquals(
+        actionButton.getAttribute('title'),
+        loadTimeData.getString('shoppingListUntrackPriceButtonDescription'));
+  });
 });
diff --git a/chrome/test/data/webui/side_panel/bookmarks/commerce/test_shopping_list_api_proxy.ts b/chrome/test/data/webui/side_panel/bookmarks/commerce/test_shopping_list_api_proxy.ts
index bf1e6cc..d1fe044 100644
--- a/chrome/test/data/webui/side_panel/bookmarks/commerce/test_shopping_list_api_proxy.ts
+++ b/chrome/test/data/webui/side_panel/bookmarks/commerce/test_shopping_list_api_proxy.ts
@@ -11,7 +11,11 @@
   private products_: BookmarkProductInfo[] = [];
 
   constructor() {
-    super(['getAllBookmarkProductInfo']);
+    super([
+      'getAllBookmarkProductInfo',
+      'trackPriceForBookmark',
+      'untrackPriceForBookmark',
+    ]);
   }
 
   setProducts(products: BookmarkProductInfo[]) {
@@ -22,4 +26,12 @@
     this.methodCalled('getAllBookmarkProductInfo');
     return Promise.resolve({productInfos: this.products_});
   }
+
+  trackPriceForBookmark(bookmarkId: bigint) {
+    this.methodCalled('trackPriceForBookmark', bookmarkId);
+  }
+
+  untrackPriceForBookmark(bookmarkId: bigint) {
+    this.methodCalled('untrackPriceForBookmark', bookmarkId);
+  }
 }
diff --git a/chrome/test/data/webui/side_panel/reading_list/test_reading_list_api_proxy.ts b/chrome/test/data/webui/side_panel/reading_list/test_reading_list_api_proxy.ts
index 2e70937..1b19a3c 100644
--- a/chrome/test/data/webui/side_panel/reading_list/test_reading_list_api_proxy.ts
+++ b/chrome/test/data/webui/side_panel/reading_list/test_reading_list_api_proxy.ts
@@ -19,6 +19,7 @@
       'openURL',
       'updateReadStatus',
       'addCurrentTab',
+      'markCurrentTabAsRead',
       'removeEntry',
       'showContextMenuForURL',
       'updateCurrentPageActionButtonState',
@@ -49,6 +50,10 @@
     this.methodCalled('addCurrentTab');
   }
 
+  markCurrentTabAsRead() {
+    this.methodCalled('markCurrentTabAsRead');
+  }
+
   removeEntry(url: Url) {
     this.methodCalled('removeEntry', url);
   }
diff --git a/chrome/updater/app/app_install.cc b/chrome/updater/app/app_install.cc
index c202ae4..3151b817 100644
--- a/chrome/updater/app/app_install.cc
+++ b/chrome/updater/app/app_install.cc
@@ -222,7 +222,7 @@
 }
 #endif  // BUILDFLAG(IS_LINUX)
 
-void AppInstall::RegisterUpdater() {
+void AppInstall::FetchPolicies() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
 #if BUILDFLAG(IS_MAC)
@@ -232,6 +232,13 @@
       updater_scope(), external_constants_->OverinstallTimeout());
 #endif
 
+  update_service_->FetchPolicies(
+      base::BindOnce(&AppInstall::RegisterUpdater, this));
+}
+
+void AppInstall::RegisterUpdater() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
   RegistrationRequest request;
   request.app_id = kUpdaterAppId;
   request.version = base::Version(kUpdaterVersion);
diff --git a/chrome/updater/app/app_install.h b/chrome/updater/app/app_install.h
index 024ad11..131f810 100644
--- a/chrome/updater/app/app_install.h
+++ b/chrome/updater/app/app_install.h
@@ -74,6 +74,8 @@
 
   void WakeCandidateDone();
 
+  void FetchPolicies();
+
   void RegisterUpdater();
 
   // Handles the --tag and --app-id command line arguments, and triggers
diff --git a/chrome/updater/app/app_install_mac.mm b/chrome/updater/app/app_install_mac.mm
index 7b2aeacc..55071ef 100644
--- a/chrome/updater/app/app_install_mac.mm
+++ b/chrome/updater/app/app_install_mac.mm
@@ -19,7 +19,7 @@
       updater_scope(), GetUpdateServiceLaunchdName(updater_scope()),
       LaunchctlPresence::kPresent, base::Seconds(kWaitForLaunchctlUpdateSec),
       base::BindOnce([](scoped_refptr<AppInstall> installer,
-                        bool unused) { installer->RegisterUpdater(); },
+                        bool unused) { installer->FetchPolicies(); },
                      base::WrapRefCounted(this)));
 }
 
diff --git a/chrome/updater/app/app_install_win.cc b/chrome/updater/app/app_install_win.cc
index f439c93..f50190b 100644
--- a/chrome/updater/app/app_install_win.cc
+++ b/chrome/updater/app/app_install_win.cc
@@ -7,7 +7,7 @@
 namespace updater {
 
 void AppInstall::WakeCandidateDone() {
-  RegisterUpdater();
+  FetchPolicies();
 }
 
 }  // namespace updater
diff --git a/chrome/updater/app/server/mac/service_delegate.mm b/chrome/updater/app/server/mac/service_delegate.mm
index 2aa85cd4..91b8c028 100644
--- a/chrome/updater/app/server/mac/service_delegate.mm
+++ b/chrome/updater/app/server/mac/service_delegate.mm
@@ -85,6 +85,21 @@
                                 std::move(cb)));
 }
 
+- (void)fetchPoliciesWithReply:(void (^)(void))reply {
+  auto cb = base::BindOnce(base::RetainBlock(^(void) {
+    VLOG(0) << "FetchPolicies complete.";
+    if (reply)
+      reply();
+
+    _appServer->TaskCompleted();
+  }));
+
+  _appServer->TaskStarted();
+  _callbackRunner->PostTask(
+      FROM_HERE, base::BindOnce(&updater::UpdateService::FetchPolicies,
+                                _service, std::move(cb)));
+}
+
 - (void)runPeriodicTasksWithReply:(void (^)(void))reply {
   auto cb = base::BindOnce(base::RetainBlock(^(void) {
     VLOG(0) << "RunPeriodicTasks complete.";
@@ -410,6 +425,13 @@
   [_service getVersionWithReply:reply];
 }
 
+- (void)fetchPoliciesWithReply:(void (^)(void))reply {
+  // This function may only be called by the same user.
+  VLOG(1) << "Rejecting cross-user attempt to call " << __func__;
+  if (reply)
+    reply();
+}
+
 - (void)runPeriodicTasksWithReply:(void (^)(void))reply {
   // This function may only be called by the same user.
   VLOG(1) << "Rejecting cross-user attempt to call " << __func__;
diff --git a/chrome/updater/app/server/mac/service_protocol.h b/chrome/updater/app/server/mac/service_protocol.h
index da86dfa..9b3cd2d 100644
--- a/chrome/updater/app/server/mac/service_protocol.h
+++ b/chrome/updater/app/server/mac/service_protocol.h
@@ -31,6 +31,9 @@
 - (void)getVersionWithReply:
     (void (^_Nonnull)(NSString* _Nullable version))reply;
 
+// Fetches policies from device management.
+- (void)fetchPoliciesWithReply:(void (^_Nullable)(void))reply;
+
 // Checks for updates and returns the result in the reply block.
 - (void)checkForUpdatesWithUpdateState:
             (CRUUpdateStateObserver* _Nonnull)updateState
diff --git a/chrome/updater/app/server/win/com_classes.cc b/chrome/updater/app/server/win/com_classes.cc
index 15514ad..9defe99d 100644
--- a/chrome/updater/app/server/win/com_classes.cc
+++ b/chrome/updater/app/server/win/com_classes.cc
@@ -155,6 +155,26 @@
   return S_OK;
 }
 
+HRESULT UpdaterImpl::FetchPolicies(IUpdaterCallback* callback) {
+  scoped_refptr<ComServerApp> com_server = AppServerSingletonInstance();
+  com_server->main_task_runner()->PostTask(
+      FROM_HERE,
+      base::BindOnce(
+          [](scoped_refptr<UpdateService> update_service,
+             base::OnceClosure callback_closure) {
+            update_service->FetchPolicies(std::move(callback_closure));
+          },
+          com_server->update_service(),
+          base::BindPostTask(
+              base::ThreadPool::CreateSequencedTaskRunner(
+                  {base::MayBlock(),
+                   base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}),
+              base::BindOnce(base::IgnoreResult(&IUpdaterCallback::Run),
+                             Microsoft::WRL::ComPtr<IUpdaterCallback>(callback),
+                             0))));
+  return S_OK;
+}
+
 HRESULT UpdaterImpl::CheckForUpdate(const wchar_t* app_id) {
   return E_NOTIMPL;
 }
diff --git a/chrome/updater/app/server/win/com_classes.h b/chrome/updater/app/server/win/com_classes.h
index dd29538..ea8cb55 100644
--- a/chrome/updater/app/server/win/com_classes.h
+++ b/chrome/updater/app/server/win/com_classes.h
@@ -95,6 +95,7 @@
 
   // Overrides for IUpdater.
   IFACEMETHODIMP GetVersion(BSTR* version) override;
+  IFACEMETHODIMP FetchPolicies(IUpdaterCallback* callback) override;
   IFACEMETHODIMP CheckForUpdate(const wchar_t* app_id) override;
   IFACEMETHODIMP RegisterApp(const wchar_t* app_id,
                              const wchar_t* brand_code,
diff --git a/chrome/updater/app/server/win/updater_idl.template b/chrome/updater/app/server/win/updater_idl.template
index 55543c3..3970c71 100644
--- a/chrome/updater/app/server/win/updater_idl.template
+++ b/chrome/updater/app/server/win/updater_idl.template
@@ -85,6 +85,7 @@
 ]
 interface IUpdater : IUnknown {
   HRESULT GetVersion([out, retval] BSTR* version);
+  HRESULT FetchPolicies([in] IUpdaterCallback* callback);
   HRESULT CheckForUpdate([in, string] const WCHAR* app_id);
   HRESULT RegisterApp([in, string] const WCHAR* app_id,
                       [in, string] const WCHAR* brand_code,
diff --git a/chrome/updater/mac/update_service_proxy.h b/chrome/updater/mac/update_service_proxy.h
index 7101645..2e08c98c 100644
--- a/chrome/updater/mac/update_service_proxy.h
+++ b/chrome/updater/mac/update_service_proxy.h
@@ -41,6 +41,7 @@
   // Overrides for UpdateService.
   void GetVersion(
       base::OnceCallback<void(const base::Version&)> callback) override;
+  void FetchPolicies(base::OnceClosure callback) override;
   void RegisterApp(
       const RegistrationRequest& request,
       base::OnceCallback<void(const RegistrationResponse&)> callback) override;
diff --git a/chrome/updater/mac/update_service_proxy.mm b/chrome/updater/mac/update_service_proxy.mm
index 1458e56..5d0bf52 100644
--- a/chrome/updater/mac/update_service_proxy.mm
+++ b/chrome/updater/mac/update_service_proxy.mm
@@ -91,6 +91,17 @@
       getVersionWithReply:reply];
 }
 
+- (void)fetchPoliciesWithReply:(void (^)(void))reply {
+  auto errorHandler = ^(NSError* xpcError) {
+    LOG(ERROR) << "XPC connection failed: "
+               << base::SysNSStringToUTF8([xpcError description]);
+    reply();
+  };
+
+  [[_updateCheckXPCConnection remoteObjectProxyWithErrorHandler:errorHandler]
+      fetchPoliciesWithReply:reply];
+}
+
 - (void)registerForUpdatesWithAppId:(NSString* _Nullable)appId
                           brandCode:(NSString* _Nullable)brandCode
                           brandPath:(NSString* _Nullable)brandPath
@@ -277,6 +288,16 @@
   [client_ getVersionWithReply:reply];
 }
 
+void UpdateServiceProxy::FetchPolicies(base::OnceClosure callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  VLOG(1) << __func__;
+  __block base::OnceClosure block_callback = std::move(callback);
+  auto reply = ^() {
+    callback_runner_->PostTask(FROM_HERE, std::move(block_callback));
+  };
+  [client_ fetchPoliciesWithReply:reply];
+}
+
 void UpdateServiceProxy::RegisterApp(
     const RegistrationRequest& request,
     base::OnceCallback<void(const RegistrationResponse&)> callback) {
diff --git a/chrome/updater/policy/policy_manager.cc b/chrome/updater/policy/policy_manager.cc
index a2b3dc86..a09ac86 100644
--- a/chrome/updater/policy/policy_manager.cc
+++ b/chrome/updater/policy/policy_manager.cc
@@ -18,11 +18,11 @@
 namespace {
 
 // Preferences Category.
-const char kAutoUpdateCheckPeriodOverrideMinutes[] =
+constexpr char kAutoUpdateCheckPeriodOverrideMinutes[] =
     "AutoUpdateCheckPeriodMinutes";
-const char kUpdatesSuppressedStartHour[] = "UpdatesSuppressedStartHour";
-const char kUpdatesSuppressedStartMin[] = "UpdatesSuppressedStartMin";
-const char kUpdatesSuppressedDurationMin[] = "UpdatesSuppressedDurationMin";
+constexpr char kUpdatesSuppressedStartHour[] = "UpdatesSuppressedStartHour";
+constexpr char kUpdatesSuppressedStartMin[] = "UpdatesSuppressedStartMin";
+constexpr char kUpdatesSuppressedDurationMin[] = "UpdatesSuppressedDurationMin";
 
 // This policy specifies what kind of download URLs could be returned to the
 // client in the update response and in which order of priority. The client
@@ -30,39 +30,39 @@
 // The server may decide to ignore the hint. As a general idea, some urls are
 // cacheable, some urls have higher bandwidth, and some urls are slightly more
 // secure since they are https.
-const char kDownloadPreference[] = "DownloadPreference";
+constexpr char kDownloadPreference[] = "DownloadPreference";
 
 // Proxy Server Category.  (The keys used, and the values of ProxyMode,
 // directly mirror that of Chrome.  However, we omit ProxyBypassList, as the
 // domains that Omaha uses are largely fixed.)
-const char kProxyMode[] = "ProxyMode";
-const char kProxyServer[] = "ProxyServer";
-const char kProxyPacUrl[] = "ProxyPacUrl";
+constexpr char kProxyMode[] = "ProxyMode";
+constexpr char kProxyServer[] = "ProxyServer";
+constexpr char kProxyPacUrl[] = "ProxyPacUrl";
 
 // Package cache constants.
-const char kCacheSizeLimitMBytes[] = "PackageCacheSizeLimit";
-const char kCacheLifeLimitDays[] = "PackageCacheLifeLimit";
+constexpr char kCacheSizeLimitMBytes[] = "PackageCacheSizeLimit";
+constexpr char kCacheLifeLimitDays[] = "PackageCacheLifeLimit";
 
 // Applications Category.
 // The prefix strings have the app's GUID appended to them.
-const char kInstallAppsDefault[] = "InstallDefault";
-const char kInstallAppPrefix[] = "Install";
-const char kUpdateAppsDefault[] = "UpdateDefault";
-const char kUpdateAppPrefix[] = "Update";
-const char kTargetVersionPrefix[] = "TargetVersionPrefix";
-const char kTargetChannel[] = "TargetChannel";
-const char kRollbackToTargetVersion[] = "RollbackToTargetVersion";
+constexpr char kInstallAppsDefault[] = "InstallDefault";
+constexpr char kInstallAppPrefix[] = "Install";
+constexpr char kUpdateAppsDefault[] = "UpdateDefault";
+constexpr char kUpdateAppPrefix[] = "Update";
+constexpr char kTargetVersionPrefix[] = "TargetVersionPrefix";
+constexpr char kTargetChannel[] = "TargetChannel";
+constexpr char kRollbackToTargetVersion[] = "RollbackToTargetVersion";
 
 }  // namespace
 
 PolicyManager::PolicyManager(base::Value::Dict policies)
     : policies_(std::move(policies)) {
+  constexpr size_t kInstallAppPrefixLength =
+      base::StringPiece(kInstallAppPrefix).length();
   std::for_each(std::begin(policies_), std::end(policies_),
                 [&](const auto& policy) {
                   const std::string policy_name = policy.first;
-                  const size_t install_app_prefix_length =
-                      std::string(kInstallAppPrefix).length();
-                  if (policy_name.length() <= install_app_prefix_length ||
+                  if (policy_name.length() <= kInstallAppPrefixLength ||
                       !base::StartsWith(policy_name, kInstallAppPrefix) ||
                       base::StartsWith(policy_name, kInstallAppsDefault) ||
                       !policy.second.is_int()) {
@@ -77,7 +77,7 @@
                   }
 
                   force_install_apps_.push_back(
-                      policy_name.substr(install_app_prefix_length));
+                      policy_name.substr(kInstallAppPrefixLength));
                 });
 }
 
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc
index 13ee745e..813d270 100644
--- a/chrome/updater/test/integration_tests.cc
+++ b/chrome/updater/test/integration_tests.cc
@@ -349,7 +349,9 @@
   Uninstall();
 }
 
-TEST_F(IntegrationTest, OverinstallWorking) {
+// TODO(crbug.com/1345407): this test is disabled temporarily. Reenable after
+// the build that adds `IUpdater::FetchPolicies` is published to CIPD.
+TEST_F(IntegrationTest, DISABLED_OverinstallWorking) {
   SetupRealUpdaterLowerVersion();
   WaitForUpdaterExit();
   ExpectVersionNotActive(kUpdaterVersion);
diff --git a/chrome/updater/update_service.h b/chrome/updater/update_service.h
index 2d47d9f6..2404f9d 100644
--- a/chrome/updater/update_service.h
+++ b/chrome/updater/update_service.h
@@ -211,6 +211,9 @@
   // if an error (including timeout) occurs.
   virtual void GetVersion(base::OnceCallback<void(const base::Version&)>) = 0;
 
+  // Fetches policies from device management.
+  virtual void FetchPolicies(base::OnceClosure callback) = 0;
+
   // Registers given request to the updater.
   virtual void RegisterApp(const RegistrationRequest& request,
                            RegisterAppCallback callback) = 0;
diff --git a/chrome/updater/update_service_impl.cc b/chrome/updater/update_service_impl.cc
index f40867b..b474ccd 100644
--- a/chrome/updater/update_service_impl.cc
+++ b/chrome/updater/update_service_impl.cc
@@ -237,6 +237,18 @@
       base::BindOnce(std::move(callback), base::Version(kUpdaterVersion)));
 }
 
+void UpdateServiceImpl::FetchPolicies(base::OnceClosure callback) {
+  VLOG(1) << __func__;
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  base::MakeRefCounted<DeviceManagementTask>(config_, main_task_runner_)
+      ->RunRegisterDevice(
+          base::BindOnce(&DeviceManagementTask::RunFetchPolicy,
+                         base::MakeRefCounted<DeviceManagementTask>(
+                             config_, main_task_runner_),
+                         std::move(callback)));
+}
+
 void UpdateServiceImpl::RegisterApp(
     const RegistrationRequest& request,
     base::OnceCallback<void(const RegistrationResponse&)> callback) {
@@ -395,32 +407,11 @@
           priority, UpdateService::PolicySameVersionUpdate::kNotAllowed));
 }
 
-void UpdateServiceImpl::GetDMPolicies(base::OnceClosure callback) {
-  VLOG(1) << __func__;
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  base::MakeRefCounted<DeviceManagementTask>(config_, main_task_runner_)
-      ->RunRegisterDevice(
-          base::BindOnce(&DeviceManagementTask::RunFetchPolicy,
-                         base::MakeRefCounted<DeviceManagementTask>(
-                             config_, main_task_runner_),
-                         std::move(callback)));
-}
-
 void UpdateServiceImpl::UpdateAll(StateChangeCallback state_update,
                                   Callback callback) {
   VLOG(1) << __func__;
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  GetDMPolicies(base::BindOnce(&UpdateServiceImpl::UpdateAllInternal, this,
-                               state_update, std::move(callback)));
-}
-
-void UpdateServiceImpl::UpdateAllInternal(StateChangeCallback state_update,
-                                          Callback callback) {
-  VLOG(1) << __func__;
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
   const auto app_ids = persisted_data_->GetAppIds();
   DCHECK(base::Contains(app_ids, kUpdaterAppId));
 
@@ -457,21 +448,6 @@
   VLOG(1) << __func__;
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  GetDMPolicies(base::BindOnce(
-      &UpdateServiceImpl::UpdateInternal, this, app_id, install_data_index,
-      priority, policy_same_version_update, state_update, std::move(callback)));
-}
-
-void UpdateServiceImpl::UpdateInternal(
-    const std::string& app_id,
-    const std::string& install_data_index,
-    Priority priority,
-    PolicySameVersionUpdate policy_same_version_update,
-    StateChangeCallback state_update,
-    Callback callback) {
-  VLOG(1) << __func__;
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
   int policy = kPolicyEnabled;
   if (IsUpdateDisabledByPolicy(app_id, priority, false, policy)) {
     HandleUpdateDisabledByPolicy(app_id, policy, false, state_update,
@@ -496,18 +472,6 @@
   VLOG(1) << __func__;
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  GetDMPolicies(base::BindOnce(&UpdateServiceImpl::InstallInternal, this,
-                               registration, install_data_index, priority,
-                               state_update, std::move(callback)));
-}
-
-void UpdateServiceImpl::InstallInternal(const RegistrationRequest& registration,
-                                        const std::string& install_data_index,
-                                        Priority priority,
-                                        StateChangeCallback state_update,
-                                        Callback callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  VLOG(1) << __func__;
   int policy = kPolicyEnabled;
   if (IsUpdateDisabledByPolicy(registration.app_id, priority, true, policy)) {
     HandleUpdateDisabledByPolicy(registration.app_id, policy, true,
@@ -559,23 +523,6 @@
   VLOG(1) << __func__;
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  GetDMPolicies(base::BindOnce(&UpdateServiceImpl::RunInstallerInternal, this,
-                               app_id, installer_path, install_args,
-                               install_data, install_settings, state_update,
-                               std::move(callback)));
-}
-
-void UpdateServiceImpl::RunInstallerInternal(
-    const std::string& app_id,
-    const base::FilePath& installer_path,
-    const std::string& install_args,
-    const std::string& install_data,
-    const std::string& install_settings,
-    StateChangeCallback state_update,
-    Callback callback) {
-  VLOG(1) << __func__;
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
   int policy = kPolicyEnabled;
   if (IsUpdateDisabledByPolicy(app_id, Priority::kForeground, true, policy)) {
     HandleUpdateDisabledByPolicy(app_id, policy, true, state_update,
diff --git a/chrome/updater/update_service_impl.h b/chrome/updater/update_service_impl.h
index 8ea194f..b1cf825d 100644
--- a/chrome/updater/update_service_impl.h
+++ b/chrome/updater/update_service_impl.h
@@ -44,6 +44,7 @@
   // Overrides for updater::UpdateService.
   void GetVersion(
       base::OnceCallback<void(const base::Version&)> callback) override;
+  void FetchPolicies(base::OnceClosure callback) override;
   void RegisterApp(
       const RegistrationRequest& request,
       base::OnceCallback<void(const RegistrationResponse&)> callback) override;
@@ -85,32 +86,6 @@
   // Installs applications in the wake task based on the ForceInstalls policy.
   void ForceInstall(StateChangeCallback state_update, Callback callback);
 
-  // `GetDMPolicies` refreshes the DM registration and policies, and is called
-  // before all installs and updates.
-  void GetDMPolicies(base::OnceClosure callback);
-
-  // After `GetDMPolicies` completes, it calls on these `Internal` method to do
-  // the actual install or update.
-  void UpdateAllInternal(StateChangeCallback state_update, Callback callback);
-  void UpdateInternal(const std::string& app_id,
-                      const std::string& install_data_index,
-                      Priority priority,
-                      PolicySameVersionUpdate policy_same_version_update,
-                      StateChangeCallback state_update,
-                      Callback callback);
-  void InstallInternal(const RegistrationRequest& registration,
-                       const std::string& install_data_index,
-                       Priority priority,
-                       StateChangeCallback state_update,
-                       Callback callback);
-  void RunInstallerInternal(const std::string& app_id,
-                            const base::FilePath& installer_path,
-                            const std::string& install_args,
-                            const std::string& install_data,
-                            const std::string& install_settings,
-                            StateChangeCallback state_update,
-                            Callback callback);
-
   bool IsUpdateDisabledByPolicy(const std::string& app_id,
                                 Priority priority,
                                 bool is_install,
diff --git a/chrome/updater/update_service_impl_inactive.cc b/chrome/updater/update_service_impl_inactive.cc
index ad16062..3438525 100644
--- a/chrome/updater/update_service_impl_inactive.cc
+++ b/chrome/updater/update_service_impl_inactive.cc
@@ -32,6 +32,11 @@
         FROM_HERE, base::BindOnce(std::move(callback), base::Version()));
   }
 
+  void FetchPolicies(base::OnceClosure callback) override {
+    VLOG(1) << __func__ << " (Inactive)";
+    std::move(callback).Run();
+  }
+
   void RegisterApp(
       const RegistrationRequest& request,
       base::OnceCallback<void(const RegistrationResponse&)> callback) override {
diff --git a/chrome/updater/win/update_service_proxy.cc b/chrome/updater/win/update_service_proxy.cc
index 00a89b4..7b7a3ca 100644
--- a/chrome/updater/win/update_service_proxy.cc
+++ b/chrome/updater/win/update_service_proxy.cc
@@ -389,6 +389,17 @@
               base::BindPostTask(main_task_runner_, std::move(callback)))));
 }
 
+void UpdateServiceProxy::FetchPolicies(base::OnceClosure callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_main_);
+  VLOG(1) << __func__;
+  com_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(&UpdateServiceProxy::InitializeSTA, this)
+          .Then(base::BindOnce(
+              &UpdateServiceProxy::FetchPoliciesOnSTA, this,
+              base::BindPostTask(main_task_runner_, std::move(callback)))));
+}
+
 void UpdateServiceProxy::RegisterApp(const RegistrationRequest& request,
                                      RegisterAppCallback callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_main_);
@@ -544,6 +555,31 @@
   std::move(callback).Run(base::Version(base::WideToUTF8(version.Get())));
 }
 
+void UpdateServiceProxy::FetchPoliciesOnSTA(base::OnceClosure callback,
+                                            HRESULT prev_hr) {
+  DCHECK(com_task_runner_->BelongsToCurrentThread());
+
+  if (FAILED(prev_hr)) {
+    std::move(callback).Run();
+    return;
+  }
+  Microsoft::WRL::ComPtr<IUpdater> updater;
+  if (HRESULT hr = CreateUpdater(scope_, updater); FAILED(hr)) {
+    std::move(callback).Run();
+    return;
+  }
+  auto callback_wrapper = Microsoft::WRL::Make<UpdaterCallback>(
+      updater,
+      base::BindOnce([](base::OnceClosure callback,
+                        LONG /*status_code*/) { std::move(callback).Run(); },
+                     std::move(callback)));
+  if (HRESULT hr = updater->FetchPolicies(callback_wrapper.Get()); FAILED(hr)) {
+    VLOG(2) << "Failed to call IUpdater::FetchPolicies" << std::hex << hr;
+    callback_wrapper->Disconnect().Run(hr);
+    return;
+  }
+}
+
 void UpdateServiceProxy::RegisterAppOnSTA(
     const RegistrationRequest& request,
     base::OnceCallback<void(const RegistrationResponse&)> callback,
diff --git a/chrome/updater/win/update_service_proxy.h b/chrome/updater/win/update_service_proxy.h
index 37a6aa8..ae1c1ab 100644
--- a/chrome/updater/win/update_service_proxy.h
+++ b/chrome/updater/win/update_service_proxy.h
@@ -47,6 +47,7 @@
   // Overrides for updater::UpdateService.
   void GetVersion(
       base::OnceCallback<void(const base::Version&)> callback) override;
+  void FetchPolicies(base::OnceClosure callback) override;
   void RegisterApp(const RegistrationRequest& request,
                    RegisterAppCallback callback) override;
   void GetAppStates(
@@ -83,6 +84,7 @@
   void UninitializeOnSTA();
   void GetVersionOnSTA(base::OnceCallback<void(const base::Version&)> callback,
                        HRESULT prev_hr);
+  void FetchPoliciesOnSTA(base::OnceClosure callback, HRESULT prev_hr);
   void RegisterAppOnSTA(const RegistrationRequest& request,
                         RegisterAppCallback callback,
                         HRESULT prev_hr);
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc
index 08ac25d..8558011 100644
--- a/components/autofill/core/browser/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -123,6 +123,9 @@
 // This is used for sites that change multiple things consecutively.
 constexpr base::TimeDelta kWaitTimeForDynamicForms = base::Milliseconds(200);
 
+// Characters to be removed from the string before comparisons.
+constexpr char16_t kCharsToBeRemoved[] = u"-_/\\.";
+
 // Returns whether the |field| is predicted as being any kind of name.
 bool IsNameType(const AutofillField& field) {
   return field.Type().group() == FieldTypeGroup::kName ||
@@ -409,6 +412,15 @@
   }
 }
 
+// Removes whitespace and `kCharsToBeRemoved` from the `value` and returns it.
+std::u16string RemoveWhiteSpaceAndConjugatingCharacters(
+    const std::u16string& value) {
+  std::u16string sanitized_value;
+  base::TrimWhitespace(value, base::TRIM_ALL, &sanitized_value);
+  base::RemoveChars(sanitized_value, kCharsToBeRemoved, &sanitized_value);
+  return sanitized_value;
+}
+
 }  // namespace
 
 BrowserAutofillManager::FillingContext::FillingContext(
@@ -745,12 +757,14 @@
         (submitted_form->field(i)->properties_mask & kUserTyped)) {
       // Compare and record if the currently filled value is same as the
       // non-empty value that was to be autofilled in the field.
+      std::u16string sanitized_submitted_value =
+          RemoveWhiteSpaceAndConjugatingCharacters(
+              submitted_form->field(i)->value);
       AutofillMetrics::
           LogIsValueNotAutofilledOverExistingValueSameAsSubmittedValue(
               *submitted_form->field(i)
                    ->value_not_autofilled_over_existing_value_hash() ==
-              base::FastHash(
-                  base::UTF16ToUTF8(submitted_form->field(i)->value)));
+              base::FastHash(base::UTF16ToUTF8(sanitized_submitted_value)));
     }
   }
   single_field_form_fill_router_->OnWillSubmitForm(
@@ -2172,6 +2186,12 @@
     absl::variant<const AutofillProfile*, const CreditCard*>
         profile_or_credit_card,
     const std::u16string* optional_cvc) {
+  // Keeping the credit card fields out of the experiment group.
+  // The default behaviour would be to override the credit card pre-filled
+  // fields.
+  if (cached_field->Type().group() == FieldTypeGroup::kCreditCard)
+    return false;
+
   if (!base::FeatureList::IsEnabled(
           features::kAutofillPreventOverridingPrefilledValues)) {
     return false;
@@ -2180,8 +2200,12 @@
   cached_field->set_value_not_autofilled_over_existing_value_hash(
       absl::nullopt);
 
+  // Some sites have empty values in the fields, for example.
+  std::u16string sanitized_field_value =
+      RemoveWhiteSpaceAndConjugatingCharacters(to_be_filled_field.value);
+
   if (to_be_filled_field.form_control_type != "select-one" &&
-      !to_be_filled_field.value.empty() &&
+      !sanitized_field_value.empty() &&
       !FormFieldData::DeepEqual(to_be_filled_field, initiating_field)) {
     std::string unused_failure_to_fill;
     const std::u16string kEmptyCvc{};
@@ -2189,14 +2213,18 @@
         *cached_field, profile_or_credit_card, field_data,
         optional_cvc ? *optional_cvc : kEmptyCvc, action,
         &unused_failure_to_fill);
+    std::u16string sanitized_fill_value =
+        RemoveWhiteSpaceAndConjugatingCharacters(fill_value);
 
-    if (action == mojom::RendererFormDataAction::kFill && !fill_value.empty() &&
-        fill_value != to_be_filled_field.value &&
+    if (action == mojom::RendererFormDataAction::kFill &&
+        !sanitized_fill_value.empty() &&
+        !base::EqualsCaseInsensitiveASCII(sanitized_field_value,
+                                          sanitized_fill_value) &&
         !cached_field->value.empty()) {
       // Save the value that was supposed to be autofilled for this
       // field if the field contained an initial value.
       cached_field->set_value_not_autofilled_over_existing_value_hash(
-          base::FastHash(base::UTF16ToUTF8(fill_value)));
+          base::FastHash(base::UTF16ToUTF8(sanitized_fill_value)));
     }
     return true;
   }
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
index 60e1631..e29f2893 100644
--- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -9372,6 +9372,8 @@
   test::CreateTestFormField("Phone Number", "phonenumber", "12345678901", "tel",
                             &field);
   form.fields.push_back(field);
+  test::CreateTestFormField("Zip Code", "zipcode", "_____", "text", &field);
+  form.fields.push_back(field);
   std::vector<FormData> forms(1, form);
   FormsSeen(forms);
 
@@ -9386,12 +9388,13 @@
   EXPECT_EQ(response_data.fields[2].value, u"Tennessee");
   EXPECT_EQ(response_data.fields[3].value, u"Test Country");
   EXPECT_EQ(response_data.fields[4].value, u"12345678901");
+  EXPECT_EQ(response_data.fields[5].value, u"38116");
 
   {
     FormStructure* form_structure;
     AutofillField* autofill_field;
-    std::vector<std::string> expected_values = {"", "Memphis", "",
-                                                "United States", ""};
+    std::vector<std::string> expected_values = {
+        "", "Memphis", "", "United States", "", ""};
     bool found = browser_autofill_manager_->GetCachedFormAndField(
         form, form.fields[0], &form_structure, &autofill_field);
     ASSERT_TRUE(found);
@@ -9411,11 +9414,14 @@
     EXPECT_TRUE(form_structure->field(0)->is_autofilled);  // No prefilled value
     EXPECT_TRUE(form_structure->field(2)->is_autofilled);  // Selection field.
 
-    // Prefilled value is same as the value to be autofilled so
-    // |value_not_autofilled_over_existing_value_hash| is not set for the field.
+    // Prefilled value is same as the value to be autofilled so the field is
+    // overridden.
     EXPECT_FALSE(form_structure->field(4)->is_autofilled);
     EXPECT_FALSE(form_structure->field(4)
                      ->value_not_autofilled_over_existing_value_hash());
+
+    // Field contained placeholder "______" value.
+    EXPECT_TRUE(form_structure->field(5)->is_autofilled);
   }
 
   features.Reset();
@@ -9430,6 +9436,7 @@
   EXPECT_EQ(response_data.fields[2].value, u"Tennessee");
   EXPECT_EQ(response_data.fields[3].value, u"United States");
   EXPECT_EQ(response_data.fields[4].value, u"12345678901");
+  EXPECT_EQ(response_data.fields[5].value, u"38116");
 }
 
 // Tests that the Autofill does override the prefilled field value since the
@@ -9439,6 +9446,7 @@
   base::test::ScopedFeatureList features;
   features.InitAndEnableFeature(
       autofill::features::kAutofillPreventOverridingPrefilledValues);
+
   // Set up our form data.
   FormData form;
   form.name = u"MyForm";
diff --git a/components/bookmarks/common/bookmark_metrics.cc b/components/bookmarks/common/bookmark_metrics.cc
index c748778..a792b68c 100644
--- a/components/bookmarks/common/bookmark_metrics.cc
+++ b/components/bookmarks/common/bookmark_metrics.cc
@@ -35,12 +35,12 @@
 }
 
 void RecordTimeToLoadAtStartup(base::TimeDelta delta) {
-  UmaHistogramTimes("Bookmarks.Storage.TimeToLoadAtStartup", delta);
+  UmaHistogramTimes("Bookmarks.Storage.TimeToLoadAtStartup2", delta);
 }
 
 void RecordFileSizeAtStartup(int64_t total_bytes) {
   int total_size_kb = base::saturated_cast<int>(total_bytes / kBytesPerKB);
-  base::UmaHistogramCounts1M("Bookmarks.Storage.FileSizeAtStartup",
+  base::UmaHistogramCounts1M("Bookmarks.Storage.FileSizeAtStartup2",
                              total_size_kb);
 }
 
@@ -52,45 +52,45 @@
             stats.duplicate_url_and_title_bookmark_count);
 
   base::UmaHistogramCounts100000(
-      "Bookmarks.Count.OnProfileLoad",
+      "Bookmarks.Count.OnProfileLoad3",
       base::saturated_cast<int>(stats.total_url_bookmark_count));
 
   if (stats.duplicate_url_bookmark_count != 0) {
     base::UmaHistogramCounts100000(
-        "Bookmarks.Count.OnProfileLoad.DuplicateUrl2",
+        "Bookmarks.Count.OnProfileLoad.DuplicateUrl3",
         base::saturated_cast<int>(stats.duplicate_url_bookmark_count));
   }
 
   if (stats.duplicate_url_and_title_bookmark_count != 0) {
     base::UmaHistogramCounts100000(
-        "Bookmarks.Count.OnProfileLoad.DuplicateUrlAndTitle",
+        "Bookmarks.Count.OnProfileLoad.DuplicateUrlAndTitle3",
         base::saturated_cast<int>(
             stats.duplicate_url_and_title_bookmark_count));
   }
 
   if (stats.duplicate_url_and_title_and_parent_bookmark_count != 0) {
     base::UmaHistogramCounts100000(
-        "Bookmarks.Count.OnProfileLoad.DuplicateUrlAndTitleAndParent",
+        "Bookmarks.Count.OnProfileLoad.DuplicateUrlAndTitleAndParent3",
         base::saturated_cast<int>(
             stats.duplicate_url_and_title_and_parent_bookmark_count));
   }
 
   // Log derived metrics for convenience.
   base::UmaHistogramCounts100000(
-      "Bookmarks.Count.OnProfileLoad.UniqueUrl",
+      "Bookmarks.Count.OnProfileLoad.UniqueUrl3",
       base::saturated_cast<int>(stats.total_url_bookmark_count -
                                 stats.duplicate_url_bookmark_count));
   base::UmaHistogramCounts100000(
-      "Bookmarks.Count.OnProfileLoad.UniqueUrlAndTitle",
+      "Bookmarks.Count.OnProfileLoad.UniqueUrlAndTitle3",
       base::saturated_cast<int>(stats.total_url_bookmark_count -
                                 stats.duplicate_url_and_title_bookmark_count));
   base::UmaHistogramCounts100000(
-      "Bookmarks.Count.OnProfileLoad.UniqueUrlAndTitleAndParent",
+      "Bookmarks.Count.OnProfileLoad.UniqueUrlAndTitleAndParent3",
       base::saturated_cast<int>(
           stats.total_url_bookmark_count -
           stats.duplicate_url_and_title_and_parent_bookmark_count));
   base::UmaHistogramCounts1000(
-      "Bookmarks.Times.OnProfileLoad.TimeSinceAdded",
+      "Bookmarks.Times.OnProfileLoad.TimeSinceAdded3",
       base::saturated_cast<int>(stats.avg_num_days_since_added));
 }
 
@@ -98,4 +98,4 @@
   base::UmaHistogramCounts100("Bookmarks.Clone.NumCloned", num_cloned);
 }
 
-}  // namespace bookmarks::metrics
\ No newline at end of file
+}  // namespace bookmarks::metrics
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/AddExceptionPreference.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/AddExceptionPreference.java
index 65becdf..d9f4e82 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/AddExceptionPreference.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/AddExceptionPreference.java
@@ -4,6 +4,7 @@
 
 package org.chromium.components.browser_ui.site_settings;
 
+import static org.chromium.components.browser_ui.site_settings.WebsitePreference.PARAM_SUBDOMAIN_SETTINGS;
 import static org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge.SITE_WILDCARD;
 
 import android.content.Context;
@@ -31,6 +32,7 @@
 
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.components.browser_ui.styles.SemanticColorUtils;
+import org.chromium.content_public.browser.ContentFeatureList;
 import org.chromium.ui.KeyboardVisibilityDelegate;
 
 /**
@@ -129,9 +131,14 @@
             checkBox.setVisibility(View.VISIBLE);
             checkBox.setText(R.string.website_settings_third_party_cookies_exception_label);
         } else if (mCategory.getType() == SiteSettingsCategory.Type.REQUEST_DESKTOP_SITE) {
-            checkBox.setVisibility(View.VISIBLE);
-            checkBox.setText(R.string.website_settings_domain_desktop_site_exception_checkbox);
+            // Default to domain level setting for Request Desktop Site.
             checkBox.setChecked(true);
+            if (ContentFeatureList.getFieldTrialParamByFeatureAsBoolean(
+                        ContentFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS,
+                        PARAM_SUBDOMAIN_SETTINGS, false)) {
+                checkBox.setVisibility(View.VISIBLE);
+                checkBox.setText(R.string.website_settings_domain_desktop_site_exception_checkbox);
+            }
         }
 
         DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteAddress.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteAddress.java
index 81b92bc..697e965 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteAddress.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsiteAddress.java
@@ -96,6 +96,10 @@
         return mHost;
     }
 
+    public boolean getIsAnySubdomainPattern() {
+        return mOriginOrHostPattern.startsWith(ANY_SUBDOMAIN_PATTERN);
+    }
+
     public String getTitle() {
         if (mOrigin == null) return mHost;
         return UrlFormatter.formatUrlForSecurityDisplay(mOrigin,
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreference.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreference.java
index cb5539d9..b62ae53 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreference.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreference.java
@@ -19,6 +19,7 @@
 import org.chromium.components.browser_ui.settings.ChromeImageViewPreference;
 import org.chromium.components.browser_ui.settings.FaviconViewUtils;
 import org.chromium.components.embedder_support.util.UrlUtilities;
+import org.chromium.content_public.browser.ContentFeatureList;
 import org.chromium.url.GURL;
 
 /**
@@ -39,6 +40,9 @@
     // Whether the favicon has been fetched already.
     private boolean mFaviconFetched;
 
+    // Finch param to allow subdomain settings for Request Desktop Site.
+    static final String PARAM_SUBDOMAIN_SETTINGS = "SubdomainSettings";
+
     WebsitePreference(Context context, SiteSettingsDelegate siteSettingsClient, Website site,
             SiteSettingsCategory category) {
         super(context);
@@ -87,6 +91,14 @@
         if (mSite.getEmbedder() == null) {
             if (mSite.isEmbargoed(mCategory.getContentSettingsType())) {
                 setSummary(getContext().getString(R.string.automatically_blocked));
+            } else if (mCategory.getType() == SiteSettingsCategory.Type.REQUEST_DESKTOP_SITE
+                    && ContentFeatureList.getFieldTrialParamByFeatureAsBoolean(
+                            ContentFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS,
+                            PARAM_SUBDOMAIN_SETTINGS, false)
+                    && mSite.getAddress().getIsAnySubdomainPattern()) {
+                setSummary(String.format(
+                        getContext().getString(R.string.website_settings_domain_exception_label),
+                        mSite.getAddress().getHost()));
             }
             return;
         }
diff --git a/components/browser_ui/site_settings/android/javatests/src/org/chromium/components/browser_ui/site_settings/WebsiteAddressTest.java b/components/browser_ui/site_settings/android/javatests/src/org/chromium/components/browser_ui/site_settings/WebsiteAddressTest.java
index f1ee1ed..3402e5b4 100644
--- a/components/browser_ui/site_settings/android/javatests/src/org/chromium/components/browser_ui/site_settings/WebsiteAddressTest.java
+++ b/components/browser_ui/site_settings/android/javatests/src/org/chromium/components/browser_ui/site_settings/WebsiteAddressTest.java
@@ -40,26 +40,31 @@
         Assert.assertEquals("http://a.google.com", httpAddress.getOrigin());
         Assert.assertEquals("a.google.com", httpAddress.getHost());
         Assert.assertEquals("a.google.com", httpAddress.getTitle());
+        Assert.assertFalse(httpAddress.getIsAnySubdomainPattern());
 
         WebsiteAddress http8080Address = WebsiteAddress.create("http://a.google.com:8080/");
         Assert.assertEquals("http://a.google.com:8080", http8080Address.getOrigin());
         Assert.assertEquals("a.google.com", http8080Address.getHost());
         Assert.assertEquals("http://a.google.com:8080", http8080Address.getTitle());
+        Assert.assertFalse(http8080Address.getIsAnySubdomainPattern());
 
         WebsiteAddress httpsAddress = WebsiteAddress.create("https://a.google.com/");
         Assert.assertEquals("https://a.google.com", httpsAddress.getOrigin());
         Assert.assertEquals("a.google.com", httpsAddress.getHost());
         Assert.assertEquals("https://a.google.com", httpsAddress.getTitle());
+        Assert.assertFalse(httpsAddress.getIsAnySubdomainPattern());
 
         WebsiteAddress hostAddress = WebsiteAddress.create("a.google.com");
         Assert.assertEquals("http://a.google.com", hostAddress.getOrigin());
         Assert.assertEquals("a.google.com", hostAddress.getHost());
         Assert.assertEquals("a.google.com", hostAddress.getTitle());
+        Assert.assertFalse(hostAddress.getIsAnySubdomainPattern());
 
         WebsiteAddress anySubdomainAddress = WebsiteAddress.create("[*.]google.com");
         Assert.assertEquals("http://google.com", anySubdomainAddress.getOrigin());
         Assert.assertEquals("google.com", anySubdomainAddress.getHost());
         Assert.assertEquals("google.com", anySubdomainAddress.getTitle());
+        Assert.assertTrue(anySubdomainAddress.getIsAnySubdomainPattern());
     }
 
     @Test
diff --git a/components/browser_ui/strings/android/site_settings.grdp b/components/browser_ui/strings/android/site_settings.grdp
index c0536ed..b1ff239 100644
--- a/components/browser_ui/strings/android/site_settings.grdp
+++ b/components/browser_ui/strings/android/site_settings.grdp
@@ -191,6 +191,9 @@
   <message name="IDS_WEBSITE_SETTINGS_THIRD_PARTY_COOKIES_EXCEPTION_LABEL" desc="The label for site exceptions that affect third party cookies.">
    Including third-party cookies on this site
   </message>
+  <message name="IDS_WEBSITE_SETTINGS_DOMAIN_EXCEPTION_LABEL" desc="The label for site exceptions that apply to the entire domain.">
+    All sites under <ph name="DOMAIN">%1$s<ex>google.com</ex></ph>
+  </message>
 
   <!-- Site settings Add Exception dialog -->
 
diff --git a/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_DOMAIN_EXCEPTION_LABEL.png.sha1 b/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_DOMAIN_EXCEPTION_LABEL.png.sha1
new file mode 100644
index 0000000..7dba3cbc
--- /dev/null
+++ b/components/browser_ui/strings/android/site_settings_grdp/IDS_WEBSITE_SETTINGS_DOMAIN_EXCEPTION_LABEL.png.sha1
@@ -0,0 +1 @@
+0ba052b49bd87a31aad51e4c42cfdef12df6c50d
\ No newline at end of file
diff --git a/components/commerce/core/mojom/shopping_list.mojom b/components/commerce/core/mojom/shopping_list.mojom
index 8c64f31..8630fee4 100644
--- a/components/commerce/core/mojom/shopping_list.mojom
+++ b/components/commerce/core/mojom/shopping_list.mojom
@@ -54,4 +54,10 @@
 interface ShoppingListHandler {
   // Returns all the tracked product info from bookmarks.
   GetAllBookmarkProductInfo() => (array<BookmarkProductInfo> productInfos);
+
+  // Track price for bookmark with 'bookmark_id'.
+  TrackPriceForBookmark(int64 bookmark_id);
+
+  // Untrack price for bookmark with 'bookmark_id'.
+  UntrackPriceForBookmark(int64 bookmark_id);
 };
\ No newline at end of file
diff --git a/components/commerce/core/webui/BUILD.gn b/components/commerce/core/webui/BUILD.gn
index 169b44c..95a79cf6 100644
--- a/components/commerce/core/webui/BUILD.gn
+++ b/components/commerce/core/webui/BUILD.gn
@@ -11,6 +11,8 @@
   deps = [
     "../mojom:mojo_bindings",
     "//base",
+    "//components/bookmarks/browser",
+    "//components/commerce/core:shopping_service",
     "//mojo/public/cpp/bindings",
   ]
 }
diff --git a/components/commerce/core/webui/shopping_list_handler.cc b/components/commerce/core/webui/shopping_list_handler.cc
index a30fafad..028d2c2c 100644
--- a/components/commerce/core/webui/shopping_list_handler.cc
+++ b/components/commerce/core/webui/shopping_list_handler.cc
@@ -3,14 +3,23 @@
 // found in the LICENSE file.
 
 #include "components/commerce/core/webui/shopping_list_handler.h"
+#include "components/commerce/core/price_tracking_utils.h"
 
 #include <vector>
+#include "components/bookmarks/browser/bookmark_model.h"
+#include "components/bookmarks/browser/bookmark_node.h"
+#include "components/bookmarks/browser/bookmark_utils.h"
+#include "components/commerce/core/shopping_service.h"
 
 namespace commerce {
 
 ShoppingListHandler::ShoppingListHandler(
-    mojo::PendingReceiver<shopping_list::mojom::ShoppingListHandler> receiver)
-    : receiver_(this, std::move(receiver)) {}
+    mojo::PendingReceiver<shopping_list::mojom::ShoppingListHandler> receiver,
+    bookmarks::BookmarkModel* bookmark_model,
+    ShoppingService* shopping_service)
+    : receiver_(this, std::move(receiver)),
+      bookmark_model_(bookmark_model),
+      shopping_service_(shopping_service) {}
 
 ShoppingListHandler::~ShoppingListHandler() = default;
 
@@ -22,4 +31,18 @@
   // get data.
   std::move(callback).Run(std::move(info_list));
 }
+
+void ShoppingListHandler::TrackPriceForBookmark(int64_t bookmark_id) {
+  commerce::SetPriceTrackingStateForBookmark(
+      shopping_service_, bookmark_model_,
+      bookmarks::GetBookmarkNodeByID(bookmark_model_, bookmark_id), true,
+      base::DoNothing());
+}
+
+void ShoppingListHandler::UntrackPriceForBookmark(int64_t bookmark_id) {
+  commerce::SetPriceTrackingStateForBookmark(
+      shopping_service_, bookmark_model_,
+      bookmarks::GetBookmarkNodeByID(bookmark_model_, bookmark_id), false,
+      base::DoNothing());
+}
 }  // namespace commerce
diff --git a/components/commerce/core/webui/shopping_list_handler.h b/components/commerce/core/webui/shopping_list_handler.h
index f9728ca..a48996c 100644
--- a/components/commerce/core/webui/shopping_list_handler.h
+++ b/components/commerce/core/webui/shopping_list_handler.h
@@ -5,17 +5,25 @@
 #ifndef COMPONENTS_COMMERCE_CORE_WEBUI_SHOPPING_LIST_HANDLER_H_
 #define COMPONENTS_COMMERCE_CORE_WEBUI_SHOPPING_LIST_HANDLER_H_
 
+#include "base/memory/raw_ptr.h"
 #include "components/commerce/core/mojom/shopping_list.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 
+namespace bookmarks {
+class BookmarkModel;
+}  // namespace bookmarks
+
 namespace commerce {
 
+class ShoppingService;
+
 class ShoppingListHandler : public shopping_list::mojom::ShoppingListHandler {
  public:
-  explicit ShoppingListHandler(
-      mojo::PendingReceiver<shopping_list::mojom::ShoppingListHandler>
-          receiver);
+  ShoppingListHandler(
+      mojo::PendingReceiver<shopping_list::mojom::ShoppingListHandler> receiver,
+      bookmarks::BookmarkModel* bookmark_model,
+      ShoppingService* shopping_service);
   ShoppingListHandler(const ShoppingListHandler&) = delete;
   ShoppingListHandler& operator=(const ShoppingListHandler&) = delete;
   ~ShoppingListHandler() override;
@@ -23,9 +31,17 @@
   // shopping_list::mojom::ShoppingListHandler:
   void GetAllBookmarkProductInfo(
       GetAllBookmarkProductInfoCallback callback) override;
+  void TrackPriceForBookmark(int64_t bookmark_id) override;
+  void UntrackPriceForBookmark(int64_t bookmark_id) override;
 
  private:
   mojo::Receiver<shopping_list::mojom::ShoppingListHandler> receiver_;
+  // The bookmark model and shopping service will outlive this implementation
+  // since it is a keyed service bound to the browser context (which in turn has
+  // the same lifecycle as the browser). The web UI that hosts this will be shut
+  // down prior to the rest of the browser.
+  raw_ptr<bookmarks::BookmarkModel> bookmark_model_;
+  raw_ptr<ShoppingService> shopping_service_;
 };
 
 }  // namespace commerce
diff --git a/components/content_capture/browser/content_capture_receiver_test.cc b/components/content_capture/browser/content_capture_receiver_test.cc
index 62518f96c..87047f46 100644
--- a/components/content_capture/browser/content_capture_receiver_test.cc
+++ b/components/content_capture/browser/content_capture_receiver_test.cc
@@ -30,11 +30,9 @@
                                    public ::testing::WithParamInterface<bool> {
  public:
   void SetUp() override {
-    // TODO (crbug.com/1115234): Remove the param when BFCache same site feature
-    // launched.
     if (GetParam()) {
       scoped_feature_list_.InitWithFeaturesAndParameters(
-          {{{features::kBackForwardCache}, {{"enable_same_site", "true"}}}},
+          {{{features::kBackForwardCache}, {}}},
           // Allow BackForwardCache for all devices regardless of their memory.
           {features::kBackForwardCacheMemoryControls});
     }
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index cce4fb0..047860d3 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -489,7 +489,6 @@
     proguard_configs = [
       "$target_gen_dir/cronet_impl_native_proguard.cfg",
       "cronet_impl_common_proguard.cfg",
-      "//base/android/proguard/chromium_apk.flags",
     ]
   }
 }
@@ -1229,7 +1228,6 @@
         "$target_gen_dir/cronet_impl_native_proguard.cfg",
         "cronet_impl_common_proguard.cfg",
         "test/proguard.cfg",
-        "//base/android/proguard/chromium_apk.flags",
         "//testing/android/proguard_for_test.flags",
       ]
       enable_proguard_checks = false
diff --git a/components/desks_storage/core/desk_model_observer.h b/components/desks_storage/core/desk_model_observer.h
index 65a1f0d..2d329be9 100644
--- a/components/desks_storage/core/desk_model_observer.h
+++ b/components/desks_storage/core/desk_model_observer.h
@@ -5,9 +5,10 @@
 #ifndef COMPONENTS_DESKS_STORAGE_CORE_DESK_MODEL_OBSERVER_H_
 #define COMPONENTS_DESKS_STORAGE_CORE_DESK_MODEL_OBSERVER_H_
 
-#include <string>
 #include <vector>
 
+#include "base/guid.h"
+
 namespace ash {
 class DeskTemplate;
 }
@@ -36,13 +37,12 @@
   // the model to clients.
   virtual void EntriesAddedOrUpdatedRemotely(
       const std::vector<const ash::DeskTemplate*>& new_entries) = 0;
-  virtual void EntriesRemovedRemotely(
-      const std::vector<std::string>& uuids) = 0;
+  virtual void EntriesRemovedRemotely(const std::vector<base::GUID>& uuids) = 0;
 
   // Invoked when desk templates are added/updated, removed locally.
   virtual void EntriesAddedOrUpdatedLocally(
       const std::vector<const ash::DeskTemplate*>& new_entries) = 0;
-  virtual void EntriesRemovedLocally(const std::vector<std::string>& uuids) = 0;
+  virtual void EntriesRemovedLocally(const std::vector<base::GUID>& uuids) = 0;
 
  protected:
   virtual ~DeskModelObserver() = default;
diff --git a/components/desks_storage/core/desk_model_wrapper_unittests.cc b/components/desks_storage/core/desk_model_wrapper_unittests.cc
index 9ebb596..bb65ceb7 100644
--- a/components/desks_storage/core/desk_model_wrapper_unittests.cc
+++ b/components/desks_storage/core/desk_model_wrapper_unittests.cc
@@ -147,10 +147,10 @@
   MOCK_METHOD0(DeskModelLoaded, void());
   MOCK_METHOD1(EntriesAddedOrUpdatedRemotely,
                void(const std::vector<const ash::DeskTemplate*>&));
-  MOCK_METHOD1(EntriesRemovedRemotely, void(const std::vector<std::string>&));
+  MOCK_METHOD1(EntriesRemovedRemotely, void(const std::vector<base::GUID>&));
   MOCK_METHOD1(EntriesAddedOrUpdatedLocally,
                void(const std::vector<const ash::DeskTemplate*>&));
-  MOCK_METHOD1(EntriesRemovedLocally, void(const std::vector<std::string>&));
+  MOCK_METHOD1(EntriesRemovedLocally, void(const std::vector<base::GUID>&));
 };
 
 // This test class only tests the overall wrapper desk model class. The
diff --git a/components/desks_storage/core/desk_sync_bridge.cc b/components/desks_storage/core/desk_sync_bridge.cc
index df95847..dc3700e6 100644
--- a/components/desks_storage/core/desk_sync_bridge.cc
+++ b/components/desks_storage/core/desk_sync_bridge.cc
@@ -962,7 +962,7 @@
     std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
     syncer::EntityChangeList entity_changes) {
   std::vector<const DeskTemplate*> added_or_updated;
-  std::vector<std::string> removed;
+  std::vector<base::GUID> removed;
   std::unique_ptr<ModelTypeStore::WriteBatch> batch =
       store_->CreateWriteBatch();
 
@@ -979,7 +979,7 @@
         if (desk_template_entries_.find(uuid) != desk_template_entries_.end()) {
           desk_template_entries_.erase(uuid);
           batch->DeleteData(uuid.AsLowercaseString());
-          removed.push_back(uuid.AsLowercaseString());
+          removed.push_back(uuid);
         }
         break;
       }
@@ -1318,7 +1318,7 @@
 }
 
 void DeskSyncBridge::NotifyRemoteDeskTemplateDeleted(
-    const std::vector<std::string>& uuids) {
+    const std::vector<base::GUID>& uuids) {
   if (uuids.empty()) {
     return;
   }
diff --git a/components/desks_storage/core/desk_sync_bridge.h b/components/desks_storage/core/desk_sync_bridge.h
index 4041a3cf..e83f2ee 100644
--- a/components/desks_storage/core/desk_sync_bridge.h
+++ b/components/desks_storage/core/desk_sync_bridge.h
@@ -118,7 +118,7 @@
 
   // Notify all observers when the entries with `uuids` have been removed via
   // sync or disabling sync locally.
-  void NotifyRemoteDeskTemplateDeleted(const std::vector<std::string>& uuids);
+  void NotifyRemoteDeskTemplateDeleted(const std::vector<base::GUID>& uuids);
 
   // Methods used as callbacks given to DataTypeStore.
   void OnStoreCreated(const absl::optional<syncer::ModelError>& error,
diff --git a/components/desks_storage/core/desk_sync_bridge_unittest.cc b/components/desks_storage/core/desk_sync_bridge_unittest.cc
index b38f646..427fce4 100644
--- a/components/desks_storage/core/desk_sync_bridge_unittest.cc
+++ b/components/desks_storage/core/desk_sync_bridge_unittest.cc
@@ -485,10 +485,10 @@
   MOCK_METHOD0(DeskModelLoaded, void());
   MOCK_METHOD1(EntriesAddedOrUpdatedRemotely,
                void(const std::vector<const DeskTemplate*>&));
-  MOCK_METHOD1(EntriesRemovedRemotely, void(const std::vector<std::string>&));
+  MOCK_METHOD1(EntriesRemovedRemotely, void(const std::vector<base::GUID>&));
   MOCK_METHOD1(EntriesAddedOrUpdatedLocally,
                void(const std::vector<const DeskTemplate*>&));
-  MOCK_METHOD1(EntriesRemovedLocally, void(const std::vector<std::string>&));
+  MOCK_METHOD1(EntriesRemovedLocally, void(const std::vector<base::GUID>&));
 };
 
 MATCHER_P(UuidIs, e, "") {
diff --git a/components/file_access/scoped_file_access_delegate.h b/components/file_access/scoped_file_access_delegate.h
index 622d3fd..1316643 100644
--- a/components/file_access/scoped_file_access_delegate.h
+++ b/components/file_access/scoped_file_access_delegate.h
@@ -38,11 +38,21 @@
   // The instance will be deconstructed
   static void DeleteInstance();
 
+  // Requests access to |files| in order to be sent to |destination_url|.
+  // |callback| is called with a token that should be hold until
+  // `open()` operation on the files finished.
   virtual void RequestFilesAccess(
       const std::vector<base::FilePath>& files,
       const GURL& destination_url,
       base::OnceCallback<void(file_access::ScopedFileAccess)> callback) = 0;
 
+  // Requests access to |files| in order to be sent to a system process.
+  // |callback| is called with a token that should be hold until
+  // `open()` operation on the files finished.
+  virtual void RequestFilesAccessForSystem(
+      const std::vector<base::FilePath>& files,
+      base::OnceCallback<void(file_access::ScopedFileAccess)> callback) = 0;
+
  protected:
   ScopedFileAccessDelegate();
 
diff --git a/components/file_access/scoped_file_access_delegate_unittest.cc b/components/file_access/scoped_file_access_delegate_unittest.cc
index 9004642d..e3e0023a 100644
--- a/components/file_access/scoped_file_access_delegate_unittest.cc
+++ b/components/file_access/scoped_file_access_delegate_unittest.cc
@@ -12,11 +12,17 @@
   static int instance_counter;
   ScopedFileAccessDelegateTestInstance() { ++instance_counter; }
   ~ScopedFileAccessDelegateTestInstance() override { --instance_counter; }
+
+  // ScopedFileAccessDelegate:
   void RequestFilesAccess(
       const std::vector<base::FilePath>& files,
       const GURL& destination_url,
       base::OnceCallback<void(file_access::ScopedFileAccess)> callback)
       override {}
+  void RequestFilesAccessForSystem(
+      const std::vector<base::FilePath>& files,
+      base::OnceCallback<void(file_access::ScopedFileAccess)> callback)
+      override {}
 };
 int ScopedFileAccessDelegateTestInstance::instance_counter = 0;
 }  // namespace file_access
diff --git a/components/history/core/browser/visit_database.cc b/components/history/core/browser/visit_database.cc
index 0ea42ad..16d88ca3 100644
--- a/components/history/core/browser/visit_database.cc
+++ b/components/history/core/browser/visit_database.cc
@@ -96,6 +96,22 @@
                                        ui::PAGE_TRANSITION_KEYWORD_GENERATED);
 }
 
+VisitSource VisitSourceFromInt(int value) {
+  auto converted = static_cast<VisitSource>(value);
+  // Verify that `converted` is actually a valid enum value.
+  switch (converted) {
+    case SOURCE_SYNCED:
+    case SOURCE_BROWSED:
+    case SOURCE_EXTENSION:
+    case SOURCE_FIREFOX_IMPORTED:
+    case SOURCE_IE_IMPORTED:
+    case SOURCE_SAFARI_IMPORTED:
+      return converted;
+  }
+  // In cases of database corruption, SOURCE_BROWSED is a safe default value.
+  return SOURCE_BROWSED;
+}
+
 }  // namespace
 
 VisitDatabase::VisitDatabase() = default;
@@ -957,8 +973,7 @@
     // Get the source entries out of the query result.
     while (statement.Step()) {
       std::pair<VisitID, VisitSource> source_entry(
-          statement.ColumnInt64(0),
-          static_cast<VisitSource>(statement.ColumnInt(1)));
+          statement.ColumnInt64(0), VisitSourceFromInt(statement.ColumnInt(1)));
       sources->insert(source_entry);
     }
   }
@@ -970,7 +985,7 @@
   statement.BindInt64(0, visit_id);
   if (!statement.Step())
     return VisitSource::SOURCE_BROWSED;
-  return static_cast<VisitSource>(statement.ColumnInt(0));
+  return VisitSourceFromInt(statement.ColumnInt(0));
 }
 
 std::vector<DomainVisit>
diff --git a/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc b/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc
index fc5c281..8957ec2d 100644
--- a/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc
+++ b/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc
@@ -1469,9 +1469,7 @@
   WaitForThreadTasks();
 
   // In case of invalid data, only the initialized data should be in the tree.
-  ASSERT_EQ(ax::mojom::Role::kUnknown,
-            pdf_accessibility_tree.GetRoot()->GetRole());
-  ASSERT_EQ(0u, pdf_accessibility_tree.GetRoot()->children().size());
+  ASSERT_FALSE(pdf_accessibility_tree.GetRoot());
 }
 
 TEST_F(PdfAccessibilityTreeTest, UnsortedLinkVector) {
@@ -1515,9 +1513,7 @@
   WaitForThreadTasks();
 
   // In case of invalid data, only the initialized data should be in the tree.
-  ASSERT_EQ(ax::mojom::Role::kUnknown,
-            pdf_accessibility_tree.GetRoot()->GetRole());
-  ASSERT_EQ(0u, pdf_accessibility_tree.GetRoot()->children().size());
+  ASSERT_FALSE(pdf_accessibility_tree.GetRoot());
 }
 
 TEST_F(PdfAccessibilityTreeTest, OutOfBoundLink) {
@@ -1552,9 +1548,7 @@
   WaitForThreadTasks();
 
   // In case of invalid data, only the initialized data should be in the tree.
-  ASSERT_EQ(ax::mojom::Role::kUnknown,
-            pdf_accessibility_tree.GetRoot()->GetRole());
-  ASSERT_EQ(0u, pdf_accessibility_tree.GetRoot()->children().size());
+  ASSERT_FALSE(pdf_accessibility_tree.GetRoot());
 }
 
 TEST_F(PdfAccessibilityTreeTest, UnsortedImageVector) {
@@ -1596,9 +1590,7 @@
   WaitForThreadTasks();
 
   // In case of invalid data, only the initialized data should be in the tree.
-  ASSERT_EQ(ax::mojom::Role::kUnknown,
-            pdf_accessibility_tree.GetRoot()->GetRole());
-  ASSERT_EQ(0u, pdf_accessibility_tree.GetRoot()->children().size());
+  ASSERT_FALSE(pdf_accessibility_tree.GetRoot());
 }
 
 TEST_F(PdfAccessibilityTreeTest, OutOfBoundImage) {
@@ -1631,9 +1623,7 @@
   WaitForThreadTasks();
 
   // In case of invalid data, only the initialized data should be in the tree.
-  ASSERT_EQ(ax::mojom::Role::kUnknown,
-            pdf_accessibility_tree.GetRoot()->GetRole());
-  ASSERT_EQ(0u, pdf_accessibility_tree.GetRoot()->children().size());
+  ASSERT_FALSE(pdf_accessibility_tree.GetRoot());
 }
 
 TEST_F(PdfAccessibilityTreeTest, UnsortedHighlightVector) {
@@ -1680,9 +1670,7 @@
   WaitForThreadTasks();
 
   // In case of invalid data, only the initialized data should be in the tree.
-  ASSERT_EQ(ax::mojom::Role::kUnknown,
-            pdf_accessibility_tree.GetRoot()->GetRole());
-  ASSERT_EQ(0u, pdf_accessibility_tree.GetRoot()->children().size());
+  ASSERT_FALSE(pdf_accessibility_tree.GetRoot());
 }
 
 TEST_F(PdfAccessibilityTreeTest, OutOfBoundHighlight) {
@@ -1718,9 +1706,7 @@
   WaitForThreadTasks();
 
   // In case of invalid data, only the initialized data should be in the tree.
-  ASSERT_EQ(ax::mojom::Role::kUnknown,
-            pdf_accessibility_tree.GetRoot()->GetRole());
-  ASSERT_EQ(0u, pdf_accessibility_tree.GetRoot()->children().size());
+  ASSERT_FALSE(pdf_accessibility_tree.GetRoot());
 }
 
 TEST_F(PdfAccessibilityTreeTest, TestActionDataConversion) {
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index ee97a78..bed0c2d 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -26732,7 +26732,8 @@
         'cloud_only': True,
       },
       'id': 931,
-      'future_on': ['chrome.*', 'chrome_os', 'fuchsia'],
+      'supported_on': ['chrome.*:106-', 'chrome_os:106-'],
+      'future_on': ['fuchsia'],
       'caption': '''Configuration policy for the OnPrint <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> Enterprise Connector''',
       'tags': [],
       'desc': '''List of <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> Enterprise Connectors services settings to be applied to the <ph name="ON_PRINT_ENTERPRISE_CONNECTOR">OnPrint</ph> Enterprise Connector, which triggers when a page or file is printed from <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>.
diff --git a/components/segmentation_platform/internal/metadata/metadata_writer.cc b/components/segmentation_platform/internal/metadata/metadata_writer.cc
index d19c4c1..9b848ef 100644
--- a/components/segmentation_platform/internal/metadata/metadata_writer.cc
+++ b/components/segmentation_platform/internal/metadata/metadata_writer.cc
@@ -72,6 +72,13 @@
   }
 }
 
+void MetadataWriter::AddBooleanSegmentDiscreteMapping(const std::string& key,
+                                                      float threshold) {
+  DCHECK_GT(threshold, 0);
+  const std::pair<float, int> mappings[]{{threshold, 1}};
+  AddDiscreteMappingEntries(key, mappings, 1);
+}
+
 void MetadataWriter::SetSegmentationMetadataConfig(
     proto::TimeUnit time_unit,
     uint64_t bucket_duration,
@@ -85,4 +92,13 @@
   metadata_->set_result_time_to_live(result_time_to_live);
 }
 
+void MetadataWriter::SetDefaultSegmentationMetadataConfig(
+    int min_signal_collection_length_days,
+    int signal_storage_length_days) {
+  SetSegmentationMetadataConfig(proto::TimeUnit::DAY, /*bucket_duration=*/1,
+                                signal_storage_length_days,
+                                min_signal_collection_length_days,
+                                /*result_time_to_live=*/1);
+}
+
 }  // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/metadata/metadata_writer.h b/components/segmentation_platform/internal/metadata/metadata_writer.h
index 9ad064c..376b575 100644
--- a/components/segmentation_platform/internal/metadata/metadata_writer.h
+++ b/components/segmentation_platform/internal/metadata/metadata_writer.h
@@ -109,6 +109,12 @@
                                  const std::pair<float, int>* mappings,
                                  size_t mappings_size);
 
+  // Appends a boolean segmentation mapping. If the model records subsegments,
+  // then set the threshold to the cutoff segment value, and for any value
+  // strictly less than `threshold`, then the selection will return no.
+  void AddBooleanSegmentDiscreteMapping(const std::string& key,
+                                        float threshold = 1);
+
   // Writes the model metadata with the given parameters.
   void SetSegmentationMetadataConfig(proto::TimeUnit time_unit,
                                      uint64_t bucket_duration,
@@ -116,6 +122,12 @@
                                      int64_t min_signal_collection_length,
                                      int64_t result_time_to_live);
 
+  // Uses default setting for model metadata using DAY time unit and 1 day
+  // buckets.
+  void SetDefaultSegmentationMetadataConfig(
+      int min_signal_collection_length_days = 7,
+      int signal_storage_length_days = 28);
+
  private:
   const raw_ptr<proto::SegmentationModelMetadata> metadata_;
 };
diff --git a/components/services/app_service/public/cpp/features.cc b/components/services/app_service/public/cpp/features.cc
index 04adc4d..2411f352 100644
--- a/components/services/app_service/public/cpp/features.cc
+++ b/components/services/app_service/public/cpp/features.cc
@@ -22,6 +22,6 @@
                                             base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kAppServiceGetMenuWithoutMojom{
-    "AppServiceGetMenuWithoutMojom", base::FEATURE_DISABLED_BY_DEFAULT};
+    "AppServiceGetMenuWithoutMojom", base::FEATURE_ENABLED_BY_DEFAULT};
 
 }  // namespace apps
diff --git a/components/sessions/core/tab_restore_service_helper.cc b/components/sessions/core/tab_restore_service_helper.cc
index aa7c9c3..023bb3d 100644
--- a/components/sessions/core/tab_restore_service_helper.cc
+++ b/components/sessions/core/tab_restore_service_helper.cc
@@ -465,7 +465,7 @@
   // Normally an entry's ID should match the ID that is being restored. If it
   // does not, then the entry is a window or group from which a single tab will
   // be restored (reachable through OS-level menus like Mac > History).
-  bool entry_id_matches_restore_id = entry.id == id;
+  bool entry_id_matches_restore_id = entry.id == id || entry.original_id == id;
 
   // |context| will be NULL in cases where one isn't already available (eg,
   // when invoked on Mac OS X with no windows open). In this case, create a
@@ -550,7 +550,7 @@
           SessionID::id_type restored_tab_browser_id;
           {
             const Tab& tab = *window.tabs[tab_i];
-            if (tab.id != id)
+            if (tab.id != id && tab.original_id != id)
               continue;
 
             restored_tab_browser_id = tab.browser_id;
@@ -710,7 +710,7 @@
 TabRestoreService::Entries::iterator
 TabRestoreServiceHelper::GetEntryIteratorById(SessionID id) {
   for (auto i = entries_.begin(); i != entries_.end(); ++i) {
-    if ((*i)->id == id)
+    if ((*i)->id == id || (*i)->original_id == id)
       return i;
 
     // For Window and Group entries, see if the ID matches a tab. If so, report
@@ -718,14 +718,14 @@
     if ((*i)->type == TabRestoreService::WINDOW) {
       auto& window = static_cast<const Window&>(**i);
       for (const auto& tab : window.tabs) {
-        if (tab->id == id) {
+        if (tab->id == id || tab->original_id == id) {
           return i;
         }
       }
     } else if ((*i)->type == TabRestoreService::GROUP) {
       auto& group = static_cast<const Group&>(**i);
       for (const auto& tab : group.tabs) {
-        if (tab->id == id) {
+        if (tab->id == id || tab->original_id == id) {
           return i;
         }
       }
diff --git a/components/sessions/core/tab_restore_service_helper.h b/components/sessions/core/tab_restore_service_helper.h
index 9f14d817..4ba8265 100644
--- a/components/sessions/core/tab_restore_service_helper.h
+++ b/components/sessions/core/tab_restore_service_helper.h
@@ -123,10 +123,10 @@
   // entries.
   void PruneEntries();
 
-  // Returns an iterator into |entries_| whose id matches |id|. If |id|
-  // identifies a Window, then its iterator position will be returned. If it
-  // identifies a tab, then the iterator position of the Window in which the Tab
-  // resides is returned.
+  // Returns an iterator into |entries_| whose id or original_id matches |id|.
+  // If |id| identifies a Window, then its iterator position will be returned.
+  // If it identifies a tab, then the iterator position of the Window in which
+  // the Tab resides is returned.
   Entries::iterator GetEntryIteratorById(SessionID id);
 
   // From base::trace_event::MemoryDumpProvider
diff --git a/components/viz/service/display_embedder/skia_output_device_buffer_queue_unittest.cc b/components/viz/service/display_embedder/skia_output_device_buffer_queue_unittest.cc
index 0abe5bf..a3456d59 100644
--- a/components/viz/service/display_embedder/skia_output_device_buffer_queue_unittest.cc
+++ b/components/viz/service/display_embedder/skia_output_device_buffer_queue_unittest.cc
@@ -191,10 +191,11 @@
   }
   bool IsSupported(uint32_t usage,
                    ResourceFormat format,
+                   const gfx::Size& size,
                    bool thread_safe,
                    gfx::GpuMemoryBufferType gmb_type,
-                   gpu::GrContextType gr_context_type_,
-                   bool is_pixel_used) override {
+                   gpu::GrContextType gr_context_type,
+                   base::span<const uint8_t> pixel_data) override {
     return true;
   }
 };
diff --git a/components/viz/service/frame_sinks/video_detector.cc b/components/viz/service/frame_sinks/video_detector.cc
index 185ee06..a8a34a8 100644
--- a/components/viz/service/frame_sinks/video_detector.cc
+++ b/components/viz/service/frame_sinks/video_detector.cc
@@ -11,6 +11,8 @@
 #include "base/time/time.h"
 #include "components/viz/common/features.h"
 #include "components/viz/common/quads/compositor_frame.h"
+#include "components/viz/common/quads/draw_quad.h"
+#include "components/viz/common/quads/texture_draw_quad.h"
 #include "components/viz/service/surfaces/surface.h"
 #include "components/viz/service/surfaces/surface_manager.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -51,9 +53,22 @@
       return false;
     }
 
-    gfx::Rect damage =
-        gfx::ScaleToEnclosingRect(frame.render_pass_list.back()->damage_rect,
-                                  1.f / frame.device_scale_factor());
+    gfx::Rect damage = frame.render_pass_list.back()->damage_rect;
+    if (frame.render_pass_list.back()->has_per_quad_damage) {
+      for (auto* quad : frame.render_pass_list.back()->quad_list) {
+        if (quad->material != DrawQuad::Material::kTextureContent)
+          continue;
+
+        auto* texture_quad = TextureDrawQuad::MaterialCast(quad);
+        if (!texture_quad->damage_rect)
+          continue;
+
+        damage.Union(*texture_quad->damage_rect);
+      }
+    }
+
+    damage =
+        gfx::ScaleToEnclosingRect(damage, 1.f / frame.device_scale_factor());
 
     if (damage.width() < kMinDamageWidth || damage.height() < kMinDamageHeight)
       return false;
diff --git a/components/viz/service/frame_sinks/video_detector_unittest.cc b/components/viz/service/frame_sinks/video_detector_unittest.cc
index 485a8d0..16461eb 100644
--- a/components/viz/service/frame_sinks/video_detector_unittest.cc
+++ b/components/viz/service/frame_sinks/video_detector_unittest.cc
@@ -17,6 +17,8 @@
 #include "base/time/time.h"
 #include "components/viz/common/features.h"
 #include "components/viz/common/quads/surface_draw_quad.h"
+#include "components/viz/common/quads/texture_draw_quad.h"
+#include "components/viz/common/resources/transferable_resource.h"
 #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
 #include "components/viz/service/display/display_resource_provider_software.h"
 #include "components/viz/service/display/surface_aggregator.h"
@@ -160,7 +162,8 @@
 
   void SendUpdate(CompositorFrameSinkSupport* frame_sink,
                   const gfx::Rect& damage,
-                  bool may_contain_video) {
+                  bool may_contain_video,
+                  bool use_per_quad_damage) {
     LocalSurfaceId local_surface_id =
         frame_sink->last_activated_local_surface_id();
     if (!local_surface_id.is_valid()) {
@@ -171,7 +174,10 @@
     }
     frame_sink->SubmitCompositorFrame(
         local_surface_id,
-        MakeDamagedCompositorFrame(damage, may_contain_video));
+        use_per_quad_damage
+            ? MakeDamagedCompositorFrameWithPerQuadDamage(damage,
+                                                          may_contain_video)
+            : MakeDamagedCompositorFrame(damage, may_contain_video));
   }
 
   // Report updates to |client| of area |damage| at a rate of
@@ -180,12 +186,13 @@
   void SendUpdates(CompositorFrameSinkSupport* frame_sink,
                    const gfx::Rect& damage,
                    bool may_contain_video,
+                   bool use_per_quad_damage,
                    int updates_per_second,
                    base::TimeDelta duration) {
     const base::TimeDelta time_between_updates =
         base::Seconds(1.0 / updates_per_second);
     for (base::TimeDelta d; d < duration; d += time_between_updates) {
-      SendUpdate(frame_sink, damage, may_contain_video);
+      SendUpdate(frame_sink, damage, may_contain_video, use_per_quad_damage);
       CreateDisplayFrame();
       AdvanceTime(std::min(time_between_updates, duration - d));
     }
@@ -199,7 +206,8 @@
                                             true /* report_activation */);
     auto frame_sink = std::make_unique<CompositorFrameSinkSupport>(
         &frame_sink_client_, &frame_sink_manager_, frame_sink_id, is_root);
-    SendUpdate(frame_sink.get(), gfx::Rect(), /*may_contain_video*/ false);
+    SendUpdate(frame_sink.get(), gfx::Rect(), /*may_contain_video*/ false,
+               /*use_per_quad_damage*/ false);
     return frame_sink;
   }
 
@@ -219,6 +227,22 @@
     return frame;
   }
 
+  CompositorFrame MakeDamagedCompositorFrameWithPerQuadDamage(
+      const gfx::Rect& damage,
+      bool may_contain_video) {
+    constexpr gfx::Rect kFrameSinkRect(10000, 10000);
+    auto frame =
+        CompositorFrameBuilder()
+            .AddRenderPass(RenderPassBuilder(kFrameSinkRect)
+                               .AddTextureQuad(kFrameSinkRect, ResourceId(1234))
+                               .SetQuadDamageRect(kFrameSinkRect))
+            .PopulateResources()
+            .Build();
+    frame.metadata.may_contain_video = may_contain_video;
+
+    return frame;
+  }
+
   base::test::ScopedFeatureList scoped_feature_list_;
   ServerSharedBitmapManager shared_bitmap_manager_;
   FrameSinkManagerImpl frame_sink_manager_{
@@ -253,8 +277,8 @@
     // activity isn't detected.
     gfx::Rect rect = kMinRect;
     rect.Inset(gfx::Insets::TLBR(0, 0, 0, 1));
-    SendUpdates(frame_sink.get(), rect, /*may_contain_video=*/true, 2 * kMinFps,
-                2 * kMinDuration);
+    SendUpdates(frame_sink.get(), rect, /*may_contain_video=*/true,
+                /*use_per_quad_damage=*/false, 2 * kMinFps, 2 * kMinDuration);
     EXPECT_TRUE(observer_.IsEmpty());
   }
 
@@ -263,8 +287,8 @@
     // activity isn't detected.
     gfx::Rect rect = kMinRect;
     rect.Inset(gfx::Insets::TLBR(0, 0, 0, 1));
-    SendUpdates(frame_sink.get(), rect, /*may_contain_video=*/true, 2 * kMinFps,
-                2 * kMinDuration);
+    SendUpdates(frame_sink.get(), rect, /*may_contain_video=*/true,
+                /*use_per_quad_damage=*/false, 2 * kMinFps, 2 * kMinDuration);
     EXPECT_TRUE(observer_.IsEmpty());
   }
 }
@@ -274,7 +298,7 @@
   std::unique_ptr<CompositorFrameSinkSupport> frame_sink = CreateFrameSink();
   EmbedClient(frame_sink.get());
   SendUpdates(frame_sink.get(), kMinRect, /*may_contain_video=*/true,
-              kMinFps - 5, 2 * kMinDuration);
+              /*use_per_quad_damage=*/false, kMinFps - 5, 2 * kMinDuration);
   EXPECT_TRUE(observer_.IsEmpty());
 }
 
@@ -284,11 +308,11 @@
   std::unique_ptr<CompositorFrameSinkSupport> frame_sink = CreateFrameSink();
   EmbedClient(frame_sink.get());
   SendUpdates(frame_sink.get(), kMinRect, /*may_contain_video=*/true,
-              2 * kMinFps, 0.5 * kMinDuration);
+              /*use_per_quad_damage=*/false, 2 * kMinFps, 0.5 * kMinDuration);
   EXPECT_TRUE(observer_.IsEmpty());
 
   SendUpdates(frame_sink.get(), kMinRect, /*may_contain_video=*/true,
-              2 * kMinFps, 0.6 * kMinDuration);
+              /*use_per_quad_damage=*/false, 2 * kMinFps, 0.6 * kMinDuration);
   EXPECT_TRUE(observer_.PopState());
   EXPECT_TRUE(observer_.IsEmpty());
 }
@@ -299,7 +323,7 @@
   std::unique_ptr<CompositorFrameSinkSupport> frame_sink = CreateFrameSink();
 
   SendUpdates(frame_sink.get(), kMinRect, /*may_contain_video=*/true,
-              kMinFps + 5, 2 * kMinDuration);
+              /*use_per_quad_damage=*/false, kMinFps + 5, 2 * kMinDuration);
   EXPECT_TRUE(observer_.IsEmpty());
 
   // Make the client visible.
@@ -307,7 +331,7 @@
   AdvanceTime(kTimeout);
   EmbedClient(frame_sink.get());
   SendUpdates(frame_sink.get(), kMinRect, /*may_contain_video=*/true,
-              kMinFps + 5, 2 * kMinDuration);
+              /*use_per_quad_damage=*/false, kMinFps + 5, 2 * kMinDuration);
   EXPECT_TRUE(observer_.PopState());
   EXPECT_TRUE(observer_.IsEmpty());
 }
@@ -317,7 +341,7 @@
   std::unique_ptr<CompositorFrameSinkSupport> frame_sink = CreateFrameSink();
   EmbedClient(frame_sink.get());
   SendUpdates(frame_sink.get(), kMinRect, /*may_contain_video=*/false,
-              kMinFps + 5, kDuration);
+              /*use_per_quad_damage=*/false, kMinFps + 5, kDuration);
   EXPECT_TRUE(observer_.IsEmpty());
 }
 
@@ -326,7 +350,7 @@
   std::unique_ptr<CompositorFrameSinkSupport> frame_sink = CreateFrameSink();
   EmbedClient(frame_sink.get());
   SendUpdates(frame_sink.get(), kMinRect, /*may_contain_video=*/false,
-              kMinFps + 5, kDuration);
+              /*use_per_quad_damage=*/false, kMinFps + 5, kDuration);
   EXPECT_FALSE(observer_.IsEmpty());
 }
 
@@ -337,7 +361,7 @@
   std::unique_ptr<CompositorFrameSinkSupport> frame_sink = CreateFrameSink();
   EmbedClient(frame_sink.get());
   SendUpdates(frame_sink.get(), kMinRect, /*may_contain_video=*/true,
-              kMinFps + 5, kDuration);
+              /*use_per_quad_damage=*/false, kMinFps + 5, kDuration);
   EXPECT_TRUE(observer_.PopState());
   EXPECT_TRUE(observer_.IsEmpty());
 
@@ -347,7 +371,7 @@
 
   // Start playing again.
   SendUpdates(frame_sink.get(), kMinRect, /*may_contain_video=*/true,
-              kMinFps + 5, kDuration);
+              /*use_per_quad_damage=*/false, kMinFps + 5, kDuration);
   EXPECT_TRUE(observer_.PopState());
   EXPECT_TRUE(observer_.IsEmpty());
 
@@ -369,8 +393,10 @@
   constexpr int fps = 2 * kMinFps;
   constexpr base::TimeDelta time_between_updates = base::Seconds(1.0 / fps);
   for (base::TimeDelta d; d < 2 * kMinDuration; d += time_between_updates) {
-    SendUpdate(frame_sink1.get(), kMinRect, /*may_contain_video=*/true);
-    SendUpdate(frame_sink2.get(), kMinRect, /*may_contain_video=*/true);
+    SendUpdate(frame_sink1.get(), kMinRect, /*may_contain_video=*/true,
+               /*use_per_quad_damage=*/false);
+    SendUpdate(frame_sink2.get(), kMinRect, /*may_contain_video=*/true,
+               /*use_per_quad_damage=*/false);
     AdvanceTime(time_between_updates);
     CreateDisplayFrame();
   }
@@ -378,4 +404,18 @@
   EXPECT_TRUE(observer_.IsEmpty());
 }
 
+TEST_F(VideoDetectorTest, ReportBasedOnPerQuadDamage) {
+  const base::TimeDelta kDuration = kMinDuration + base::Milliseconds(100);
+  std::unique_ptr<CompositorFrameSinkSupport> frame_sink = CreateFrameSink();
+  EmbedClient(frame_sink.get());
+  SendUpdates(frame_sink.get(), kMinRect, /*may_contain_video=*/true,
+              /*use_per_quad_damage=*/true, kMinFps + 5, kDuration);
+  EXPECT_TRUE(observer_.PopState());
+  EXPECT_TRUE(observer_.IsEmpty());
+
+  AdvanceTime(kTimeout);
+  EXPECT_FALSE(observer_.PopState());
+  EXPECT_TRUE(observer_.IsEmpty());
+}
+
 }  // namespace viz
diff --git a/content/browser/accessibility/accessibility_action_browsertest.cc b/content/browser/accessibility/accessibility_action_browsertest.cc
index 1e6d9ca..482636c9 100644
--- a/content/browser/accessibility/accessibility_action_browsertest.cc
+++ b/content/browser/accessibility/accessibility_action_browsertest.cc
@@ -49,7 +49,7 @@
  protected:
   BrowserAccessibility* FindNode(ax::mojom::Role role,
                                  const std::string& name_or_value) {
-    BrowserAccessibility* root = GetManager()->GetRoot();
+    BrowserAccessibility* root = GetManager()->GetBrowserAccessibilityRoot();
     CHECK(root);
     return FindNodeInSubtree(*root, role, name_or_value);
   }
@@ -116,7 +116,8 @@
         will_scroll_horizontally
             ? ui::AXEventGenerator::Event::SCROLL_HORIZONTAL_POSITION_CHANGED
             : ui::AXEventGenerator::Event::SCROLL_VERTICAL_POSITION_CHANGED);
-    BrowserAccessibility* document = GetManager()->GetRoot();
+    BrowserAccessibility* document =
+        GetManager()->GetBrowserAccessibilityRoot();
     ui::AXActionData action_data;
     action_data.target_node_id = document->GetData().id;
     action_data.action = ax::mojom::Action::kSetScrollOffset;
@@ -1050,7 +1051,7 @@
       </html>"
       )HTML");
 
-  BrowserAccessibility* root = GetManager()->GetRoot();
+  BrowserAccessibility* root = GetManager()->GetBrowserAccessibilityRoot();
   gfx::Rect doc_bounds = root->GetClippedScreenBoundsRect();
 
   int one_third_doc_height = base::ClampRound(doc_bounds.height() / 3.0f);
diff --git a/content/browser/accessibility/accessibility_auralinux_browsertest.cc b/content/browser/accessibility/accessibility_auralinux_browsertest.cc
index b08f4ab..674da72 100644
--- a/content/browser/accessibility/accessibility_auralinux_browsertest.cc
+++ b/content/browser/accessibility/accessibility_auralinux_browsertest.cc
@@ -2124,7 +2124,7 @@
 
   // Find a node to hit test. Note that this is a really simple page,
   // so synchronous hit testing will work fine.
-  BrowserAccessibility* node = manager->GetRoot();
+  BrowserAccessibility* node = manager->GetBrowserAccessibilityRoot();
   while (node && node->GetRole() != ax::mojom::Role::kButton)
     node = manager->NextInTreeOrder(node);
   DCHECK(node);
@@ -2137,7 +2137,8 @@
   ui::AXPlatformNodeAuraLinux* root_platform_node =
       static_cast<ui::AXPlatformNodeAuraLinux*>(
           ui::AXPlatformNode::FromNativeViewAccessible(
-              manager->GetRoot()->GetNativeViewAccessible()));
+              manager->GetBrowserAccessibilityRoot()
+                  ->GetNativeViewAccessible()));
 
   // First test that calling accHitTest on the root node returns the button.
   {
diff --git a/content/browser/accessibility/accessibility_content_browsertest.cc b/content/browser/accessibility/accessibility_content_browsertest.cc
index da7a219..f4b1f147 100644
--- a/content/browser/accessibility/accessibility_content_browsertest.cc
+++ b/content/browser/accessibility/accessibility_content_browsertest.cc
@@ -91,7 +91,7 @@
   // return type.
   auto GetRootAndAssertNonNull = [this](BrowserAccessibility** result) {
     BrowserAccessibility* root_browser_accessibility =
-        GetManagerAndAssertNonNull()->GetRoot();
+        GetManagerAndAssertNonNull()->GetBrowserAccessibilityRoot();
     ASSERT_NE(nullptr, result);
     *result = root_browser_accessibility;
   };
diff --git a/content/browser/accessibility/accessibility_event_recorder_auralinux.cc b/content/browser/accessibility/accessibility_event_recorder_auralinux.cc
index 08a7fd46..523967e 100644
--- a/content/browser/accessibility/accessibility_event_recorder_auralinux.cc
+++ b/content/browser/accessibility/accessibility_event_recorder_auralinux.cc
@@ -139,7 +139,7 @@
     unsigned int n_params,
     const GValue* params) {
   // If we don't have a root object, it means the tree is being destroyed.
-  if (!manager_->GetRoot()) {
+  if (!manager_->GetBrowserAccessibilityRoot()) {
     RemoveATKEventListeners();
     return;
   }
diff --git a/content/browser/accessibility/accessibility_mode_browsertest.cc b/content/browser/accessibility/accessibility_mode_browsertest.cc
index 6b48058..754553d0 100644
--- a/content/browser/accessibility/accessibility_mode_browsertest.cc
+++ b/content/browser/accessibility/accessibility_mode_browsertest.cc
@@ -36,7 +36,8 @@
  protected:
   const BrowserAccessibility* FindNode(ax::mojom::Role role,
                                        const std::string& name) {
-    const BrowserAccessibility* root = GetManager()->GetRoot();
+    const BrowserAccessibility* root =
+        GetManager()->GetBrowserAccessibilityRoot();
     CHECK(root);
     return FindNodeInSubtree(*root, role, name);
   }
diff --git a/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc b/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc
index 2a9ed273..9a1a930 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_uia_win.cc
@@ -127,7 +127,7 @@
       content::BrowserAccessibility::FromAXPlatformNodeDelegate(start);
   // Start by getting the root element for the HWND hosting the web content.
   HWND hwnd = start_internal->manager()
-                  ->GetRoot()
+                  ->GetBrowserAccessibilityRoot()
                   ->GetTargetForNativeAccessibilityEvent();
   uia->ElementFromHandle(hwnd, root);
 }
diff --git a/content/browser/accessibility/accessibility_tree_formatter_win.cc b/content/browser/accessibility/accessibility_tree_formatter_win.cc
index 24c77cd25..d783d58 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_win.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_win.cc
@@ -103,7 +103,7 @@
 
   base::win::ScopedVariant variant_self(CHILDID_SELF);
   LONG root_width, root_height;
-  BrowserAccessibility* root = root_manager->GetRoot();
+  BrowserAccessibility* root = root_manager->GetBrowserAccessibilityRoot();
   HRESULT hr = ToBrowserAccessibilityWin(root)->GetCOM()->accLocation(
       &root_x, &root_y, &root_width, &root_height, variant_self);
   DCHECK(SUCCEEDED(hr));
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc
index 0acf423..2313b35 100644
--- a/content/browser/accessibility/accessibility_win_browsertest.cc
+++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -458,7 +458,7 @@
 BrowserAccessibility* AccessibilityWinBrowserTest::FindNode(
     ax::mojom::Role role,
     const std::string& name_or_value) {
-  BrowserAccessibility* root = GetManager()->GetRoot();
+  BrowserAccessibility* root = GetManager()->GetBrowserAccessibilityRoot();
   CHECK(root);
   return FindNodeInSubtree(*root, role, name_or_value);
 }
@@ -852,8 +852,8 @@
             type,
             manager,
             base::GetCurrentProcId(),
-            ui::AXTreeSelector(
-                manager->GetRoot()->GetTargetForNativeAccessibilityEvent()))),
+            ui::AXTreeSelector(manager->GetBrowserAccessibilityRoot()
+                                   ->GetTargetForNativeAccessibilityEvent()))),
         match_pattern_(match_pattern),
         browser_accessibility_manager_(manager) {
     event_recorder_->ListenToEvents(base::BindRepeating(
@@ -4914,9 +4914,10 @@
 
   // Content root node's parent's child should still be the content root node.
   Microsoft::WRL::ComPtr<IRawElementProviderFragment> content_root;
-  ASSERT_HRESULT_SUCCEEDED(
-      GetManager()->GetRoot()->GetNativeViewAccessible()->QueryInterface(
-          IID_PPV_ARGS(&content_root)));
+  ASSERT_HRESULT_SUCCEEDED(GetManager()
+                               ->GetBrowserAccessibilityRoot()
+                               ->GetNativeViewAccessible()
+                               ->QueryInterface(IID_PPV_ARGS(&content_root)));
 
   Microsoft::WRL::ComPtr<IRawElementProviderFragment> parent;
   ASSERT_HRESULT_SUCCEEDED(
@@ -4938,9 +4939,10 @@
       </html>)HTML");
 
   Microsoft::WRL::ComPtr<IRawElementProviderFragment> content_root;
-  ASSERT_HRESULT_SUCCEEDED(
-      GetManager()->GetRoot()->GetNativeViewAccessible()->QueryInterface(
-          IID_PPV_ARGS(&content_root)));
+  ASSERT_HRESULT_SUCCEEDED(GetManager()
+                               ->GetBrowserAccessibilityRoot()
+                               ->GetNativeViewAccessible()
+                               ->QueryInterface(IID_PPV_ARGS(&content_root)));
 
   Microsoft::WRL::ComPtr<IRawElementProviderFragmentRoot> fragment_root;
   ASSERT_HRESULT_SUCCEEDED(content_root->get_FragmentRoot(&fragment_root));
@@ -5262,7 +5264,7 @@
   // Start by getting the root element for the HWND hosting the web content.
   HWND hwnd = view->host()
                   ->GetRootBrowserAccessibilityManager()
-                  ->GetRoot()
+                  ->GetBrowserAccessibilityRoot()
                   ->GetTargetForNativeAccessibilityEvent();
   ASSERT_NE(gfx::kNullAcceleratedWidget, hwnd);
   Microsoft::WRL::ComPtr<IUIAutomationElement> root;
diff --git a/content/browser/accessibility/android_granularity_movement_browsertest.cc b/content/browser/accessibility/android_granularity_movement_browsertest.cc
index fb84e12..aff8d49e 100644
--- a/content/browser/accessibility/android_granularity_movement_browsertest.cc
+++ b/content/browser/accessibility/android_granularity_movement_browsertest.cc
@@ -48,7 +48,8 @@
     // Get the BrowserAccessibilityManager.
     WebContentsImpl* web_contents =
         static_cast<WebContentsImpl*>(shell()->web_contents());
-    return web_contents->GetRootBrowserAccessibilityManager()->GetRoot();
+    return web_contents->GetRootBrowserAccessibilityManager()
+        ->GetBrowserAccessibilityRoot();
   }
 
   // First, set accessibility focus to a node and wait for the update that
diff --git a/content/browser/accessibility/aom_browsertest.cc b/content/browser/accessibility/aom_browsertest.cc
index ab9dea8..28ac2fc 100644
--- a/content/browser/accessibility/aom_browsertest.cc
+++ b/content/browser/accessibility/aom_browsertest.cc
@@ -38,7 +38,7 @@
  protected:
   BrowserAccessibility* FindNode(ax::mojom::Role role,
                                  const std::string& name) {
-    BrowserAccessibility* root = GetManager()->GetRoot();
+    BrowserAccessibility* root = GetManager()->GetBrowserAccessibilityRoot();
     CHECK(root);
     return FindNodeInSubtree(*root, role, name);
   }
diff --git a/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc b/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc
index 32a546c1..4bd43f5 100644
--- a/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc
+++ b/content/browser/accessibility/ax_platform_node_textprovider_win_browsertest.cc
@@ -104,7 +104,7 @@
   BrowserAccessibility* GetRootAndAssertNonNull() {
     auto GetRootAndAssertNonNull = [this](BrowserAccessibility** result) {
       BrowserAccessibility* root_browser_accessibility =
-          GetManagerAndAssertNonNull()->GetRoot();
+          GetManagerAndAssertNonNull()->GetBrowserAccessibilityRoot();
       ASSERT_NE(nullptr, result);
       *result = root_browser_accessibility;
     };
diff --git a/content/browser/accessibility/ax_platform_node_textrangeprovider_win_browsertest.cc b/content/browser/accessibility/ax_platform_node_textrangeprovider_win_browsertest.cc
index 2c49ac9c..6045eec 100644
--- a/content/browser/accessibility/ax_platform_node_textrangeprovider_win_browsertest.cc
+++ b/content/browser/accessibility/ax_platform_node_textrangeprovider_win_browsertest.cc
@@ -161,8 +161,8 @@
   void GetDocumentRangeForMarkup(const std::string& html_markup,
                                  ITextRangeProvider** text_range_provider) {
     LoadInitialAccessibilityTreeFromHtml(html_markup);
-    GetTextRangeProviderFromTextNode(*GetManager()->GetRoot(),
-                                     text_range_provider);
+    GetTextRangeProviderFromTextNode(
+        *GetManager()->GetBrowserAccessibilityRoot(), text_range_provider);
   }
 
   // Run through ITextRangeProvider::ScrollIntoView top tests. It's assumed that
@@ -270,7 +270,7 @@
         BrowserAccessibilityManager::FromID(iframe_tree_id);
     ASSERT_NE(nullptr, iframe_browser_accessibility_manager);
     BrowserAccessibility* root_iframe_browser_accessibility =
-        iframe_browser_accessibility_manager->GetRoot();
+        iframe_browser_accessibility_manager->GetBrowserAccessibilityRoot();
     ASSERT_NE(nullptr, root_iframe_browser_accessibility);
     ASSERT_EQ(ax::mojom::Role::kRootWebArea,
               root_iframe_browser_accessibility->GetRole());
diff --git a/content/browser/accessibility/ax_platform_node_win_browsertest.cc b/content/browser/accessibility/ax_platform_node_win_browsertest.cc
index d4e9927..658e6f3 100644
--- a/content/browser/accessibility/ax_platform_node_win_browsertest.cc
+++ b/content/browser/accessibility/ax_platform_node_win_browsertest.cc
@@ -200,7 +200,7 @@
   ASSERT_EQ(ax::mojom::Role::kStaticText, browser_accessibility->GetRole());
 
   BrowserAccessibility* iframe_browser_accessibility =
-      browser_accessibility->manager()->GetRoot();
+      browser_accessibility->manager()->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, iframe_browser_accessibility);
   ASSERT_EQ(ax::mojom::Role::kRootWebArea,
             iframe_browser_accessibility->GetRole());
@@ -662,7 +662,7 @@
 
   // Find a node to hit test. Note that this is a really simple page,
   // so synchronous hit testing will work fine.
-  BrowserAccessibility* node = manager->GetRoot();
+  BrowserAccessibility* node = manager->GetBrowserAccessibilityRoot();
   while (node && node->GetRole() != ax::mojom::Role::kButton)
     node = manager->NextInTreeOrder(node);
   DCHECK(node);
@@ -675,7 +675,8 @@
   ui::AXPlatformNodeWin* root_platform_node =
       static_cast<ui::AXPlatformNodeWin*>(
           ui::AXPlatformNode::FromNativeViewAccessible(
-              manager->GetRoot()->GetNativeViewAccessible()));
+              manager->GetBrowserAccessibilityRoot()
+                  ->GetNativeViewAccessible()));
 
   // First test that calling accHitTest on the root node returns the button.
   {
diff --git a/content/browser/accessibility/ax_tree_formatter_mac_browsertest.mm b/content/browser/accessibility/ax_tree_formatter_mac_browsertest.mm
index 7a2caf1c..5b1bf87 100644
--- a/content/browser/accessibility/ax_tree_formatter_mac_browsertest.mm
+++ b/content/browser/accessibility/ax_tree_formatter_mac_browsertest.mm
@@ -89,7 +89,7 @@
                                 ui::AXTreeFormatter::kFiltersEmptySet);
   formatter->SetNodeFilters(node_filters);
 
-  BrowserAccessibility* root = GetManager()->GetRoot();
+  BrowserAccessibility* root = GetManager()->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root);
 
   std::string actual = formatter->Format(root);
@@ -123,7 +123,7 @@
   std::unique_ptr<ui::AXTreeFormatter> formatter =
       AXInspectFactory::CreatePlatformFormatter();
 
-  BrowserAccessibility* root = GetManager()->GetRoot();
+  BrowserAccessibility* root = GetManager()->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root);
 
   std::vector<ui::AXScriptInstruction> instructions;
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index ce0522c..3c378e7b 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -52,6 +52,8 @@
                                            ui::AXNode* node)
     : AXPlatformNodeDelegate(node), manager_(manager) {
   DCHECK(manager);
+  DCHECK(node);
+  DCHECK(node->IsDataValid());
 }
 
 BrowserAccessibility::~BrowserAccessibility() = default;
@@ -812,7 +814,7 @@
     if (coordinate_system == ui::AXCoordinateSystem::kFrame)
       break;
 
-    const BrowserAccessibility* root = manager->GetRoot();
+    const BrowserAccessibility* root = manager->GetBrowserAccessibilityRoot();
     node = root->PlatformGetParent();
   }
 
@@ -1197,6 +1199,10 @@
 BrowserAccessibility::AXPosition BrowserAccessibility::CreateTextPositionAt(
     int offset,
     ax::mojom::TextAffinity affinity) const {
+  DCHECK(node()->IsDataValid());
+  DCHECK(manager_->GetNode(GetId()))
+      << "No node for id: " << GetId() << "   " << node()->id() << "  "
+      << node()->data().id;
   return ui::AXNodePosition::CreateTextPosition(manager_->ax_tree_id(), GetId(),
                                                 offset, affinity);
 }
@@ -1462,7 +1468,8 @@
 }
 
 absl::optional<size_t> BrowserAccessibility::GetIndexInParent() {
-  if (manager()->GetRoot() == this && PlatformGetParent() == nullptr) {
+  if (manager()->GetBrowserAccessibilityRoot() == this &&
+      PlatformGetParent() == nullptr) {
     // If it is a root node of WebContent, it doesn't have a parent and a
     // valid index in parent. So it returns -1 in order to compute its
     // index at AXPlatformNodeBase.
@@ -1610,7 +1617,7 @@
     case ax::mojom::Action::kScrollToPoint: {
       // Convert the target point from screen coordinates to frame coordinates.
       gfx::Point target =
-          data.target_point - manager_->GetRoot()
+          data.target_point - manager_->GetBrowserAccessibilityRoot()
                                   ->GetUnclippedScreenBoundsRect()
                                   .OffsetFromOrigin();
       manager_->ScrollToPoint(*this, target);
@@ -2281,8 +2288,9 @@
   BrowserAccessibilityManager* child_manager =
       BrowserAccessibilityManager::FromID(
           ui::AXTreeID::FromString(child_tree_id));
-  if (child_manager && child_manager->GetRoot()->PlatformGetParent() == this)
-    return child_manager->GetRoot();
+  if (child_manager &&
+      child_manager->GetBrowserAccessibilityRoot()->PlatformGetParent() == this)
+    return child_manager->GetBrowserAccessibilityRoot();
   return nullptr;
 }
 
diff --git a/content/browser/accessibility/browser_accessibility_android_unittest.cc b/content/browser/accessibility/browser_accessibility_android_unittest.cc
index 5f05dd35..e6b11edd 100644
--- a/content/browser/accessibility/browser_accessibility_android_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_android_unittest.cc
@@ -103,7 +103,7 @@
           MakeAXTreeUpdateForTesting(root, para1, text1),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_obj = manager->GetRoot();
+  BrowserAccessibility* root_obj = manager->GetBrowserAccessibilityRoot();
   EXPECT_FALSE(root_obj->IsLeaf());
   EXPECT_TRUE(root_obj->CanFireEvents());
   BrowserAccessibility* para_obj = root_obj->PlatformGetChild(0);
@@ -142,7 +142,7 @@
           MakeAXTreeUpdateForTesting(root, heading1, text1),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_obj = manager->GetRoot();
+  BrowserAccessibility* root_obj = manager->GetBrowserAccessibilityRoot();
   EXPECT_FALSE(root_obj->IsLeaf());
   EXPECT_TRUE(root_obj->CanFireEvents());
   BrowserAccessibility* heading_obj = root_obj->PlatformGetChild(0);
@@ -182,7 +182,7 @@
           MakeAXTreeUpdateForTesting(root, para1, text1),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_obj = manager->GetRoot();
+  BrowserAccessibility* root_obj = manager->GetBrowserAccessibilityRoot();
   EXPECT_FALSE(root_obj->IsLeaf());
   EXPECT_TRUE(root_obj->CanFireEvents());
   BrowserAccessibility* para_obj = root_obj->PlatformGetChild(0);
@@ -271,7 +271,7 @@
                                      button, button_text),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_obj = manager->GetRoot();
+  BrowserAccessibility* root_obj = manager->GetBrowserAccessibilityRoot();
   EXPECT_FALSE(root_obj->IsLeaf());
   EXPECT_TRUE(root_obj->CanFireEvents());
   BrowserAccessibility* label_obj = manager->GetFromID(label.id);
@@ -368,7 +368,8 @@
        ++child_index) {
     BrowserAccessibilityAndroid* child =
         static_cast<BrowserAccessibilityAndroid*>(
-            manager->GetRoot()->PlatformGetChild(child_index));
+            manager->GetBrowserAccessibilityRoot()->PlatformGetChild(
+                child_index));
 
     EXPECT_EQ(u"Unlabeled image", child->GetRoleDescription());
   }
@@ -420,7 +421,8 @@
        ++child_index) {
     BrowserAccessibilityAndroid* child =
         static_cast<BrowserAccessibilityAndroid*>(
-            manager->GetRoot()->PlatformGetChild(child_index));
+            manager->GetBrowserAccessibilityRoot()->PlatformGetChild(
+                child_index));
 
     EXPECT_EQ(std::u16string(), child->GetRoleDescription());
   }
@@ -460,7 +462,7 @@
 
   BrowserAccessibilityAndroid* image_ltr =
       static_cast<BrowserAccessibilityAndroid*>(
-          manager->GetRoot()->PlatformGetChild(0));
+          manager->GetBrowserAccessibilityRoot()->PlatformGetChild(0));
 
   EXPECT_EQ(
       u"This image isn't labeled. Open the More Options menu "
@@ -469,7 +471,7 @@
 
   BrowserAccessibilityAndroid* image_rtl =
       static_cast<BrowserAccessibilityAndroid*>(
-          manager->GetRoot()->PlatformGetChild(1));
+          manager->GetBrowserAccessibilityRoot()->PlatformGetChild(1));
 
   EXPECT_EQ(
       u"image_name, This image isn't labeled. Open the More Options "
@@ -515,19 +517,19 @@
 
   BrowserAccessibilityAndroid* image_pending =
       static_cast<BrowserAccessibilityAndroid*>(
-          manager->GetRoot()->PlatformGetChild(0));
+          manager->GetBrowserAccessibilityRoot()->PlatformGetChild(0));
 
   BrowserAccessibilityAndroid* image_empty =
       static_cast<BrowserAccessibilityAndroid*>(
-          manager->GetRoot()->PlatformGetChild(1));
+          manager->GetBrowserAccessibilityRoot()->PlatformGetChild(1));
 
   BrowserAccessibilityAndroid* image_adult =
       static_cast<BrowserAccessibilityAndroid*>(
-          manager->GetRoot()->PlatformGetChild(2));
+          manager->GetBrowserAccessibilityRoot()->PlatformGetChild(2));
 
   BrowserAccessibilityAndroid* image_failed =
       static_cast<BrowserAccessibilityAndroid*>(
-          manager->GetRoot()->PlatformGetChild(3));
+          manager->GetBrowserAccessibilityRoot()->PlatformGetChild(3));
 
   EXPECT_EQ(u"Getting description...", image_pending->GetTextContentUTF16());
   EXPECT_EQ(u"No description available.", image_empty->GetTextContentUTF16());
@@ -574,19 +576,19 @@
 
   BrowserAccessibilityAndroid* image_none =
       static_cast<BrowserAccessibilityAndroid*>(
-          manager->GetRoot()->PlatformGetChild(0));
+          manager->GetBrowserAccessibilityRoot()->PlatformGetChild(0));
 
   BrowserAccessibilityAndroid* image_scheme =
       static_cast<BrowserAccessibilityAndroid*>(
-          manager->GetRoot()->PlatformGetChild(1));
+          manager->GetBrowserAccessibilityRoot()->PlatformGetChild(1));
 
   BrowserAccessibilityAndroid* image_ineligible =
       static_cast<BrowserAccessibilityAndroid*>(
-          manager->GetRoot()->PlatformGetChild(2));
+          manager->GetBrowserAccessibilityRoot()->PlatformGetChild(2));
 
   BrowserAccessibilityAndroid* image_silent =
       static_cast<BrowserAccessibilityAndroid*>(
-          manager->GetRoot()->PlatformGetChild(3));
+          manager->GetBrowserAccessibilityRoot()->PlatformGetChild(3));
 
   EXPECT_EQ(std::u16string(), image_none->GetTextContentUTF16());
   EXPECT_EQ(u"image_name", image_scheme->GetTextContentUTF16());
@@ -627,11 +629,11 @@
 
   BrowserAccessibilityAndroid* image_succeeded =
       static_cast<BrowserAccessibilityAndroid*>(
-          manager->GetRoot()->PlatformGetChild(0));
+          manager->GetBrowserAccessibilityRoot()->PlatformGetChild(0));
 
   BrowserAccessibilityAndroid* image_succeeded_with_name =
       static_cast<BrowserAccessibilityAndroid*>(
-          manager->GetRoot()->PlatformGetChild(1));
+          manager->GetBrowserAccessibilityRoot()->PlatformGetChild(1));
 
   EXPECT_EQ(u"test_annotation", image_succeeded->GetTextContentUTF16());
   EXPECT_EQ(u"test_annotation",
diff --git a/content/browser/accessibility/browser_accessibility_auralinux_unittest.cc b/content/browser/accessibility/browser_accessibility_auralinux_unittest.cc
index 9f1c753..c266feca 100644
--- a/content/browser/accessibility/browser_accessibility_auralinux_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_auralinux_unittest.cc
@@ -63,7 +63,8 @@
           test_browser_accessibility_delegate_.get()));
 
   ui::AXPlatformNodeAuraLinux* root_obj =
-      ToBrowserAccessibilityAuraLinux(manager->GetRoot())->GetNode();
+      ToBrowserAccessibilityAuraLinux(manager->GetBrowserAccessibilityRoot())
+          ->GetNode();
   AtkObject* root_atk_object(root_obj->GetNativeViewAccessible());
   ASSERT_TRUE(ATK_IS_OBJECT(root_atk_object));
   ASSERT_TRUE(ATK_IS_TEXT(root_atk_object));
@@ -116,7 +117,8 @@
           test_browser_accessibility_delegate_.get()));
 
   ui::AXPlatformNodeAuraLinux* root_obj =
-      ToBrowserAccessibilityAuraLinux(manager->GetRoot())->GetNode();
+      ToBrowserAccessibilityAuraLinux(manager->GetBrowserAccessibilityRoot())
+          ->GetNode();
   AtkObject* root_atk_object(root_obj->GetNativeViewAccessible());
 
   ASSERT_TRUE(ATK_IS_OBJECT(root_atk_object));
@@ -224,7 +226,8 @@
           test_browser_accessibility_delegate_.get()));
 
   ui::AXPlatformNodeAuraLinux* root_obj =
-      ToBrowserAccessibilityAuraLinux(manager->GetRoot())->GetNode();
+      ToBrowserAccessibilityAuraLinux(manager->GetBrowserAccessibilityRoot())
+          ->GetNode();
   AtkObject* root_atk_object(root_obj->GetNativeViewAccessible());
 
   ASSERT_TRUE(ATK_IS_OBJECT(root_atk_object));
@@ -349,7 +352,7 @@
           update, test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityAuraLinux* ax_root =
-      ToBrowserAccessibilityAuraLinux(manager->GetRoot());
+      ToBrowserAccessibilityAuraLinux(manager->GetBrowserAccessibilityRoot());
 
   BrowserAccessibilityAuraLinux* ax_button =
       ToBrowserAccessibilityAuraLinux(ax_root->PlatformGetChild(0));
@@ -462,9 +465,9 @@
       BrowserAccessibilityManager::Create(
           update, test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityAuraLinux* ax_root =
-      ToBrowserAccessibilityAuraLinux(manager->GetRoot());
+      ToBrowserAccessibilityAuraLinux(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, ax_root);
   ASSERT_EQ(1U, ax_root->PlatformChildCount());
 
@@ -734,9 +737,9 @@
                                      static_text1, static_text2),
           test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityAuraLinux* ax_root =
-      ToBrowserAccessibilityAuraLinux(manager->GetRoot());
+      ToBrowserAccessibilityAuraLinux(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, ax_root);
   ASSERT_EQ(1U, ax_root->PlatformChildCount());
 
@@ -862,9 +865,9 @@
           MakeAXTreeUpdateForTesting(static_text1, inline_box1),
           test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityAuraLinux* ax_root =
-      ToBrowserAccessibilityAuraLinux(manager->GetRoot());
+      ToBrowserAccessibilityAuraLinux(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, ax_root);
 
   AtkObject* root_atk_object = ax_root->GetNode()->GetNativeViewAccessible();
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
index 6bfbb5ce..534e599b 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -1512,6 +1512,8 @@
   if (![self instanceActive])
     return nil;
 
+  DCHECK(_owner->node()->IsDataValid());
+
   if (ui::IsNameExposedInAXValueForRole([self internalRole])) {
     std::u16string name = _owner->GetTextContentUTF16();
     // Leaf node with aria-label will have empty text content.
@@ -2187,7 +2189,8 @@
     if (index < 0)
       return nil;
 
-    const BrowserAccessibility* root = _owner->manager()->GetRoot();
+    const BrowserAccessibility* root =
+        _owner->manager()->GetBrowserAccessibilityRoot();
     if (!root)
       return nil;
 
diff --git a/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm b/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm
index 1108161..f63dd9f 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa_browsertest.mm
@@ -34,7 +34,7 @@
 
  protected:
   BrowserAccessibility* FindNode(ax::mojom::Role role) {
-    BrowserAccessibility* root = GetManager()->GetRoot();
+    BrowserAccessibility* root = GetManager()->GetBrowserAccessibilityRoot();
     CHECK(root);
     return FindNodeInSubtree(*root, role);
   }
@@ -399,7 +399,7 @@
 
   for (int child_index = 0; child_index < child_count; child_index++) {
     BrowserAccessibility* child =
-        manager->GetRoot()->PlatformGetChild(child_index);
+        manager->GetBrowserAccessibilityRoot()->PlatformGetChild(child_index);
     base::scoped_nsobject<BrowserAccessibilityCocoa> child_obj(
         [child->GetNativeViewAccessible() retain]);
 
@@ -486,7 +486,8 @@
   std::unique_ptr<BrowserAccessibilityManagerMac> manager(
       new BrowserAccessibilityManagerMac(tree, nullptr));
 
-  BrowserAccessibility* table = manager->GetRoot()->PlatformGetChild(0);
+  BrowserAccessibility* table =
+      manager->GetBrowserAccessibilityRoot()->PlatformGetChild(0);
   base::scoped_nsobject<BrowserAccessibilityCocoa> table_obj(
       [table->GetNativeViewAccessible() retain]);
   NSArray* row_nodes = [table_obj accessibilityRows];
@@ -536,7 +537,8 @@
   std::unique_ptr<BrowserAccessibilityManagerMac> manager(
       new BrowserAccessibilityManagerMac(tree, nullptr));
 
-  BrowserAccessibility* column = manager->GetRoot()->PlatformGetChild(0);
+  BrowserAccessibility* column =
+      manager->GetBrowserAccessibilityRoot()->PlatformGetChild(0);
   base::scoped_nsobject<BrowserAccessibilityCocoa> col_obj(
       [column->GetNativeViewAccessible() retain]);
   EXPECT_NSEQ(@"AXColumn", [col_obj role]);
@@ -726,8 +728,10 @@
   ASSERT_TRUE(waiter.WaitForNotification());
 
   base::scoped_nsobject<BrowserAccessibilityCocoa> content_editable(
-      [GetManager()->GetRoot()->PlatformGetChild(0)->GetNativeViewAccessible()
-          retain]);
+      [GetManager()
+              ->GetBrowserAccessibilityRoot()
+              ->PlatformGetChild(0)
+              ->GetNativeViewAccessible() retain]);
   EXPECT_EQ([[content_editable children] count], 5ul);
 
   WebContents* web_contents = shell()->web_contents();
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc
index d6a00de6..347c4dfb 100644
--- a/content/browser/accessibility/browser_accessibility_com_win.cc
+++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -845,7 +845,7 @@
   if (!url)
     return E_INVALIDARG;
 
-  if (owner() != manager->GetRoot())
+  if (owner() != manager->GetBrowserAccessibilityRoot())
     return E_FAIL;
 
   std::string str = manager->GetTreeData().url;
@@ -1408,7 +1408,8 @@
     // on the root document vs on an iframe.
     BrowserAccessibility* node = owner();
     while (node->PlatformGetParent())
-      node = node->PlatformGetParent()->manager()->GetRoot();
+      node =
+          node->PlatformGetParent()->manager()->GetBrowserAccessibilityRoot();
     return ToBrowserAccessibilityComWin(node)->QueryInterface(IID_IAccessible2,
                                                               object);
   }
diff --git a/content/browser/accessibility/browser_accessibility_fuchsia.cc b/content/browser/accessibility/browser_accessibility_fuchsia.cc
index c8e1c712..fdc488e4 100644
--- a/content/browser/accessibility/browser_accessibility_fuchsia.cc
+++ b/content/browser/accessibility/browser_accessibility_fuchsia.cc
@@ -72,7 +72,8 @@
 
   // Declare this node as the fuchsia tree root if it's the root of the main
   // frame's tree.
-  if (manager()->IsRootTree() && manager()->GetRoot() == this) {
+  if (manager()->IsRootTree() &&
+      manager()->GetBrowserAccessibilityRoot() == this) {
     ui::AccessibilityBridgeFuchsia* accessibility_bridge =
         GetAccessibilityBridge();
     if (accessibility_bridge)
@@ -382,7 +383,7 @@
   int offset_container_id = GetData().relative_bounds.offset_container_id;
 
   BrowserAccessibility* offset_container =
-      offset_container_id == -1 ? manager()->GetRoot()
+      offset_container_id == -1 ? manager()->GetBrowserAccessibilityRoot()
                                 : manager()->GetFromID(offset_container_id);
 
   BrowserAccessibilityFuchsia* fuchsia_container =
diff --git a/content/browser/accessibility/browser_accessibility_fuchsia_unittest.cc b/content/browser/accessibility/browser_accessibility_fuchsia_unittest.cc
index 2753295..8f5aad54 100644
--- a/content/browser/accessibility/browser_accessibility_fuchsia_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_fuchsia_unittest.cc
@@ -175,7 +175,7 @@
             test_browser_accessibility_delegate_.get()));
 
     BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-        ToBrowserAccessibilityFuchsia(manager->GetRoot());
+        ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
 
     ASSERT_TRUE(browser_accessibility_fuchsia);
     auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
@@ -208,7 +208,7 @@
             test_browser_accessibility_delegate_.get()));
 
     BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-        ToBrowserAccessibilityFuchsia(manager->GetRoot());
+        ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
 
     ASSERT_TRUE(browser_accessibility_fuchsia);
     auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
@@ -235,7 +235,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-      ToBrowserAccessibilityFuchsia(manager->GetRoot());
+      ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
 
   ASSERT_TRUE(browser_accessibility_fuchsia);
   auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
@@ -267,7 +267,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-      ToBrowserAccessibilityFuchsia(manager->GetRoot());
+      ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
 
   ASSERT_TRUE(browser_accessibility_fuchsia);
   auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
@@ -292,7 +292,7 @@
   // Verify table node translation.
   {
     BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-        ToBrowserAccessibilityFuchsia(manager->GetRoot());
+        ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
 
     ASSERT_TRUE(browser_accessibility_fuchsia);
     auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
@@ -353,7 +353,7 @@
   // Verify that the list root was translated.
   {
     BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-        ToBrowserAccessibilityFuchsia(manager->GetRoot());
+        ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
     ASSERT_TRUE(browser_accessibility_fuchsia);
     auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
     EXPECT_EQ(fuchsia_node_data.role(),
@@ -406,7 +406,7 @@
             test_browser_accessibility_delegate_.get()));
 
     BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-        ToBrowserAccessibilityFuchsia(manager->GetRoot());
+        ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
 
     ASSERT_TRUE(browser_accessibility_fuchsia);
     auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
@@ -429,7 +429,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-      ToBrowserAccessibilityFuchsia(manager->GetRoot());
+      ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
 
   ASSERT_TRUE(browser_accessibility_fuchsia);
   auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
@@ -451,7 +451,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-      ToBrowserAccessibilityFuchsia(manager->GetRoot());
+      ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
 
   ASSERT_TRUE(browser_accessibility_fuchsia);
   auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
@@ -473,7 +473,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-      ToBrowserAccessibilityFuchsia(manager->GetRoot());
+      ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
 
   ASSERT_TRUE(browser_accessibility_fuchsia);
   auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
@@ -499,7 +499,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-      ToBrowserAccessibilityFuchsia(manager->GetRoot());
+      ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
 
   ASSERT_TRUE(browser_accessibility_fuchsia);
   auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
@@ -525,7 +525,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-      ToBrowserAccessibilityFuchsia(manager->GetRoot());
+      ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
 
   ASSERT_TRUE(browser_accessibility_fuchsia);
   auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
@@ -565,7 +565,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-      ToBrowserAccessibilityFuchsia(manager->GetRoot());
+      ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
 
   ASSERT_TRUE(browser_accessibility_fuchsia);
   auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
@@ -662,7 +662,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-      ToBrowserAccessibilityFuchsia(manager->GetRoot());
+      ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
 
   ASSERT_TRUE(browser_accessibility_fuchsia);
   auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
@@ -722,8 +722,8 @@
 
     // Get the root of the child tree to verify that it's present in the parent
     // node's children.
-    BrowserAccessibilityFuchsia* child_root =
-        ToBrowserAccessibilityFuchsia(child_manager->GetRoot());
+    BrowserAccessibilityFuchsia* child_root = ToBrowserAccessibilityFuchsia(
+        child_manager->GetBrowserAccessibilityRoot());
 
     ASSERT_EQ(fuchsia_node_data.child_ids().size(), 1u);
     EXPECT_EQ(fuchsia_node_data.child_ids()[0], child_root->GetFuchsiaNodeID());
@@ -779,7 +779,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityFuchsia* browser_accessibility_fuchsia =
-      ToBrowserAccessibilityFuchsia(manager->GetRoot());
+      ToBrowserAccessibilityFuchsia(manager->GetBrowserAccessibilityRoot());
 
   ASSERT_TRUE(browser_accessibility_fuchsia);
   auto fuchsia_node_data = browser_accessibility_fuchsia->ToFuchsiaNodeData();
diff --git a/content/browser/accessibility/browser_accessibility_mac_unittest.mm b/content/browser/accessibility/browser_accessibility_mac_unittest.mm
index 9c66da4..c466ed9 100644
--- a/content/browser/accessibility/browser_accessibility_mac_unittest.mm
+++ b/content/browser/accessibility/browser_accessibility_mac_unittest.mm
@@ -106,7 +106,8 @@
     manager_ = std::make_unique<BrowserAccessibilityManagerMac>(
         MakeAXTreeUpdateForTesting(root_, child1, child2), nullptr);
     accessibility_.reset(
-        [manager_->GetRoot()->GetNativeViewAccessible() retain]);
+        [manager_->GetBrowserAccessibilityRoot()->GetNativeViewAccessible()
+            retain]);
   }
 
   void SetRootValue(std::string value) {
@@ -180,7 +181,9 @@
   root_.role = ax::mojom::Role::kTextField;
   manager_ = std::make_unique<BrowserAccessibilityManagerMac>(
       MakeAXTreeUpdateForTesting(root_), nullptr);
-  accessibility_.reset([manager_->GetRoot()->GetNativeViewAccessible() retain]);
+  accessibility_.reset(
+      [manager_->GetBrowserAccessibilityRoot()->GetNativeViewAccessible()
+          retain]);
 
   // Insertion but no deletion.
 
@@ -265,7 +268,8 @@
   manager_ =
       std::make_unique<BrowserAccessibilityManagerMac>(initial_state, nullptr);
   base::scoped_nsobject<BrowserAccessibilityCocoa> ax_table_(
-      [manager_->GetRoot()->GetNativeViewAccessible() retain]);
+      [manager_->GetBrowserAccessibilityRoot()->GetNativeViewAccessible()
+          retain]);
   id children = [ax_table_ children];
   EXPECT_EQ(5U, [children count]);
 
@@ -319,8 +323,8 @@
   manager_ =
       std::make_unique<BrowserAccessibilityManagerMac>(initial_state, nullptr);
 
-  BrowserAccessibilityMac* root =
-      static_cast<BrowserAccessibilityMac*>(manager_->GetRoot());
+  BrowserAccessibilityMac* root = static_cast<BrowserAccessibilityMac*>(
+      manager_->GetBrowserAccessibilityRoot());
 
   // This triggers computation of the extra Mac table cells. 2 rows, 2 extra
   // columns, and 1 extra column header. This used to crash.
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index ec9d2f56..122b651 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -355,9 +355,10 @@
   }
 }
 
-BrowserAccessibility* BrowserAccessibilityManager::GetRoot() const {
+BrowserAccessibility* BrowserAccessibilityManager::GetBrowserAccessibilityRoot()
+    const {
   ui::AXNode* root = GetRootAsAXNode();
-  return root ? GetFromAXNode(root) : nullptr;
+  return root ? GetFromID(root->id()) : nullptr;
 }
 
 BrowserAccessibility* BrowserAccessibilityManager::GetFromAXNode(
@@ -366,6 +367,9 @@
   // `AXPlatformTreeManager`.
   if (!node)
     return nullptr;
+  // TODO(aleventhal) Why would node->GetManager() return null?
+  // TODO(aleventhal) Should we just use |this| as the manager in most cases? It
+  // looks like node->GetManager() may be slow because of AXTreeID usage.
   if (AXTreeManager* manager = node->GetManager()) {
     return static_cast<BrowserAccessibilityManager*>(manager)->GetFromID(
         node->id());
@@ -374,11 +378,16 @@
 }
 
 BrowserAccessibility* BrowserAccessibilityManager::GetFromID(int32_t id) const {
+  if (id == ui::kInvalidAXNodeID)
+    return nullptr;
   const auto iter = id_wrapper_map_.find(id);
   if (iter != id_wrapper_map_.end()) {
     DCHECK(iter->second);
     return iter->second.get();
   }
+  DCHECK(!ax_tree()->GetFromId(id))
+      << "BAM's map was missing id " << id
+      << ", but AXTree's map had it: " << *ax_tree()->GetFromId(id);
 
   return nullptr;
 }
@@ -540,8 +549,13 @@
     // but it should still be investigated and could be the sign of a
     // performance issue.
     DCHECK_LE(static_cast<int>(tree_update.nodes.size()), ax_tree()->size());
+    // Every node in the AXTree must also be in BAM's map. However, the BAM map
+    // can have extra nodes, specifically extra mac nodes from AXTableInfo.
+    DCHECK_GE(static_cast<int>(id_wrapper_map_.size()), ax_tree()->size());
   }
 
+  DCHECK(ax_tree()->root());
+
   EnsureParentConnectionIfNotRootManager();
 
   if (!CanFireEvents()) {
@@ -592,7 +606,8 @@
   if (defer_load_complete_event_) {
     received_load_complete_event = true;
     defer_load_complete_event_ = false;
-    FireBlinkEvent(ax::mojom::Event::kLoadComplete, GetRoot(), -1);
+    FireBlinkEvent(ax::mojom::Event::kLoadComplete,
+                   GetBrowserAccessibilityRoot(), -1);
   }
 
   // Fire any events related to changes to the tree that come from ancestors of
@@ -668,7 +683,7 @@
       root_manager->CacheHitTestResult(event_target);
 
     if (event.event_type == ax::mojom::Event::kLoadComplete) {
-      DCHECK_EQ(event_target, GetRoot());
+      DCHECK_EQ(event_target, GetBrowserAccessibilityRoot());
       DCHECK(event_target->IsPlatformDocument());
 
       // Don't fire multiple load-complete events. One may have been added by
@@ -682,7 +697,7 @@
     }
 
     if (event.event_type == ax::mojom::Event::kLoadStart) {
-      DCHECK_EQ(event_target, GetRoot());
+      DCHECK_EQ(event_target, GetBrowserAccessibilityRoot());
       DCHECK(event_target->IsPlatformDocument());
       // If we already have a load-complete event, the load-start event is no
       // longer relevant. In addition, some code checks for the presence of
@@ -725,15 +740,17 @@
   // as for some clusterfuzz runs.
   static int g_max_ax_tree_exercise_iterations = 3;  // Avoid timeouts.
   static int count = 0;
-  if (GetRoot()->GetChildCount() > 0 &&
-      !GetRoot()->GetBoolAttribute(ax::mojom::BoolAttribute::kBusy) &&
+  if (GetBrowserAccessibilityRoot()->GetChildCount() > 0 &&
+      !GetBrowserAccessibilityRoot()->GetBoolAttribute(
+          ax::mojom::BoolAttribute::kBusy) &&
       ++count <= g_max_ax_tree_exercise_iterations) {
     base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
     if (command_line->HasSwitch(::switches::kForceRendererAccessibility)) {
       std::unique_ptr<ui::AXTreeFormatter> formatter(
           AXInspectFactory::CreatePlatformFormatter());
       formatter->SetPropertyFilters({{"*", ui::AXPropertyFilter::ALLOW}});
-      std::string formatted_tree = formatter->Format(GetRoot());
+      std::string formatted_tree =
+          formatter->Format(GetBrowserAccessibilityRoot());
       VLOG(1) << "\n\n******** Formatted tree ********\n\n"
               << formatted_tree << "\n*********************************\n\n";
     }
@@ -899,7 +916,7 @@
   BrowserAccessibility* obj = GetFromID(focus_id);
   // If nothing is focused, then the top document has the focus.
   if (!obj)
-    return GetRoot();
+    return GetBrowserAccessibilityRoot();
 
   if (obj->HasStringAttribute(ax::mojom::StringAttribute::kChildTreeId)) {
     ui::AXTreeID child_tree_id = ui::AXTreeID::FromString(
@@ -1264,7 +1281,8 @@
 
   // For android, this needs to be handled carefully. If not, there is a chance
   // of getting into infinite loop.
-  if (can_wrap_to_last_element && object->manager()->GetRoot() == object &&
+  if (can_wrap_to_last_element &&
+      object->manager()->GetBrowserAccessibilityRoot() == object &&
       object->PlatformChildCount() != 0) {
     return object->PlatformDeepestLastChild();
   }
@@ -1611,6 +1629,10 @@
 void BrowserAccessibilityManager::OnNodeCreated(ui::AXTree* tree,
                                                 ui::AXNode* node) {
   DCHECK(node);
+  DCHECK(node->IsDataValid());
+  DCHECK(tree->GetFromId(node->id()) || node->IsGenerated())
+      << "Node must be in AXTree's map, unless it's an ExtraMacNode.";
+
   id_wrapper_map_[node->id()] = BrowserAccessibility::Create(this, node);
 
   if (tree->root() != node &&
@@ -1630,16 +1652,18 @@
                                                    ui::AXNode* node) {
   DCHECK(node);
   auto iter = id_wrapper_map_.find(node->id());
-  // TODO(crbug.com/1315661): This if statement ideally should never be entered.
-  // Identify why we are entering this code path and fix the root cause.
-  if (iter == id_wrapper_map_.end()) {
-    bool success;
-    std::tie(iter, success) = id_wrapper_map_.insert(
-        {node->id(), BrowserAccessibility::Create(this, node)});
-    DCHECK(success);
-  }
-  DCHECK(iter != id_wrapper_map_.end());
+  // TODO(crbug.com/1315661): This condition should never occur.
+  // Identify why we are entering this code path and fix the root cause, then
+  // remove the early return. Will need to update
+  // BrowserAccessibilityManagerTest.TestOnNodeReparented, which purposely
+  // triggers this condition.
+  SANITIZER_CHECK(iter != id_wrapper_map_.end())
+      << "Missing BrowserAccessibility* for node: " << *node
+      << "\nTree: " << tree->ToString();
+  if (iter == id_wrapper_map_.end())
+    return;
   BrowserAccessibility* wrapper = iter->second.get();
+  DCHECK(wrapper);
   wrapper->SetNode(*node);
 }
 
@@ -1682,6 +1706,14 @@
   return manager->GetNode(node_id);
 }
 
+ui::AXNode* BrowserAccessibilityManager::GetNode(
+    const ui::AXNodeID node_id) const {
+  // This does not use ax_tree()->FromID(), because that uses a different map
+  // that does not contain extra mac nodes from AXTableInfo.
+  BrowserAccessibility* browser_accessibility = GetFromID(node_id);
+  return browser_accessibility ? browser_accessibility->node() : nullptr;
+}
+
 ui::AXPlatformNode* BrowserAccessibilityManager::GetPlatformNodeFromTree(
     const ui::AXNodeID node_id) const {
   BrowserAccessibility* wrapper = GetFromID(node_id);
@@ -1893,7 +1925,7 @@
   if (cached_node_rtree_)
     return AXTreeHitTest(blink_screen_point);
 
-  return GetRoot()->ApproximateHitTest(blink_screen_point);
+  return GetBrowserAccessibilityRoot()->ApproximateHitTest(blink_screen_point);
 }
 
 void BrowserAccessibilityManager::DetachFromParentManager() {
@@ -1902,7 +1934,7 @@
 }
 
 void BrowserAccessibilityManager::BuildAXTreeHitTestCache() {
-  auto* root = GetRoot();
+  auto* root = GetBrowserAccessibilityRoot();
   if (!root)
     return;
 
@@ -1981,7 +2013,7 @@
     base::TimeTicks activation_time) {
   if (GetTreeData().loaded) {
     FireGeneratedEvent(ui::AXEventGenerator::Event::PORTAL_ACTIVATED,
-                       GetRoot());
+                       GetBrowserAccessibilityRoot());
   }
 }
 
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h
index c463092..ed0c5d11d 100644
--- a/content/browser/accessibility/browser_accessibility_manager.h
+++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -196,7 +196,7 @@
   virtual bool CanFireEvents() const;
 
   // Return a pointer to the root of the tree.
-  BrowserAccessibility* GetRoot() const;
+  BrowserAccessibility* GetBrowserAccessibilityRoot() const;
 
   // Returns a pointer to the BrowserAccessibility object for a given AXNode.
   BrowserAccessibility* GetFromAXNode(const ui::AXNode* node) const;
@@ -484,6 +484,8 @@
   // AXTreeManager overrides.
   ui::AXNode* GetNodeFromTree(const ui::AXTreeID& tree_id,
                               ui::AXNodeID node_id) const override;
+  ui::AXNode* GetNode(const ui::AXNodeID node_id) const override;
+
   ui::AXPlatformNode* GetPlatformNodeFromTree(
       const ui::AXNodeID node_id) const override;
   ui::AXPlatformNode* GetPlatformNodeFromTree(const ui::AXNode&) const override;
@@ -585,6 +587,10 @@
   raw_ptr<BrowserAccessibilityDelegate> delegate_;
 
   // A mapping from a node id to its wrapper of type BrowserAccessibility.
+  // This is different from the map in AXTree, which does not contain extra mac
+  // nodes from AXTableInfo.
+  // TODO(accessibility) Find a way to have a single map for both, perhaps by
+  // having BrowserAccessibility into a subclass of AXNode.
   std::map<ui::AXNodeID, std::unique_ptr<BrowserAccessibility>> id_wrapper_map_;
 
   // True if the user has initiated a navigation to another page.
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc
index 7309cf15..2dd114a 100644
--- a/content/browser/accessibility/browser_accessibility_manager_android.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -67,7 +67,7 @@
 // static
 ui::AXTreeUpdate BrowserAccessibilityManagerAndroid::GetEmptyDocument() {
   ui::AXNodeData empty_document;
-  empty_document.id = 0;
+  empty_document.id = 1;
   empty_document.role = ax::mojom::Role::kRootWebArea;
   empty_document.SetRestriction(ax::mojom::Restriction::kReadOnly);
   ui::AXTreeUpdate update;
diff --git a/content/browser/accessibility/browser_accessibility_manager_auralinux.cc b/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
index f92917a1..1c03b68 100644
--- a/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
@@ -428,7 +428,7 @@
 }
 
 void BrowserAccessibilityManagerAuraLinux::OnFindInPageTermination() {
-  static_cast<BrowserAccessibilityAuraLinux*>(GetRoot())
+  static_cast<BrowserAccessibilityAuraLinux*>(GetBrowserAccessibilityRoot())
       ->GetNode()
       ->TerminateFindInPage();
 }
diff --git a/content/browser/accessibility/browser_accessibility_manager_auralinux_unittest.cc b/content/browser/accessibility/browser_accessibility_manager_auralinux_unittest.cc
index aa42360..6b5947e 100644
--- a/content/browser/accessibility/browser_accessibility_manager_auralinux_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_auralinux_unittest.cc
@@ -70,7 +70,8 @@
       BrowserAccessibilityManager::Create(
           initial_state, test_browser_accessibility_delegate_.get()));
 
-  AtkObject* atk_root = manager->GetRoot()->GetNativeViewAccessible();
+  AtkObject* atk_root =
+      manager->GetBrowserAccessibilityRoot()->GetNativeViewAccessible();
   ui::AXPlatformNodeAuraLinux* root_document_root_node =
       static_cast<ui::AXPlatformNodeAuraLinux*>(
           ui::AXPlatformNode::FromNativeViewAccessible(atk_root));
@@ -87,7 +88,7 @@
                    }),
                    nullptr);
   BrowserAccessibility* static_text_accessible =
-      manager->GetRoot()->PlatformGetChild(0);
+      manager->GetBrowserAccessibilityRoot()->PlatformGetChild(0);
   // StaticText node triggers 'children-changed' event to the parent,
   // ATK_ROLE_DOCUMENT_WEB, when subtree is changed.
   BrowserAccessibilityManagerAuraLinux* aura_linux_manager =
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm
index 6c0700b..c107750 100644
--- a/content/browser/accessibility/browser_accessibility_manager_mac.mm
+++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -193,7 +193,7 @@
       BrowserAccessibilityManager* root_manager = GetRootManager();
       if (!root_manager)
         return;
-      BrowserAccessibility* root = root_manager->GetRoot();
+      BrowserAccessibility* root = root_manager->GetBrowserAccessibilityRoot();
       if (!root)
         return;
 
@@ -264,7 +264,8 @@
       // AXMenuClosed on the document itself when an accessible menu is being
       // detached. See WebKit's AccessibilityObject::detachRemoteParts
       if (BrowserAccessibilityManager* root_manager = GetRootManager()) {
-        if (BrowserAccessibility* root = root_manager->GetRoot())
+        if (BrowserAccessibility* root =
+                root_manager->GetBrowserAccessibilityRoot())
           FireNativeMacNotification((NSString*)kAXMenuClosedNotification, root);
       }
       return;
@@ -336,7 +337,7 @@
         NSDictionary* user_info = GetUserInfoForValueChangedNotification(
             native_node, deleted_text, inserted_text, edit_text_marker);
 
-        BrowserAccessibility* root = GetRoot();
+        BrowserAccessibility* root = GetBrowserAccessibilityRoot();
         if (!root)
           return;
 
diff --git a/content/browser/accessibility/browser_accessibility_manager_unittest.cc b/content/browser/accessibility/browser_accessibility_manager_unittest.cc
index 2e35f994..7be5dc21 100644
--- a/content/browser/accessibility/browser_accessibility_manager_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_unittest.cc
@@ -19,6 +19,7 @@
 #include "content/public/browser/ax_event_notification_details.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/accessibility/ax_common.h"
 #include "ui/accessibility/ax_tree.h"
 
 namespace content {
@@ -197,7 +198,8 @@
                                      inline_text2),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_accessible = manager->GetRoot();
+  BrowserAccessibility* root_accessible =
+      manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   BrowserAccessibility* static_text_accessible =
       root_accessible->PlatformGetChild(0);
@@ -297,7 +299,8 @@
                                      static_text2, inline_text2),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_accessible = manager->GetRoot();
+  BrowserAccessibility* root_accessible =
+      manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   BrowserAccessibility* static_text_accessible =
       root_accessible->PlatformGetChild(0);
@@ -415,7 +418,8 @@
                                      inline_text2),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_accessible = manager->GetRoot();
+  BrowserAccessibility* root_accessible =
+      manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   BrowserAccessibility* static_text_accessible =
       root_accessible->PlatformGetChild(0);
@@ -498,7 +502,8 @@
           MakeAXTreeUpdateForTesting(root, static_text, inline_text),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_accessible = manager->GetRoot();
+  BrowserAccessibility* root_accessible =
+      manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   BrowserAccessibility* static_text_accessible =
       root_accessible->PlatformGetChild(0);
@@ -587,7 +592,8 @@
           MakeAXTreeUpdateForTesting(root, div, static_text1, img, static_text2,
                                      inline_text1, inline_text2),
           test_browser_accessibility_delegate_.get()));
-  BrowserAccessibility* root_accessible = manager->GetRoot();
+  BrowserAccessibility* root_accessible =
+      manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   BrowserAccessibility* div_accessible = root_accessible->PlatformGetChild(0);
   ASSERT_NE(nullptr, div_accessible);
@@ -656,7 +662,8 @@
           MakeAXTreeUpdateForTesting(root, node2, node3, node4, node5),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_accessible = manager->GetRoot();
+  BrowserAccessibility* root_accessible =
+      manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(3U, root_accessible->PlatformChildCount());
   BrowserAccessibility* node2_accessible = root_accessible->PlatformGetChild(0);
@@ -759,7 +766,8 @@
           MakeAXTreeUpdateForTesting(root, node2, node3, node4, node5),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_accessible = manager->GetRoot();
+  BrowserAccessibility* root_accessible =
+      manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(3U, root_accessible->PlatformChildCount());
   BrowserAccessibility* node2_accessible = root_accessible->PlatformGetChild(0);
@@ -835,7 +843,8 @@
                                      text2, text3, text4, link),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_accessible = manager->GetRoot();
+  BrowserAccessibility* root_accessible =
+      manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(4U, root_accessible->PlatformChildCount());
   BrowserAccessibility* node2_accessible = root_accessible->PlatformGetChild(0);
@@ -948,7 +957,8 @@
                                      paragraph_line2),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_accessible = manager->GetRoot();
+  BrowserAccessibility* root_accessible =
+      manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(2U, root_accessible->PlatformChildCount());
   BrowserAccessibility* div_accessible = root_accessible->PlatformGetChild(0);
@@ -1108,7 +1118,8 @@
                                      paragraph_line2),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_accessible = manager->GetRoot();
+  BrowserAccessibility* root_accessible =
+      manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(2U, root_accessible->PlatformChildCount());
   BrowserAccessibility* div_accessible = root_accessible->PlatformGetChild(0);
@@ -1235,7 +1246,7 @@
       BrowserAccessibilityManager::Create(
           initial_state, test_browser_accessibility_delegate_.get()));
 
-  EXPECT_EQ(1, manager->GetRoot()->GetId());
+  EXPECT_EQ(1, manager->GetBrowserAccessibilityRoot()->GetId());
   ASSERT_NE(nullptr, manager->GetFocus());
   EXPECT_EQ(2, manager->GetFocus()->GetId());
 
@@ -1253,7 +1264,7 @@
 
   // Make sure that the focused node was updated to the new root and
   // that this doesn't crash.
-  EXPECT_EQ(3, manager->GetRoot()->GetId());
+  EXPECT_EQ(3, manager->GetBrowserAccessibilityRoot()->GetId());
   ASSERT_NE(nullptr, manager->GetFocus());
   EXPECT_EQ(3, manager->GetFocus()->GetId());
 }
@@ -1284,7 +1295,7 @@
       BrowserAccessibilityManager::Create(
           initial_state, test_browser_accessibility_delegate_.get()));
 
-  EXPECT_EQ(1, manager->GetRoot()->GetId());
+  EXPECT_EQ(1, manager->GetBrowserAccessibilityRoot()->GetId());
   ASSERT_NE(nullptr, manager->GetFocus());
   EXPECT_EQ(2, manager->GetFocus()->GetId());
 
@@ -1303,7 +1314,7 @@
 
   // Make sure that the focused node was updated to the new root and
   // that this doesn't crash.
-  EXPECT_EQ(3, manager->GetRoot()->GetId());
+  EXPECT_EQ(3, manager->GetBrowserAccessibilityRoot()->GetId());
   ASSERT_NE(nullptr, manager->GetFocus());
   EXPECT_EQ(3, manager->GetFocus()->GetId());
 }
@@ -1325,7 +1336,7 @@
   std::unique_ptr<BrowserAccessibilityManager> manager(
       BrowserAccessibilityManager::Create(
           initial_state, test_browser_accessibility_delegate_.get()));
-  ASSERT_EQ(0u, manager->GetRoot()->PlatformChildCount());
+  ASSERT_EQ(0u, manager->GetBrowserAccessibilityRoot()->PlatformChildCount());
 
   // On purpose we omit "button" from the list of updated nodes. It should be
   // added due to the focus changing.
@@ -1340,9 +1351,10 @@
   ASSERT_TRUE(manager->OnAccessibilityEvents(events));
 
   // Now that the button is focused, it is no longer ignored.
-  ASSERT_EQ(1u, manager->GetRoot()->PlatformChildCount());
-  EXPECT_EQ(ax::mojom::Role::kButton,
-            manager->GetRoot()->PlatformGetChild(0)->GetRole());
+  ASSERT_EQ(1u, manager->GetBrowserAccessibilityRoot()->PlatformChildCount());
+  EXPECT_EQ(
+      ax::mojom::Role::kButton,
+      manager->GetBrowserAccessibilityRoot()->PlatformGetChild(0)->GetRole());
 }
 
 TEST_F(BrowserAccessibilityManagerTest, TreeUpdatesAreMergedWhenPossible) {
@@ -1631,10 +1643,17 @@
   EXPECT_EQ(1, observer.reparent_count());
   EXPECT_EQ(3, observer.node_count());
 
-  // Reparenting a new child that is not found in the tree should not crash.
+  // Reparenting a new child that is not found in the tree should trigger a
+  // DCHECK in AX_FAIL_FAST_BUILD builds, otherwise it should not crash.
   ui::AXNode child3(manager->ax_tree(), /* parent */ nullptr, /* id */ 4,
                     /* index_in_parent */ 0u);
+#if defined(AX_FAIL_FAST_BUILD)
+  EXPECT_DEATH_IF_SUPPORTED(
+      manager->OnNodeReparented(manager->ax_tree(), &child3),
+      "Missing BrowserAccessibility");
+#else
   manager->OnNodeReparented(manager->ax_tree(), &child3);
+#endif
   // We avoid checking the observer on purpose, since reparenting a non-existent
   // node should not trigger any tree observers. The node is not in the tree,
   // hence the normal tree update process cannot be followed.
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
index b6ea0100..3ca84711 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -104,8 +104,9 @@
 }
 
 void BrowserAccessibilityManagerWin::UserIsReloading() {
-  if (GetRoot())
-    FireWinAccessibilityEvent(IA2_EVENT_DOCUMENT_RELOAD, GetRoot());
+  if (GetBrowserAccessibilityRoot())
+    FireWinAccessibilityEvent(IA2_EVENT_DOCUMENT_RELOAD,
+                              GetBrowserAccessibilityRoot());
 }
 
 BrowserAccessibility* BrowserAccessibilityManagerWin::GetFocus() const {
diff --git a/content/browser/accessibility/browser_accessibility_manager_win_unittest.cc b/content/browser/accessibility/browser_accessibility_manager_win_unittest.cc
index a277383..6c7761d 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win_unittest.cc
@@ -25,7 +25,8 @@
   ~TestFragmentRootDelegate() = default;
 
   gfx::NativeViewAccessible GetChildOfAXFragmentRoot() override {
-    return browser_accessibility_manager_->GetRoot()->GetNativeViewAccessible();
+    return browser_accessibility_manager_->GetBrowserAccessibilityRoot()
+        ->GetNativeViewAccessible();
   }
 
   gfx::NativeViewAccessible GetParentOfAXFragmentRoot() override {
@@ -85,7 +86,8 @@
 
   ui::AXPlatformNode* root_document_root_node =
       ui::AXPlatformNode::FromNativeViewAccessible(
-          root_manager->GetRoot()->GetNativeViewAccessible());
+          root_manager->GetBrowserAccessibilityRoot()
+              ->GetNativeViewAccessible());
 
   std::unique_ptr<ui::AXPlatformNodeDelegate> fragment_root =
       std::make_unique<ui::AXFragmentRootWin>(gfx::kMockAcceleratedWidget,
@@ -144,7 +146,8 @@
 
   ui::AXPlatformNode* root_document_root_node =
       ui::AXPlatformNode::FromNativeViewAccessible(
-          parent_manager->GetRoot()->GetNativeViewAccessible());
+          parent_manager->GetBrowserAccessibilityRoot()
+              ->GetNativeViewAccessible());
 
   std::unique_ptr<ui::AXPlatformNodeDelegate> fragment_root =
       std::make_unique<ui::AXFragmentRootWin>(gfx::kMockAcceleratedWidget,
diff --git a/content/browser/accessibility/browser_accessibility_state_impl_unittest.cc b/content/browser/accessibility/browser_accessibility_state_impl_unittest.cc
index 37b7a98..bb356fd 100644
--- a/content/browser/accessibility/browser_accessibility_state_impl_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_state_impl_unittest.cc
@@ -159,7 +159,8 @@
           MakeAXTreeUpdateForTesting(root),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* ax_root = browser_accessibility_manager->GetRoot();
+  BrowserAccessibility* ax_root =
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, ax_root);
 
   // Initially, accessibility should be disabled.
diff --git a/content/browser/accessibility/browser_accessibility_unittest.cc b/content/browser/accessibility/browser_accessibility_unittest.cc
index 57f7c2a..bafab08 100644
--- a/content/browser/accessibility/browser_accessibility_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_unittest.cc
@@ -65,7 +65,7 @@
           MakeAXTreeUpdateForTesting(root, para1, text1),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_obj = manager->GetRoot();
+  BrowserAccessibility* root_obj = manager->GetBrowserAccessibilityRoot();
   EXPECT_FALSE(root_obj->IsLeaf());
   EXPECT_TRUE(root_obj->CanFireEvents());
 
@@ -186,7 +186,8 @@
   std::unique_ptr<BrowserAccessibilityManager> child_manager(
       BrowserAccessibilityManager::Create(child_tree_update, nullptr));
 
-  BrowserAccessibility* root_obj = parent_manager->GetRoot();
+  BrowserAccessibility* root_obj =
+      parent_manager->GetBrowserAccessibilityRoot();
   // Test traversal
   // PlatformChildren(root_obj) = {5, 6, 13, 15, 11, 3, 4}
   BrowserAccessibility::PlatformChildIterator platform_iterator =
@@ -329,7 +330,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibility* root_accessible =
-      browser_accessibility_manager->GetRoot();
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   BrowserAccessibility* static_text_accessible =
       root_accessible->PlatformGetChild(0);
@@ -446,7 +447,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibility* root_accessible =
-      browser_accessibility_manager->GetRoot();
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   BrowserAccessibility* textarea_accessible =
       root_accessible->PlatformGetChild(0);
@@ -507,7 +508,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibility* root_accessible =
-      browser_accessibility_manager->GetRoot();
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   BrowserAccessibility* static_text_accessible =
       root_accessible->PlatformGetChild(0);
@@ -634,7 +635,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibility* root_accessible =
-      browser_accessibility_manager->GetRoot();
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   BrowserAccessibility* static_text_accessible =
       root_accessible->PlatformGetChild(0);
@@ -723,7 +724,7 @@
       ->SetUseRootScrollOffsetsWhenComputingBoundsForTesting(true);
 
   BrowserAccessibility* root_accessible =
-      browser_accessibility_manager->GetRoot();
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   BrowserAccessibility* static_text_accessible =
       root_accessible->PlatformGetChild(0);
@@ -760,7 +761,7 @@
   ASSERT_NE(nullptr, browser_accessibility_manager.get());
 
   BrowserAccessibility* root_accessible =
-      browser_accessibility_manager->GetRoot();
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
 
   ASSERT_EQ(u"my_html_id", root_accessible->GetAuthorUniqueId());
@@ -809,7 +810,7 @@
   ASSERT_NE(nullptr, browser_accessibility_manager.get());
 
   BrowserAccessibility* root_accessible =
-      browser_accessibility_manager->GetRoot();
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_NE(0u, root_accessible->InternalChildCount());
   BrowserAccessibility* input_accessible = root_accessible->InternalGetChild(0);
@@ -891,8 +892,8 @@
       BrowserAccessibilityManager::Create(child_tree_update, nullptr));
 
   // Portal node should use name from root of child tree.
-  EXPECT_EQ("name", child_manager->GetRoot()->GetName());
-  EXPECT_EQ("name", parent_manager->GetRoot()->GetName());
+  EXPECT_EQ("name", child_manager->GetBrowserAccessibilityRoot()->GetName());
+  EXPECT_EQ("name", parent_manager->GetBrowserAccessibilityRoot()->GetName());
 
   // Explicitly add name to portal node.
   parent_tree_update.nodes[0].AddStringAttribute(
@@ -901,8 +902,8 @@
   parent_manager->Initialize(parent_tree_update);
 
   // Portal node should now use name from attribute.
-  EXPECT_EQ("name", child_manager->GetRoot()->GetName());
-  EXPECT_EQ("name2", parent_manager->GetRoot()->GetName());
+  EXPECT_EQ("name", child_manager->GetBrowserAccessibilityRoot()->GetName());
+  EXPECT_EQ("name2", parent_manager->GetBrowserAccessibilityRoot()->GetName());
 }
 
 TEST_F(BrowserAccessibilityTest, GetIndexInParent) {
@@ -923,7 +924,7 @@
   ASSERT_NE(nullptr, browser_accessibility_manager.get());
 
   BrowserAccessibility* root_accessible =
-      browser_accessibility_manager->GetRoot();
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   // Should be nullopt for kRootWebArea since it doesn't have a calculated
   // index.
@@ -957,7 +958,8 @@
   ASSERT_NE(nullptr, browser_accessibility_manager.get());
 
   BrowserAccessibility* gc_accessible =
-      browser_accessibility_manager->GetRoot()->PlatformGetChild(0);
+      browser_accessibility_manager->GetBrowserAccessibilityRoot()
+          ->PlatformGetChild(0);
   ASSERT_NE(nullptr, gc_accessible);
 
   BrowserAccessibility::AXPosition pos = gc_accessible->CreatePositionAt(0);
diff --git a/content/browser/accessibility/browser_accessibility_win_unittest.cc b/content/browser/accessibility/browser_accessibility_win_unittest.cc
index 95c23dc..975b09d 100644
--- a/content/browser/accessibility/browser_accessibility_win_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_win_unittest.cc
@@ -169,7 +169,8 @@
       MakeAXTreeUpdateForTesting(root, button, checkbox),
       test_browser_accessibility_delegate_.get()));
   IAccessible* root_accessible =
-      ToBrowserAccessibilityWin(manager->GetRoot())->GetCOM();
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot())
+          ->GetCOM();
   IDispatch* root_iaccessible = NULL;
   IDispatch* child1_iaccessible = NULL;
   base::win::ScopedVariant childid_self(CHILDID_SELF);
@@ -216,7 +217,7 @@
   // value.
   base::win::ScopedVariant one(1);
   Microsoft::WRL::ComPtr<IDispatch> text_dispatch;
-  HRESULT hr = ToBrowserAccessibilityWin(manager->GetRoot())
+  HRESULT hr = ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot())
                    ->GetCOM()
                    ->get_accChild(one, &text_dispatch);
   ASSERT_EQ(S_OK, hr);
@@ -247,7 +248,7 @@
 
   // Query for the text IAccessible and verify that it now returns "new text"
   // as its value.
-  hr = ToBrowserAccessibilityWin(manager->GetRoot())
+  hr = ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot())
            ->GetCOM()
            ->get_accChild(one, &text_dispatch);
   ASSERT_EQ(S_OK, hr);
@@ -433,7 +434,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityWin* root_obj =
-      ToBrowserAccessibilityWin(manager->GetRoot());
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, root_obj);
   ASSERT_EQ(1U, root_obj->PlatformChildCount());
 
@@ -656,7 +657,8 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityComWin* root_obj =
-      ToBrowserAccessibilityWin(manager->GetRoot())->GetCOM();
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot())
+          ->GetCOM();
 
   LONG text_len;
   EXPECT_EQ(S_OK, root_obj->get_nCharacters(&text_len));
@@ -776,7 +778,8 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityComWin* root_obj =
-      ToBrowserAccessibilityWin(manager->GetRoot())->GetCOM();
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot())
+          ->GetCOM();
 
   LONG text_len;
   EXPECT_EQ(S_OK, root_obj->get_nCharacters(&text_len));
@@ -938,7 +941,7 @@
                                      text6),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_obj = manager->GetRoot();
+  BrowserAccessibility* root_obj = manager->GetBrowserAccessibilityRoot();
   BrowserAccessibility* para1_obj = manager->GetFromID(11);
   BrowserAccessibility* link2_obj = manager->GetFromID(13);
   BrowserAccessibility* button_obj = manager->GetFromID(14);
@@ -1014,7 +1017,7 @@
           test_browser_accessibility_delegate_.get()));
 
   // Verify the root is as we expect by default.
-  BrowserAccessibility* root = manager->GetRoot();
+  BrowserAccessibility* root = manager->GetBrowserAccessibilityRoot();
   EXPECT_EQ(1, root->GetId());
   EXPECT_EQ(ax::mojom::Role::kRootWebArea, root->GetRole());
   EXPECT_EQ(ax::mojom::State::kNone, root->GetState());
@@ -1043,7 +1046,7 @@
 
   // The root should have been cleared,not replaced, because in the former case
   // this could cause multiple focus and load complete events.
-  EXPECT_EQ(root, manager->GetRoot());
+  EXPECT_EQ(root, manager->GetBrowserAccessibilityRoot());
 
   BrowserAccessibility* acc1_2 = manager->GetFromID(2);
   EXPECT_EQ(ax::mojom::Role::kTextField, acc1_2->GetRole());
@@ -1069,7 +1072,7 @@
   ASSERT_TRUE(manager->OnAccessibilityEvents(event_bundle));
 
   // Verify that the root has been cleared, not replaced.
-  EXPECT_EQ(root, manager->GetRoot());
+  EXPECT_EQ(root, manager->GetBrowserAccessibilityRoot());
 
   BrowserAccessibility* acc2_2 = manager->GetFromID(3);
   EXPECT_EQ(ax::mojom::Role::kButton, acc2_2->GetRole());
@@ -1096,7 +1099,7 @@
           test_browser_accessibility_delegate_.get()));
 
   // Verify the root is as we expect by default.
-  BrowserAccessibility* root = manager->GetRoot();
+  BrowserAccessibility* root = manager->GetBrowserAccessibilityRoot();
   EXPECT_EQ(1, root->GetId());
   EXPECT_EQ(ax::mojom::Role::kRootWebArea, root->GetRole());
   EXPECT_EQ(ax::mojom::State::kNone, root->GetState());
@@ -1139,9 +1142,9 @@
           MakeAXTreeUpdateForTesting(root, pseudo_before, checkbox),
           test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityWin* root_accessible =
-      ToBrowserAccessibilityWin(manager->GetRoot());
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(2U, root_accessible->PlatformChildCount());
 
@@ -1259,9 +1262,9 @@
               slider_text),
           test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityWin* root_accessible =
-      ToBrowserAccessibilityWin(manager->GetRoot());
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(5U, root_accessible->PlatformChildCount());
 
@@ -1429,9 +1432,9 @@
                                      text_field_text, text_field_line),
           test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityWin* root_accessible =
-      ToBrowserAccessibilityWin(manager->GetRoot());
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(2U, root_accessible->PlatformChildCount());
 
@@ -1529,9 +1532,9 @@
                                      button_2_data, static_text_data),
           test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityWin* root_accessible =
-      ToBrowserAccessibilityWin(manager->GetRoot());
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(2U, root_accessible->PlatformChildCount());
 
@@ -1658,9 +1661,9 @@
       BrowserAccessibilityManager::Create(
           update, test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityWin* root_accessible =
-      ToBrowserAccessibilityWin(manager->GetRoot());
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(1U, root_accessible->PlatformChildCount());
 
@@ -1922,9 +1925,9 @@
           MakeAXTreeUpdateForTesting(root, combo_box, text_field),
           test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityWin* root_accessible =
-      ToBrowserAccessibilityWin(manager->GetRoot());
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(2U, root_accessible->PlatformChildCount());
 
@@ -2051,9 +2054,9 @@
       BrowserAccessibilityManager::Create(
           update, test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityWin* root_accessible =
-      ToBrowserAccessibilityWin(manager->GetRoot());
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(1U, root_accessible->PlatformChildCount());
 
@@ -2175,9 +2178,9 @@
       BrowserAccessibilityManager::Create(
           update, test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityWin* root_accessible =
-      ToBrowserAccessibilityWin(manager->GetRoot());
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(1U, root_accessible->PlatformChildCount());
 
@@ -2312,9 +2315,9 @@
           MakeAXTreeUpdateForTesting(root, div, link, text),
           test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityWin* root_accessible =
-      ToBrowserAccessibilityWin(manager->GetRoot());
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(1U, root_accessible->PlatformChildCount());
 
@@ -2519,9 +2522,9 @@
       BrowserAccessibilityManager::Create(
           update, test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityWin* ax_root =
-      ToBrowserAccessibilityWin(manager->GetRoot());
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, ax_root);
   ASSERT_EQ(1U, ax_root->PlatformChildCount());
 
@@ -2745,9 +2748,9 @@
                                      static_text1, static_text2),
           test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityWin* ax_root =
-      ToBrowserAccessibilityWin(manager->GetRoot());
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, ax_root);
   ASSERT_EQ(1U, ax_root->PlatformChildCount());
 
@@ -2846,9 +2849,9 @@
                                      static_text1, static_text2),
           test_browser_accessibility_delegate_.get()));
 
-  ASSERT_NE(nullptr, manager->GetRoot());
+  ASSERT_NE(nullptr, manager->GetBrowserAccessibilityRoot());
   BrowserAccessibilityWin* ax_root =
-      ToBrowserAccessibilityWin(manager->GetRoot());
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, ax_root);
   ASSERT_EQ(1U, ax_root->PlatformChildCount());
 
@@ -2952,7 +2955,8 @@
                                      child2_child2),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_accessible = manager->GetRoot();
+  BrowserAccessibility* root_accessible =
+      manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   ASSERT_EQ(2U, root_accessible->PlatformChildCount());
   BrowserAccessibility* child1_accessible =
@@ -3036,7 +3040,8 @@
                                      child2_child2),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root_accessible = manager->GetRoot();
+  BrowserAccessibility* root_accessible =
+      manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_accessible);
   BrowserAccessibility* child1_accessible =
       root_accessible->PlatformGetChild(0);
@@ -3090,7 +3095,7 @@
           MakeAXTreeUpdateForTesting(root_node, child_node),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root = manager->GetRoot();
+  BrowserAccessibility* root = manager->GetBrowserAccessibilityRoot();
   int32_t root_unique_id = GetUniqueId(root);
   BrowserAccessibility* child = root->PlatformGetChild(0);
   int32_t child_unique_id = GetUniqueId(child);
@@ -3099,7 +3104,7 @@
   manager = std::make_unique<BrowserAccessibilityManagerWin>(
       MakeAXTreeUpdateForTesting(root_node, child_node),
       test_browser_accessibility_delegate_.get());
-  root = manager->GetRoot();
+  root = manager->GetBrowserAccessibilityRoot();
   int32_t root_unique_id_2 = GetUniqueId(root);
   child = root->PlatformGetChild(0);
   int32_t child_unique_id_2 = GetUniqueId(child);
@@ -3149,7 +3154,7 @@
           MakeAXTreeUpdateForTesting(root_node, child_node),
           test_browser_accessibility_delegate_.get()));
 
-  BrowserAccessibility* root = manager->GetRoot();
+  BrowserAccessibility* root = manager->GetBrowserAccessibilityRoot();
   BrowserAccessibility* child = root->PlatformGetChild(0);
 
   base::win::ScopedVariant root_unique_id_variant(-GetUniqueId(root));
@@ -3189,7 +3194,7 @@
           test_browser_accessibility_delegate_.get()));
 
   BrowserAccessibilityWin* ax_root =
-      ToBrowserAccessibilityWin(manager->GetRoot());
+      ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, ax_root);
   BrowserAccessibilityWin* ax_child1 =
       ToBrowserAccessibilityWin(ax_root->PlatformGetChild(0));
diff --git a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
index 1edfb710..8c8c81f 100644
--- a/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
+++ b/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
@@ -137,7 +137,8 @@
   }
 
   BrowserAccessibility* FindNode(const std::string& name_or_value) {
-    return FindNodeInSubtree(*GetManager()->GetRoot(), name_or_value);
+    return FindNodeInSubtree(*GetManager()->GetBrowserAccessibilityRoot(),
+                             name_or_value);
   }
 
   BrowserAccessibility* FindNodeInSubtree(BrowserAccessibility& node,
@@ -167,7 +168,8 @@
   }
 
   BrowserAccessibility* FindFirstNodeWithRole(ax::mojom::Role role_value) {
-    return FindFirstNodeWithRoleInSubtree(*GetManager()->GetRoot(), role_value);
+    return FindFirstNodeWithRoleInSubtree(
+        *GetManager()->GetBrowserAccessibilityRoot(), role_value);
   }
 
   BrowserAccessibility* FindFirstNodeWithRoleInSubtree(
@@ -572,7 +574,8 @@
   WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(),
                                                 "Button 2");
 
-  const BrowserAccessibility* root = GetManager()->GetRoot();
+  const BrowserAccessibility* root =
+      GetManager()->GetBrowserAccessibilityRoot();
   ASSERT_EQ(1U, root->PlatformChildCount());
   const BrowserAccessibility* body = root->PlatformGetChild(0);
   ASSERT_EQ(3U, body->PlatformChildCount());
@@ -628,7 +631,8 @@
   WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(),
                                                 "Text in iframe");
 
-  const BrowserAccessibility* root = GetManager()->GetRoot();
+  const BrowserAccessibility* root =
+      GetManager()->GetBrowserAccessibilityRoot();
   ASSERT_NE(root, nullptr);
   const BrowserAccessibility* body = root->PlatformGetChild(0);
   ASSERT_NE(body, nullptr);
@@ -718,7 +722,8 @@
   WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(),
                                                 "Sample text");
 
-  const BrowserAccessibility* root = GetManager()->GetRoot();
+  const BrowserAccessibility* root =
+      GetManager()->GetBrowserAccessibilityRoot();
   ASSERT_NE(root, nullptr);
   const BrowserAccessibility* body = root->PlatformGetChild(0);
   ASSERT_NE(body, nullptr);
@@ -758,7 +763,8 @@
   WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(),
                                                 "Select");
 
-  const BrowserAccessibility* root = GetManager()->GetRoot();
+  const BrowserAccessibility* root =
+      GetManager()->GetBrowserAccessibilityRoot();
   ASSERT_NE(root, nullptr);
   const BrowserAccessibility* body = root->PlatformGetChild(0);
   ASSERT_NE(body, nullptr);
@@ -817,7 +823,8 @@
   WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(),
                                                 "Select");
 
-  const BrowserAccessibility* root = GetManager()->GetRoot();
+  const BrowserAccessibility* root =
+      GetManager()->GetBrowserAccessibilityRoot();
   ASSERT_NE(root, nullptr);
   const BrowserAccessibility* body = root->PlatformGetChild(0);
   ASSERT_NE(body, nullptr);
@@ -981,7 +988,8 @@
   WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(),
                                                 "Select");
 
-  const BrowserAccessibility* root = GetManager()->GetRoot();
+  const BrowserAccessibility* root =
+      GetManager()->GetBrowserAccessibilityRoot();
   ASSERT_NE(root, nullptr);
   const BrowserAccessibility* body = root->PlatformGetChild(0);
   ASSERT_NE(body, nullptr);
@@ -1026,7 +1034,8 @@
 
   WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(),
                                                 "Button 2");
-  const BrowserAccessibility* root = GetManager()->GetRoot();
+  const BrowserAccessibility* root =
+      GetManager()->GetBrowserAccessibilityRoot();
   BrowserAccessibility::PlatformChildIterator it =
       root->PlatformChildrenBegin();
   EXPECT_EQ(ax::mojom::Role::kGenericContainer, (*it).GetRole());
@@ -1170,7 +1179,7 @@
       </body>
       </html>)HTML");
 
-  BrowserAccessibility* root = GetManager()->GetRoot();
+  BrowserAccessibility* root = GetManager()->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root);
   ASSERT_EQ(18u, root->PlatformChildCount());
 
@@ -1249,7 +1258,7 @@
       </body>
       </html>)HTML");
 
-  BrowserAccessibility* root = GetManager()->GetRoot();
+  BrowserAccessibility* root = GetManager()->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root);
   ASSERT_EQ(20u, root->PlatformChildCount());
 
@@ -1296,7 +1305,7 @@
       </body>
       </html>)HTML");
 
-  BrowserAccessibility* root = GetManager()->GetRoot();
+  BrowserAccessibility* root = GetManager()->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root);
   ASSERT_EQ(1u, root->PlatformChildCount());
 
@@ -1415,7 +1424,7 @@
   BrowserAccessibilityManager* browser_accessibility_manager = GetManager();
   ASSERT_NE(nullptr, browser_accessibility_manager);
   BrowserAccessibility* root_browser_accessibility =
-      browser_accessibility_manager->GetRoot();
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_browser_accessibility);
   BrowserAccessibility* leaf_iframe_browser_accessibility =
       root_browser_accessibility->InternalDeepestLastChild();
@@ -1440,7 +1449,7 @@
       BrowserAccessibilityManager::FromID(iframe_tree_id);
   ASSERT_NE(nullptr, iframe_browser_accessibility_manager);
   BrowserAccessibility* root_iframe_browser_accessibility =
-      iframe_browser_accessibility_manager->GetRoot();
+      iframe_browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_iframe_browser_accessibility);
   ASSERT_EQ(ax::mojom::Role::kRootWebArea,
             root_iframe_browser_accessibility->GetRole());
@@ -1466,7 +1475,7 @@
   BrowserAccessibilityManager* browser_accessibility_manager = GetManager();
   ASSERT_NE(nullptr, browser_accessibility_manager);
   BrowserAccessibility* root_browser_accessibility =
-      browser_accessibility_manager->GetRoot();
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_browser_accessibility);
   BrowserAccessibility* leaf_iframe_browser_accessibility =
       root_browser_accessibility->InternalDeepestLastChild();
@@ -1490,7 +1499,7 @@
       BrowserAccessibilityManager::FromID(iframe_tree_id);
   ASSERT_NE(nullptr, iframe_browser_accessibility_manager);
   BrowserAccessibility* root_iframe_browser_accessibility =
-      iframe_browser_accessibility_manager->GetRoot();
+      iframe_browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_iframe_browser_accessibility);
   ASSERT_EQ(ax::mojom::Role::kRootWebArea,
             root_iframe_browser_accessibility->GetRole());
@@ -1526,7 +1535,7 @@
 
   BrowserAccessibilityManager* manager = GetManager();
   ASSERT_NE(nullptr, manager);
-  BrowserAccessibility* root = manager->GetRoot();
+  BrowserAccessibility* root = manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root);
 
   // Find the input control, and the popup-button
@@ -1600,7 +1609,7 @@
 
   BrowserAccessibilityManager* manager = GetManager();
   ASSERT_NE(nullptr, manager);
-  BrowserAccessibility* root = manager->GetRoot();
+  BrowserAccessibility* root = manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root);
 
   // Find the input control
@@ -1661,7 +1670,8 @@
   WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(),
                                                 "Anchor text");
 
-  const BrowserAccessibility* root = GetManager()->GetRoot();
+  const BrowserAccessibility* root =
+      GetManager()->GetBrowserAccessibilityRoot();
   ASSERT_EQ(2u, root->PlatformChildCount());
   const BrowserAccessibility* target = root->PlatformGetChild(1);
   ASSERT_EQ(1u, target->PlatformChildCount());
@@ -1689,7 +1699,8 @@
       </body>
       </html>)HTML");
 
-  const BrowserAccessibility* root = GetManager()->GetRoot();
+  const BrowserAccessibility* root =
+      GetManager()->GetBrowserAccessibilityRoot();
   ASSERT_EQ(1U, root->PlatformChildCount());
 
   const BrowserAccessibility* heading = root->PlatformGetChild(0);
@@ -1728,7 +1739,7 @@
   BrowserAccessibilityManager* root_accessibility_manager = GetManager();
   ASSERT_NE(nullptr, root_accessibility_manager);
   BrowserAccessibility* root_browser_accessibility =
-      root_accessibility_manager->GetRoot();
+      root_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_browser_accessibility);
 
   // Focus the button within the second iframe to set focus on that document,
@@ -1778,7 +1789,7 @@
   BrowserAccessibilityManager* root_accessibility_manager = GetManager();
   ASSERT_NE(nullptr, root_accessibility_manager);
   BrowserAccessibility* root_browser_accessibility =
-      root_accessibility_manager->GetRoot();
+      root_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(nullptr, root_browser_accessibility);
   ASSERT_EQ(ax::mojom::Role::kRootWebArea,
             root_browser_accessibility->GetRole());
@@ -1830,15 +1841,15 @@
       "/accessibility/scrolling/implicit-root-scroller.html");
 
   BrowserAccessibilityManager* manager = GetManager();
-  const BrowserAccessibility* heading =
-      FindNodeByRole(manager->GetRoot(), ax::mojom::Role::kHeading);
+  const BrowserAccessibility* heading = FindNodeByRole(
+      manager->GetBrowserAccessibilityRoot(), ax::mojom::Role::kHeading);
 
   // Ensure that this page has an implicit root scroller that's something
   // other than the root of the accessibility tree.
   ui::AXNodeID root_scroller_id = manager->GetTreeData().root_scroller_id;
   BrowserAccessibility* root_scroller = manager->GetFromID(root_scroller_id);
   ASSERT_TRUE(root_scroller);
-  EXPECT_NE(root_scroller_id, manager->GetRoot()->GetId());
+  EXPECT_NE(root_scroller_id, manager->GetBrowserAccessibilityRoot()->GetId());
 
   // If we take the root scroll offsets into account (most platforms)
   // the heading should be scrolled above the top.
@@ -2038,7 +2049,7 @@
 
   BrowserAccessibilityManager* browser_accessibility_manager = GetManager();
   BrowserAccessibility* root_browser_accessibility =
-      browser_accessibility_manager->GetRoot();
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(root_browser_accessibility, nullptr);
 
   const ui::AXNode* root_node = root_browser_accessibility->node();
@@ -2110,7 +2121,7 @@
 
   BrowserAccessibilityManager* browser_accessibility_manager = GetManager();
   BrowserAccessibility* root_browser_accessibility =
-      browser_accessibility_manager->GetRoot();
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(root_browser_accessibility, nullptr);
 
   BrowserAccessibility* input_browser_accessibility =
@@ -2186,7 +2197,7 @@
 
   BrowserAccessibilityManager* browser_accessibility_manager = GetManager();
   BrowserAccessibility* root_browser_accessibility =
-      browser_accessibility_manager->GetRoot();
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(root_browser_accessibility, nullptr);
 
   BrowserAccessibility* input_browser_accessibility =
@@ -2271,7 +2282,7 @@
 
   BrowserAccessibilityManager* browser_accessibility_manager = GetManager();
   BrowserAccessibility* root_browser_accessibility =
-      browser_accessibility_manager->GetRoot();
+      browser_accessibility_manager->GetBrowserAccessibilityRoot();
   ASSERT_NE(root_browser_accessibility, nullptr);
 
   BrowserAccessibility* input_browser_accessibility =
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.cc b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
index 1a4f85c..c0b7008 100644
--- a/content/browser/accessibility/dump_accessibility_browsertest_base.cc
+++ b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -450,7 +450,8 @@
     BrowserAccessibilityManager* manager =
         main_frame->browser_accessibility_manager();
     if (manager) {
-      BrowserAccessibility* accessibility_root = manager->GetRoot();
+      BrowserAccessibility* accessibility_root =
+          manager->GetBrowserAccessibilityRoot();
 
       // Check to see if all frames have loaded. If not, we invoke
       // WaitForEndOfTest to listen for a kEndOfTest signal which will be
@@ -491,7 +492,7 @@
     const std::string& name,
     BrowserAccessibility* search_root) const {
   if (!search_root)
-    search_root = GetManager()->GetRoot();
+    search_root = GetManager()->GetBrowserAccessibilityRoot();
 
   CHECK(search_root);
   BrowserAccessibility* node = FindNodeInSubtree(*search_root, name);
@@ -515,8 +516,8 @@
 DumpAccessibilityTestBase::CaptureEvents(InvokeAction invoke_action) {
   // Create a new Event Recorder for the run.
   BrowserAccessibilityManager* manager = GetManager();
-  ui::AXTreeSelector selector(
-      manager->GetRoot()->GetTargetForNativeAccessibilityEvent());
+  ui::AXTreeSelector selector(manager->GetBrowserAccessibilityRoot()
+                                  ->GetTargetForNativeAccessibilityEvent());
   std::unique_ptr<ui::AXEventRecorder> event_recorder =
       AXInspectFactory::CreateRecorder(GetParam(), manager,
                                        base::GetCurrentProcId(), selector);
@@ -605,7 +606,7 @@
 BrowserAccessibility* DumpAccessibilityTestBase::FindNodeByHTMLAttribute(
     const char* attr,
     const std::string& value) const {
-  BrowserAccessibility* root = GetManager()->GetRoot();
+  BrowserAccessibility* root = GetManager()->GetBrowserAccessibilityRoot();
 
   CHECK(root);
   return FindNodeByHTMLAttributeInSubtree(*root, attr, value);
diff --git a/content/browser/accessibility/dump_accessibility_scripts_browsertest.cc b/content/browser/accessibility/dump_accessibility_scripts_browsertest.cc
index 782ec84..5feb167a 100644
--- a/content/browser/accessibility/dump_accessibility_scripts_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_scripts_browsertest.cc
@@ -80,7 +80,7 @@
   std::vector<std::string> Dump() override {
     std::vector<std::string> dump;
     std::unique_ptr<AXTreeFormatter> formatter(CreateFormatter());
-    BrowserAccessibility* root = GetManager()->GetRoot();
+    BrowserAccessibility* root = GetManager()->GetBrowserAccessibilityRoot();
 
     size_t start_index = 0;
     size_t length = scenario_.script_instructions.size();
diff --git a/content/browser/accessibility/fullscreen_browsertest.cc b/content/browser/accessibility/fullscreen_browsertest.cc
index 26e18d05..32295a9a 100644
--- a/content/browser/accessibility/fullscreen_browsertest.cc
+++ b/content/browser/accessibility/fullscreen_browsertest.cc
@@ -96,11 +96,12 @@
       web_contents->GetRootBrowserAccessibilityManager();
 
   // Initially there are 3 links in the accessibility tree.
-  EXPECT_EQ(3, CountLinks(manager->GetRoot()));
+  EXPECT_EQ(3, CountLinks(manager->GetBrowserAccessibilityRoot()));
 
   // Enter fullscreen by finding the button and performing the default action,
   // which is to click it.
-  BrowserAccessibility* button = FindButton(manager->GetRoot());
+  BrowserAccessibility* button =
+      FindButton(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, button);
   manager->DoDefaultAction(*button);
 
@@ -108,7 +109,7 @@
   WaitForAccessibilityTreeToContainNodeWithName(web_contents, "Done");
 
   // Now, the two links outside of the fullscreen element are gone.
-  EXPECT_EQ(1, CountLinks(manager->GetRoot()));
+  EXPECT_EQ(1, CountLinks(manager->GetBrowserAccessibilityRoot()));
 }
 
 // Fails flakily on all platforms: crbug.com/825735
@@ -133,11 +134,12 @@
       web_contents->GetRootBrowserAccessibilityManager();
 
   // Initially there's just one link, in the top frame.
-  EXPECT_EQ(1, CountLinks(manager->GetRoot()));
+  EXPECT_EQ(1, CountLinks(manager->GetBrowserAccessibilityRoot()));
 
   // Enter fullscreen by finding the button and performing the default action,
   // which is to click it.
-  BrowserAccessibility* button = FindButton(manager->GetRoot());
+  BrowserAccessibility* button =
+      FindButton(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, button);
   manager->DoDefaultAction(*button);
 
@@ -145,7 +147,7 @@
   // in the inert part of the page, then exit fullscreen and change the button
   // text to "Done". Then the link inside the iframe should also be exposed.
   WaitForAccessibilityTreeToContainNodeWithName(web_contents, "Done");
-  EXPECT_EQ(2, CountLinks(manager->GetRoot()));
+  EXPECT_EQ(2, CountLinks(manager->GetBrowserAccessibilityRoot()));
 }
 
 }  // namespace content
diff --git a/content/browser/accessibility/hit_testing_browsertest.cc b/content/browser/accessibility/hit_testing_browsertest.cc
index 5188abc..720b8a5 100644
--- a/content/browser/accessibility/hit_testing_browsertest.cc
+++ b/content/browser/accessibility/hit_testing_browsertest.cc
@@ -213,10 +213,11 @@
   AccessibilityNotificationWaiter hover_waiter(
       shell()->web_contents(), ui::kAXModeComplete, ax::mojom::Event::kHover);
   ui::AXPlatformNodeBase* platform_node = nullptr;
-  if (manager->GetRoot()->GetAXPlatformNode()) {
-    platform_node = static_cast<ui::AXPlatformNodeBase*>(
-                        manager->GetRoot()->GetAXPlatformNode())
-                        ->NearestLeafToPoint(screen_point);
+  if (manager->GetBrowserAccessibilityRoot()->GetAXPlatformNode()) {
+    platform_node =
+        static_cast<ui::AXPlatformNodeBase*>(
+            manager->GetBrowserAccessibilityRoot()->GetAXPlatformNode())
+            ->NearestLeafToPoint(screen_point);
   }
   EXPECT_TRUE(hover_waiter.WaitForNotification());
   if (platform_node) {
diff --git a/content/browser/accessibility/hit_testing_mac_browsertest.mm b/content/browser/accessibility/hit_testing_mac_browsertest.mm
index c44c5d8..d06d10a7 100644
--- a/content/browser/accessibility/hit_testing_mac_browsertest.mm
+++ b/content/browser/accessibility/hit_testing_mac_browsertest.mm
@@ -23,7 +23,7 @@
  public:
   BrowserAccessibilityCocoa* GetWebContentRoot() {
     return GetRootBrowserAccessibilityManager()
-        ->GetRoot()
+        ->GetBrowserAccessibilityRoot()
         ->GetNativeViewAccessible();
   }
 };
diff --git a/content/browser/accessibility/hit_testing_win_browsertest.cc b/content/browser/accessibility/hit_testing_win_browsertest.cc
index 06d5177..c40cc63 100644
--- a/content/browser/accessibility/hit_testing_win_browsertest.cc
+++ b/content/browser/accessibility/hit_testing_win_browsertest.cc
@@ -43,7 +43,7 @@
   ComPtr<IAccessible> GetWebContentRootIAccessible() {
     ComPtr<IAccessible> content_root;
     GetRootBrowserAccessibilityManager()
-        ->GetRoot()
+        ->GetBrowserAccessibilityRoot()
         ->GetNativeViewAccessible()
         ->QueryInterface(IID_PPV_ARGS(&content_root));
     return content_root;
diff --git a/content/browser/accessibility/line_layout_browsertest.cc b/content/browser/accessibility/line_layout_browsertest.cc
index 258e9fd..831e4ed 100644
--- a/content/browser/accessibility/line_layout_browsertest.cc
+++ b/content/browser/accessibility/line_layout_browsertest.cc
@@ -84,11 +84,13 @@
       web_contents->GetRootBrowserAccessibilityManager();
 
   // There should be at least 2 links between nodes on the same line.
-  int line_link_count = CountNextPreviousOnLineLinks(manager->GetRoot(), false);
+  int line_link_count = CountNextPreviousOnLineLinks(
+      manager->GetBrowserAccessibilityRoot(), false);
   ASSERT_GE(line_link_count, 2);
 
   // Find the button and click it.
-  BrowserAccessibility* button = FindButton(manager->GetRoot());
+  BrowserAccessibility* button =
+      FindButton(manager->GetBrowserAccessibilityRoot());
   ASSERT_NE(nullptr, button);
   manager->DoDefaultAction(*button);
 
@@ -97,7 +99,8 @@
 
   // There should be at least 2 links between nodes on the same line,
   // though not necessarily the same as before.
-  line_link_count = CountNextPreviousOnLineLinks(manager->GetRoot(), false);
+  line_link_count = CountNextPreviousOnLineLinks(
+      manager->GetBrowserAccessibilityRoot(), false);
   ASSERT_GE(line_link_count, 2);
 }
 
@@ -126,12 +129,13 @@
   AccessibilityNotificationWaiter waiter2(shell()->web_contents(),
                                           ui::kAXModeComplete,
                                           ax::mojom::Event::kTreeChanged);
-  manager->LoadInlineTextBoxes(*manager->GetRoot());
+  manager->LoadInlineTextBoxes(*manager->GetBrowserAccessibilityRoot());
   ASSERT_TRUE(waiter2.WaitForNotification());
 
   // There are three pieces of text, and they should be cross-linked:
   //   before <-> inside <-> after
-  int line_link_count = CountNextPreviousOnLineLinks(manager->GetRoot(), true);
+  int line_link_count = CountNextPreviousOnLineLinks(
+      manager->GetBrowserAccessibilityRoot(), true);
   ASSERT_EQ(line_link_count, 4);
 }
 #endif
diff --git a/content/browser/accessibility/one_shot_accessibility_tree_search.cc b/content/browser/accessibility/one_shot_accessibility_tree_search.cc
index bb7f104..9d5dd10e 100644
--- a/content/browser/accessibility/one_shot_accessibility_tree_search.cc
+++ b/content/browser/accessibility/one_shot_accessibility_tree_search.cc
@@ -182,7 +182,7 @@
       // This needs to be handled carefully. If not, there is a chance of
       // getting into infinite loop.
       if (can_wrap_to_last_element_ && !stop_node &&
-          node->manager()->GetRoot() == node) {
+          node->manager()->GetBrowserAccessibilityRoot() == node) {
         stop_node = node;
       }
       node = tree_->PreviousInTreeOrder(node, can_wrap_to_last_element_);
diff --git a/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc b/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc
index d232963..5b565107 100644
--- a/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc
+++ b/content/browser/accessibility/one_shot_accessibility_tree_search_unittest.cc
@@ -142,7 +142,7 @@
 }
 
 TEST_F(OneShotAccessibilityTreeSearchTest, GetAll) {
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
 #if BUILDFLAG(IS_MAC)
   ASSERT_EQ(13U, search.CountMatches());
 #else
@@ -151,7 +151,7 @@
 }
 
 TEST_F(OneShotAccessibilityTreeSearchTest, BackwardsWrapFromRoot) {
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
   search.SetDirection(OneShotAccessibilityTreeSearch::BACKWARDS);
   search.SetResultLimit(100);
   search.SetCanWrapToLastElement(true);
@@ -186,14 +186,14 @@
 TEST_F(OneShotAccessibilityTreeSearchTest, NoCycle) {
   // If you set a result limit of 1, you won't get the root node back as
   // the first match.
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
   search.SetResultLimit(1);
   ASSERT_EQ(1U, search.CountMatches());
   EXPECT_NE(1, search.GetMatchAtIndex(0)->GetId());
 }
 
 TEST_F(OneShotAccessibilityTreeSearchTest, ForwardsWithStartNode) {
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
   search.SetStartNode(tree_->GetFromID(7));
   ASSERT_EQ(3U, search.CountMatches());
   EXPECT_EQ(8, search.GetMatchAtIndex(0)->GetId());
@@ -202,7 +202,7 @@
 }
 
 TEST_F(OneShotAccessibilityTreeSearchTest, BackwardsWithStartNode) {
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
   search.SetStartNode(tree_->GetFromID(4));
   search.SetDirection(OneShotAccessibilityTreeSearch::BACKWARDS);
   ASSERT_EQ(3U, search.CountMatches());
@@ -212,7 +212,7 @@
 }
 
 TEST_F(OneShotAccessibilityTreeSearchTest, BackwardsWithStartNodeForAndroid) {
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
   search.SetStartNode(tree_->GetFromID(4));
   search.SetDirection(OneShotAccessibilityTreeSearch::BACKWARDS);
   search.SetResultLimit(3);
@@ -232,19 +232,19 @@
 }
 
 TEST_F(OneShotAccessibilityTreeSearchTest, ResultLimitZero) {
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
   search.SetResultLimit(0);
   ASSERT_EQ(0U, search.CountMatches());
 }
 
 TEST_F(OneShotAccessibilityTreeSearchTest, ResultLimitFive) {
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
   search.SetResultLimit(5);
   ASSERT_EQ(5U, search.CountMatches());
 }
 
 TEST_F(OneShotAccessibilityTreeSearchTest, DescendantsOnlyOfRoot) {
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
   search.SetStartNode(tree_->GetFromID(1));
   search.SetImmediateDescendantsOnly(true);
   ASSERT_EQ(4U, search.CountMatches());
@@ -290,7 +290,7 @@
 }
 
 TEST_F(OneShotAccessibilityTreeSearchTest, OnscreenOnly) {
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
   search.SetOnscreenOnly(true);
   ASSERT_EQ(7U, search.CountMatches());
   EXPECT_EQ(1, search.GetMatchAtIndex(0)->GetId());
@@ -303,14 +303,14 @@
 }
 
 TEST_F(OneShotAccessibilityTreeSearchTest, CaseInsensitiveStringMatch) {
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
   search.SetSearchText("eCEptiCOn");
   ASSERT_EQ(1U, search.CountMatches());
   EXPECT_EQ(9, search.GetMatchAtIndex(0)->GetId());
 }
 
 TEST_F(OneShotAccessibilityTreeSearchTest, OnePredicateTableCell) {
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
   search.AddPredicate(
       [](BrowserAccessibility* start, BrowserAccessibility* current) {
         return current->GetRole() == ax::mojom::Role::kColumnHeader;
@@ -321,7 +321,7 @@
 }
 
 TEST_F(OneShotAccessibilityTreeSearchTest, OnePredicateListItem) {
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
   search.AddPredicate(
       [](BrowserAccessibility* start, BrowserAccessibility* current) {
         return current->GetRole() == ax::mojom::Role::kListItem;
@@ -332,7 +332,7 @@
 }
 
 TEST_F(OneShotAccessibilityTreeSearchTest, TwoPredicatesTableRowAndCell) {
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
   search.AddPredicate(
       [](BrowserAccessibility* start, BrowserAccessibility* current) {
         return (current->GetRole() == ax::mojom::Role::kRow);
@@ -348,7 +348,7 @@
 }
 
 TEST_F(OneShotAccessibilityTreeSearchTest, TwoPredicatesListItem) {
-  OneShotAccessibilityTreeSearch search(tree_->GetRoot());
+  OneShotAccessibilityTreeSearch search(tree_->GetBrowserAccessibilityRoot());
   search.AddPredicate(
       [](BrowserAccessibility* start, BrowserAccessibility* current) {
         return (current->GetRole() == ax::mojom::Role::kList);
diff --git a/content/browser/accessibility/site_per_process_accessibility_browsertest.cc b/content/browser/accessibility/site_per_process_accessibility_browsertest.cc
index 31e44a6..609599bc 100644
--- a/content/browser/accessibility/site_per_process_accessibility_browsertest.cc
+++ b/content/browser/accessibility/site_per_process_accessibility_browsertest.cc
@@ -110,7 +110,8 @@
 
   // Assert that we can walk from the main frame down into the child frame
   // directly, getting correct roles and data along the way.
-  BrowserAccessibility* ax_root = main_frame_manager->GetRoot();
+  BrowserAccessibility* ax_root =
+      main_frame_manager->GetBrowserAccessibilityRoot();
   EXPECT_EQ(ax::mojom::Role::kRootWebArea, ax_root->GetRole());
   ASSERT_EQ(1U, ax_root->PlatformChildCount());
 
@@ -249,7 +250,8 @@
 
   // Assert that we can walk from the main frame down into the child frame
   // directly, getting correct roles and data along the way.
-  BrowserAccessibility* ax_root = main_frame_manager->GetRoot();
+  BrowserAccessibility* ax_root =
+      main_frame_manager->GetBrowserAccessibilityRoot();
   EXPECT_EQ(ax::mojom::Role::kRootWebArea, ax_root->GetRole());
   ASSERT_EQ(1U, ax_root->PlatformChildCount());
 
diff --git a/content/browser/accessibility/touch_passthrough_manager_unittest.cc b/content/browser/accessibility/touch_passthrough_manager_unittest.cc
index 0d8aebb..e6e7d73 100644
--- a/content/browser/accessibility/touch_passthrough_manager_unittest.cc
+++ b/content/browser/accessibility/touch_passthrough_manager_unittest.cc
@@ -63,8 +63,8 @@
       base::OnceCallback<void(BrowserAccessibilityManager* hit_manager,
                               int hit_node_id)> callback) override {
     BrowserAccessibility* result =
-        browser_accessibility_manager_->GetRoot()->ApproximateHitTest(
-            point_in_frame_pixels);
+        browser_accessibility_manager_->GetBrowserAccessibilityRoot()
+            ->ApproximateHitTest(point_in_frame_pixels);
     int hit_node_id = result ? result->GetId() : 0;
     std::move(callback).Run(browser_accessibility_manager_.get(), hit_node_id);
   }
diff --git a/content/browser/accessibility/web_contents_accessibility_android.cc b/content/browser/accessibility/web_contents_accessibility_android.cc
index d50f0ca..77303e8b 100644
--- a/content/browser/accessibility/web_contents_accessibility_android.cc
+++ b/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -358,8 +358,8 @@
     BrowserAccessibilityManagerAndroid* root_manager =
         GetRootBrowserAccessibilityManager();
     if (root_manager) {
-      auto* root_node =
-          static_cast<BrowserAccessibilityAndroid*>(root_manager->GetRoot());
+      auto* root_node = static_cast<BrowserAccessibilityAndroid*>(
+          root_manager->GetBrowserAccessibilityRoot());
       if (root_node) {
         Java_WebContentsAccessibilityImpl_handleContentChanged(
             env, obj, root_node->unique_id());
@@ -584,7 +584,8 @@
           GetRootBrowserAccessibilityManager()) {
     auto* hover_node = static_cast<BrowserAccessibilityAndroid*>(
         root_manager->ApproximateHitTest(gfx::ToFlooredPoint(point)));
-    if (hover_node && hover_node != root_manager->GetRoot()) {
+    if (hover_node &&
+        hover_node != root_manager->GetBrowserAccessibilityRoot()) {
       HandleHover(hover_node->unique_id());
       return true;
     }
@@ -642,8 +643,8 @@
 jint WebContentsAccessibilityAndroid::GetRootId(JNIEnv* env) {
   if (BrowserAccessibilityManagerAndroid* root_manager =
           GetRootBrowserAccessibilityManager()) {
-    auto* root =
-        static_cast<BrowserAccessibilityAndroid*>(root_manager->GetRoot());
+    auto* root = static_cast<BrowserAccessibilityAndroid*>(
+        root_manager->GetBrowserAccessibilityRoot());
     if (root)
       return static_cast<jint>(root->unique_id());
   }
@@ -1017,7 +1018,7 @@
 void WebContentsAccessibilityAndroid::Blur(JNIEnv* env) {
   if (BrowserAccessibilityManagerAndroid* root_manager =
           GetRootBrowserAccessibilityManager())
-    root_manager->SetFocus(*root_manager->GetRoot());
+    root_manager->SetFocus(*root_manager->GetBrowserAccessibilityRoot());
 }
 
 void WebContentsAccessibilityAndroid::ScrollToMakeNodeVisible(JNIEnv* env,
@@ -1122,7 +1123,7 @@
   if (!root_manager)
     return 0;
 
-  BrowserAccessibility* root = root_manager->GetRoot();
+  BrowserAccessibility* root = root_manager->GetBrowserAccessibilityRoot();
   if (!root)
     return 0;
 
@@ -1288,7 +1289,7 @@
   // boxes for that node so that subsequent requests for character bounding
   // boxes will succeed. However, don't do that for the root of the tree,
   // as that will result in loading inline text boxes for the whole tree.
-  if (node != node->manager()->GetRoot())
+  if (node != node->manager()->GetBrowserAccessibilityRoot())
     node->manager()->LoadInlineTextBoxes(*node);
 }
 
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc
index 7e41714..0caabc8 100644
--- a/content/browser/back_forward_cache_browsertest.cc
+++ b/content/browser/back_forward_cache_browsertest.cc
@@ -162,12 +162,6 @@
   EnableFeatureAndSetParams(features::kBackForwardCache,
                             "message_handling_when_cached", "log");
   EnableFeatureAndSetParams(
-      features::kBackForwardCache, "enable_same_site",
-      same_site_back_forward_cache_enabled_ ? "true" : "false");
-  EnableFeatureAndSetParams(
-      features::kBackForwardCache, "skip_same_site_if_unload_exists",
-      skip_same_site_if_unload_exists_ ? "true" : "false");
-  EnableFeatureAndSetParams(
       blink::features::kLogUnexpectedIPCPostedToBackForwardCachedDocuments,
       "delay_before_tracking_ms", "0");
   EnableFeatureAndSetParams(blink::features::kLoadingTasksUnfreezable,
@@ -918,130 +912,6 @@
   delete_rfh_a2.WaitUntilDeleted();
 }
 
-class BackForwardCacheBrowserTestSkipSameSiteUnload
-    : public BackForwardCacheBrowserTest {
- public:
-  BackForwardCacheBrowserTestSkipSameSiteUnload() = default;
-  ~BackForwardCacheBrowserTestSkipSameSiteUnload() override = default;
-
- protected:
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    skip_same_site_if_unload_exists_ = true;
-    BackForwardCacheBrowserTest::SetUpCommandLine(command_line);
-  }
-};
-
-// We won't cache pages with unload handler on same-site navigations when
-// skip_same_site_if_unload_exists is set to true.
-IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestSkipSameSiteUnload,
-                       SameSiteNavigationFromPageWithUnload) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-  GURL url_a1(embedded_test_server()->GetURL("a.com", "/title1.html"));
-  GURL url_a2(embedded_test_server()->GetURL("a.com", "/title2.html"));
-
-  // 1) Navigate to A1 and add an unload handler.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a1));
-
-  RenderFrameHostImpl* rfh_a1 = current_frame_host();
-  EXPECT_TRUE(ExecJs(rfh_a1, "window.onunload = () => {} "));
-
-  // 2) Navigate to A2.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a2));
-  RenderFrameHostImpl* rfh_a2 = current_frame_host();
-  // We should not swap RFHs and A1 should not be in the back-forward cache.
-  EXPECT_EQ(rfh_a1, rfh_a2);
-  EXPECT_FALSE(rfh_a1->IsInBackForwardCache());
-}
-
-// We won't cache pages with an unload handler in a same-SiteInstance subframe
-// on same-site navigations when skip_same_site_if_unload_exists is set to true.
-IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestSkipSameSiteUnload,
-                       SameSiteNavigationFromPageWithUnloadInSameSiteSubframe) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-  GURL url_a1(embedded_test_server()->GetURL(
-      "a.com", "/cross_site_iframe_factory.html?a(b(a))"));
-  GURL url_a2(embedded_test_server()->GetURL("a.com", "/title2.html"));
-
-  // 1) Navigate to A1 and add an unload handler to a.com subframe.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a1));
-  RenderFrameHostImpl* rfh_a_main = current_frame_host();
-  RenderFrameHostImpl* rfh_b = rfh_a_main->child_at(0)->current_frame_host();
-  RenderFrameHostImpl* rfh_a_subframe =
-      rfh_b->child_at(0)->current_frame_host();
-  EXPECT_TRUE(ExecJs(rfh_a_subframe, "window.onunload = () => {} "));
-
-  // 2) Navigate to A2.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a2));
-  RenderFrameHostImpl* rfh_a2 = current_frame_host();
-  // We should not swap RFHs and A1 should not be in the back-forward cache.
-  EXPECT_EQ(rfh_a_main, rfh_a2);
-  EXPECT_FALSE(rfh_a_main->IsInBackForwardCache());
-}
-
-// We won't cache pages with an unload handler in a cross-site subframe on
-// same-site navigations when skip_same_site_if_unload_exists is set to true
-// iff the cross-site subframe is in the same SiteInstance as the mainframe.
-IN_PROC_BROWSER_TEST_F(
-    BackForwardCacheBrowserTestSkipSameSiteUnload,
-    SameSiteNavigationFromPageWithUnloadInCrossSiteSubframe) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-  GURL url_a1(embedded_test_server()->GetURL(
-      "a.com", "/cross_site_iframe_factory.html?a(b)"));
-  GURL url_a2(embedded_test_server()->GetURL("a.com", "/title2.html"));
-
-  // 1) Navigate to A1 and add an unload handler to b.com subframe.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a1));
-  RenderFrameHostImpl* rfh_a1 = current_frame_host();
-  RenderFrameHostImpl* rfh_b = rfh_a1->child_at(0)->current_frame_host();
-  EXPECT_TRUE(ExecJs(rfh_b, "window.onunload = () => {} "));
-  EXPECT_EQ(AreStrictSiteInstancesEnabled(),
-            rfh_a1->GetSiteInstance() != rfh_b->GetSiteInstance());
-
-  // 2) Navigate to A2.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a2));
-  RenderFrameHostImpl* rfh_a2 = current_frame_host();
-  if (AreStrictSiteInstancesEnabled()) {
-    // Test this block only for Android, as |rfh_a1| is not eligible for bfcache
-    // because of the unload handler on other platforms.
-    if (IsUnloadAllowedToEnterBackForwardCache()) {
-      // We should swap RFH & BIs and A1 should be in the back-forward cache.
-      EXPECT_NE(rfh_a1, rfh_a2);
-      EXPECT_FALSE(rfh_a1->GetSiteInstance()->IsRelatedSiteInstance(
-          rfh_a2->GetSiteInstance()));
-      EXPECT_TRUE(rfh_a1->IsInBackForwardCache());
-    }
-  } else {
-    // We should not swap RFHs and A1 should not be in the back-forward cache.
-    EXPECT_EQ(rfh_a1, rfh_a2);
-    EXPECT_FALSE(rfh_a1->IsInBackForwardCache());
-  }
-}
-
-// We will cache pages with unload handler on cross-site navigations even when
-// skip_same_site_if_unload_exists is set to true.
-IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestSkipSameSiteUnload,
-                       CrossSiteNavigationFromPageWithUnload) {
-  // This test is only enabled for Android, as pages with unload handlers are
-  // only eligible for bfcache on Android.
-  if (!IsUnloadAllowedToEnterBackForwardCache())
-    return;
-  ASSERT_TRUE(embedded_test_server()->Start());
-  GURL url_a1(embedded_test_server()->GetURL("a.com", "/title1.html"));
-  GURL url_a2(embedded_test_server()->GetURL("b.com", "/title2.html"));
-
-  // 1) Navigate to A and add an unload handler.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a1));
-  RenderFrameHostImpl* rfh_a = current_frame_host();
-  EXPECT_TRUE(ExecJs(rfh_a, "window.onunload = () => {} "));
-
-  // 2) Navigate to B.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a2));
-  RenderFrameHostImpl* rfh_b = current_frame_host();
-  // We should swap RFHs and A should be in the back-forward cache.
-  EXPECT_NE(rfh_a, rfh_b);
-  EXPECT_TRUE(rfh_a->IsInBackForwardCache());
-}
-
 // Sub-frame doesn't transition from LifecycleStateImpl::kInBackForwardCache to
 // LifecycleStateImpl::kRunningUnloadHandlers even when the sub-frame having
 // unload handlers is being evicted from BackForwardCache.
diff --git a/content/browser/back_forward_cache_browsertest.h b/content/browser/back_forward_cache_browsertest.h
index 9e35467..ff05b2f 100644
--- a/content/browser/back_forward_cache_browsertest.h
+++ b/content/browser/back_forward_cache_browsertest.h
@@ -184,9 +184,6 @@
   const ukm::TestAutoSetUkmRecorder& ukm_recorder() override;
   const base::HistogramTester& histogram_tester() override;
 
-  bool same_site_back_forward_cache_enabled_ = true;
-  bool skip_same_site_if_unload_exists_ = false;
-
   const int kMaxBufferedBytesPerProcess = 10000;
   const base::TimeDelta kGracePeriodToFinishLoading = base::Seconds(5);
 
diff --git a/content/browser/back_forward_cache_internal_browsertest.cc b/content/browser/back_forward_cache_internal_browsertest.cc
index b4fe8a1..74081348 100644
--- a/content/browser/back_forward_cache_internal_browsertest.cc
+++ b/content/browser/back_forward_cache_internal_browsertest.cc
@@ -991,141 +991,6 @@
   delete_observer_rfh_a.WaitUntilDeleted();
 }
 
-class BackForwardCacheBrowserTestWithSameSiteDisabled
-    : public BackForwardCacheBrowserTest {
- public:
-  BackForwardCacheBrowserTestWithSameSiteDisabled() = default;
-  ~BackForwardCacheBrowserTestWithSameSiteDisabled() override = default;
-
- protected:
-  void SetUpCommandLine(base::CommandLine* command_line) override {
-    same_site_back_forward_cache_enabled_ = false;
-    DisableFeature(features::kProactivelySwapBrowsingInstance);
-    BackForwardCacheBrowserTest::SetUpCommandLine(command_line);
-  }
-};
-
-IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestWithSameSiteDisabled,
-                       ConflictingBrowsingInstances) {
-  // This test assumes navigation from A1 to A2 will not switch
-  // BrowsingInstances, which is not true when either BackForwardCache or
-  // ProactivelySwapBrowsingInstance is enabled on same-site navigations.
-  DCHECK(!CanSameSiteMainFrameNavigationsChangeSiteInstances());
-  ASSERT_TRUE(embedded_test_server()->Start());
-  GURL url_a1(embedded_test_server()->GetURL("a.com", "/title1.html"));
-  GURL url_a2(embedded_test_server()->GetURL("a.com", "/title2.html"));
-  GURL url_b3(embedded_test_server()->GetURL("b.com", "/title1.html"));
-
-  // 1) Navigate to A1.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a1));
-
-  // 2) Navigate to A2.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a2));
-  RenderFrameHostImpl* rfh_a2 = current_frame_host();
-  RenderFrameDeletedObserver delete_rfh_a2(current_frame_host());
-
-  // 3) Navigate to B3.
-  EXPECT_TRUE(NavigateToURL(shell(), url_b3));
-  EXPECT_TRUE(rfh_a2->IsInBackForwardCache());
-  RenderFrameHostImpl* rfh_b3 = current_frame_host();
-  // Make B3 ineligible for caching, so that navigating doesn't evict A2
-  // due to the cache size limit.
-  DisableBFCacheForRFHForTesting(rfh_b3);
-
-  // 4) Do a history navigation back to A1.  At this point, A1 is going to have
-  // the same BrowsingInstance as A2. This should cause A2 to get
-  // evicted from the BackForwardCache due to its conflicting BrowsingInstance.
-  ASSERT_TRUE(HistoryGoToIndex(web_contents(), 0));
-  EXPECT_EQ(current_frame_host()->GetLastCommittedURL(), url_a1);
-  delete_rfh_a2.WaitUntilDeleted();
-
-  ExpectNotRestored({NotRestoredReason::kBrowsingInstanceNotSwapped}, {},
-                    {ShouldSwapBrowsingInstance::kNo_SameSiteNavigation}, {},
-                    {}, FROM_HERE);
-
-  // 5) Go to A2.
-  ASSERT_TRUE(HistoryGoForward(web_contents()));
-
-  ExpectNotRestored(
-      {
-          NotRestoredReason::kConflictingBrowsingInstance,
-      },
-      {}, {}, {}, {}, FROM_HERE);
-}
-
-// When same-site bfcache is disabled, we should not cache on same-site
-// navigations.
-IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestWithSameSiteDisabled,
-                       DoesNotCacheOnSameSiteNavigation) {
-  ASSERT_TRUE(embedded_test_server()->Start());
-  GURL url_a1(embedded_test_server()->GetURL("a.com", "/title1.html"));
-  GURL url_a2(embedded_test_server()->GetURL("a.com", "/title2.html"));
-  GURL url_a3(
-      embedded_test_server()->GetURL("subdomain.a.com", "/title3.html"));
-
-  // 1) Navigate to A1.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a1));
-  RenderFrameHostImpl* rfh_a1 = current_frame_host();
-  RenderFrameDeletedObserver delete_rfh_a1(rfh_a1);
-  auto browsing_instance_id =
-      rfh_a1->GetSiteInstance()->GetBrowsingInstanceId();
-
-  // 2) Navigate same-site and same-origin to A2.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a2));
-  RenderFrameHostImpl* rfh_a2 = current_frame_host();
-  // The BrowsingInstance shouldn't have changed.
-  EXPECT_EQ(browsing_instance_id,
-            rfh_a2->GetSiteInstance()->GetBrowsingInstanceId());
-  // The previous page should not be cached.
-  EXPECT_FALSE(rfh_a1->IsInBackForwardCache());
-
-  // 2) Navigate same-site but cross-origin to A3.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a3));
-  RenderFrameHostImpl* rfh_a3 = current_frame_host();
-  // The BrowsingInstance shouldn't have changed.
-  EXPECT_EQ(browsing_instance_id,
-            rfh_a3->GetSiteInstance()->GetBrowsingInstanceId());
-  // The previous page should not be cached.
-  EXPECT_FALSE(rfh_a2->IsInBackForwardCache());
-}
-
-// Check that during a same-RenderFrameHost cross-document navigation, the
-// disabled reasons is still tracked.
-IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestWithSameSiteDisabled,
-                       DisableForRenderFrameHostPersistsAcrossNavigations) {
-  // This test assumes navigation from A1 to A2 will not switch
-  // RenderFrameHosts which is not true when BackForwardCache,
-  // ProactivelySwapBrowsingInstance or RenderDocument is enabled on same-site
-  // main frame navigations.
-  DCHECK(!CanSameSiteMainFrameNavigationsChangeRenderFrameHosts());
-  ASSERT_TRUE(embedded_test_server()->Start());
-  GURL url_a1(embedded_test_server()->GetURL("a.com", "/title1.html"));
-  GURL url_a2(embedded_test_server()->GetURL("a.com", "/title2.html"));
-  GURL url_b3(embedded_test_server()->GetURL("b.com", "/title1.html"));
-
-  // 1) Navigate to A1.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a1));
-  RenderFrameHostImpl* rfh_a1 = current_frame_host();
-  RenderFrameDeletedObserver deleted_observer_rfh_a1(rfh_a1);
-  // Disable back-forward cache for A.
-  DisableBFCacheForRFHForTesting(rfh_a1);
-
-  // 2) Navigate to A2.
-  EXPECT_TRUE(NavigateToURL(shell(), url_a2));
-  EXPECT_FALSE(deleted_observer_rfh_a1.deleted());
-  EXPECT_EQ(rfh_a1, current_frame_host());
-
-  // 3) Navigate to B3.
-  EXPECT_TRUE(NavigateToURL(shell(), url_b3));
-  deleted_observer_rfh_a1.WaitUntilDeleted();
-
-  // 4) Go back to A2.
-  ASSERT_TRUE(HistoryGoBack(web_contents()));
-  ExpectNotRestored({NotRestoredReason::kDisableForRenderFrameHostCalled}, {},
-                    {}, {RenderFrameHostDisabledForTestingReason()}, {},
-                    FROM_HERE);
-}
-
 // The BackForwardCache caches same-website navigations.
 IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, SameSiteNavigationCaching) {
   ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/content/browser/download/mhtml_generation_manager.cc b/content/browser/download/mhtml_generation_manager.cc
index 32167b7..fa540bb 100644
--- a/content/browser/download/mhtml_generation_manager.cc
+++ b/content/browser/download/mhtml_generation_manager.cc
@@ -18,6 +18,7 @@
 #include "base/task/task_runner_util.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
+#include "base/types/optional_util.h"
 #include "components/download/public/common/download_task_runner.h"
 #include "content/browser/bad_message.h"
 #include "content/browser/download/mhtml_extra_parts_impl.h"
@@ -68,7 +69,7 @@
 
   content::MHTMLGenerationResult toMHTMLGenerationResult() const {
     return content::MHTMLGenerationResult(file_size,
-                                          base::OptionalOrNullptr(file_digest));
+                                          base::OptionalToPtr(file_digest));
   }
 };
 
diff --git a/content/browser/net/socket_broker_impl.cc b/content/browser/net/socket_broker_impl.cc
index c3c287f..ffd7d77 100644
--- a/content/browser/net/socket_broker_impl.cc
+++ b/content/browser/net/socket_broker_impl.cc
@@ -13,6 +13,7 @@
 #include "net/log/net_log_source.h"
 #include "net/socket/socket_descriptor.h"
 #include "net/socket/tcp_socket.h"
+#include "services/network/public/cpp/transferable_socket.h"
 
 #if !BUILDFLAG(IS_WIN)
 #include <netinet/in.h>
@@ -29,7 +30,7 @@
                                        CreateTcpSocketCallback callback) {
 // TODO(https://crbug.com/1311014): Open and release raw socket on Windows.
 #if BUILDFLAG(IS_WIN)
-  std::move(callback).Run(mojo::PlatformHandle(), net::ERR_FAILED);
+  std::move(callback).Run(network::TransferableSocket(), net::ERR_FAILED);
 #else
   base::ScopedFD socket(net::CreatePlatformSocket(
       net::ConvertAddressFamily(address_family), SOCK_STREAM,
@@ -41,7 +42,9 @@
     rv = net::MapSystemError(errno);
     socket.reset();
   }
-  std::move(callback).Run(mojo::PlatformHandle(std::move(socket)), rv);
+  std::move(callback).Run(
+      network::TransferableSocket(base::kNullProcessHandle, socket.release()),
+      rv);
 #endif
 }
 
diff --git a/content/browser/net/socket_broker_impl_unittest.cc b/content/browser/net/socket_broker_impl_unittest.cc
index 7841c40..c32fdb3 100644
--- a/content/browser/net/socket_broker_impl_unittest.cc
+++ b/content/browser/net/socket_broker_impl_unittest.cc
@@ -18,14 +18,14 @@
 namespace content {
 
 void DidCompleteCreateTest(base::RunLoop* run_loop,
-                           mojo::PlatformHandle fd,
+                           network::TransferableSocket socket,
                            int rv) {
 // TODO(https://crbug.com/1311014): Remove ifdef and expect a result of net::OK
 // on Windows.
 #if BUILDFLAG(IS_WIN)
   EXPECT_EQ(rv, net::ERR_FAILED);
 #else
-  EXPECT_NE(fd.ReleaseFD(), net::kInvalidSocket);
+  EXPECT_NE(socket.TakeSocket(), net::kInvalidSocket);
   EXPECT_EQ(rv, net::OK);
 #endif
 
diff --git a/content/browser/preloading/prerender/prerender_browsertest.cc b/content/browser/preloading/prerender/prerender_browsertest.cc
index d24c5db4..9c6c6ff 100644
--- a/content/browser/preloading/prerender/prerender_browsertest.cc
+++ b/content/browser/preloading/prerender/prerender_browsertest.cc
@@ -117,18 +117,15 @@
 
 enum class BackForwardCacheType {
   kDisabled,
-  kEnabledCrossSiteOnly,
-  kEnabledWithSameSite,
+  kEnabled,
 };
 
 std::string ToString(const testing::TestParamInfo<BackForwardCacheType>& info) {
   switch (info.param) {
     case BackForwardCacheType::kDisabled:
       return "Disabled";
-    case BackForwardCacheType::kEnabledCrossSiteOnly:
+    case BackForwardCacheType::kEnabled:
       return "Enabled";
-    case BackForwardCacheType::kEnabledWithSameSite:
-      return "EnabledWithSameSite";
   }
 }
 
@@ -4788,7 +4785,7 @@
  public:
   PrerenderBackForwardCacheBrowserTest() {
     feature_list_.InitWithFeaturesAndParameters(
-        {{features::kBackForwardCache, {{"enable_same_site", "true"}}},
+        {{features::kBackForwardCache, {}},
          {kBackForwardCacheNoTimeEviction, {}}},
         // Allow BackForwardCache for all devices regardless of their memory.
         {features::kBackForwardCacheMemoryControls});
@@ -5009,12 +5006,7 @@
       case BackForwardCacheType::kDisabled:
         feature_list_.InitAndDisableFeature(features::kBackForwardCache);
         break;
-      case BackForwardCacheType::kEnabledCrossSiteOnly:
-        feature_params["enable_same_site"] = "false";
-        feature_list_.InitWithFeaturesAndParameters(
-            {{features::kBackForwardCache, feature_params}}, disabled_features);
-        break;
-      case BackForwardCacheType::kEnabledWithSameSite:
+      case BackForwardCacheType::kEnabled:
         feature_list_.InitWithFeaturesAndParameters(
             {{features::kBackForwardCache, feature_params}}, disabled_features);
         break;
@@ -5025,13 +5017,11 @@
   base::test::ScopedFeatureList feature_list_;
 };
 
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    PrerenderWithBackForwardCacheBrowserTest,
-    testing::Values(BackForwardCacheType::kDisabled,
-                    BackForwardCacheType::kEnabledCrossSiteOnly,
-                    BackForwardCacheType::kEnabledWithSameSite),
-    ToString);
+INSTANTIATE_TEST_SUITE_P(All,
+                         PrerenderWithBackForwardCacheBrowserTest,
+                         testing::Values(BackForwardCacheType::kDisabled,
+                                         BackForwardCacheType::kEnabled),
+                         ToString);
 
 // Tests that history navigation works after activation. This runs with variaous
 // BFCache configurations that may modify behavior of history navigation.
@@ -5064,19 +5054,10 @@
       // not cached in the BFCache.
       delete_observer.WaitUntilDeleted();
       break;
-    case BackForwardCacheType::kEnabledCrossSiteOnly:
-      // Same-origin prerender activation should allow the initial page to be
-      // cached in the BFCache even if BFCache for same-site navigations is not
-      // enabled. This is because prerender activation always swaps
-      // BrowsingInstance, making the previous page cacheable, unlike regular
-      // same-origin navigation.
-      ASSERT_FALSE(IsSameSiteBackForwardCacheEnabled());
-      EXPECT_TRUE(initial_frame_host->IsInBackForwardCache());
-      break;
-    case BackForwardCacheType::kEnabledWithSameSite:
+    case BackForwardCacheType::kEnabled:
       // Same-origin prerender activation should allow the initial page to be
       // cached in the BFCache.
-      ASSERT_TRUE(IsSameSiteBackForwardCacheEnabled());
+      ASSERT_TRUE(IsBackForwardCacheEnabled());
       EXPECT_TRUE(initial_frame_host->IsInBackForwardCache());
       break;
   }
@@ -5093,8 +5074,7 @@
       // The frame host should be created again.
       EXPECT_NE(current_frame_host()->GetFrameToken(), initial_frame_token);
       break;
-    case BackForwardCacheType::kEnabledCrossSiteOnly:
-    case BackForwardCacheType::kEnabledWithSameSite:
+    case BackForwardCacheType::kEnabled:
       // The frame host should be restored.
       EXPECT_EQ(current_frame_host()->GetFrameToken(), initial_frame_token);
       EXPECT_FALSE(initial_frame_host->IsInBackForwardCache());
@@ -5103,7 +5083,7 @@
 }
 
 // Tests that a trigger page destroys a prerendered page when it navigates
-// forward and goes into the BFCache.
+// forward and goes into the back/forward cache.
 IN_PROC_BROWSER_TEST_P(PrerenderWithBackForwardCacheBrowserTest,
                        CancelOnAfterTriggerIsStoredInBackForwardCache_Forward) {
   const GURL kInitialUrl = GetUrl("/empty.html");
@@ -5121,28 +5101,23 @@
   // Navigate the initial page to a non-prerendered page.
   ASSERT_TRUE(NavigateToURL(shell(), kNextUrl));
 
-  // Check if the initial page is in the BFCache.
+  // Check if the initial page is in the back/forward cache.
   switch (GetParam()) {
     case BackForwardCacheType::kDisabled:
-      // The BFCache is disabled, so the initial page is not in the BFCache.
+      // The BFCache is disabled, so the initial page is not in the
+      // back/forward cache.
       ASSERT_FALSE(initial_frame_host->IsInBackForwardCache());
       break;
-    case BackForwardCacheType::kEnabledCrossSiteOnly:
-      // The BFCache is enabled but the same-site BFCache is disabled. The
-      // navigation was same-origin, so the initial page is not in the BFCache.
-      ASSERT_FALSE(IsSameSiteBackForwardCacheEnabled());
-      ASSERT_FALSE(initial_frame_host->IsInBackForwardCache());
-      break;
-    case BackForwardCacheType::kEnabledWithSameSite:
-      // The same-site BFCache is enabled, so the initial page is in the BFCache
-      // after the same-origin navigation.
-      ASSERT_TRUE(IsSameSiteBackForwardCacheEnabled());
+    case BackForwardCacheType::kEnabled:
+      // The back/forward cache is enabled, so the initial page is in the
+      // back/forward cache after the same-origin navigation.
+      ASSERT_TRUE(IsBackForwardCacheEnabled());
       ASSERT_TRUE(initial_frame_host->IsInBackForwardCache());
       break;
   }
 
   // The navigation should destroy the prerendered page regardless of if the
-  // initial page was in the BFCache.
+  // initial page was in the back/forward cache.
   prerender_observer.WaitForDestroyed();
   EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
   ExpectFinalStatusForSpeculationRule(
@@ -5174,28 +5149,23 @@
   navigation_observer.Wait();
   EXPECT_EQ(web_contents()->GetLastCommittedURL(), kInitialUrl);
 
-  // Check if the next page is in the BFCache.
+  // Check if the next page is in the back/forward cache.
   switch (GetParam()) {
     case BackForwardCacheType::kDisabled:
-      // The BFCache is disabled, so the next page is not in the BFCache.
+      // The back/forward cache is disabled, so the next page is not in the
+      // back/forward cache.
       ASSERT_FALSE(next_frame_host->IsInBackForwardCache());
       break;
-    case BackForwardCacheType::kEnabledCrossSiteOnly:
-      // The BFCache is enabled but the same-site BFCache is disabled. The back
-      // navigation was same-origin, so the next page is not in the BFCache.
-      ASSERT_FALSE(IsSameSiteBackForwardCacheEnabled());
-      ASSERT_FALSE(next_frame_host->IsInBackForwardCache());
-      break;
-    case BackForwardCacheType::kEnabledWithSameSite:
-      // The same-site BFCache is enabled, so the next page is in the BFCache
-      // after the same-origin back navigation.
-      ASSERT_TRUE(IsSameSiteBackForwardCacheEnabled());
+    case BackForwardCacheType::kEnabled:
+      // The back/forward cache is enabled, so the next page is in the
+      // back/forward cache after the same-origin back navigation.
+      ASSERT_TRUE(IsBackForwardCacheEnabled());
       ASSERT_TRUE(next_frame_host->IsInBackForwardCache());
       break;
   }
 
   // The navigation should destroy the prerendered page regardless of if the
-  // next page was in the BFCache.
+  // next page was in the back/forward cache.
   prerender_observer.WaitForDestroyed();
   EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
   ExpectFinalStatusForSpeculationRule(
diff --git a/content/browser/renderer_host/accessibility_tree_linkage_win_browsertest.cc b/content/browser/renderer_host/accessibility_tree_linkage_win_browsertest.cc
index 4186873..a3bdb0ee 100644
--- a/content/browser/renderer_host/accessibility_tree_linkage_win_browsertest.cc
+++ b/content/browser/renderer_host/accessibility_tree_linkage_win_browsertest.cc
@@ -93,7 +93,7 @@
   EXPECT_EQ(native_view_accessible, GetView()
                                         ->host()
                                         ->GetRootBrowserAccessibilityManager()
-                                        ->GetRoot()
+                                        ->GetBrowserAccessibilityRoot()
                                         ->GetNativeViewAccessible());
 
   // Used by LegacyRenderWidgetHostHWND to find the parent of the UIA fragment
diff --git a/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc b/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc
index 9ce6702..6e466724 100644
--- a/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc
+++ b/content/browser/renderer_host/back_forward_cache_can_store_document_result.cc
@@ -73,10 +73,6 @@
       return "BI not swapped - <webview> guest";
     case ShouldSwapBrowsingInstance::kNo_HasNotComittedAnyNavigation:
       return "BI not swapped - hasn't committed any navigation";
-    case ShouldSwapBrowsingInstance::
-        kNo_UnloadHandlerExistsOnSameSiteNavigation:
-      return "BI not swapped - unload handler exists and the navigation is "
-             "same-site";
     case ShouldSwapBrowsingInstance::kNo_NotPrimaryMainFrame:
       return "BI not swapped - not a primary main frame";
   }
diff --git a/content/browser/renderer_host/back_forward_cache_impl.cc b/content/browser/renderer_host/back_forward_cache_impl.cc
index 19e70fb..d948b03 100644
--- a/content/browser/renderer_host/back_forward_cache_impl.cc
+++ b/content/browser/renderer_host/back_forward_cache_impl.cc
@@ -1193,11 +1193,6 @@
 }
 
 // static
-bool BackForwardCache::IsSameSiteBackForwardCacheFeatureEnabled() {
-  return IsSameSiteBackForwardCacheEnabled();
-}
-
-// static
 void BackForwardCache::DisableForRenderFrameHost(
     RenderFrameHost* render_frame_host,
     BackForwardCache::DisabledReason reason) {
diff --git a/content/browser/renderer_host/back_forward_cache_metrics.cc b/content/browser/renderer_host/back_forward_cache_metrics.cc
index 90c0315..9ba9985 100644
--- a/content/browser/renderer_host/back_forward_cache_metrics.cc
+++ b/content/browser/renderer_host/back_forward_cache_metrics.cc
@@ -576,8 +576,6 @@
     case ShouldSwapBrowsingInstance::kNo_Reload:
     case ShouldSwapBrowsingInstance::kNo_Guest:
     case ShouldSwapBrowsingInstance::kNo_HasNotComittedAnyNavigation:
-    case ShouldSwapBrowsingInstance::
-        kNo_UnloadHandlerExistsOnSameSiteNavigation:
     case ShouldSwapBrowsingInstance::kNo_NotPrimaryMainFrame:
       return false;
     case ShouldSwapBrowsingInstance::kYes_ForceSwap:
diff --git a/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc b/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc
index 64a2f99..91438dc 100644
--- a/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc
+++ b/content/browser/renderer_host/back_forward_cache_metrics_browsertest.cc
@@ -141,11 +141,11 @@
     if (GetParam() == BackForwardCacheStatus::kEnabled) {
       // Enable BackForwardCache.
       feature_list_.InitWithFeaturesAndParameters(
-          {{features::kBackForwardCache, {{"enable_same_site", "true"}}},
+          {{features::kBackForwardCache, {}},
            {kBackForwardCacheNoTimeEviction, {}}},
           // Allow BackForwardCache for all devices regardless of their memory.
           {features::kBackForwardCacheMemoryControls});
-      DCHECK(IsSameSiteBackForwardCacheEnabled());
+      DCHECK(IsBackForwardCacheEnabled());
     } else {
       feature_list_.InitAndDisableFeature(features::kBackForwardCache);
       DCHECK(!IsBackForwardCacheEnabled());
diff --git a/content/browser/renderer_host/document_service_browsertest.cc b/content/browser/renderer_host/document_service_browsertest.cc
index 5e54afe..3baf1f9 100644
--- a/content/browser/renderer_host/document_service_browsertest.cc
+++ b/content/browser/renderer_host/document_service_browsertest.cc
@@ -100,8 +100,7 @@
  public:
   DocumentServiceBFCacheBrowserTest() {
     std::vector<base::test::ScopedFeatureList::FeatureAndParams>
-        additional_features = {
-            {features::kBackForwardCache, {{"enable_same_site", "true"}}}};
+        additional_features = {{features::kBackForwardCache, {}}};
     feature_list_.InitWithFeaturesAndParameters(
         DefaultEnabledBackForwardCacheParametersForTests(additional_features),
         DefaultDisabledBackForwardCacheParametersForTests());
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.cc b/content/browser/renderer_host/legacy_render_widget_host_win.cc
index 4a894ef..c60db9e 100644
--- a/content/browser/renderer_host/legacy_render_widget_host_win.cc
+++ b/content/browser/renderer_host/legacy_render_widget_host_win.cc
@@ -562,10 +562,10 @@
   BrowserAccessibilityManagerWin* manager =
       static_cast<BrowserAccessibilityManagerWin*>(
           rwhi->GetOrCreateRootBrowserAccessibilityManager());
-  if (!manager || !manager->GetRoot())
+  if (!manager || !manager->GetBrowserAccessibilityRoot())
     return nullptr;
 
-  BrowserAccessibility* root_node = manager->GetRoot();
+  BrowserAccessibility* root_node = manager->GetBrowserAccessibilityRoot();
 
   // Popups with HTML content (such as <input type="date">) will create a new
   // HWND with its own fragment root, but will also inject accessible nodes into
diff --git a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
index 89a0481..6f4e54a 100644
--- a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
+++ b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
@@ -160,8 +160,7 @@
                                  bool enable_back_forward_cache) {
   if (enable_back_forward_cache) {
     std::vector<base::test::ScopedFeatureList::FeatureAndParams> features;
-    features.push_back(
-        {features::kBackForwardCache, {{"enable_same_site", "true"}}});
+    features.push_back({features::kBackForwardCache, {}});
     features.push_back({kBackForwardCacheNoTimeEviction, {}});
     features.push_back({features::kBackForwardCacheMemoryControls, {}});
     feature_list->InitWithFeaturesAndParameters(features, {});
diff --git a/content/browser/renderer_host/navigation_controller_impl_unittest.cc b/content/browser/renderer_host/navigation_controller_impl_unittest.cc
index 20ebf96..560c829 100644
--- a/content/browser/renderer_host/navigation_controller_impl_unittest.cc
+++ b/content/browser/renderer_host/navigation_controller_impl_unittest.cc
@@ -418,10 +418,9 @@
   const int test_offsets[NUM_TESTS] = {
       GO_TO_MIDDLE_PAGE, GO_FORWARDS, GO_BACKWARDS, GO_TO_BEGINNING, GO_TO_END};
 
-  if (IsSameSiteBackForwardCacheEnabled()) {
-    // The |navigation_entry_committed_counter_| checks below currently fail on
-    // the linux-bfcache-rel bot with same-site bfcache enabled, so return
-    // early.
+  if (IsBackForwardCacheEnabled()) {
+    // The `navigation_entry_committed_counter_` checks below currently fail on
+    // the linux-bfcache-rel bot with bfcache enabled, so return early.
     // TODO(https://crbug.com/1232883): re-enable this test.
     return;
   }
@@ -3717,8 +3716,8 @@
   main_test_rfh()->GoToEntryAtOffset(120, false);  // Out of bounds.
   EXPECT_EQ(-1, controller.GetPendingEntryIndex());
   // TODO(https://crbug.com/1232883): Figure out why HasNavigationRequest() is
-  // true when same-site back/forward cache is enabled.
-  EXPECT_EQ(IsSameSiteBackForwardCacheEnabled(), HasNavigationRequest());
+  // true when back/forward cache is enabled.
+  EXPECT_EQ(IsBackForwardCacheEnabled(), HasNavigationRequest());
 }
 
 // Test call to PruneAllButLastCommitted for the only entry.
@@ -3739,9 +3738,9 @@
 
 // Test call to PruneAllButLastCommitted for first entry.
 TEST_F(NavigationControllerTest, PruneAllButLastCommittedForFirst) {
-  if (IsSameSiteBackForwardCacheEnabled()) {
+  if (IsBackForwardCacheEnabled()) {
     // The PruneAllButLastCommitted() call below currently DCHECKS on the
-    // linux-bfcache-rel bot with same-site bfcache enabled because
+    // linux-bfcache-rel bot with back/forward cache enabled because
     // CanPruneAllButLastCommitted() returns false, so just return early here.
     // TODO(https://crbug.com/1232883): Figure out why the DCHECK happened and
     // re-enable this test.
diff --git a/content/browser/renderer_host/page_impl_browsertest.cc b/content/browser/renderer_host/page_impl_browsertest.cc
index f63e400a..3621d9fa 100644
--- a/content/browser/renderer_host/page_impl_browsertest.cc
+++ b/content/browser/renderer_host/page_impl_browsertest.cc
@@ -426,8 +426,8 @@
             main_rfh_a1.get() != main_rfh_a2.get());
   PageImpl& page_a2 = main_rfh_a2.get()->GetPage();
 
-  if (IsSameSiteBackForwardCacheEnabled()) {
-    // 3a) With same-site bfcache enabled, both Page objects should be in
+  if (IsBackForwardCacheEnabled()) {
+    // 3a) With back/forward cache enabled, both Page objects should be in
     // existence at the same time.
     EXPECT_TRUE(page_a1);
     EXPECT_NE(page_a1.get(), &page_a2);
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 36f7376..94e3225 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -6679,24 +6679,6 @@
   }
 }
 
-bool RenderFrameHostImpl::UnloadHandlerExistsInSameSiteInstanceSubtree() {
-  DCHECK(!GetParent());
-  bool result = false;
-  ForEachRenderFrameHostWithAction(
-      [this, &result](RenderFrameHostImpl* rfhi) -> FrameIterationAction {
-        // If we aren't from the same page ignore unload handlers.
-        if (&rfhi->GetPage() != &GetPage())
-          return FrameIterationAction::kSkipChildren;
-        if (rfhi->GetSiteInstance() == GetSiteInstance() &&
-            rfhi->has_unload_handler_) {
-          result = true;
-          return FrameIterationAction::kStop;
-        }
-        return FrameIterationAction::kContinue;
-      });
-  return result;
-}
-
 void RenderFrameHostImpl::DidDispatchDOMContentLoadedEvent() {
   document_associated_data_->dom_content_loaded = true;
 
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h
index 27116b4..41c7079 100644
--- a/content/browser/renderer_host/render_frame_host_impl.h
+++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -1953,11 +1953,6 @@
   void DidCommitPageActivation(NavigationRequest* committing_navigation_request,
                                mojom::DidCommitProvisionalLoadParamsPtr params);
 
-  // Whether there's any "unload" event handlers registered on this
-  // RenderFrameHost or subframes that share the same SiteInstance as this
-  // RenderFrameHost.
-  bool UnloadHandlerExistsInSameSiteInstanceSubtree();
-
   bool has_unload_handler() const { return has_unload_handler_; }
 
   bool has_committed_any_navigation() const {
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc
index cc5ada1..6edf115 100644
--- a/content/browser/renderer_host/render_frame_host_manager.cc
+++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -247,10 +247,6 @@
     case ShouldSwapBrowsingInstance::kNo_HasNotComittedAnyNavigation:
       return ProtoLevel::
           SHOULD_SWAP_BROWSING_INSTANCE_NO_HAS_NOT_COMMITTED_ANY_NAVIGATION;
-    case ShouldSwapBrowsingInstance::
-        kNo_UnloadHandlerExistsOnSameSiteNavigation:
-      return ProtoLevel::
-          SHOULD_SWAP_BROWSING_INSTANCE_NO_UNLOAD_HANDLER_EXISTS_ON_SAME_SITE_NAVIGATION;
     case ShouldSwapBrowsingInstance::kNo_NotPrimaryMainFrame:
       return ProtoLevel::
           SHOULD_SWAP_BROWSING_INSTANCE_NO_NOT_PRIMARY_MAIN_FRAME;
@@ -1821,27 +1817,14 @@
       render_frame_host_->IsNavigationSameSite(destination_url_info);
   if (is_same_site) {
     // If it's a same-site navigation, we should only swap if same-site
-    // ProactivelySwapBrowsingInstance is enabled, or if same-site
-    // BackForwardCache is enabled and the current RFH is eligible for
-    // back-forward cache (checked later).
+    // ProactivelySwapBrowsingInstance is enabled, or if BackForwardCache
+    // is enabled and the current RFH is eligible for back/forward cache
+    // (checked later).
     if (IsProactivelySwapBrowsingInstanceOnSameSiteNavigationEnabled()) {
       return ShouldSwapBrowsingInstance::kYes_SameSiteProactiveSwap;
     }
-    if (!IsSameSiteBackForwardCacheEnabled())
+    if (!IsBackForwardCacheEnabled())
       return ShouldSwapBrowsingInstance::kNo_SameSiteNavigation;
-    // We should not do a proactive BrowsingInstance swap on pages with unload
-    // handlers if we explicitly specified to do so to avoid exposing a
-    // web-observable behavior change (unload handlers running after a same-site
-    // navigation). Note that we're only checking for unload handlers in frames
-    // that share the same SiteInstance as the main frame, because unload
-    // handlers that exist in cross-SiteInstance subframes will be dispatched
-    // after we committed the navigation, regardless of our decision to swap
-    // BrowsingInstances or not.
-    if (ShouldSkipSameSiteBackForwardCacheForPageWithUnload() &&
-        render_frame_host_->UnloadHandlerExistsInSameSiteInstanceSubtree()) {
-      return ShouldSwapBrowsingInstance::
-          kNo_UnloadHandlerExistsOnSameSiteNavigation;
-    }
   }
 
   if (IsProactivelySwapBrowsingInstanceEnabled())
@@ -2057,13 +2040,13 @@
     reuse_current_process_if_possible = true;
   }
 
-  // 2) When BackForwardCache is enabled on same-site navigations.
+  // 2) When BackForwardCache is enabled.
   // Note 1: When BackForwardCache is disabled, we typically reuse processes on
   // same-site navigations. This follows that behavior.
   // Note 2: This doesn't cover cross-site navigations. Cross-site process-reuse
   // is being experimented independently and is covered in path #1 above.
   // See crbug.com/1122974 for further details.
-  if (IsSameSiteBackForwardCacheEnabled() && is_same_site_proactive_swap) {
+  if (IsBackForwardCacheEnabled() && is_same_site_proactive_swap) {
     reuse_current_process_if_possible = true;
   }
 
@@ -2077,7 +2060,7 @@
       !new_instance->IsRelatedSiteInstance(current_instance);
   bool is_same_site_proactive_swap_enabled =
       IsProactivelySwapBrowsingInstanceOnSameSiteNavigationEnabled() ||
-      IsSameSiteBackForwardCacheEnabled();
+      IsBackForwardCacheEnabled();
   if (is_same_site_proactive_swap_enabled && is_history_navigation &&
       swapped_browsing_instance &&
       render_frame_host_->IsNavigationSameSite(dest_url_info)) {
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 780952908..e5218977 100644
--- a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
@@ -4490,7 +4490,7 @@
   // SiteInstance, unless we do a proactive BrowsingInstance swap due to
   // back/forward cache.
   EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL)));
-  if (IsSameSiteBackForwardCacheEnabled()) {
+  if (IsBackForwardCacheEnabled()) {
     site_instance = shell()->web_contents()->GetSiteInstance();
   } else {
     EXPECT_EQ(site_instance, shell()->web_contents()->GetSiteInstance());
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 9d1301a5..24a1e12 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -439,13 +439,14 @@
   BrowserAccessibilityManager* manager =
       host()->GetOrCreateRootBrowserAccessibilityManager();
   if (manager)
-    return ToBrowserAccessibilityWin(manager->GetRoot())->GetCOM();
+    return ToBrowserAccessibilityWin(manager->GetBrowserAccessibilityRoot())
+        ->GetCOM();
 
 #elif BUILDFLAG(IS_LINUX)
   BrowserAccessibilityManager* manager =
       host()->GetOrCreateRootBrowserAccessibilityManager();
-  if (manager && manager->GetRoot())
-    return manager->GetRoot()->GetNativeViewAccessible();
+  if (manager && manager->GetBrowserAccessibilityRoot())
+    return manager->GetBrowserAccessibilityRoot()->GetNativeViewAccessible();
 #endif
 
   NOTIMPLEMENTED_LOG_ONCE();
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_vk_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_aura_vk_browsertest.cc
index 47747d7..7ddb0e12 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_vk_browsertest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_vk_browsertest.cc
@@ -153,7 +153,7 @@
 
   BrowserAccessibility* FindNode(ax::mojom::Role role,
                                  const std::string& name_or_value) {
-    BrowserAccessibility* root = GetManager()->GetRoot();
+    BrowserAccessibility* root = GetManager()->GetBrowserAccessibilityRoot();
     CHECK(root);
     return FindNodeInSubtree(*root, role, name_or_value);
   }
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index d460e05..1773eb6 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -1597,7 +1597,7 @@
 
 id RenderWidgetHostViewMac::GetRootBrowserAccessibilityElement() {
   if (auto* manager = host()->GetRootBrowserAccessibilityManager())
-    return manager->GetRoot()->GetNativeViewAccessible();
+    return manager->GetBrowserAccessibilityRoot()->GetNativeViewAccessible();
   return nil;
 }
 
diff --git a/content/browser/renderer_host/should_swap_browsing_instance.h b/content/browser/renderer_host/should_swap_browsing_instance.h
index 49309f7..466693e0 100644
--- a/content/browser/renderer_host/should_swap_browsing_instance.h
+++ b/content/browser/renderer_host/should_swap_browsing_instance.h
@@ -36,7 +36,9 @@
   kNo_Reload = 17,
   kNo_Guest = 18,
   kNo_HasNotComittedAnyNavigation = 19,
-  kNo_UnloadHandlerExistsOnSameSiteNavigation = 20,
+  // 20: kNo_UnloadHandlerExistsOnSameSiteNavigation was removed as it's not
+  // triggering BrowsingInstance swap anymore. See
+  // https://groups.google.com/a/google.com/g/chrome-bfcache/c/L-ZreZDY4n0
   kNo_NotPrimaryMainFrame = 21,
 
   kMaxValue = kNo_NotPrimaryMainFrame
diff --git a/content/browser/renderer_host/unassigned_site_instance_browsertest.cc b/content/browser/renderer_host/unassigned_site_instance_browsertest.cc
index e9bb13c4..51694044 100644
--- a/content/browser/renderer_host/unassigned_site_instance_browsertest.cc
+++ b/content/browser/renderer_host/unassigned_site_instance_browsertest.cc
@@ -96,8 +96,7 @@
                                  bool enable_back_forward_cache) {
   if (enable_back_forward_cache) {
     std::vector<base::test::ScopedFeatureList::FeatureAndParams> features;
-    features.push_back(
-        {features::kBackForwardCache, {{"enable_same_site", "true"}}});
+    features.push_back({features::kBackForwardCache, {}});
     features.push_back({kBackForwardCacheNoTimeEviction, {}});
     features.push_back({features::kBackForwardCacheMemoryControls, {}});
     feature_list->InitWithFeaturesAndParameters(features, {});
@@ -268,12 +267,12 @@
   scoped_refptr<SiteInstanceImpl> unassigned_si =
       web_contents()->GetPrimaryMainFrame()->GetSiteInstance();
 
-  if (!BackForwardCache::IsSameSiteBackForwardCacheFeatureEnabled()) {
+  if (!BackForwardCache::IsBackForwardCacheFeatureEnabled()) {
     // Normally we reuse the SiteInstance.
     EXPECT_TRUE(unassigned_si->HasSite());
     EXPECT_EQ(unassigned_si, initial_si);
   } else {
-    // With same-site BFCache, we will swap browsing instance for same-site
+    // With back/forward cache, we will swap browsing instance for same-site
     // navigations, not reusing the previous SiteInstance.
     EXPECT_FALSE(unassigned_si->HasSite());
     EXPECT_FALSE(unassigned_si->IsRelatedSiteInstance(initial_si.get()));
@@ -293,12 +292,12 @@
   scoped_refptr<SiteInstanceImpl> unassigned_si =
       web_contents()->GetPrimaryMainFrame()->GetSiteInstance();
 
-  if (!BackForwardCache::IsSameSiteBackForwardCacheFeatureEnabled()) {
+  if (!BackForwardCache::IsBackForwardCacheFeatureEnabled()) {
     // Normally we reuse the SiteInstance.
     EXPECT_TRUE(unassigned_si->HasSite());
     EXPECT_EQ(unassigned_si, initial_si);
   } else {
-    // With same-site BFCache, we will swap browsing instance for same-site
+    // With back/forward cache, we will swap browsing instance for same-site
     // navigations, not reusing the previous SiteInstance.
     EXPECT_FALSE(unassigned_si->HasSite());
     EXPECT_FALSE(unassigned_si->IsRelatedSiteInstance(initial_si.get()));
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc
index f2b6570..0118fe92 100644
--- a/content/browser/service_worker/service_worker_browsertest.cc
+++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -3504,10 +3504,7 @@
     feature_list_.InitWithFeaturesAndParameters(
         {{{features::kBackForwardCache,
            {{"TimeToLiveInBackForwardCacheInSeconds", "3600"},
-            {"enable_same_site", "true"},
-            {"process_binding_strength", "NORMAL"}}}}
-
-        },
+            {"process_binding_strength", "NORMAL"}}}}},
         {features::kBackForwardCacheMemoryControls});
   }
 
@@ -3749,7 +3746,7 @@
  protected:
   ServiceWorkerBackForwardCacheBrowserTest() {
     feature_list_.InitAndEnableFeatureWithParameters(
-        features::kBackForwardCache, {{"enable_same_site", "true"}});
+        features::kBackForwardCache, {});
   }
 
   RenderFrameHostImpl* current_frame_host() {
diff --git a/content/browser/session_history_browsertest.cc b/content/browser/session_history_browsertest.cc
index c3c22539..a7f9feb 100644
--- a/content/browser/session_history_browsertest.cc
+++ b/content/browser/session_history_browsertest.cc
@@ -341,8 +341,7 @@
   // set to "form". If not, the page will be reloaded from scratch, setting the
   // title to "bot1" again.
   GoBack();
-  EXPECT_EQ(IsSameSiteBackForwardCacheEnabled() ? "form" : "bot1",
-            GetTabTitle());
+  EXPECT_EQ(IsBackForwardCacheEnabled() ? "form" : "bot1", GetTabTitle());
   EXPECT_EQ(frames, GetTabURL());
 
   // Submit the form in the "fbot" iframe again . This submits to /echotitle
diff --git a/content/browser/shared_storage/shared_storage_browsertest.cc b/content/browser/shared_storage/shared_storage_browsertest.cc
index ef1aa00..c66946a 100644
--- a/content/browser/shared_storage/shared_storage_browsertest.cc
+++ b/content/browser/shared_storage/shared_storage_browsertest.cc
@@ -71,6 +71,9 @@
 const char kTimingUsefulResourceHistogram[] =
     "Storage.SharedStorage.Worklet.Timing.UsefulResourceDuration";
 
+const char kTimingRunExecutedInWorkletHistogram[] =
+    "Storage.SharedStorage.Document.Timing.Run.ExecutedInWorklet";
+
 const char kTimingSelectUrlExecutedInWorkletHistogram[] =
     "Storage.SharedStorage.Document.Timing.SelectURL.ExecutedInWorklet";
 
@@ -197,23 +200,25 @@
   }
 
   void OnRunOperationOnWorkletFinished(
+      base::TimeTicks start_time,
       bool success,
       const std::string& error_message) override {
-    OnRunOperationOnWorkletFinishedHelper(success, error_message,
+    OnRunOperationOnWorkletFinishedHelper(start_time, success, error_message,
                                           /*initial_message=*/true);
   }
 
-  void OnRunOperationOnWorkletFinishedHelper(bool success,
+  void OnRunOperationOnWorkletFinishedHelper(base::TimeTicks start_time,
+                                             bool success,
                                              const std::string& error_message,
                                              bool initial_message) {
     if (should_defer_worklet_messages_ && initial_message) {
       pending_worklet_messages_.push_back(base::BindOnce(
           &TestSharedStorageWorkletHost::OnRunOperationOnWorkletFinishedHelper,
-          weak_ptr_factory_.GetWeakPtr(), success, error_message,
+          weak_ptr_factory_.GetWeakPtr(), start_time, success, error_message,
           /*initial_message=*/false));
     } else {
-      SharedStorageWorkletHost::OnRunOperationOnWorkletFinished(success,
-                                                                error_message);
+      SharedStorageWorkletHost::OnRunOperationOnWorkletFinished(
+          start_time, success, error_message);
     }
 
     if (initial_message)
@@ -678,6 +683,9 @@
             base::UTF16ToUTF8(console_observer.messages()[3].message));
   EXPECT_EQ("Finish executing 'test-operation'",
             base::UTF16ToUTF8(console_observer.messages()[4].message));
+
+  WaitForHistograms({kTimingRunExecutedInWorkletHistogram});
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest,
@@ -725,7 +733,8 @@
   // Navigate again to record histograms.
   EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL)));
   WaitForHistograms({kDestroyedStatusHistogram, kTimingUsefulResourceHistogram,
-                     kErrorTypeHistogram});
+                     kErrorTypeHistogram,
+                     kTimingRunExecutedInWorkletHistogram});
 
   histogram_tester_.ExpectUniqueSample(
       kDestroyedStatusHistogram,
@@ -734,6 +743,7 @@
       kErrorTypeHistogram,
       blink::SharedStorageWorkletErrorType::kRunNonWebVisible, 1);
   histogram_tester_.ExpectTotalCount(kTimingUsefulResourceHistogram, 1);
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest,
@@ -759,6 +769,8 @@
                   "              sharedStorage.run(\n"
                   "                            ^^^^^\n"),
       result.error);
+
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 0);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest,
@@ -804,6 +816,9 @@
             base::UTF16ToUTF8(console_observer.messages()[3].message));
   EXPECT_EQ(blink::mojom::ConsoleMessageLevel::kError,
             console_observer.messages()[3].log_level);
+
+  WaitForHistograms({kTimingRunExecutedInWorkletHistogram});
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest, WorkletDestroyed) {
@@ -1073,7 +1088,8 @@
   EXPECT_EQ(2u, console_observer.messages().size());
 
   WaitForHistograms({kDestroyedStatusHistogram, kTimingUsefulResourceHistogram,
-                     kTimingKeepAliveDurationHistogram});
+                     kTimingKeepAliveDurationHistogram,
+                     kTimingRunExecutedInWorkletHistogram});
 
   histogram_tester_.ExpectUniqueSample(
       kDestroyedStatusHistogram,
@@ -1082,6 +1098,7 @@
       1);
   histogram_tester_.ExpectTotalCount(kTimingKeepAliveDurationHistogram, 1);
   histogram_tester_.ExpectTotalCount(kTimingUsefulResourceHistogram, 1);
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest, KeepAlive_SubframeWorklet) {
@@ -1449,6 +1466,9 @@
   EXPECT_EQ("value3value333",
             base::UTF16ToUTF8(console_observer.messages()[3].message));
   EXPECT_EQ("4", base::UTF16ToUTF8(console_observer.messages()[4].message));
+
+  WaitForHistograms({kTimingRunExecutedInWorkletHistogram});
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest, DeleteOperationInDocument) {
@@ -1475,6 +1495,9 @@
             base::UTF16ToUTF8(console_observer.messages()[1].message));
   EXPECT_EQ(blink::mojom::ConsoleMessageLevel::kInfo,
             console_observer.messages()[1].log_level);
+
+  WaitForHistograms({kTimingRunExecutedInWorkletHistogram});
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest, ClearOperationInDocument) {
@@ -1494,6 +1517,9 @@
 
   EXPECT_EQ(1u, console_observer.messages().size());
   EXPECT_EQ("0", base::UTF16ToUTF8(console_observer.messages()[0].message));
+
+  WaitForHistograms({kTimingRunExecutedInWorkletHistogram});
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest, SetAppendOperationInWorklet) {
@@ -1531,6 +1557,9 @@
   EXPECT_EQ("value3value333",
             base::UTF16ToUTF8(console_observer.messages()[3].message));
   EXPECT_EQ("4", base::UTF16ToUTF8(console_observer.messages()[4].message));
+
+  WaitForHistograms({kTimingRunExecutedInWorkletHistogram});
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest,
@@ -1552,6 +1581,9 @@
             base::UTF16ToUTF8(console_observer.messages()[0].message));
   EXPECT_EQ(blink::mojom::ConsoleMessageLevel::kError,
             console_observer.messages()[0].log_level);
+
+  WaitForHistograms({kTimingRunExecutedInWorkletHistogram});
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest, DeleteOperationInWorklet) {
@@ -1586,6 +1618,9 @@
             console_observer.messages()[2].log_level);
   EXPECT_EQ(blink::mojom::ConsoleMessageLevel::kInfo,
             console_observer.messages()[3].log_level);
+
+  WaitForHistograms({kTimingRunExecutedInWorkletHistogram});
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest, ClearOperationInWorklet) {
@@ -1609,6 +1644,9 @@
   EXPECT_EQ("value0",
             base::UTF16ToUTF8(console_observer.messages()[1].message));
   EXPECT_EQ("0", base::UTF16ToUTF8(console_observer.messages()[2].message));
+
+  WaitForHistograms({kTimingRunExecutedInWorkletHistogram});
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest,
@@ -1631,6 +1669,9 @@
 
   EXPECT_EQ(1u, console_observer.messages().size());
   EXPECT_EQ("1", base::UTF16ToUTF8(console_observer.messages()[0].message));
+
+  WaitForHistograms({kTimingRunExecutedInWorkletHistogram});
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest,
@@ -1653,6 +1694,9 @@
 
   EXPECT_EQ(1u, console_observer.messages().size());
   EXPECT_EQ("0", base::UTF16ToUTF8(console_observer.messages()[0].message));
+
+  WaitForHistograms({kTimingRunExecutedInWorkletHistogram});
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest, KeysAndEntriesOperation) {
@@ -1686,6 +1730,9 @@
             base::UTF16ToUTF8(console_observer.messages()[4].message));
   EXPECT_EQ("key2;value2",
             base::UTF16ToUTF8(console_observer.messages()[5].message));
+
+  WaitForHistograms({kTimingRunExecutedInWorkletHistogram});
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 IN_PROC_BROWSER_TEST_F(SharedStorageBrowserTest,
@@ -1721,6 +1768,9 @@
     EXPECT_EQ(base::StrCat({"key", zero_padded_i, ";value", zero_padded_i}),
               base::UTF16ToUTF8(console_observer.messages()[i + 150].message));
   }
+
+  WaitForHistograms({kTimingRunExecutedInWorkletHistogram});
+  histogram_tester_.ExpectTotalCount(kTimingRunExecutedInWorkletHistogram, 1);
 }
 
 class SharedStorageFencedFrameInteractionBrowserTest
@@ -1827,7 +1877,7 @@
     std::string urn_uuid =
         EvalJs(iframe, kSelectFrom8URLsScript).ExtractString();
 
-    // There are 2 "worklet operations": `addModule()` and `run()`.
+    // There are 2 "worklet operations": `addModule()` and `selectURL()`.
     test_worklet_host_manager()
         .GetAttachedWorkletHostForOrigin(origin)
         ->WaitForWorkletResponsesCount(2);
diff --git a/content/browser/shared_storage/shared_storage_worklet_host.cc b/content/browser/shared_storage/shared_storage_worklet_host.cc
index d6221f70..60dfbf3 100644
--- a/content/browser/shared_storage/shared_storage_worklet_host.cc
+++ b/content/browser/shared_storage/shared_storage_worklet_host.cc
@@ -182,6 +182,7 @@
 
   if (add_module_state_ != AddModuleState::kInitiated) {
     OnRunOperationOnWorkletFinished(
+        base::TimeTicks::Now(),
         /*success=*/false,
         /*error_message=*/
         "sharedStorage.worklet.addModule() has to be called before "
@@ -192,7 +193,7 @@
   GetAndConnectToSharedStorageWorkletService()->RunOperation(
       name, serialized_data,
       base::BindOnce(&SharedStorageWorkletHost::OnRunOperationOnWorkletFinished,
-                     weak_ptr_factory_.GetWeakPtr()));
+                     weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now()));
 }
 
 void SharedStorageWorkletHost::RunURLSelectionOperationOnWorklet(
@@ -546,6 +547,7 @@
 }
 
 void SharedStorageWorkletHost::OnRunOperationOnWorkletFinished(
+    base::TimeTicks start_time,
     bool success,
     const std::string& error_message) {
   if (!success) {
@@ -560,6 +562,9 @@
     }
   }
 
+  base::UmaHistogramLongTimes(
+      "Storage.SharedStorage.Document.Timing.Run.ExecutedInWorklet",
+      base::TimeTicks::Now() - start_time);
   DecrementPendingOperationsCount();
 }
 
diff --git a/content/browser/shared_storage/shared_storage_worklet_host.h b/content/browser/shared_storage/shared_storage_worklet_host.h
index 5f9e77e..bf1f33cf 100644
--- a/content/browser/shared_storage/shared_storage_worklet_host.h
+++ b/content/browser/shared_storage/shared_storage_worklet_host.h
@@ -122,6 +122,7 @@
       const std::string& error_message);
 
   virtual void OnRunOperationOnWorkletFinished(
+      base::TimeTicks start_time,
       bool success,
       const std::string& error_message);
 
diff --git a/content/browser/speech/speech_recognizer_impl.cc b/content/browser/speech/speech_recognizer_impl.cc
index 43a3f00e..35538f1 100644
--- a/content/browser/speech/speech_recognizer_impl.cc
+++ b/content/browser/speech/speech_recognizer_impl.cc
@@ -22,6 +22,7 @@
 #include "content/public/browser/speech_recognition_event_listener.h"
 #include "media/audio/audio_system.h"
 #include "media/base/audio_converter.h"
+#include "media/base/audio_parameters.h"
 #include "media/mojo/mojom/audio_logging.mojom.h"
 #include "services/audio/public/cpp/device_factory.h"
 
@@ -584,7 +585,8 @@
   // Hard coded, WebSpeech specific parameters are utilized here.
   int frames_per_buffer = (kAudioSampleRate * chunk_duration_ms) / 1000;
   AudioParameters output_parameters =
-      AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, kChannelLayout,
+      AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                      media::ChannelLayoutConfig::FromLayout<kChannelLayout>(),
                       kAudioSampleRate, frames_per_buffer);
   DVLOG(1) << "SRI::output_parameters: "
            << output_parameters.AsHumanReadableString();
diff --git a/content/browser/utility_process_host_browsertest.cc b/content/browser/utility_process_host_browsertest.cc
index 42d802a0..0b71dae 100644
--- a/content/browser/utility_process_host_browsertest.cc
+++ b/content/browser/utility_process_host_browsertest.cc
@@ -183,7 +183,10 @@
   RunUtilityProcess(/*elevated=*/false, /*crash=*/false, /*fail_launch=*/false);
 }
 
-IN_PROC_BROWSER_TEST_F(UtilityProcessHostBrowserTest, LaunchProcessAndCrash) {
+// Disabled because it crashes on android-arm64-tests:
+// https://crbug.com/1358585.
+IN_PROC_BROWSER_TEST_F(UtilityProcessHostBrowserTest,
+                       DISABLED_LaunchProcessAndCrash) {
   RunUtilityProcess(/*elevated=*/false, /*crash=*/true, /*fail_launch=*/false);
 }
 
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 2ece7e1..29e19a8 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4496,7 +4496,7 @@
                : AXInspectFactory::CreatePlatformFormatter();
 
   formatter->SetPropertyFilters(property_filters);
-  return formatter->Format(ax_mgr->GetRoot());
+  return formatter->Format(ax_mgr->GetBrowserAccessibilityRoot());
 }
 
 void WebContentsImpl::RecordAccessibilityEvents(
@@ -4513,7 +4513,8 @@
     DCHECK(ax_mgr);
     base::ProcessId pid = base::Process::Current().Pid();
     gfx::AcceleratedWidget widget =
-        ax_mgr->GetRoot()->GetTargetForNativeAccessibilityEvent();
+        ax_mgr->GetBrowserAccessibilityRoot()
+            ->GetTargetForNativeAccessibilityEvent();
     event_recorder_ = content::AXInspectFactory::CreatePlatformRecorder(
         ax_mgr, pid, ui::AXTreeSelector(widget));
     event_recorder_->ListenToEvents(*callback);
diff --git a/content/browser/webauth/webauth_browsertest.cc b/content/browser/webauth/webauth_browsertest.cc
index 5bc3d681..5f797358 100644
--- a/content/browser/webauth/webauth_browsertest.cc
+++ b/content/browser/webauth/webauth_browsertest.cc
@@ -121,7 +121,9 @@
     "suffix of, nor equal to the current domain.";
 
 constexpr char kAbortErrorMessage[] =
-    "webauth: AbortError: Request has been aborted.";
+    "webauth: AbortError: signal is aborted without reason";
+
+constexpr char kAbortReasonMessage[] = "webauth: Error";
 
 constexpr char kGetPermissionsPolicyMissingMessage[] =
     "webauth: NotAllowedError: The 'publickey-credentials-get' feature is "
@@ -992,6 +994,26 @@
 }
 
 // Tests that when navigator.credentials.create() is called with abort
+// signal's aborted flag set with reason before sending request,
+// we get an error from the reason.
+IN_PROC_BROWSER_TEST_F(
+    WebAuthJavascriptClientBrowserTest,
+    CreatePublicKeyCredentialWithAbortSetWithReasonBeforeCreate) {
+  CreateParameters parameters;
+  parameters.signal = "authAbortSignal";
+  std::string script =
+      "authAbortController = new AbortController();"
+      "authAbortSignal = authAbortController.signal;"
+      "authAbortController.abort('Error');" +
+      BuildCreateCallWithParameters(parameters);
+
+  std::string result = EvalJs(shell()->web_contents()->GetPrimaryMainFrame(),
+                              script, EXECUTE_SCRIPT_USE_MANUAL_REPLY)
+                           .ExtractString();
+  ASSERT_EQ(kAbortReasonMessage, result.substr(0, strlen(kAbortReasonMessage)));
+}
+
+// Tests that when navigator.credentials.create() is called with abort
 // signal's aborted flag set after sending request, we get an AbortError.
 IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
                        CreatePublicKeyCredentialWithAbortSetAfterCreate) {
@@ -1020,6 +1042,37 @@
   ASSERT_EQ(kAbortErrorMessage, result.substr(0, strlen(kAbortErrorMessage)));
 }
 
+// Tests that when navigator.credentials.create() is called with abort
+// signal's aborted flag set with reason after sending request, we get an error
+// from the reason.
+IN_PROC_BROWSER_TEST_F(
+    WebAuthJavascriptClientBrowserTest,
+    CreatePublicKeyCredentialWithAbortSetWithReasonAfterCreate) {
+  // This test sends the abort signal after making the WebAuthn call. However,
+  // the WebAuthn call could complete before the abort signal is sent, leading
+  // to a flakey test. Thus the |simulate_press_callback| is installed and
+  // always returns false, to ensure that the VirtualFidoDevice stalls the
+  // WebAuthn call and the abort signal will happen in time.
+  device::test::VirtualFidoDeviceFactory* virtual_device_factory =
+      InjectVirtualFidoDeviceFactory();
+  virtual_device_factory->mutable_state()->simulate_press_callback =
+      base::BindRepeating(
+          [](device::VirtualFidoDevice*) -> bool { return false; });
+
+  CreateParameters parameters;
+  parameters.signal = "authAbortSignal";
+  std::string script =
+      "authAbortController = new AbortController();"
+      "authAbortSignal = authAbortController.signal;" +
+      BuildCreateCallWithParameters(parameters) +
+      "authAbortController.abort('Error');";
+
+  std::string result = EvalJs(shell()->web_contents()->GetPrimaryMainFrame(),
+                              script, EXECUTE_SCRIPT_USE_MANUAL_REPLY)
+                           .ExtractString();
+  ASSERT_EQ(kAbortReasonMessage, result.substr(0, strlen(kAbortReasonMessage)));
+}
+
 // Tests that when navigator.credentials.get() is called with user verification
 // required, we get an NotAllowedError because the virtual device isn't
 // configured with UV and GetAssertionRequestHandler will return
@@ -1156,6 +1209,25 @@
 }
 
 // Tests that when navigator.credentials.get() is called with abort
+// signal's aborted flag set with reason before sending request,
+// we get an error from the reason.
+IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
+                       GetPublicKeyCredentialWithAbortSetWithReasonBeforeGet) {
+  GetParameters parameters;
+  parameters.signal = "authAbortSignal";
+  std::string script =
+      "authAbortController = new AbortController();"
+      "authAbortSignal = authAbortController.signal;"
+      "authAbortController.abort('Error');" +
+      BuildGetCallWithParameters(parameters);
+
+  std::string result = EvalJs(shell()->web_contents()->GetPrimaryMainFrame(),
+                              script, EXECUTE_SCRIPT_USE_MANUAL_REPLY)
+                           .ExtractString();
+  ASSERT_EQ(kAbortReasonMessage, result.substr(0, strlen(kAbortReasonMessage)));
+}
+
+// Tests that when navigator.credentials.get() is called with abort
 // signal's aborted flag set after sending request, we get an AbortError.
 IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
                        GetPublicKeyCredentialWithAbortSetAfterGet) {
@@ -1183,6 +1255,36 @@
   ASSERT_EQ(kAbortErrorMessage, result.substr(0, strlen(kAbortErrorMessage)));
 }
 
+// Tests that when navigator.credentials.get() is called with abort
+// signal's aborted flag set with reason after sending request,
+// we get an error from the reason.
+IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
+                       GetPublicKeyCredentialWithAbortSetWithReasonAfterGet) {
+  // This test sends the abort signal after making the WebAuthn call. However,
+  // the WebAuthn call could complete before the abort signal is sent, leading
+  // to a flakey test. Thus the |simulate_press_callback| is installed and
+  // always returns false, to ensure that the VirtualFidoDevice stalls the
+  // WebAuthn call and the abort signal will happen in time.
+  device::test::VirtualFidoDeviceFactory* virtual_device_factory =
+      InjectVirtualFidoDeviceFactory();
+  virtual_device_factory->mutable_state()->simulate_press_callback =
+      base::BindRepeating(
+          [](device::VirtualFidoDevice*) -> bool { return false; });
+
+  GetParameters parameters;
+  parameters.signal = "authAbortSignal";
+  std::string script =
+      "authAbortController = new AbortController();"
+      "authAbortSignal = authAbortController.signal;" +
+      BuildGetCallWithParameters(parameters) +
+      "authAbortController.abort('Error');";
+
+  std::string result = EvalJs(shell()->web_contents()->GetPrimaryMainFrame(),
+                              script, EXECUTE_SCRIPT_USE_MANUAL_REPLY)
+                           .ExtractString();
+  ASSERT_EQ(kAbortReasonMessage, result.substr(0, strlen(kAbortReasonMessage)));
+}
+
 // Executes Javascript in the given WebContents and waits until a string with
 // the given prefix is received. It will ignore values other than strings, and
 // strings without the given prefix. Since messages are broadcast to
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc
index 6aa72c2..7f26f3d3 100644
--- a/content/browser/webid/federated_auth_request_impl.cc
+++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -284,6 +284,17 @@
 
 }  // namespace
 
+FederatedAuthRequestImpl::IdentityProviderInfo::IdentityProviderInfo() =
+    default;
+FederatedAuthRequestImpl::IdentityProviderInfo::~IdentityProviderInfo() =
+    default;
+FederatedAuthRequestImpl::IdentityProviderInfo::IdentityProviderInfo(
+    const IdentityProviderInfo&) = default;
+
+FederatedAuthRequestImpl::Endpoints::Endpoints() = default;
+FederatedAuthRequestImpl::Endpoints::~Endpoints() = default;
+FederatedAuthRequestImpl::Endpoints::Endpoints(const Endpoints&) = default;
+
 FederatedAuthRequestImpl::FederatedAuthRequestImpl(
     RenderFrameHost& host,
     FederatedIdentityApiPermissionContextDelegate* api_permission_context,
@@ -352,26 +363,25 @@
 }
 
 void FederatedAuthRequestImpl::RequestToken(
-    std::vector<IdentityProviderPtr> identity_provider_ptrs,
+    std::vector<IdentityProviderPtr> idp_ptrs,
     bool prefer_auto_sign_in,
     bool show_iframe_requester,
     RequestTokenCallback callback) {
   // TODO(crbug.com/1348262): Temporarily support only the first IDP, extend to
   // support multiple IDPs.
-  if (identity_provider_ptrs.empty()) {
+  if (idp_ptrs.empty()) {
     std::move(callback).Run(RequestTokenStatus::kError, "");
     return;
   }
 
-  for (const auto& identity_provider : identity_provider_ptrs) {
-    if (!identity_provider) {
+  for (const auto& idp : idp_ptrs) {
+    if (!idp) {
       std::move(callback).Run(RequestTokenStatus::kError, "");
       return;
     }
   }
 
-  blink::mojom::IdentityProviderPtr identity_provider_ptr =
-      std::move(identity_provider_ptrs[0]);
+  blink::mojom::IdentityProviderPtr idp_ptr = std::move(idp_ptrs[0]);
 
   if (HasPendingRequest()) {
     fedcm_metrics_->RecordRequestTokenStatus(TokenStatus::kTooManyRequests);
@@ -387,14 +397,14 @@
       1, 1 << 30);
   // TODO(crbug.com/1307709): Handle FedCmMetrics for multiple IDPs.
   fedcm_metrics_ = std::make_unique<FedCmMetrics>(
-      identity_provider_ptr->config_url,
-      render_frame_host().GetPageUkmSourceId(), uniform_dist(rng),
-      /*is_disabled=*/identity_provider_ptrs.size() > 1);
+      idp_ptr->config_url, render_frame_host().GetPageUkmSourceId(),
+      uniform_dist(rng),
+      /*is_disabled=*/idp_ptrs.size() > 1);
   prefer_auto_sign_in_ = prefer_auto_sign_in && IsFedCmAutoSigninEnabled();
   start_time_ = base::TimeTicks::Now();
 
   if (!network::IsOriginPotentiallyTrustworthy(
-          url::Origin::Create(identity_provider_ptr->config_url))) {
+          url::Origin::Create(idp_ptr->config_url))) {
     CompleteRequestWithError(FederatedAuthRequestResult::kError,
                              TokenStatus::kIdpNotPotentiallyTrustworthy,
                              /*should_delay_callback=*/false);
@@ -441,7 +451,8 @@
 
   request_dialog_controller_ = CreateDialogController();
 
-  FetchManifest(std::move(identity_provider_ptr));
+  idp_info_[idp_ptr->config_url].provider = *idp_ptr;
+  FetchManifest(*idp_ptr);
 }
 
 void FederatedAuthRequestImpl::CancelTokenRequest() {
@@ -519,25 +530,21 @@
   return auth_request_callback_ || logout_callback_;
 }
 
-GURL FederatedAuthRequestImpl::ResolveManifestUrl(
-    const IdentityProvider& identity_provider,
-    const std::string& endpoint) {
+GURL FederatedAuthRequestImpl::ResolveManifestUrl(const IdentityProvider& idp,
+                                                  const std::string& endpoint) {
   if (endpoint.empty())
     return GURL();
-  GURL manifest_url = identity_provider.config_url.Resolve(
-      IdpNetworkRequestManager::kManifestFilePath);
+  GURL manifest_url =
+      idp.config_url.Resolve(IdpNetworkRequestManager::kManifestFilePath);
   return manifest_url.Resolve(endpoint);
 }
 
-bool FederatedAuthRequestImpl::IsEndpointUrlValid(
-    const IdentityProvider& identity_provider,
-    const GURL& endpoint_url) {
-  return url::Origin::Create(identity_provider.config_url)
-      .IsSameOriginWith(endpoint_url);
+bool FederatedAuthRequestImpl::IsEndpointUrlValid(const IdentityProvider& idp,
+                                                  const GURL& endpoint_url) {
+  return url::Origin::Create(idp.config_url).IsSameOriginWith(endpoint_url);
 }
 
-void FederatedAuthRequestImpl::FetchManifest(
-    IdentityProviderPtr identity_provider_ptr) {
+void FederatedAuthRequestImpl::FetchManifest(const IdentityProvider& idp) {
   absl::optional<int> icon_ideal_size = absl::nullopt;
   absl::optional<int> icon_minimum_size = absl::nullopt;
   if (request_dialog_controller_) {
@@ -547,24 +554,24 @@
 
   IdpNetworkRequestManager::FetchManifestCallback manifest_callback =
       base::BindOnce(&FederatedAuthRequestImpl::OnManifestFetched,
-                     weak_ptr_factory_.GetWeakPtr(), *identity_provider_ptr);
+                     weak_ptr_factory_.GetWeakPtr(), idp);
   IdpNetworkRequestManager::FetchManifestListCallback manifest_list_callback =
       base::BindOnce(&FederatedAuthRequestImpl::OnManifestListFetched,
-                     weak_ptr_factory_.GetWeakPtr(), *identity_provider_ptr);
+                     weak_ptr_factory_.GetWeakPtr(), idp);
 
   if (IsFedCmManifestValidationEnabled()) {
-    network_manager_->FetchManifestList(identity_provider_ptr->config_url,
+    network_manager_->FetchManifestList(idp.config_url,
                                         std::move(manifest_list_callback));
   } else {
-    manifest_lists_checked_.insert(identity_provider_ptr->config_url);
+    idp_info_[idp.config_url].manifest_list_checked = true;
   }
-  network_manager_->FetchManifest(identity_provider_ptr->config_url,
-                                  icon_ideal_size, icon_minimum_size,
+  network_manager_->FetchManifest(idp.config_url, icon_ideal_size,
+                                  icon_minimum_size,
                                   std::move(manifest_callback));
 }
 
 void FederatedAuthRequestImpl::OnManifestListFetched(
-    const IdentityProvider& identity_provider,
+    const IdentityProvider& idp,
     IdpNetworkRequestManager::FetchStatus status,
     const std::set<GURL>& urls) {
   switch (status) {
@@ -617,7 +624,7 @@
   //     "https://foo.idp.example/fedcm.json"
   //   ]
   // }
-  bool provider_url_is_valid = (urls.count(identity_provider.config_url) != 0);
+  bool provider_url_is_valid = (urls.count(idp.config_url) != 0);
 
   if (!provider_url_is_valid) {
     CompleteRequestWithError(
@@ -627,13 +634,13 @@
     return;
   }
 
-  manifest_lists_checked_.insert(identity_provider.config_url);
-  if (idp_metadata_)
-    OnManifestReady(identity_provider, *idp_metadata_);
+  idp_info_[idp.config_url].manifest_list_checked = true;
+  if (idp_info_[idp.config_url].metadata)
+    OnManifestReady(idp_info_[idp.config_url]);
 }
 
 void FederatedAuthRequestImpl::OnManifestFetched(
-    const IdentityProvider& identity_provider,
+    const IdentityProvider& idp,
     IdpNetworkRequestManager::FetchStatus status,
     IdpNetworkRequestManager::Endpoints endpoints,
     IdentityProviderMetadata idp_metadata) {
@@ -664,24 +671,26 @@
     }
   }
 
-  endpoints_.token = ResolveManifestUrl(identity_provider, endpoints.token);
-  endpoints_.accounts =
-      ResolveManifestUrl(identity_provider, endpoints.accounts);
-  endpoints_.client_metadata =
-      ResolveManifestUrl(identity_provider, endpoints.client_metadata);
-  endpoints_.metrics = ResolveManifestUrl(identity_provider, endpoints.metrics);
-  idp_metadata_ = idp_metadata;
+  idp_info_[idp.config_url].endpoints.token =
+      ResolveManifestUrl(idp, endpoints.token);
+  idp_info_[idp.config_url].endpoints.accounts =
+      ResolveManifestUrl(idp, endpoints.accounts);
+  idp_info_[idp.config_url].endpoints.client_metadata =
+      ResolveManifestUrl(idp, endpoints.client_metadata);
+  // TODO(crbug.com/1307709): Fix metrics endpoint for multi IDPs.
+  endpoints_.metrics = ResolveManifestUrl(idp, endpoints.metrics);
+  idp_info_[idp.config_url].metadata = idp_metadata;
 
-  if (manifest_lists_checked_.count(identity_provider.config_url))
-    OnManifestReady(identity_provider, idp_metadata);
+  if (idp_info_[idp.config_url].manifest_list_checked)
+    OnManifestReady(idp_info_[idp.config_url]);
 }
 
 void FederatedAuthRequestImpl::OnManifestReady(
-    const IdentityProvider& identity_provider,
-    IdentityProviderMetadata idp_metadata) {
-  bool is_token_valid = IsEndpointUrlValid(identity_provider, endpoints_.token);
+    const IdentityProviderInfo& idp_info) {
+  bool is_token_valid =
+      IsEndpointUrlValid(idp_info.provider, idp_info.endpoints.token);
   bool is_accounts_valid =
-      IsEndpointUrlValid(identity_provider, endpoints_.accounts);
+      IsEndpointUrlValid(idp_info.provider, idp_info.endpoints.accounts);
   if (!is_token_valid || !is_accounts_valid) {
     std::string message =
         "Manifest is missing or has an invalid URL for the following "
@@ -700,40 +709,39 @@
         /*should_delay_callback=*/true);
     return;
   }
-  if (IsEndpointUrlValid(identity_provider, endpoints_.client_metadata)) {
+  if (IsEndpointUrlValid(idp_info.provider,
+                         idp_info.endpoints.client_metadata)) {
     network_manager_->FetchClientMetadata(
-        endpoints_.client_metadata, identity_provider.client_id,
+        idp_info.endpoints.client_metadata, idp_info.provider.client_id,
         base::BindOnce(
             &FederatedAuthRequestImpl::OnClientMetadataResponseReceived,
-            weak_ptr_factory_.GetWeakPtr(), identity_provider,
-            std::move(idp_metadata)));
+            weak_ptr_factory_.GetWeakPtr(),
+            idp_info_[idp_info.provider.config_url]));
   } else {
     network_manager_->SendAccountsRequest(
-        endpoints_.accounts, identity_provider.client_id,
+        idp_info.endpoints.accounts, idp_info.provider.client_id,
         base::BindOnce(&FederatedAuthRequestImpl::OnAccountsResponseReceived,
-                       weak_ptr_factory_.GetWeakPtr(), identity_provider,
-                       std::move(idp_metadata)));
+                       weak_ptr_factory_.GetWeakPtr(),
+                       idp_info_[idp_info.provider.config_url]));
   }
 }
 
 void FederatedAuthRequestImpl::OnClientMetadataResponseReceived(
-    const IdentityProvider& identity_provider,
-    IdentityProviderMetadata idp_metadata,
+    const IdentityProviderInfo& idp_info,
     IdpNetworkRequestManager::FetchStatus status,
     IdpNetworkRequestManager::ClientMetadata data) {
   // TODO(yigu): Clean up the client metadata related errors for metrics and
   // console logs.
   client_metadata_ = data;
   network_manager_->SendAccountsRequest(
-      endpoints_.accounts, identity_provider.client_id,
+      idp_info.endpoints.accounts, idp_info.provider.client_id,
       base::BindOnce(&FederatedAuthRequestImpl::OnAccountsResponseReceived,
-                     weak_ptr_factory_.GetWeakPtr(), identity_provider,
-                     std::move(idp_metadata)));
+                     weak_ptr_factory_.GetWeakPtr(),
+                     idp_info_[idp_info.provider.config_url]));
 }
 
 void FederatedAuthRequestImpl::OnAccountsResponseReceived(
-    const IdentityProvider& identity_provider,
-    IdentityProviderMetadata idp_metadata,
+    const IdentityProviderInfo& idp_info,
     IdpNetworkRequestManager::FetchStatus status,
     IdpNetworkRequestManager::AccountList accounts) {
   switch (status) {
@@ -778,7 +786,7 @@
           WebContents::FromRenderFrameHost(&render_frame_host());
       DCHECK(render_frame_host().GetMainFrame()->IsInPrimaryMainFrame());
 
-      ComputeLoginStateAndReorderAccounts(identity_provider, accounts);
+      ComputeLoginStateAndReorderAccounts(idp_info.provider, accounts);
 
       bool screen_reader_is_on =
           rp_web_contents->GetAccessibilityMode().has_mode(
@@ -799,15 +807,17 @@
                                                    start_time_);
 
       std::vector<IdentityProviderData> identity_providers_data;
-      IdentityProviderData identity_provider_data(
-          identity_provider.config_url, accounts, idp_metadata, client_id_data);
+      IdentityProviderData identity_provider_data(idp_info.provider.config_url,
+                                                  accounts, *idp_info.metadata,
+                                                  client_id_data);
       identity_providers_data.push_back(identity_provider_data);
 
       request_dialog_controller_->ShowAccountsDialog(
           rp_web_contents, identity_providers_data,
           is_auto_sign_in ? SignInMode::kAuto : SignInMode::kExplicit,
           base::BindOnce(&FederatedAuthRequestImpl::OnAccountSelected,
-                         weak_ptr_factory_.GetWeakPtr(), identity_provider),
+                         weak_ptr_factory_.GetWeakPtr(),
+                         idp_info_[idp_info.provider.config_url]),
           base::BindOnce(&FederatedAuthRequestImpl::OnDialogDismissed,
                          weak_ptr_factory_.GetWeakPtr()));
       return;
@@ -816,7 +826,7 @@
 }
 
 void FederatedAuthRequestImpl::ComputeLoginStateAndReorderAccounts(
-    const IdentityProvider& identity_provider,
+    const IdentityProvider& idp,
     IdpNetworkRequestManager::AccountList& accounts) {
   // Populate the accounts login state.
   for (auto& account : accounts) {
@@ -824,8 +834,8 @@
     bool idp_claimed_sign_in = account.login_state == LoginState::kSignIn;
     bool browser_observed_sign_in =
         sharing_permission_delegate_->HasSharingPermission(
-            origin(), GetEmbeddingOrigin(),
-            url::Origin::Create(identity_provider.config_url), account.id);
+            origin(), GetEmbeddingOrigin(), url::Origin::Create(idp.config_url),
+            account.id);
 
     if (idp_claimed_sign_in == browser_observed_sign_in) {
       fedcm_metrics_->RecordSignInStateMatchStatus(
@@ -862,7 +872,7 @@
 }
 
 void FederatedAuthRequestImpl::OnAccountSelected(
-    const IdentityProvider& identity_provider,
+    const IdentityProviderInfo& idp_info,
     const std::string& account_id,
     bool is_sign_in) {
   DCHECK(!account_id.empty());
@@ -891,12 +901,12 @@
                                              show_accounts_dialog_time_);
 
   network_manager_->SendTokenRequest(
-      endpoints_.token, account_id_,
-      ComputeUrlEncodedTokenPostData(identity_provider.client_id,
-                                     identity_provider.nonce, account_id,
+      idp_info.endpoints.token, account_id_,
+      ComputeUrlEncodedTokenPostData(idp_info.provider.client_id,
+                                     idp_info.provider.nonce, account_id,
                                      is_sign_in),
       base::BindOnce(&FederatedAuthRequestImpl::OnTokenResponseReceived,
-                     weak_ptr_factory_.GetWeakPtr(), identity_provider));
+                     weak_ptr_factory_.GetWeakPtr(), idp_info.provider));
 }
 
 void FederatedAuthRequestImpl::OnDialogDismissed(
@@ -937,7 +947,7 @@
 }
 
 void FederatedAuthRequestImpl::OnTokenResponseReceived(
-    const IdentityProvider& identity_provider,
+    const IdentityProvider& idp,
     IdpNetworkRequestManager::FetchStatus status,
     const std::string& id_token) {
   if (!auth_request_callback_)
@@ -951,20 +961,19 @@
   base::TimeDelta fetch_time = token_response_time_ - select_account_time_;
   if (ShouldCompleteRequestImmediately() ||
       fetch_time >= token_request_delay_) {
-    CompleteTokenRequest(identity_provider, status, id_token);
+    CompleteTokenRequest(idp, status, id_token);
     return;
   }
 
   base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
       base::BindOnce(&FederatedAuthRequestImpl::CompleteTokenRequest,
-                     weak_ptr_factory_.GetWeakPtr(), identity_provider, status,
-                     id_token),
+                     weak_ptr_factory_.GetWeakPtr(), idp, status, id_token),
       token_request_delay_ - fetch_time);
 }
 
 void FederatedAuthRequestImpl::CompleteTokenRequest(
-    const IdentityProvider& identity_provider,
+    const IdentityProvider& idp,
     IdpNetworkRequestManager::FetchStatus status,
     const std::string& token) {
   DCHECK(!start_time_.is_null());
@@ -1005,12 +1014,11 @@
       // https://crbug.com/1199088
       CHECK(!account_id_.empty());
       sharing_permission_delegate_->GrantSharingPermission(
-          origin(), GetEmbeddingOrigin(),
-          url::Origin::Create(identity_provider.config_url), account_id_);
+          origin(), GetEmbeddingOrigin(), url::Origin::Create(idp.config_url),
+          account_id_);
 
       active_session_permission_delegate_->GrantActiveSession(
-          origin(), url::Origin::Create(identity_provider.config_url),
-          account_id_);
+          origin(), url::Origin::Create(idp.config_url), account_id_);
 
       fedcm_metrics_->RecordTokenResponseAndTurnaroundTime(
           token_response_time_ - select_account_time_,
@@ -1134,8 +1142,7 @@
   show_accounts_dialog_time_ = base::TimeTicks();
   select_account_time_ = base::TimeTicks();
   token_response_time_ = base::TimeTicks();
-  manifest_lists_checked_.clear();
-  idp_metadata_.reset();
+  idp_info_.clear();
 }
 
 void FederatedAuthRequestImpl::AddInspectorIssue(
diff --git a/content/browser/webid/federated_auth_request_impl.h b/content/browser/webid/federated_auth_request_impl.h
index 36faf72..c96a5c6 100644
--- a/content/browser/webid/federated_auth_request_impl.h
+++ b/content/browser/webid/federated_auth_request_impl.h
@@ -56,11 +56,10 @@
   ~FederatedAuthRequestImpl() override;
 
   // blink::mojom::FederatedAuthRequest:
-  void RequestToken(
-      std::vector<blink::mojom::IdentityProviderPtr> identity_provider_ptrs,
-      bool prefer_auto_sign_in,
-      bool show_iframe_requester,
-      RequestTokenCallback) override;
+  void RequestToken(std::vector<blink::mojom::IdentityProviderPtr> idp_ptrs,
+                    bool prefer_auto_sign_in,
+                    bool show_iframe_requester,
+                    RequestTokenCallback) override;
   void CancelTokenRequest() override;
   void LogoutRps(std::vector<blink::mojom::LogoutRpsRequestPtr> logout_requests,
                  LogoutRpsCallback) override;
@@ -74,6 +73,30 @@
   // Rejects the pending request if it has not been resolved naturally yet.
   void OnRejectRequest();
 
+  // Fetched from the IDP FedCM manifest configuration.
+  struct Endpoints {
+    Endpoints();
+    ~Endpoints();
+    Endpoints(const Endpoints&);
+
+    GURL idp;
+    GURL token;
+    GURL accounts;
+    GURL client_metadata;
+    GURL metrics;
+  };
+
+  struct IdentityProviderInfo {
+    IdentityProviderInfo();
+    ~IdentityProviderInfo();
+    IdentityProviderInfo(const IdentityProviderInfo&);
+
+    blink::mojom::IdentityProvider provider;
+    Endpoints endpoints;
+    bool manifest_list_checked{false};
+    absl::optional<IdentityProviderMetadata> metadata;
+  };
+
  private:
   friend class FederatedAuthRequestImplTest;
 
@@ -85,52 +108,42 @@
       mojo::PendingReceiver<blink::mojom::FederatedAuthRequest>);
 
   bool HasPendingRequest() const;
-  GURL ResolveManifestUrl(
-      const blink::mojom::IdentityProvider& identity_provider,
-      const std::string& url);
+  GURL ResolveManifestUrl(const blink::mojom::IdentityProvider& idp,
+                          const std::string& url);
 
   // Checks validity of the passed-in endpoint URL origin.
-  bool IsEndpointUrlValid(
-      const blink::mojom::IdentityProvider& identity_provider,
-      const GURL& endpoint_url);
+  bool IsEndpointUrlValid(const blink::mojom::IdentityProvider& idp,
+                          const GURL& endpoint_url);
 
-  void FetchManifest(blink::mojom::IdentityProviderPtr identity_provider_ptr);
-  void OnManifestListFetched(
-      const blink::mojom::IdentityProvider& identity_provider,
-      IdpNetworkRequestManager::FetchStatus status,
-      const std::set<GURL>& urls);
-  void OnManifestFetched(
-      const blink::mojom::IdentityProvider& identity_provider,
-      IdpNetworkRequestManager::FetchStatus status,
-      IdpNetworkRequestManager::Endpoints,
-      IdentityProviderMetadata idp_metadata);
-  void OnManifestReady(const blink::mojom::IdentityProvider& identity_provider,
-                       IdentityProviderMetadata idp_metadata);
+  void FetchManifest(const blink::mojom::IdentityProvider& idp);
+  void OnManifestListFetched(const blink::mojom::IdentityProvider& idp,
+                             IdpNetworkRequestManager::FetchStatus status,
+                             const std::set<GURL>& urls);
+  void OnManifestFetched(const blink::mojom::IdentityProvider& idp,
+                         IdpNetworkRequestManager::FetchStatus status,
+                         IdpNetworkRequestManager::Endpoints,
+                         IdentityProviderMetadata idp_metadata);
+  void OnManifestReady(const IdentityProviderInfo& idp_info);
   void OnClientMetadataResponseReceived(
-      const blink::mojom::IdentityProvider& identity_provider,
-      IdentityProviderMetadata idp_metadata,
+      const IdentityProviderInfo& idp_info,
       IdpNetworkRequestManager::FetchStatus status,
       IdpNetworkRequestManager::ClientMetadata data);
 
   void OnAccountsResponseReceived(
-      const blink::mojom::IdentityProvider& identity_provider,
-      IdentityProviderMetadata idp_metadata,
+      const IdentityProviderInfo& idp_info,
       IdpNetworkRequestManager::FetchStatus status,
       IdpNetworkRequestManager::AccountList accounts);
-  void OnAccountSelected(
-      const blink::mojom::IdentityProvider& identity_provider,
-      const std::string& account_id,
-      bool is_sign_in);
+  void OnAccountSelected(const IdentityProviderInfo& idp_info,
+                         const std::string& account_id,
+                         bool is_sign_in);
   void OnDialogDismissed(
       IdentityRequestDialogController::DismissReason dismiss_reason);
-  void CompleteTokenRequest(
-      const blink::mojom::IdentityProvider& identity_provider,
-      IdpNetworkRequestManager::FetchStatus status,
-      const std::string& token);
-  void OnTokenResponseReceived(
-      const blink::mojom::IdentityProvider& identity_provider,
-      IdpNetworkRequestManager::FetchStatus status,
-      const std::string& token);
+  void CompleteTokenRequest(const blink::mojom::IdentityProvider& idp,
+                            IdpNetworkRequestManager::FetchStatus status,
+                            const std::string& token);
+  void OnTokenResponseReceived(const blink::mojom::IdentityProvider& idp,
+                               IdpNetworkRequestManager::FetchStatus status,
+                               const std::string& token);
   void DispatchOneLogout();
   void OnLogoutCompleted();
   void CompleteRequestWithError(
@@ -169,7 +182,7 @@
   // reorders accounts so that those that are considered returning users are
   // before users that are not returning.
   void ComputeLoginStateAndReorderAccounts(
-      const blink::mojom::IdentityProvider& identity_provider,
+      const blink::mojom::IdentityProvider& idp,
       IdpNetworkRequestManager::AccountList& accounts);
 
   url::Origin GetEmbeddingOrigin() const;
@@ -196,10 +209,7 @@
     GURL metrics;
   } endpoints_;
 
-  // Tracks for which IDPs the manifest URL has been checked against the IDP's
-  // manifest list.
-  base::flat_set<GURL> manifest_lists_checked_;
-  absl::optional<IdentityProviderMetadata> idp_metadata_;
+  base::flat_map<GURL, IdentityProviderInfo> idp_info_;
 
   raw_ptr<FederatedIdentityApiPermissionContextDelegate>
       api_permission_delegate_ = nullptr;
diff --git a/content/common/content_navigation_policy.cc b/content/common/content_navigation_policy.cc
index 9b3c64d..830ef43d 100644
--- a/content/common/content_navigation_policy.cc
+++ b/content/common/content_navigation_policy.cc
@@ -98,25 +98,6 @@
   return false;
 }
 
-bool IsSameSiteBackForwardCacheEnabled() {
-  if (!IsBackForwardCacheEnabled())
-    return false;
-
-  // Same-site back-forward cache is enabled by default, but can be disabled
-  // through kBackForwardCache's "enable_same_site" param.
-  static constexpr base::FeatureParam<bool> enable_same_site_back_forward_cache(
-      &features::kBackForwardCache, "enable_same_site", true);
-  return enable_same_site_back_forward_cache.Get();
-}
-
-bool ShouldSkipSameSiteBackForwardCacheForPageWithUnload() {
-  if (!IsSameSiteBackForwardCacheEnabled())
-    return true;
-  static constexpr base::FeatureParam<bool> skip_same_site_if_unload_exists(
-      &features::kBackForwardCache, "skip_same_site_if_unload_exists", false);
-  return skip_same_site_if_unload_exists.Get();
-}
-
 bool CanCrossSiteNavigationsProactivelySwapBrowsingInstances() {
   return IsProactivelySwapBrowsingInstanceEnabled() ||
          IsBackForwardCacheEnabled();
diff --git a/content/common/content_navigation_policy.h b/content/common/content_navigation_policy.h
index 9636b2bb..252cc6e 100644
--- a/content/common/content_navigation_policy.h
+++ b/content/common/content_navigation_policy.h
@@ -30,8 +30,6 @@
 namespace content {
 
 CONTENT_EXPORT bool IsBackForwardCacheEnabled();
-CONTENT_EXPORT bool IsSameSiteBackForwardCacheEnabled();
-CONTENT_EXPORT bool ShouldSkipSameSiteBackForwardCacheForPageWithUnload();
 CONTENT_EXPORT bool IsBackForwardCacheDisabledByCommandLine();
 CONTENT_EXPORT bool DeviceHasEnoughMemoryForBackForwardCache();
 
@@ -78,7 +76,7 @@
 // or not. Will return true if the value is set to kSameSite.
 // Note that even if this returns false, we might still trigger proactive
 // BrowsingInstance swaps on same-site navigations if
-// IsSameSiteBackForwardCacheEnabled() is true.
+// IsBackForwardCacheEnabled() is true.
 CONTENT_EXPORT bool
 IsProactivelySwapBrowsingInstanceOnSameSiteNavigationEnabled();
 
diff --git a/content/public/browser/back_forward_cache.h b/content/public/browser/back_forward_cache.h
index 186ca4c..b6befe5 100644
--- a/content/public/browser/back_forward_cache.h
+++ b/content/public/browser/back_forward_cache.h
@@ -29,8 +29,6 @@
  public:
   // Returns true if BackForwardCache is enabled.
   static bool IsBackForwardCacheFeatureEnabled();
-  // Returns true if BackForwardCache is enabled for same-site navigations.
-  static bool IsSameSiteBackForwardCacheFeatureEnabled();
 
   // Back/forward cache can be disabled from within content and also from
   // embedders. This means we cannot have a unified enum that covers reasons
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index 1931aaf..d19e832 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -671,6 +671,13 @@
 bool NavigateToURLFromRendererWithoutUserGesture(
     const ToRenderFrameHost& adapter,
     const GURL& url) {
+  return NavigateToURLFromRendererWithoutUserGesture(adapter, url, url);
+}
+
+bool NavigateToURLFromRendererWithoutUserGesture(
+    const ToRenderFrameHost& adapter,
+    const GURL& url,
+    const GURL& expected_commit_url) {
   RenderFrameHost* rfh = adapter.render_frame_host();
   TestFrameNavigationObserver nav_observer(rfh);
   if (!ExecJs(rfh, JsReplace("location = $1", url),
@@ -678,7 +685,7 @@
     return false;
   }
   nav_observer.Wait();
-  return nav_observer.last_committed_url() == url;
+  return nav_observer.last_committed_url() == expected_commit_url;
 }
 
 bool BeginNavigateToURLFromRenderer(const ToRenderFrameHost& adapter,
@@ -2248,8 +2255,9 @@
       web_contents_impl->GetPrimaryMainFrame());
   BrowserAccessibilityManager* main_frame_manager =
       main_frame->browser_accessibility_manager();
-  while (!main_frame_manager || !AccessibilityTreeContainsNodeWithName(
-             main_frame_manager->GetRoot(), name)) {
+  while (!main_frame_manager ||
+         !AccessibilityTreeContainsNodeWithName(
+             main_frame_manager->GetBrowserAccessibilityRoot(), name)) {
     WaitForAccessibilityTreeToChange(web_contents);
     main_frame_manager = main_frame->browser_accessibility_manager();
   }
@@ -2278,7 +2286,7 @@
       static_cast<WebContentsImpl*>(web_contents);
   BrowserAccessibilityManager* manager =
       web_contents_impl->GetRootBrowserAccessibilityManager();
-  return manager ? manager->GetRoot() : nullptr;
+  return manager ? manager->GetBrowserAccessibilityRoot() : nullptr;
 }
 
 FindAccessibilityNodeCriteria::FindAccessibilityNodeCriteria() = default;
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h
index 141a142..3ff4a11 100644
--- a/content/public/test/browser_test_utils.h
+++ b/content/public/test/browser_test_utils.h
@@ -168,6 +168,13 @@
 [[nodiscard]] bool NavigateToURLFromRendererWithoutUserGesture(
     const ToRenderFrameHost& adapter,
     const GURL& url);
+// Similar to above but takes in an additional URL, |expected_commit_url|, to
+// which the navigation should eventually commit. (See the browser-initiated
+// counterpart for more details).
+[[nodiscard]] bool NavigateToURLFromRendererWithoutUserGesture(
+    const ToRenderFrameHost& adapter,
+    const GURL& url,
+    const GURL& expected_commit_url);
 
 // Perform a renderer-initiated navigation of |window| to |url|. Unlike the
 // previous set of helpers, does not block. The navigation is done by assigning
diff --git a/content/public/test/test_utils.cc b/content/public/test/test_utils.cc
index 2484c13..611257c 100644
--- a/content/public/test/test_utils.cc
+++ b/content/public/test/test_utils.cc
@@ -251,7 +251,7 @@
 
 bool CanSameSiteMainFrameNavigationsChangeSiteInstances() {
   return IsProactivelySwapBrowsingInstanceOnSameSiteNavigationEnabled() ||
-         IsSameSiteBackForwardCacheEnabled();
+         IsBackForwardCacheEnabled();
 }
 
 void DisableProactiveBrowsingInstanceSwapFor(RenderFrameHost* rfh) {
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc
index 624f8392..056e0f6 100644
--- a/content/renderer/accessibility/render_accessibility_impl.cc
+++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -1059,6 +1059,8 @@
     if (!obj.AccessibilityIsIncludedInTree())
       continue;
 
+    DCHECK(obj.AxID() != ui::kInvalidAXNodeID);
+
     // Further down this loop, we update |already_serialized_ids| with all IDs
     // actually serialized. However, add this object's ID first because there's
     // a chance that we try to serialize this object but the serializer ends up
@@ -1090,8 +1092,10 @@
     AddImageAnnotations(document, update.nodes);
 
     DCHECK_GT(update.nodes.size(), 0U);
-    for (auto& node : update.nodes)
+    for (auto& node : update.nodes) {
+      DCHECK(node.id != ui::kInvalidAXNodeID);
       already_serialized_ids.insert(node.id);
+    }
 
     updates.push_back(update);
 
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.cc b/content/renderer/media/renderer_webmediaplayer_delegate.cc
index 20ce11a..82c79a3 100644
--- a/content/renderer/media/renderer_webmediaplayer_delegate.cc
+++ b/content/renderer/media/renderer_webmediaplayer_delegate.cc
@@ -8,7 +8,6 @@
 
 #include "base/auto_reset.h"
 #include "base/bind.h"
-#include "base/logging.h"
 #include "base/metrics/user_metrics_action.h"
 #include "base/system/sys_info.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -20,8 +19,6 @@
 #include "third_party/blink/public/mojom/frame/user_activation_notification_type.mojom.h"
 #include "third_party/blink/public/platform/web_fullscreen_video_status.h"
 #include "third_party/blink/public/web/web_local_frame.h"
-#include "third_party/blink/public/web/web_view.h"
-#include "third_party/blink/public/web/web_view_observer.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace {
@@ -37,7 +34,6 @@
 RendererWebMediaPlayerDelegate::RendererWebMediaPlayerDelegate(
     content::RenderFrame* render_frame)
     : RenderFrameObserver(render_frame),
-      blink::WebViewObserver(render_frame->GetWebView()),
       allow_idle_cleanup_(
           content::GetContentClient()->renderer()->IsIdleMediaSuspendEnabled()),
       tick_clock_(base::DefaultTickClock::GetInstance()) {
@@ -55,17 +51,7 @@
   if (is_frame_hidden_for_testing_)
     return true;
 
-  // There is always a render frame except perhaps during teardown (though
-  // |this| should be deleted before that would be observable).
-  if (!render_frame())
-    return true;
-
-  // If the view is gone it means we are tearing down.
-  if (!render_frame()->GetWebView())
-    return true;
-
-  return render_frame()->GetWebView()->GetVisibilityState() !=
-         blink::mojom::PageVisibilityState::kVisible;
+  return (render_frame() && render_frame()->IsHidden());
 }
 
 int RendererWebMediaPlayerDelegate::AddObserver(Observer* observer) {
@@ -181,26 +167,24 @@
   return stale_players_.count(player_id);
 }
 
-void RendererWebMediaPlayerDelegate::OnPageVisibilityChanged(
-    blink::mojom::PageVisibilityState visibility_state) {
-  LOG(ERROR) << __func__ << ": " << visibility_state;
-  if (visibility_state == blink::mojom::PageVisibilityState::kVisible) {
-    RecordAction(base::UserMetricsAction("Media.Shown"));
+void RendererWebMediaPlayerDelegate::WasHidden() {
+  RecordAction(base::UserMetricsAction("Media.Hidden"));
 
-    for (base::IDMap<Observer*>::iterator it(&id_map_); !it.IsAtEnd();
-         it.Advance())
-      it.GetCurrentValue()->OnFrameShown();
+  for (base::IDMap<Observer*>::iterator it(&id_map_); !it.IsAtEnd();
+       it.Advance())
+    it.GetCurrentValue()->OnFrameHidden();
 
-    ScheduleUpdateTask();
-  } else {
-    RecordAction(base::UserMetricsAction("Media.Hidden"));
+  ScheduleUpdateTask();
+}
 
-    for (base::IDMap<Observer*>::iterator it(&id_map_); !it.IsAtEnd();
-         it.Advance())
-      it.GetCurrentValue()->OnFrameHidden();
+void RendererWebMediaPlayerDelegate::WasShown() {
+  RecordAction(base::UserMetricsAction("Media.Shown"));
 
-    ScheduleUpdateTask();
-  }
+  for (base::IDMap<Observer*>::iterator it(&id_map_); !it.IsAtEnd();
+       it.Advance())
+    it.GetCurrentValue()->OnFrameShown();
+
+  ScheduleUpdateTask();
 }
 
 void RendererWebMediaPlayerDelegate::SetIdleCleanupParamsForTesting(
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.h b/content/renderer/media/renderer_webmediaplayer_delegate.h
index 098715f..d58cbfb 100644
--- a/content/renderer/media/renderer_webmediaplayer_delegate.h
+++ b/content/renderer/media/renderer_webmediaplayer_delegate.h
@@ -20,7 +20,6 @@
 #include "content/common/content_export.h"
 #include "content/public/renderer/render_frame_observer.h"
 #include "third_party/blink/public/platform/media/webmediaplayer_delegate.h"
-#include "third_party/blink/public/web/web_view_observer.h"
 
 namespace blink {
 enum class WebFullscreenVideoStatus;
@@ -34,7 +33,6 @@
 // the MediaPlayerDelegateHost.
 class CONTENT_EXPORT RendererWebMediaPlayerDelegate
     : public content::RenderFrameObserver,
-      public blink::WebViewObserver,
       public blink::WebMediaPlayerDelegate,
       public base::SupportsWeakPtr<RendererWebMediaPlayerDelegate> {
  public:
@@ -67,12 +65,10 @@
   bool IsStale(int player_id) override;
 
   // content::RenderFrameObserver overrides.
+  void WasHidden() override;
+  void WasShown() override;
   void OnDestruct() override;
 
-  // blink::WebViewObserver overrides.
-  void OnPageVisibilityChanged(
-      blink::mojom::PageVisibilityState visibility_state) override;
-
   // Returns the number of WebMediaPlayers that are associated with this
   // delegate.
   size_t web_media_player_count() const { return id_map_.size(); }
diff --git a/content/renderer/pepper/pepper_platform_audio_input.cc b/content/renderer/pepper/pepper_platform_audio_input.cc
index ec17a01..5cbe1ee 100644
--- a/content/renderer/pepper/pepper_platform_audio_input.cc
+++ b/content/renderer/pepper/pepper_platform_audio_input.cc
@@ -150,10 +150,8 @@
   if (!GetMediaDeviceManager())
     return false;
 
-
   params_.Reset(media::AudioParameters::AUDIO_PCM_LINEAR,
-                media::CHANNEL_LAYOUT_MONO,
-                sample_rate,
+                media::ChannelLayoutConfig::Mono(), sample_rate,
                 frames_per_buffer);
 
   // We need to open the device and obtain the label and session ID before
diff --git a/content/renderer/pepper/pepper_platform_audio_output.cc b/content/renderer/pepper/pepper_platform_audio_output.cc
index 8d1fc02..1b4535e 100644
--- a/content/renderer/pepper/pepper_platform_audio_output.cc
+++ b/content/renderer/pepper/pepper_platform_audio_output.cc
@@ -141,9 +141,8 @@
   CHECK(ipc_);
 
   media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-                                media::CHANNEL_LAYOUT_STEREO,
-                                sample_rate,
-                                frames_per_buffer);
+                                media::ChannelLayoutConfig::Stereo(),
+                                sample_rate, frames_per_buffer);
 
   io_task_runner_->PostTask(
       FROM_HERE,
diff --git a/content/renderer/pepper/pepper_platform_audio_output_dev.cc b/content/renderer/pepper/pepper_platform_audio_output_dev.cc
index 12dd98e9..2be1a7fa 100644
--- a/content/renderer/pepper/pepper_platform_audio_output_dev.cc
+++ b/content/renderer/pepper/pepper_platform_audio_output_dev.cc
@@ -267,7 +267,8 @@
   CHECK(ipc_);
 
   params_.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-                media::CHANNEL_LAYOUT_STEREO, sample_rate, frames_per_buffer);
+                media::ChannelLayoutConfig::Stereo(), sample_rate,
+                frames_per_buffer);
 
   io_task_runner_->PostTask(
       FROM_HERE,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index e675234..51ce1b7 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -47,6 +47,7 @@
 #include "base/time/time.h"
 #include "base/trace_event/base_tracing.h"
 #include "base/trace_event/trace_event.h"
+#include "base/types/optional_util.h"
 #include "base/unguessable_token.h"
 #include "base/values.h"
 #include "build/build_config.h"
@@ -4175,7 +4176,7 @@
           : absl::optional<url::Origin>(request.RequestorOrigin());
   GetContentClient()->renderer()->WillSendRequest(
       frame_, transition_type, request.Url(), request.SiteForCookies(),
-      base::OptionalOrNullptr(initiator_origin), &new_url);
+      base::OptionalToPtr(initiator_origin), &new_url);
   if (!new_url.is_empty())
     request.SetUrl(WebURL(new_url));
 
diff --git a/content/test/fuzzer/browser_accessibility_fuzzer.cc b/content/test/fuzzer/browser_accessibility_fuzzer.cc
index e9913d3..4155359e 100644
--- a/content/test/fuzzer/browser_accessibility_fuzzer.cc
+++ b/content/test/fuzzer/browser_accessibility_fuzzer.cc
@@ -159,14 +159,14 @@
   std::vector<void*> results;
 
   // Test some tree-walking functions.
-  BrowserAccessibility* root = manager->GetRoot();
+  BrowserAccessibility* root = manager->GetBrowserAccessibilityRoot();
   results.push_back(root->PlatformDeepestFirstChild());
   results.push_back(root->PlatformDeepestLastChild());
   results.push_back(root->InternalDeepestFirstChild());
   results.push_back(root->InternalDeepestLastChild());
 
   // Test OneShotAccessibilityTreeSearch.
-  OneShotAccessibilityTreeSearch search(manager->GetRoot());
+  OneShotAccessibilityTreeSearch search(manager->GetBrowserAccessibilityRoot());
   search.SetDirection(fdp.ConsumeBool()
                           ? OneShotAccessibilityTreeSearch::FORWARDS
                           : OneShotAccessibilityTreeSearch::BACKWARDS);
diff --git a/device/fido/mac/credential_store.h b/device/fido/mac/credential_store.h
index ce70a3f..bf811e3 100644
--- a/device/fido/mac/credential_store.h
+++ b/device/fido/mac/credential_store.h
@@ -34,7 +34,8 @@
 struct COMPONENT_EXPORT(DEVICE_FIDO) Credential {
   Credential(base::ScopedCFTypeRef<SecKeyRef> private_key,
              std::vector<uint8_t> credential_id,
-             CredentialMetadata metadata);
+             CredentialMetadata metadata,
+             std::string rp_id);
   Credential(const Credential&);
   Credential(Credential&& other);
   Credential& operator=(const Credential&);
@@ -53,6 +54,8 @@
   std::vector<uint8_t> credential_id;
 
   CredentialMetadata metadata;
+
+  std::string rp_id;
 };
 
 // TouchIdCredentialStore allows operations on Touch ID platform authenticator
@@ -111,9 +114,10 @@
       const std::vector<PublicKeyCredentialDescriptor>& descriptors) const;
 
   // FindResidentCredentials returns the client-side discoverable credentials
-  // for the given |rp_id|, or base::nulltopt if an error occurred.
+  // for the given |rp_id|. If |rp_id| is not specified, all resident
+  // credentials are returned. base::nulltopt is returned if an error occurred.
   absl::optional<std::list<Credential>> FindResidentCredentials(
-      const std::string& rp_id) const;
+      const absl::optional<std::string>& rp_id) const;
 
   // DeleteCredentialsForUserId deletes all credentials for the given RP and
   // user ID. Returns true if deleting succeeded or no matching credential
@@ -133,6 +137,8 @@
   bool DeleteCredentialsSync(base::Time created_not_before,
                              base::Time created_not_after);
 
+  bool DeleteCredentialById(base::span<const uint8_t> credential_id) const;
+
   size_t CountCredentialsSync(base::Time created_not_before,
                               base::Time created_not_after);
 
@@ -143,11 +149,9 @@
 
  private:
   absl::optional<std::list<Credential>> FindCredentialsImpl(
-      const std::string& rp_id,
+      const absl::optional<std::string>& rp_id,
       const std::set<std::vector<uint8_t>>& credential_ids) const;
 
-  bool DeleteCredentialById(base::span<const uint8_t> credential_id) const;
-
   AuthenticatorConfig config_;
   LAContext* authentication_context_ = nullptr;
 };
diff --git a/device/fido/mac/credential_store.mm b/device/fido/mac/credential_store.mm
index 198cbd0..67fa61c 100644
--- a/device/fido/mac/credential_store.mm
+++ b/device/fido/mac/credential_store.mm
@@ -167,10 +167,12 @@
 
 Credential::Credential(base::ScopedCFTypeRef<SecKeyRef> private_key,
                        std::vector<uint8_t> credential_id,
-                       CredentialMetadata metadata)
+                       CredentialMetadata metadata,
+                       std::string rp_id)
     : private_key(std::move(private_key)),
       credential_id(std::move(credential_id)),
-      metadata(std::move(metadata)) {}
+      metadata(std::move(metadata)),
+      rp_id(rp_id) {}
 
 Credential::Credential(const Credential& other) = default;
 
@@ -265,7 +267,7 @@
 
   return std::make_pair(
       Credential(std::move(private_key), std::move(credential_id),
-                 std::move(credential_metadata)),
+                 std::move(credential_metadata), std::move(rp_id)),
       std::move(public_key));
 }
 
@@ -337,7 +339,7 @@
 
   return std::make_pair(
       Credential(std::move(private_key), std::move(credential_id),
-                 std::move(*metadata)),
+                 std::move(*metadata), std::move(rp_id)),
       std::move(public_key));
 }
 
@@ -364,7 +366,7 @@
 
 absl::optional<std::list<Credential>>
 TouchIdCredentialStore::FindResidentCredentials(
-    const std::string& rp_id) const {
+    const absl::optional<std::string>& rp_id) const {
   absl::optional<std::list<Credential>> credentials =
       FindCredentialsImpl(rp_id, /*credential_ids=*/{});
   if (!credentials) {
@@ -472,7 +474,7 @@
 
 absl::optional<std::list<Credential>>
 TouchIdCredentialStore::FindCredentialsImpl(
-    const std::string& rp_id,
+    const absl::optional<std::string>& rp_id,
     const std::set<std::vector<uint8_t>>& credential_ids) const {
   // Query all credentials for the RP. Filtering for `rp_id` here ensures we
   // don't retrieve credentials for other profiles, because their
@@ -505,6 +507,37 @@
   for (CFIndex i = 0; i < CFArrayGetCount(keychain_items); ++i) {
     CFDictionaryRef attributes = base::mac::CFCast<CFDictionaryRef>(
         CFArrayGetValueAtIndex(keychain_items, i));
+    if (!attributes) {
+      FIDO_LOG(ERROR) << "credential with missing attributes";
+      return absl::nullopt;
+    }
+    // Skip items that don't belong to the correct keychain access group
+    // because the kSecAttrAccessGroup filter is broken.
+    CFStringRef attr_access_group =
+        base::mac::GetValueFromDictionary<CFStringRef>(attributes,
+                                                       kSecAttrAccessGroup);
+    if (!attr_access_group) {
+      continue;
+    }
+    std::string rp_id_value;
+    if (!rp_id) {
+      CFStringRef sec_attr_label =
+          base::mac::GetValueFromDictionary<CFStringRef>(attributes,
+                                                         kSecAttrLabel);
+      if (!sec_attr_label) {
+        FIDO_LOG(ERROR) << "credential with missing kSecAttrLabel_data";
+        continue;
+      }
+      absl::optional<std::string> opt_rp_id = DecodeRpId(
+          config_.metadata_secret, base::SysCFStringRefToUTF8(sec_attr_label));
+      if (!opt_rp_id) {
+        FIDO_LOG(ERROR) << "could not decode RP ID";
+        continue;
+      }
+      rp_id_value = *opt_rp_id;
+    } else {
+      rp_id_value = *rp_id;
+    }
     CFDataRef application_label = base::mac::GetValueFromDictionary<CFDataRef>(
         attributes, kSecAttrApplicationLabel);
     if (!application_label) {
@@ -533,10 +566,10 @@
           CFDataGetBytePtr(application_tag_ref) +
               CFDataGetLength(application_tag_ref));
       metadata = UnsealMetadataFromApplicationTag(config_.metadata_secret,
-                                                  rp_id, application_tag);
+                                                  rp_id_value, application_tag);
     } else {
-      metadata = UnsealMetadataFromLegacyCredentialId(config_.metadata_secret,
-                                                      rp_id, credential_id);
+      metadata = UnsealMetadataFromLegacyCredentialId(
+          config_.metadata_secret, rp_id_value, credential_id);
     }
     if (!metadata) {
       FIDO_LOG(ERROR) << "credential with invalid metadata";
@@ -552,9 +585,9 @@
     base::ScopedCFTypeRef<SecKeyRef> private_key(key,
                                                  base::scoped_policy::RETAIN);
 
-    credentials.emplace_back(Credential{std::move(private_key),
-                                        std::move(credential_id),
-                                        std::move(*metadata)});
+    credentials.emplace_back(
+        Credential{std::move(private_key), std::move(credential_id),
+                   std::move(*metadata), std::move(rp_id_value)});
   }
   return std::move(credentials);
 }
diff --git a/device/fido/mac/fake_keychain.mm b/device/fido/mac/fake_keychain.mm
index 1ca6919..ae0e3f26 100644
--- a/device/fido/mac/fake_keychain.mm
+++ b/device/fido/mac/fake_keychain.mm
@@ -10,7 +10,6 @@
 #include "base/check_op.h"
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_cftyperef.h"
-#include "base/notreached.h"
 #include "device/fido/mac/credential_store.h"
 #include "device/fido/mac/keychain.h"
 
@@ -172,9 +171,6 @@
       return errSecSuccess;
     }
   }
-  // We only delete known items by credential ID currently, so not finding one
-  // would be odd.
-  NOTREACHED();
   return errSecItemNotFound;
 }
 
diff --git a/docs/clangd.md b/docs/clangd.md
index 18653160..883ea757 100644
--- a/docs/clangd.md
+++ b/docs/clangd.md
@@ -62,6 +62,12 @@
 use it, either by placing it first on your `PATH`, or through editor-specific
 configuration.
 
+*** note
+Note: The clangd provided by Chromium does not support optional features like
+remote indexing (see https://crbug.com/1358258). If you want those features,
+you'll need to use a different build of clangd.
+***
+
 ## Setting Up
 
 1. Make sure generated ninja files are up-to-date.
diff --git a/docs/updater/functional_spec.md b/docs/updater/functional_spec.md
index ce56b34..bf912ec 100644
--- a/docs/updater/functional_spec.md
+++ b/docs/updater/functional_spec.md
@@ -370,6 +370,12 @@
 to prevent the updater from starting if enrollment fails, set
 `EnrollmentMandatory` to `1`.
 
+After the updater sets itself up, the `FetchPolicies` RPC is invoked on the
+updater server to register with device management and fetch policies.
+
+The updater also checks for policy updates when the `RunPeriodicTasks` RPC is
+invoked at periodic intervals.
+
 #### Windows
 The `EnrollmentToken` REG_SZ value is read from
 `HKLM\Software\Policies\{COMPANY_SHORTNAME}\CloudManagement`.
diff --git a/extensions/browser/api/messaging/messaging_api_message_filter.cc b/extensions/browser/api/messaging/messaging_api_message_filter.cc
index 4211598..0a5f174 100644
--- a/extensions/browser/api/messaging/messaging_api_message_filter.cc
+++ b/extensions/browser/api/messaging/messaging_api_message_filter.cc
@@ -334,8 +334,17 @@
     const std::string& channel_name,
     const PortId& port_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (!browser_context_)
+  auto* process = GetRenderProcessHost();
+  if (!process)
     return;
+  TRACE_EVENT("extensions", "MessageFilter::OnOpenChannelToTab",
+              ChromeTrackEvent::kRenderProcessHost, *process);
+
+  if (!util::CanRendererHostExtensionOrigin(render_process_id_, extension_id)) {
+    bad_message::ReceivedBadMessage(
+        process, bad_message::EMF_INVALID_EXTENSION_ID_FOR_TAB_MSG);
+    return;
+  }
 
   ChannelEndpoint source_endpoint(browser_context_, render_process_id_,
                                   source_context);
diff --git a/extensions/browser/api/web_request/web_request_event_details.cc b/extensions/browser/api/web_request/web_request_event_details.cc
index 5cf03b0..f2601e6 100644
--- a/extensions/browser/api/web_request/web_request_event_details.cc
+++ b/extensions/browser/api/web_request/web_request_event_details.cc
@@ -38,10 +38,10 @@
 
 // Removes all headers for which predicate(header_name) returns true.
 void EraseHeadersIf(
-    base::Value* headers,
+    base::Value::List& headers,
     base::RepeatingCallback<bool(const std::string&)> predicate) {
-  headers->EraseListValueIf([&predicate](const base::Value& v) {
-    return predicate.Run(v.FindKey(keys::kHeaderNameKey)->GetString());
+  headers.EraseIf([&predicate](const base::Value& v) {
+    return predicate.Run(*v.GetDict().FindString(keys::kHeaderNameKey));
   });
 }
 
@@ -51,28 +51,26 @@
                                                int extra_info_spec)
     : extra_info_spec_(extra_info_spec),
       render_process_id_(content::ChildProcessHost::kInvalidUniqueID) {
-  dict_.SetStringKey(keys::kMethodKey, request.method);
-  dict_.SetStringKey(keys::kRequestIdKey, base::NumberToString(request.id));
-  dict_.SetDoubleKey(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000);
-  dict_.SetStringKey(keys::kTypeKey,
-                     WebRequestResourceTypeToString(request.web_request_type));
-  dict_.SetStringKey(keys::kUrlKey, request.url.spec());
-  dict_.SetIntKey(keys::kTabIdKey, request.frame_data.tab_id);
-  dict_.SetIntKey(keys::kFrameIdKey, request.frame_data.frame_id);
-  dict_.SetIntKey(keys::kParentFrameIdKey, request.frame_data.parent_frame_id);
+  dict_.Set(keys::kMethodKey, request.method);
+  dict_.Set(keys::kRequestIdKey, base::NumberToString(request.id));
+  dict_.Set(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000);
+  dict_.Set(keys::kTypeKey,
+            WebRequestResourceTypeToString(request.web_request_type));
+  dict_.Set(keys::kUrlKey, request.url.spec());
+  dict_.Set(keys::kTabIdKey, request.frame_data.tab_id);
+  dict_.Set(keys::kFrameIdKey, request.frame_data.frame_id);
+  dict_.Set(keys::kParentFrameIdKey, request.frame_data.parent_frame_id);
   if (request.frame_data.document_id) {
-    dict_.SetStringKey(keys::kDocumentIdKey,
-                       request.frame_data.document_id.ToString());
+    dict_.Set(keys::kDocumentIdKey, request.frame_data.document_id.ToString());
   }
   if (request.frame_data.parent_document_id) {
-    dict_.SetStringKey(keys::kParentDocumentIdKey,
-                       request.frame_data.parent_document_id.ToString());
+    dict_.Set(keys::kParentDocumentIdKey,
+              request.frame_data.parent_document_id.ToString());
   }
   if (request.frame_data.frame_id >= 0) {
-    dict_.SetStringKey(keys::kFrameTypeKey,
-                       ToString(request.frame_data.frame_type));
-    dict_.SetStringKey(keys::kDocumentLifecycleKey,
-                       ToString(request.frame_data.document_lifecycle));
+    dict_.Set(keys::kFrameTypeKey, ToString(request.frame_data.frame_type));
+    dict_.Set(keys::kDocumentLifecycleKey,
+              ToString(request.frame_data.document_lifecycle));
   }
   initiator_ = request.initiator;
   render_process_id_ = request.render_process_id;
@@ -83,7 +81,11 @@
 void WebRequestEventDetails::SetRequestBody(WebRequestInfo* request) {
   if (!(extra_info_spec_ & ExtraInfoSpec::REQUEST_BODY))
     return;
-  request_body_ = std::move(request->request_body_data);
+  request_body_ = absl::nullopt;
+  if (request->request_body_data) {
+    request_body_ = std::move(request->request_body_data->GetDict());
+    request->request_body_data.reset();
+  }
 }
 
 void WebRequestEventDetails::SetRequestHeaders(
@@ -91,24 +93,24 @@
   if (!(extra_info_spec_ & ExtraInfoSpec::REQUEST_HEADERS))
     return;
 
-  base::ListValue* headers = new base::ListValue();
-  for (net::HttpRequestHeaders::Iterator it(request_headers); it.GetNext();)
-    headers->Append(
-        base::Value(helpers::CreateHeaderDictionary(it.name(), it.value())));
-  request_headers_.reset(headers);
+  request_headers_ = base::Value::List();
+  for (net::HttpRequestHeaders::Iterator it(request_headers); it.GetNext();) {
+    request_headers_->Append(
+        helpers::CreateHeaderDictionary(it.name(), it.value()));
+  }
 }
 
 void WebRequestEventDetails::SetAuthInfo(
     const net::AuthChallengeInfo& auth_info) {
-  dict_.SetBoolKey(keys::kIsProxyKey, auth_info.is_proxy);
+  dict_.Set(keys::kIsProxyKey, auth_info.is_proxy);
   if (!auth_info.scheme.empty())
-    dict_.SetStringKey(keys::kSchemeKey, auth_info.scheme);
+    dict_.Set(keys::kSchemeKey, auth_info.scheme);
   if (!auth_info.realm.empty())
-    dict_.SetStringKey(keys::kRealmKey, auth_info.realm);
-  base::Value challenger(base::Value::Type::DICTIONARY);
-  challenger.SetStringKey(keys::kHostKey, auth_info.challenger.host());
-  challenger.SetIntKey(keys::kPortKey, auth_info.challenger.port());
-  dict_.SetKey(keys::kChallengerKey, std::move(challenger));
+    dict_.Set(keys::kRealmKey, auth_info.realm);
+  base::Value::Dict challenger;
+  challenger.Set(keys::kHostKey, auth_info.challenger.host());
+  challenger.Set(keys::kPortKey, auth_info.challenger.port());
+  dict_.Set(keys::kChallengerKey, std::move(challenger));
 }
 
 void WebRequestEventDetails::SetResponseHeaders(
@@ -117,15 +119,15 @@
   if (!response_headers) {
     // Not all URLRequestJobs specify response headers. E.g. URLRequestFTPJob,
     // URLRequestFileJob and some redirects.
-    dict_.SetIntKey(keys::kStatusCodeKey, request.response_code);
-    dict_.SetStringKey(keys::kStatusLineKey, "");
+    dict_.Set(keys::kStatusCodeKey, request.response_code);
+    dict_.Set(keys::kStatusLineKey, "");
   } else {
-    dict_.SetIntKey(keys::kStatusCodeKey, response_headers->response_code());
-    dict_.SetStringKey(keys::kStatusLineKey, response_headers->GetStatusLine());
+    dict_.Set(keys::kStatusCodeKey, response_headers->response_code());
+    dict_.Set(keys::kStatusLineKey, response_headers->GetStatusLine());
   }
 
   if (extra_info_spec_ & ExtraInfoSpec::RESPONSE_HEADERS) {
-    base::ListValue* headers = new base::ListValue();
+    response_headers_ = base::Value::List();
     if (response_headers) {
       size_t iter = 0;
       std::string name;
@@ -135,18 +137,16 @@
                                                                  name)) {
           continue;
         }
-        headers->Append(
-            base::Value(helpers::CreateHeaderDictionary(name, value)));
+        response_headers_->Append(helpers::CreateHeaderDictionary(name, value));
       }
     }
-    response_headers_.reset(headers);
   }
 }
 
 void WebRequestEventDetails::SetResponseSource(const WebRequestInfo& request) {
-  dict_.SetBoolKey(keys::kFromCache, request.response_from_cache);
+  dict_.Set(keys::kFromCache, request.response_from_cache);
   if (!request.response_ip.empty())
-    dict_.SetStringKey(keys::kIpKey, request.response_ip);
+    dict_.Set(keys::kIpKey, request.response_ip);
 }
 
 std::unique_ptr<base::DictionaryValue> WebRequestEventDetails::GetFilteredDict(
@@ -154,47 +154,48 @@
     PermissionHelper* permission_helper,
     const extensions::ExtensionId& extension_id,
     bool crosses_incognito) const {
-  std::unique_ptr<base::DictionaryValue> result = dict_.CreateDeepCopy();
+  base::Value::Dict result = dict_.Clone();
   if ((extra_info_spec & ExtraInfoSpec::REQUEST_BODY) && request_body_) {
-    result->SetKey(keys::kRequestBodyKey, request_body_->Clone());
+    result.Set(keys::kRequestBodyKey, request_body_->Clone());
   }
   if ((extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS) && request_headers_) {
     content::RenderProcessHost* process =
         content::RenderProcessHost::FromID(render_process_id_);
     content::BrowserContext* browser_context =
         process ? process->GetBrowserContext() : nullptr;
-    base::Value request_headers = request_headers_->Clone();
-    EraseHeadersIf(&request_headers,
+    base::Value::List request_headers = request_headers_->Clone();
+    EraseHeadersIf(request_headers,
                    base::BindRepeating(helpers::ShouldHideRequestHeader,
                                        browser_context, extra_info_spec));
-    result->SetKey(keys::kRequestHeadersKey, std::move(request_headers));
+    result.Set(keys::kRequestHeadersKey, std::move(request_headers));
   }
   if ((extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) &&
       response_headers_) {
-    base::Value response_headers = response_headers_->Clone();
-    EraseHeadersIf(&response_headers,
+    base::Value::List response_headers = response_headers_->Clone();
+    EraseHeadersIf(response_headers,
                    base::BindRepeating(helpers::ShouldHideResponseHeader,
                                        extra_info_spec));
-    result->SetKey(keys::kResponseHeadersKey, std::move(response_headers));
+    result.Set(keys::kResponseHeadersKey, std::move(response_headers));
   }
 
   // Only listeners with a permission for the initiator should receive it.
   if (initiator_) {
-    int tab_id = dict_.FindIntKey(keys::kTabIdKey).value_or(-1);
+    int tab_id = dict_.FindInt(keys::kTabIdKey).value_or(-1);
     if (initiator_->opaque() ||
         WebRequestPermissions::CanExtensionAccessInitiator(
             permission_helper, extension_id, initiator_, tab_id,
             crosses_incognito)) {
-      result->SetStringKey(keys::kInitiatorKey, initiator_->Serialize());
+      result.Set(keys::kInitiatorKey, initiator_->Serialize());
     }
   }
-  return result;
+  return base::DictionaryValue::From(
+      std::make_unique<base::Value>(std::move(result)));
 }
 
 std::unique_ptr<base::DictionaryValue>
 WebRequestEventDetails::GetAndClearDict() {
-  std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue);
-  dict_.Swap(result.get());
+  auto result = std::make_unique<base::DictionaryValue>();
+  std::swap(result->GetDict(), dict_);
   return result;
 }
 
diff --git a/extensions/browser/api/web_request/web_request_event_details.h b/extensions/browser/api/web_request/web_request_event_details.h
index 9c95ace..7c57ab2a 100644
--- a/extensions/browser/api/web_request/web_request_event_details.h
+++ b/extensions/browser/api/web_request/web_request_event_details.h
@@ -81,16 +81,12 @@
   // - ip
   void SetResponseSource(const WebRequestInfo& request);
 
-  void SetBoolean(const std::string& key, bool value) {
-    dict_.SetBoolPath(key, value);
-  }
+  void SetBoolean(const std::string& key, bool value) { dict_.Set(key, value); }
 
-  void SetInteger(const std::string& key, int value) {
-    dict_.SetIntPath(key, value);
-  }
+  void SetInteger(const std::string& key, int value) { dict_.Set(key, value); }
 
   void SetString(const std::string& key, const std::string& value) {
-    dict_.SetStringPath(key, value);
+    dict_.Set(key, value);
   }
 
   // Create an event dictionary that contains all required keys, and also the
@@ -110,12 +106,12 @@
 
  private:
   // The details that are always included in a webRequest event object.
-  base::DictionaryValue dict_;
+  base::Value::Dict dict_;
 
   // Extra event details: Only included when |extra_info_spec_| matches.
-  std::unique_ptr<base::DictionaryValue> request_body_;
-  std::unique_ptr<base::ListValue> request_headers_;
-  std::unique_ptr<base::ListValue> response_headers_;
+  absl::optional<base::Value::Dict> request_body_;
+  absl::optional<base::Value::List> request_headers_;
+  absl::optional<base::Value::List> response_headers_;
   absl::optional<url::Origin> initiator_;
 
   int extra_info_spec_;
diff --git a/extensions/browser/bad_message.h b/extensions/browser/bad_message.h
index c1589cbf8..a37a724 100644
--- a/extensions/browser/bad_message.h
+++ b/extensions/browser/bad_message.h
@@ -44,6 +44,7 @@
   EMF_INVALID_PORT_CONTEXT = 18,
   AWCI_INVALID_CALL_FROM_NOT_PRIMARY_MAIN_FRAME = 19,
   EFD_INVALID_EXTENSION_ID_FOR_PROCESS = 20,
+  EMF_INVALID_EXTENSION_ID_FOR_TAB_MSG = 21,
   // Please add new elements here. The naming convention is abbreviated class
   // name (e.g. ExtensionHost becomes EH) plus a unique description of the
   // reason. After making changes, you MUST update histograms.xml by running:
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 cf8f7ce..25c9cce 100644
--- a/extensions/renderer/api/automation/automation_internal_custom_bindings_unittests.cc
+++ b/extensions/renderer/api/automation/automation_internal_custom_bindings_unittests.cc
@@ -100,9 +100,11 @@
   ExtensionMsg_AccessibilityEventBundleParams bundle;
   bundle.updates.emplace_back();
   auto& tree_update = bundle.updates.back();
+  tree_update.root_id = 1;
   tree_update.nodes.emplace_back();
   auto& node_data = tree_update.nodes.back();
   node_data.role = ax::mojom::Role::kDesktop;
+  node_data.id = 1;
   SendOnAccessibilityEvents(bundle, true /* active profile */);
 
   ASSERT_EQ(1U, GetTreeIDToTreeMap().size());
diff --git a/fuchsia_web/webengine/browser/ax_tree_converter_unittest.cc b/fuchsia_web/webengine/browser/ax_tree_converter_unittest.cc
index ebd66a0d..d9ced44 100644
--- a/fuchsia_web/webengine/browser/ax_tree_converter_unittest.cc
+++ b/fuchsia_web/webengine/browser/ax_tree_converter_unittest.cc
@@ -305,7 +305,7 @@
 
 TEST_F(AXTreeConverterTest, SomeFieldsSetAndEqual) {
   ui::AXNodeData source_node_data;
-  source_node_data.id = 0;
+  source_node_data.id = 1;
   source_node_data.AddAction(ax::mojom::Action::kFocus);
   source_node_data.AddAction(ax::mojom::Action::kSetValue);
   source_node_data.child_ids = std::vector<int32_t>{kChildId1};
@@ -319,7 +319,7 @@
       ui::AXTreeID::CreateNewAXTreeID(), false, 0.0f, &mapper);
 
   Node expected_node;
-  expected_node.set_node_id(0);
+  expected_node.set_node_id(1);
   expected_node.set_actions(
       std::vector<Action>{Action::SET_FOCUS, Action::SET_VALUE});
   expected_node.set_child_ids(std::vector<uint32_t>{kChildId1});
@@ -483,7 +483,7 @@
 TEST_F(AXTreeConverterTest, ConvertRoles) {
   MockNodeIDMapper mapper;
   ui::AXNodeData node;
-  node.id = 0;
+  node.id = 1;
   node.role = ax::mojom::Role::kButton;
   EXPECT_EQ(fuchsia::accessibility::semantics::Role::BUTTON,
             AXNodeDataToSemanticNode(AddChildNode(node), root_node(),
@@ -671,7 +671,7 @@
 TEST_F(AXTreeConverterTest, IgnoredAndInvisibleNodesAreMarkedAsHidden) {
   MockNodeIDMapper mapper;
   ui::AXNodeData node;
-  node.id = 0;
+  node.id = 1;
   node.AddState(ax::mojom::State::kInvisible);
   EXPECT_TRUE(AXNodeDataToSemanticNode(AddChildNode(node), root_node(),
                                        ui::AXTreeID::CreateNewAXTreeID(), false,
diff --git a/gpu/command_buffer/client/query_tracker.h b/gpu/command_buffer/client/query_tracker.h
index 8cee050..1919b13 100644
--- a/gpu/command_buffer/client/query_tracker.h
+++ b/gpu/command_buffer/client/query_tracker.h
@@ -60,8 +60,8 @@
 
     uint32_t index() const { return sync - bucket->syncs; }
 
-    Bucket* bucket = nullptr;
-    QuerySync* sync = nullptr;
+    raw_ptr<Bucket> bucket = nullptr;
+    raw_ptr<QuerySync> sync = nullptr;
     int32_t submit_count = 0;
   };
 
diff --git a/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.cc
index 528b296..e2c0512 100644
--- a/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.cc
@@ -683,10 +683,11 @@
 bool AHardwareBufferImageBackingFactory::IsSupported(
     uint32_t usage,
     viz::ResourceFormat format,
+    const gfx::Size& size,
     bool thread_safe,
     gfx::GpuMemoryBufferType gmb_type,
     GrContextType gr_context_type,
-    bool is_pixel_used) {
+    base::span<const uint8_t> pixel_data) {
   if (gmb_type != gfx::EMPTY_BUFFER && !CanImportGpuMemoryBuffer(gmb_type)) {
     return false;
   }
diff --git a/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.h b/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.h
index 35193e5..ee9bba72 100644
--- a/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/ahardwarebuffer_image_backing_factory.h
@@ -73,10 +73,11 @@
       uint32_t usage) override;
   bool IsSupported(uint32_t usage,
                    viz::ResourceFormat format,
+                   const gfx::Size& size,
                    bool thread_safe,
                    gfx::GpuMemoryBufferType gmb_type,
                    GrContextType gr_context_type,
-                   bool is_pixel_used) override;
+                   base::span<const uint8_t> pixel_data) override;
   bool IsFormatSupported(viz::ResourceFormat format);
 
  private:
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.cc
index 616297e..531908c 100644
--- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.cc
@@ -545,17 +545,11 @@
     SkAlphaType alpha_type,
     uint32_t usage,
     bool is_thread_safe) {
-  const FormatInfo& format_info = format_info_[format];
-  if (!CanCreateSharedImage(size, /*pixel_data=*/{}, format_info,
-                            GL_TEXTURE_2D)) {
-    return nullptr;
-  }
-
   auto backing = std::make_unique<AngleVulkanImageBacking>(
       context_state_, mailbox, format, size, color_space, surface_origin,
       alpha_type, usage);
 
-  if (!backing->Initialize(format_info, {}))
+  if (!backing->Initialize(format_info_[format], {}))
     return nullptr;
 
   return backing;
@@ -571,15 +565,11 @@
     SkAlphaType alpha_type,
     uint32_t usage,
     base::span<const uint8_t> data) {
-  const FormatInfo& format_info = format_info_[format];
-  if (!CanCreateSharedImage(size, data, format_info, GL_TEXTURE_2D))
-    return nullptr;
-
   auto backing = std::make_unique<AngleVulkanImageBacking>(
       context_state_, mailbox, format, size, color_space, surface_origin,
       alpha_type, usage);
 
-  if (!backing->Initialize(format_info, data))
+  if (!backing->Initialize(format_info_[format], data))
     return nullptr;
 
   return backing;
@@ -629,10 +619,11 @@
 bool AngleVulkanImageBackingFactory::IsSupported(
     uint32_t usage,
     viz::ResourceFormat format,
+    const gfx::Size& size,
     bool thread_safe,
     gfx::GpuMemoryBufferType gmb_type,
     GrContextType gr_context_type,
-    bool is_pixel_used) {
+    base::span<const uint8_t> pixel_data) {
   DCHECK_EQ(gr_context_type, GrContextType::kVulkan);
   if (!CanUseAngleVulkanImageBacking(usage))
     return false;
@@ -644,7 +635,8 @@
     return false;
   }
 
-  return true;
+  return CanCreateSharedImage(size, pixel_data, format_info_[format],
+                              GL_TEXTURE_2D);
 }
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.h b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.h
index 11fd3f9..4a186f5 100644
--- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing_factory.h
@@ -52,10 +52,11 @@
       uint32_t usage) override;
   bool IsSupported(uint32_t usage,
                    viz::ResourceFormat format,
+                   const gfx::Size& size,
                    bool thread_safe,
                    gfx::GpuMemoryBufferType gmb_type,
                    GrContextType gr_context_type,
-                   bool is_pixel_used) override;
+                   base::span<const uint8_t> pixel_data) override;
 
  private:
   bool CanUseAngleVulkanImageBacking(uint32_t usage) const;
diff --git a/gpu/command_buffer/service/shared_image/compound_image_backing_unittest.cc b/gpu/command_buffer/service/shared_image/compound_image_backing_unittest.cc
index 0f060ed..b819154 100644
--- a/gpu/command_buffer/service/shared_image/compound_image_backing_unittest.cc
+++ b/gpu/command_buffer/service/shared_image/compound_image_backing_unittest.cc
@@ -67,10 +67,11 @@
   }
   bool IsSupported(uint32_t usage,
                    viz::ResourceFormat format,
+                   const gfx::Size& size,
                    bool thread_safe,
                    gfx::GpuMemoryBufferType gmb_type,
                    GrContextType gr_context_type,
-                   bool is_pixel_used) override {
+                   base::span<const uint8_t> pixel_data) override {
     return true;
   }
 };
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc
index c136848..07b48ba0 100644
--- a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc
@@ -567,11 +567,12 @@
 
 bool D3DImageBackingFactory::IsSupported(uint32_t usage,
                                          viz::ResourceFormat format,
+                                         const gfx::Size& size,
                                          bool thread_safe,
                                          gfx::GpuMemoryBufferType gmb_type,
                                          GrContextType gr_context_type,
-                                         bool is_pixel_used) {
-  if (is_pixel_used) {
+                                         base::span<const uint8_t> pixel_data) {
+  if (!pixel_data.empty()) {
     return false;
   }
   if (gmb_type == gfx::EMPTY_BUFFER) {
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h
index 32a1c497a..1546ea3 100644
--- a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h
@@ -112,10 +112,11 @@
 
   bool IsSupported(uint32_t usage,
                    viz::ResourceFormat format,
+                   const gfx::Size& size,
                    bool thread_safe,
                    gfx::GpuMemoryBufferType gmb_type,
                    GrContextType gr_context_type,
-                   bool is_pixel_used) override;
+                   base::span<const uint8_t> pixel_data) override;
 
   // Returns true if the specified GpuMemoryBufferType can be imported using
   // this factory.
diff --git a/gpu/command_buffer/service/shared_image/egl_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/egl_image_backing_factory.cc
index 014c2bb..dbf1afb 100644
--- a/gpu/command_buffer/service/shared_image/egl_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/egl_image_backing_factory.cc
@@ -81,11 +81,12 @@
 
 bool EGLImageBackingFactory::IsSupported(uint32_t usage,
                                          viz::ResourceFormat format,
+                                         const gfx::Size& size,
                                          bool thread_safe,
                                          gfx::GpuMemoryBufferType gmb_type,
                                          GrContextType gr_context_type,
-                                         bool is_pixel_used) {
-  if (is_pixel_used && gr_context_type != GrContextType::kGL) {
+                                         base::span<const uint8_t> pixel_data) {
+  if (!pixel_data.empty() && gr_context_type != GrContextType::kGL) {
     return false;
   }
 
@@ -106,7 +107,9 @@
   if (usage & kInvalidUsage) {
     return false;
   }
-  return true;
+
+  return CanCreateSharedImage(size, pixel_data, format_info_[format],
+                              GL_TEXTURE_2D);
 }
 
 std::unique_ptr<SharedImageBacking> EGLImageBackingFactory::MakeEglImageBacking(
@@ -120,12 +123,6 @@
     base::span<const uint8_t> pixel_data) {
   DCHECK(!(usage & SHARED_IMAGE_USAGE_SCANOUT));
 
-  const FormatInfo& format_info = format_info_[format];
-  GLenum target = GL_TEXTURE_2D;
-  if (!CanCreateSharedImage(size, pixel_data, format_info, target)) {
-    return nullptr;
-  }
-
   // Calculate SharedImage size in bytes.
   size_t estimated_size;
   if (!viz::ResourceSizes::MaybeSizeInBytes(size, format, &estimated_size)) {
@@ -135,7 +132,8 @@
 
   return std::make_unique<EGLImageBacking>(
       mailbox, format, size, color_space, surface_origin, alpha_type, usage,
-      estimated_size, format_info, workarounds_, use_passthrough_, pixel_data);
+      estimated_size, format_info_[format], workarounds_, use_passthrough_,
+      pixel_data);
 }
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image/egl_image_backing_factory.h b/gpu/command_buffer/service/shared_image/egl_image_backing_factory.h
index 6b4b0da1..d685a3d9 100644
--- a/gpu/command_buffer/service/shared_image/egl_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/egl_image_backing_factory.h
@@ -71,10 +71,11 @@
       uint32_t usage) override;
   bool IsSupported(uint32_t usage,
                    viz::ResourceFormat format,
+                   const gfx::Size& size,
                    bool thread_safe,
                    gfx::GpuMemoryBufferType gmb_type,
                    GrContextType gr_context_type,
-                   bool is_pixel_used) override;
+                   base::span<const uint8_t> pixel_data) override;
 
  private:
   std::unique_ptr<SharedImageBacking> MakeEglImageBacking(
diff --git a/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory.cc
index 63f8e16..34aded3 100644
--- a/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory.cc
@@ -163,10 +163,11 @@
 bool ExternalVkImageBackingFactory::IsSupported(
     uint32_t usage,
     viz::ResourceFormat format,
+    const gfx::Size& size,
     bool thread_safe,
     gfx::GpuMemoryBufferType gmb_type,
     GrContextType gr_context_type,
-    bool is_pixel_used) {
+    base::span<const uint8_t> pixel_data) {
   if (gmb_type != gfx::EMPTY_BUFFER && !CanImportGpuMemoryBuffer(gmb_type)) {
     return false;
   }
diff --git a/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory.h b/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory.h
index 9910edc..c906dd360 100644
--- a/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/external_vk_image_backing_factory.h
@@ -67,10 +67,11 @@
       uint32_t usage) override;
   bool IsSupported(uint32_t usage,
                    viz::ResourceFormat format,
+                   const gfx::Size& size,
                    bool thread_safe,
                    gfx::GpuMemoryBufferType gmb_type,
                    GrContextType gr_context_type,
-                   bool is_pixel_used) override;
+                   base::span<const uint8_t> pixel_data) override;
 
  private:
   VkResult CreateExternalVkImage(VkFormat format,
diff --git a/gpu/command_buffer/service/shared_image/gl_image_backing.cc b/gpu/command_buffer/service/shared_image/gl_image_backing.cc
index 3872323..3d8e21f 100644
--- a/gpu/command_buffer/service/shared_image/gl_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/gl_image_backing.cc
@@ -352,6 +352,14 @@
       cleared_rect_(params.is_cleared ? gfx::Rect(size) : gfx::Rect()),
       weak_factory_(this) {
   DCHECK(image_);
+#if BUILDFLAG(IS_MAC)
+  // NOTE: Mac currently retains GLTexture and reuses it. Not sure if this is
+  // best approach as it can lead to issues with context losses.
+  if (!gl_texture_retained_for_legacy_mailbox_) {
+    RetainGLTexture();
+    gl_texture_retained_for_legacy_mailbox_ = true;
+  }
+#endif
 }
 
 GLImageBacking::~GLImageBacking() {
diff --git a/gpu/command_buffer/service/shared_image/gl_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/gl_image_backing_factory.cc
index 30e44aa..cd45ca8 100644
--- a/gpu/command_buffer/service/shared_image/gl_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/gl_image_backing_factory.cc
@@ -245,11 +245,12 @@
 
 bool GLImageBackingFactory::IsSupported(uint32_t usage,
                                         viz::ResourceFormat format,
+                                        const gfx::Size& size,
                                         bool thread_safe,
                                         gfx::GpuMemoryBufferType gmb_type,
                                         GrContextType gr_context_type,
-                                        bool is_pixel_used) {
-  if (is_pixel_used && gr_context_type != GrContextType::kGL) {
+                                        base::span<const uint8_t> pixel_data) {
+  if (!pixel_data.empty() && gr_context_type != GrContextType::kGL) {
     return false;
   }
   if (thread_safe) {
diff --git a/gpu/command_buffer/service/shared_image/gl_image_backing_factory.h b/gpu/command_buffer/service/shared_image/gl_image_backing_factory.h
index 83cc179..b9205bf 100644
--- a/gpu/command_buffer/service/shared_image/gl_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/gl_image_backing_factory.h
@@ -81,10 +81,11 @@
       uint32_t usage) override;
   bool IsSupported(uint32_t usage,
                    viz::ResourceFormat format,
+                   const gfx::Size& size,
                    bool thread_safe,
                    gfx::GpuMemoryBufferType gmb_type,
                    GrContextType gr_context_type,
-                   bool is_pixel_used) override;
+                   base::span<const uint8_t> pixel_data) override;
 
  private:
   scoped_refptr<gl::GLImage> MakeGLImage(int client_id,
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 eaaa74a..d3ceb3ec 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
@@ -119,11 +119,12 @@
 bool GLTextureImageBackingFactory::IsSupported(
     uint32_t usage,
     viz::ResourceFormat format,
+    const gfx::Size& size,
     bool thread_safe,
     gfx::GpuMemoryBufferType gmb_type,
     GrContextType gr_context_type,
-    bool is_pixel_used) {
-  if (is_pixel_used && gr_context_type != GrContextType::kGL) {
+    base::span<const uint8_t> pixel_data) {
+  if (!pixel_data.empty() && gr_context_type != GrContextType::kGL) {
     return false;
   }
   if (thread_safe) {
@@ -160,7 +161,8 @@
 #endif
   }
 
-  return true;
+  return CanCreateSharedImage(size, pixel_data, format_info_[format],
+                              GL_TEXTURE_2D);
 }
 
 std::unique_ptr<SharedImageBacking>
@@ -176,9 +178,6 @@
     base::span<const uint8_t> pixel_data) {
   const FormatInfo& format_info = format_info_[format];
   GLenum target = GL_TEXTURE_2D;
-  if (!CanCreateSharedImage(size, pixel_data, format_info, target)) {
-    return nullptr;
-  }
 
   const bool for_framebuffer_attachment =
       (usage & (SHARED_IMAGE_USAGE_RASTER |
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.h b/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.h
index 13d5a58..d6fd864a 100644
--- a/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.h
@@ -71,10 +71,11 @@
       uint32_t usage) override;
   bool IsSupported(uint32_t usage,
                    viz::ResourceFormat format,
+                   const gfx::Size& size,
                    bool thread_safe,
                    gfx::GpuMemoryBufferType gmb_type,
                    GrContextType gr_context_type,
-                   bool is_pixel_used) override;
+                   base::span<const uint8_t> pixel_data) override;
 
   static std::unique_ptr<SharedImageBacking> CreateSharedImageForTest(
       const Mailbox& mailbox,
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory_unittest.cc b/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory_unittest.cc
index 812223a5..75a781d 100644
--- a/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory_unittest.cc
+++ b/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory_unittest.cc
@@ -35,6 +35,7 @@
 #include "third_party/skia/include/gpu/GrDirectContext.h"
 #include "ui/gfx/buffer_format_util.h"
 #include "ui/gfx/color_space.h"
+#include "ui/gfx/gpu_memory_buffer.h"
 #include "ui/gl/gl_surface.h"
 #include "ui/gl/gl_utils.h"
 #include "ui/gl/init/gl_factory.h"
@@ -178,14 +179,18 @@
   SkAlphaType alpha_type = kPremul_SkAlphaType;
   uint32_t usage = SHARED_IMAGE_USAGE_GLES2;
   gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle;
+
+  bool supported =
+      backing_factory_->IsSupported(usage, format, size, /*thread_safe=*/false,
+                                    gfx::EMPTY_BUFFER, GrContextType::kGL, {});
+
+  EXPECT_EQ(should_succeed, supported);
+  if (!should_succeed)
+    return;
+
   auto backing = backing_factory_->CreateSharedImage(
       mailbox, format, surface_handle, size, color_space, surface_origin,
       alpha_type, usage, false /* is_thread_safe */);
-
-  if (!should_succeed) {
-    EXPECT_FALSE(backing);
-    return;
-  }
   ASSERT_TRUE(backing);
 
   // Check clearing.
@@ -290,14 +295,19 @@
     uint32_t usage = SHARED_IMAGE_USAGE_GLES2;
     std::vector<uint8_t> initial_data(
         viz::ResourceSizes::CheckedSizeInBytes<unsigned int>(size, format));
+
+    bool supported = backing_factory_->IsSupported(
+        usage, format, size, /*thread_safe=*/false, gfx::EMPTY_BUFFER,
+        GrContextType::kGL, initial_data);
+
+    EXPECT_EQ(should_succeed, supported);
+    if (!should_succeed)
+      return;
+
     auto backing = backing_factory_->CreateSharedImage(
         mailbox, format, size, color_space, surface_origin, alpha_type, usage,
         initial_data);
     ::testing::Mock::VerifyAndClearExpectations(&progress_reporter_);
-    if (!should_succeed) {
-      EXPECT_FALSE(backing);
-      continue;
-    }
     ASSERT_TRUE(backing);
     EXPECT_TRUE(backing->IsCleared());
 
@@ -349,13 +359,18 @@
   SkAlphaType alpha_type = kPremul_SkAlphaType;
   uint32_t usage = SHARED_IMAGE_USAGE_GLES2;
   std::vector<uint8_t> initial_data(256 * 256 * 4);
+
+  bool supported = backing_factory_->IsSupported(
+      usage, format, size, /*thread_safe=*/false, gfx::EMPTY_BUFFER,
+      GrContextType::kGL, initial_data);
+  EXPECT_EQ(should_succeed, supported);
+
+  if (!should_succeed)
+    return;
+
   auto backing = backing_factory_->CreateSharedImage(
       mailbox, format, size, color_space, surface_origin, alpha_type, usage,
       initial_data);
-  if (!should_succeed) {
-    EXPECT_FALSE(backing);
-    return;
-  }
   ASSERT_TRUE(backing);
 
   // Validate via a GLTextureImageRepresentation(Passthrough).
@@ -388,59 +403,45 @@
 }
 
 TEST_P(GLTextureImageBackingFactoryTest, InitialDataWrongSize) {
-  auto mailbox = Mailbox::GenerateForSharedImage();
   auto format = get_format();
   gfx::Size size(256, 256);
-  auto color_space = gfx::ColorSpace::CreateSRGB();
-  GrSurfaceOrigin surface_origin = kTopLeft_GrSurfaceOrigin;
-  SkAlphaType alpha_type = kPremul_SkAlphaType;
   uint32_t usage = SHARED_IMAGE_USAGE_GLES2;
   std::vector<uint8_t> initial_data_small(256 * 128 * 4);
   std::vector<uint8_t> initial_data_large(256 * 512 * 4);
-  auto backing = backing_factory_->CreateSharedImage(
-      mailbox, format, size, color_space, surface_origin, alpha_type, usage,
-      initial_data_small);
-  EXPECT_FALSE(backing);
-  backing = backing_factory_->CreateSharedImage(
-      mailbox, format, size, color_space, surface_origin, alpha_type, usage,
-      initial_data_large);
-  EXPECT_FALSE(backing);
+  bool supported = backing_factory_->IsSupported(
+      usage, format, size, /*thread_safe=*/false, gfx::EMPTY_BUFFER,
+      GrContextType::kGL, initial_data_small);
+  EXPECT_FALSE(supported);
+  supported = backing_factory_->IsSupported(
+      usage, format, size, /*thread_safe=*/false, gfx::EMPTY_BUFFER,
+      GrContextType::kGL, initial_data_large);
+  EXPECT_FALSE(supported);
 }
 
 TEST_P(GLTextureImageBackingFactoryTest, InvalidFormat) {
-  auto mailbox = Mailbox::GenerateForSharedImage();
   auto format = viz::ResourceFormat::YUV_420_BIPLANAR;
   gfx::Size size(256, 256);
-  auto color_space = gfx::ColorSpace::CreateSRGB();
-  GrSurfaceOrigin surface_origin = kTopLeft_GrSurfaceOrigin;
-  SkAlphaType alpha_type = kPremul_SkAlphaType;
-  gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle;
   uint32_t usage = SHARED_IMAGE_USAGE_GLES2;
-  auto backing = backing_factory_->CreateSharedImage(
-      mailbox, format, surface_handle, size, color_space, surface_origin,
-      alpha_type, usage, false /* is_thread_safe */);
-  EXPECT_FALSE(backing);
+  bool supported =
+      backing_factory_->IsSupported(usage, format, size, /*thread_safe=*/false,
+                                    gfx::EMPTY_BUFFER, GrContextType::kGL, {});
+  EXPECT_FALSE(supported);
 }
 
 TEST_P(GLTextureImageBackingFactoryTest, InvalidSize) {
-  auto mailbox = Mailbox::GenerateForSharedImage();
   auto format = get_format();
   gfx::Size size(0, 0);
-  auto color_space = gfx::ColorSpace::CreateSRGB();
-  GrSurfaceOrigin surface_origin = kTopLeft_GrSurfaceOrigin;
-  SkAlphaType alpha_type = kPremul_SkAlphaType;
-  gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle;
   uint32_t usage = SHARED_IMAGE_USAGE_GLES2;
-  auto backing = backing_factory_->CreateSharedImage(
-      mailbox, format, surface_handle, size, color_space, surface_origin,
-      alpha_type, usage, false /* is_thread_safe */);
-  EXPECT_FALSE(backing);
+  bool supported =
+      backing_factory_->IsSupported(usage, format, size, /*thread_safe=*/false,
+                                    gfx::EMPTY_BUFFER, GrContextType::kGL, {});
+  EXPECT_FALSE(supported);
 
   size = gfx::Size(INT_MAX, INT_MAX);
-  backing = backing_factory_->CreateSharedImage(
-      mailbox, format, surface_handle, size, color_space, surface_origin,
-      alpha_type, usage, false /* is_thread_safe */);
-  EXPECT_FALSE(backing);
+  supported =
+      backing_factory_->IsSupported(usage, format, size, /*thread_safe=*/false,
+                                    gfx::EMPTY_BUFFER, GrContextType::kGL, {});
+  EXPECT_FALSE(supported);
 }
 
 TEST_P(GLTextureImageBackingFactoryTest, EstimatedSize) {
@@ -455,14 +456,18 @@
   SkAlphaType alpha_type = kPremul_SkAlphaType;
   gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle;
   uint32_t usage = SHARED_IMAGE_USAGE_GLES2;
+
+  bool supported =
+      backing_factory_->IsSupported(usage, format, size, /*thread_safe=*/false,
+                                    gfx::EMPTY_BUFFER, GrContextType::kGL, {});
+
+  EXPECT_EQ(should_succeed, supported);
+  if (!should_succeed)
+    return;
+
   auto backing = backing_factory_->CreateSharedImage(
       mailbox, format, surface_handle, size, color_space, surface_origin,
       alpha_type, usage, false /* is_thread_safe */);
-
-  if (!should_succeed) {
-    EXPECT_FALSE(backing);
-    return;
-  }
   ASSERT_TRUE(backing);
 
   size_t backing_estimated_size = backing->estimated_size();
diff --git a/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.cc
index 3c0c6a9..9b66c3c 100644
--- a/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.cc
@@ -173,12 +173,14 @@
   return backing;
 }
 
-bool OzoneImageBackingFactory::IsSupported(uint32_t usage,
-                                           viz::ResourceFormat format,
-                                           bool thread_safe,
-                                           gfx::GpuMemoryBufferType gmb_type,
-                                           GrContextType gr_context_type,
-                                           bool is_pixel_used) {
+bool OzoneImageBackingFactory::IsSupported(
+    uint32_t usage,
+    viz::ResourceFormat format,
+    const gfx::Size& size,
+    bool thread_safe,
+    gfx::GpuMemoryBufferType gmb_type,
+    GrContextType gr_context_type,
+    base::span<const uint8_t> pixel_data) {
   if (gmb_type != gfx::EMPTY_BUFFER && gmb_type != gfx::NATIVE_PIXMAP) {
     return false;
   }
diff --git a/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.h b/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.h
index 82402e34..2730fa03 100644
--- a/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/ozone_image_backing_factory.h
@@ -65,10 +65,11 @@
 
   bool IsSupported(uint32_t usage,
                    viz::ResourceFormat format,
+                   const gfx::Size& size,
                    bool thread_safe,
                    gfx::GpuMemoryBufferType gmb_type,
                    GrContextType gr_context_type,
-                   bool is_pixel_used) override;
+                   base::span<const uint8_t> pixel_data) override;
 
  private:
   bool CanImportNativePixmapToVulkan();
diff --git a/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.cc
index 21ac69c..c1403693 100644
--- a/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.cc
@@ -74,17 +74,19 @@
   return usage == kRawDrawImageBackingUsage;
 }
 
-bool RawDrawImageBackingFactory::IsSupported(uint32_t usage,
-                                             viz::ResourceFormat format,
-                                             bool thread_safe,
-                                             gfx::GpuMemoryBufferType gmb_type,
-                                             GrContextType gr_context_type,
-                                             bool is_pixel_used) {
+bool RawDrawImageBackingFactory::IsSupported(
+    uint32_t usage,
+    viz::ResourceFormat format,
+    const gfx::Size& size,
+    bool thread_safe,
+    gfx::GpuMemoryBufferType gmb_type,
+    GrContextType gr_context_type,
+    base::span<const uint8_t> pixel_data) {
   if (!CanUseRawDrawImageBacking(usage, gr_context_type)) {
     return false;
   }
 
-  if (is_pixel_used) {
+  if (!pixel_data.empty()) {
     return false;
   }
 
diff --git a/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.h b/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.h
index 8ab870b0..fff73361 100644
--- a/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.h
@@ -50,10 +50,11 @@
       uint32_t usage) override;
   bool IsSupported(uint32_t usage,
                    viz::ResourceFormat format,
+                   const gfx::Size& size,
                    bool thread_safe,
                    gfx::GpuMemoryBufferType gmb_type,
                    GrContextType gr_context_type,
-                   bool is_pixel_used) override;
+                   base::span<const uint8_t> pixel_data) override;
 
  private:
   bool CanUseRawDrawImageBacking(uint32_t usage,
diff --git a/gpu/command_buffer/service/shared_image/shared_image_backing_factory.h b/gpu/command_buffer/service/shared_image/shared_image_backing_factory.h
index bbbcbdc6..e8efb25 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/shared_image_backing_factory.h
@@ -71,10 +71,11 @@
   // Returns true if the factory is supported
   virtual bool IsSupported(uint32_t usage,
                            viz::ResourceFormat format,
+                           const gfx::Size& size,
                            bool thread_safe,
                            gfx::GpuMemoryBufferType gmb_type,
                            GrContextType gr_context_type,
-                           bool is_pixel_used) = 0;
+                           base::span<const uint8_t> pixel_data) = 0;
 };
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image/shared_image_factory.cc b/gpu/command_buffer/service/shared_image/shared_image_factory.cc
index ed2b50f..296c57a2 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_factory.cc
+++ b/gpu/command_buffer/service/shared_image/shared_image_factory.cc
@@ -452,8 +452,8 @@
                                            SkAlphaType alpha_type,
                                            gpu::SurfaceHandle surface_handle,
                                            uint32_t usage) {
-  auto* factory = GetFactoryByUsage(usage, format,
-                                    /*is_pixel_used=*/false, gfx::EMPTY_BUFFER);
+  auto* factory = GetFactoryByUsage(usage, format, size,
+                                    /*pixel_data=*/{}, gfx::EMPTY_BUFFER);
   if (!factory)
     return false;
 
@@ -490,8 +490,7 @@
   if (backing_factory_for_testing_) {
     factory = backing_factory_for_testing_;
   } else {
-    factory = GetFactoryByUsage(usage, format,
-                                /*is_pixel_used=*/true, gfx::EMPTY_BUFFER);
+    factory = GetFactoryByUsage(usage, format, size, data, gfx::EMPTY_BUFFER);
   }
   if (!factory)
     return false;
@@ -525,9 +524,8 @@
   gfx::GpuMemoryBufferType gmb_type = handle.type;
 
   bool use_compound = false;
-  auto* factory =
-      GetFactoryByUsage(usage, resource_format,
-                        /*is_pixel_used=*/false, gmb_type, &use_compound);
+  auto* factory = GetFactoryByUsage(usage, resource_format, size,
+                                    /*pixel_data=*/{}, gmb_type, &use_compound);
   if (!factory)
     return false;
 
@@ -747,7 +745,8 @@
 SharedImageBackingFactory* SharedImageFactory::GetFactoryByUsage(
     uint32_t usage,
     viz::ResourceFormat format,
-    bool is_pixel_used,
+    const gfx::Size& size,
+    base::span<const uint8_t> pixel_data,
     gfx::GpuMemoryBufferType gmb_type,
     bool* use_compound_backing) {
   if (backing_factory_for_testing_)
@@ -755,15 +754,15 @@
 
   bool share_between_threads = IsSharedBetweenThreads(usage);
   for (auto& factory : factories_) {
-    if (factory->IsSupported(usage, format, share_between_threads, gmb_type,
-                             gr_context_type_, is_pixel_used)) {
+    if (factory->IsSupported(usage, format, size, share_between_threads,
+                             gmb_type, gr_context_type_, pixel_data)) {
       return factory.get();
     } else if (use_compound_backing && gmb_type == gfx::SHARED_MEMORY_BUFFER) {
       // Check if backing type supports CPU upload with no buffer handle so it
       // can be used with a compound backing instead.
       if (factory->IsSupported(usage | SHARED_IMAGE_USAGE_CPU_UPLOAD, format,
-                               share_between_threads, gfx::EMPTY_BUFFER,
-                               gr_context_type_, is_pixel_used)) {
+                               size, share_between_threads, gfx::EMPTY_BUFFER,
+                               gr_context_type_, pixel_data)) {
         *use_compound_backing = true;
         return factory.get();
       }
diff --git a/gpu/command_buffer/service/shared_image/shared_image_factory.h b/gpu/command_buffer/service/shared_image/shared_image_factory.h
index cbf1ba8..f4aa23a2 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_factory.h
+++ b/gpu/command_buffer/service/shared_image/shared_image_factory.h
@@ -146,7 +146,8 @@
   SharedImageBackingFactory* GetFactoryByUsage(
       uint32_t usage,
       viz::ResourceFormat format,
-      bool is_pixel_used,
+      const gfx::Size& size,
+      base::span<const uint8_t> pixel_data,
       gfx::GpuMemoryBufferType gmb_type,
       bool* use_compound_backing = nullptr);
 
diff --git a/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.cc
index 111d238f..60594bb 100644
--- a/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.cc
@@ -76,10 +76,11 @@
 bool SharedMemoryImageBackingFactory::IsSupported(
     uint32_t usage,
     viz::ResourceFormat format,
+    const gfx::Size& size,
     bool thread_safe,
     gfx::GpuMemoryBufferType gmb_type,
     GrContextType gr_context_type,
-    bool is_pixel_used) {
+    base::span<const uint8_t> pixel_data) {
   if (gmb_type != gfx::SHARED_MEMORY_BUFFER) {
     return false;
   }
diff --git a/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.h b/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.h
index 174c83b..f6f9777 100644
--- a/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.h
@@ -56,10 +56,11 @@
 
   bool IsSupported(uint32_t usage,
                    viz::ResourceFormat format,
+                   const gfx::Size& size,
                    bool thread_safe,
                    gfx::GpuMemoryBufferType gmb_type,
                    GrContextType gr_context_type,
-                   bool is_pixel_used) override;
+                   base::span<const uint8_t> pixel_data) override;
 };
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc
index f520e8cb..e529c9b 100644
--- a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc
+++ b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc
@@ -504,10 +504,11 @@
 bool WrappedSkImageBackingFactory::IsSupported(
     uint32_t usage,
     viz::ResourceFormat format,
+    const gfx::Size& size,
     bool thread_safe,
     gfx::GpuMemoryBufferType gmb_type,
     GrContextType gr_context_type,
-    bool is_pixel_used) {
+    base::span<const uint8_t> pixel_data) {
   // Note that this backing support thread safety only for vulkan mode because
   // the underlying vulkan resources like vulkan images can be shared across
   // multiple vulkan queues. Also note that this backing currently only supports
diff --git a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.h b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.h
index cb2749e..241f634 100644
--- a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.h
+++ b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.h
@@ -64,10 +64,11 @@
       uint32_t usage) override;
   bool IsSupported(uint32_t usage,
                    viz::ResourceFormat format,
+                   const gfx::Size& size,
                    bool thread_safe,
                    gfx::GpuMemoryBufferType gmb_type,
                    GrContextType gr_context_type,
-                   bool is_pixel_used) override;
+                   base::span<const uint8_t> pixel_data) override;
 
  private:
   bool CanUseWrappedSkImage(uint32_t usage,
diff --git a/headless/app/headless_shell.cc b/headless/app/headless_shell.cc
index d73059150..e996ef9 100644
--- a/headless/app/headless_shell.cc
+++ b/headless/app/headless_shell.cc
@@ -32,7 +32,6 @@
 #include "content/public/app/content_main.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/render_process_host.h"
 #include "content/public/common/content_switches.h"
 #include "headless/app/headless_shell.h"
 #include "headless/app/headless_shell_switches.h"
@@ -332,8 +331,6 @@
 
 void HeadlessShell::Shutdown() {
   DCHECK(!web_contents_);
-  if (content::RenderProcessHost::run_renderer_in_process())
-    content::RenderProcessHost::ShutDownInProcessRenderer();
   browser_->Shutdown();
 }
 
diff --git a/headless/lib/browser/headless_browser_context_impl.cc b/headless/lib/browser/headless_browser_context_impl.cc
index b2aec65..88fac86 100644
--- a/headless/lib/browser/headless_browser_context_impl.cc
+++ b/headless/lib/browser/headless_browser_context_impl.cc
@@ -17,6 +17,7 @@
 #include "components/profile_metrics/browser_profile_type.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
 #include "content/public/browser/storage_partition.h"
 #include "headless/lib/browser/headless_browser_context_options.h"
 #include "headless/lib/browser/headless_browser_impl.h"
@@ -85,9 +86,15 @@
   SimpleKeyMap::GetInstance()->Dissociate(this);
   NotifyWillBeDestroyed();
 
-  // Destroy all web contents before shutting down storage partitions.
+  // Destroy all web contents before shutting down in process renderer and
+  // storage partitions.
   web_contents_map_.clear();
 
+  // In single process mode we can only have one browser context, so it's
+  // safe to shutdown the in-process renderer here.
+  if (content::RenderProcessHost::run_renderer_in_process())
+    content::RenderProcessHost::ShutDownInProcessRenderer();
+
   if (request_context_manager_) {
     content::GetIOThreadTaskRunner({})->DeleteSoon(
         FROM_HERE, request_context_manager_.release());
diff --git a/infra/config/generated/builders/ci/GPU FYI Mac arm64 Builder/properties.json b/infra/config/generated/builders/ci/GPU FYI Mac arm64 Builder/properties.json
index b6a971de..6d87f152 100644
--- a/infra/config/generated/builders/ci/GPU FYI Mac arm64 Builder/properties.json
+++ b/infra/config/generated/builders/ci/GPU FYI Mac arm64 Builder/properties.json
@@ -120,10 +120,10 @@
       ]
     }
   },
-  "$build/goma": {
-    "rpc_extra_params": "?prod",
-    "server_host": "goma.chromium.org",
-    "use_luci_auth": true
+  "$build/reclient": {
+    "instance": "rbe-chromium-trusted",
+    "jobs": 250,
+    "metrics_project": "chromium-reclient-metrics"
   },
   "$recipe_engine/resultdb/test_presentation": {
     "column_keys": [],
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index abfc4fa4..2f20dbfc 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -9264,7 +9264,7 @@
         '  "builder_group": "chromium.fuzz",'
         '  "recipe": "chromium_libfuzzer"'
         '}'
-      execution_timeout_secs: 10800
+      execution_timeout_secs: 14400
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
diff --git a/infra/config/subprojects/chromium/ci/chromium.fuzz.star b/infra/config/subprojects/chromium/ci/chromium.fuzz.star
index 411be5d..3a1be00 100644
--- a/infra/config/subprojects/chromium/ci/chromium.fuzz.star
+++ b/infra/config/subprojects/chromium/ci/chromium.fuzz.star
@@ -283,6 +283,7 @@
         short_name = "chromeos-asan",
     ),
     executable = "recipe:chromium_libfuzzer",
+    execution_timeout = 4 * time.hour,
     triggering_policy = scheduler.greedy_batching(
         max_concurrent_invocations = 3,
     ),
diff --git a/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star b/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star
index ca83d41..bd5bd44 100644
--- a/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star
+++ b/infra/config/subprojects/chromium/ci/chromium.gpu.fyi.star
@@ -336,8 +336,7 @@
         category = "Mac|Builder",
         short_name = "arm",
     ),
-    goma_backend = goma.backend.RBE_PROD,
-    reclient_instance = None,
+    goma_backend = None,
 )
 
 ci.thin_tester(
diff --git a/ios/chrome/app/strings/ios_chromium_strings.grd b/ios/chrome/app/strings/ios_chromium_strings.grd
index 3474704..6a527c8 100644
--- a/ios/chrome/app/strings/ios_chromium_strings.grd
+++ b/ios/chrome/app/strings/ios_chromium_strings.grd
@@ -593,6 +593,9 @@
       <message name="IDS_IOS_PASSWORD_SUGGESTIONS_TIP_VOICEOVER" desc="The VoiceOver announcement when the tip explaining to the user they can select Autofill password suggestions." meaning="The VoiceOver announcement when the tip explaining to the user they can select Autofill password suggestions.">
         Chromium tip. Sign in faster by selecting your saved password at the top of the keyboard.
       </message>
+      <message name="IDS_IOS_OVERFLOW_MENU_TIP" desc="The text of the tip explaining to the user that the Overflow Menu has new items">
+        Get to know the new Chromium menu
+      </message>
     </messages>
   </release>
 </grit>
diff --git a/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_OVERFLOW_MENU_TIP.png.sha1 b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_OVERFLOW_MENU_TIP.png.sha1
new file mode 100644
index 0000000..cdd6aec
--- /dev/null
+++ b/ios/chrome/app/strings/ios_chromium_strings_grd/IDS_IOS_OVERFLOW_MENU_TIP.png.sha1
@@ -0,0 +1 @@
+ee6eb1a27baa022d95c01c4cb66791dcbec056de
\ 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 731ef5e..8beef9c 100644
--- a/ios/chrome/app/strings/ios_google_chrome_strings.grd
+++ b/ios/chrome/app/strings/ios_google_chrome_strings.grd
@@ -593,6 +593,9 @@
       <message name="IDS_IOS_PASSWORD_SUGGESTIONS_TIP_VOICEOVER" desc="The VoiceOver announcement when the tip explaining to the user they can select Autofill password suggestions." meaning="The VoiceOver announcement when the tip explaining to the user they can select Autofill password suggestions.">
         Chrome tip. Sign in faster by selecting your saved password at the top of the keyboard.
       </message>
+      <message name="IDS_IOS_OVERFLOW_MENU_TIP" desc="The text of the tip explaining to the user that the Overflow Menu has new items">
+        Get to know the new Chrome menu
+      </message>
     </messages>
   </release>
 </grit>
diff --git a/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_OVERFLOW_MENU_TIP.png.sha1 b/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_OVERFLOW_MENU_TIP.png.sha1
new file mode 100644
index 0000000..889550b
--- /dev/null
+++ b/ios/chrome/app/strings/ios_google_chrome_strings_grd/IDS_IOS_OVERFLOW_MENU_TIP.png.sha1
@@ -0,0 +1 @@
+ce58ffbcc19e53e3991926ac929821d92bedd409
\ 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 d1874e4..d25393e3 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -3523,6 +3523,9 @@
       <message name="IDS_IOS_KEYBOARD_ACCESSORY_VIEW_PASTE_SEARCH" desc="Accessibility label for a button that starts a Paste and Search [iOS only]">
         Paste and Search
       </message>
+      <message name="IDS_IOS_OVERFLOW_MENU_CAROUSEL_TIP" desc="The text of the tip explaining to the user they can use the carousel in the overflow menu.">
+        Your saved bookmarks, passwords, settings, and more are now here
+      </message>
     </messages>
   </release>
 </grit>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_OVERFLOW_MENU_CAROUSEL_TIP.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_OVERFLOW_MENU_CAROUSEL_TIP.png.sha1
new file mode 100644
index 0000000..915964be
--- /dev/null
+++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_OVERFLOW_MENU_CAROUSEL_TIP.png.sha1
@@ -0,0 +1 @@
+47006b0010e1c00114fa306e153a4039c9e45724
\ No newline at end of file
diff --git a/ios/chrome/browser/feature_engagement/feature_engagement_app_interface.h b/ios/chrome/browser/feature_engagement/feature_engagement_app_interface.h
index 24304c61..a5aca19e 100644
--- a/ios/chrome/browser/feature_engagement/feature_engagement_app_interface.h
+++ b/ios/chrome/browser/feature_engagement/feature_engagement_app_interface.h
@@ -55,6 +55,11 @@
 // if FeatureEngagementTracker failed to load.
 + (BOOL)enablePasswordSuggestionsTipTriggering [[nodiscard]];
 
+// Enables the Overflow Menu tip to be triggered. The tip is triggered
+// after the user has opened the overflow menu twice and not scrolled. Returns
+// NO if FeatureEngagementTracker failed to load.
++ (BOOL)enableOverflowMenuTipTriggering [[nodiscard]];
+
 // Starts manual page translation.
 + (void)showTranslate;
 
diff --git a/ios/chrome/browser/feature_engagement/feature_engagement_app_interface.mm b/ios/chrome/browser/feature_engagement/feature_engagement_app_interface.mm
index 19ea193..d7c00865 100644
--- a/ios/chrome/browser/feature_engagement/feature_engagement_app_interface.mm
+++ b/ios/chrome/browser/feature_engagement/feature_engagement_app_interface.mm
@@ -230,6 +230,30 @@
   return LoadFeatureEngagementTracker();
 }
 
++ (BOOL)enableOverflowMenuTipTriggering {
+  std::map<std::string, std::string> overflow_menu_tip_params;
+
+  overflow_menu_tip_params["availability"] = "any";
+  overflow_menu_tip_params["session_rate"] = "any";
+  overflow_menu_tip_params["event_used"] =
+      "name:popup_menu_tip_used;comparator:==0;window:180;"
+      "storage:360";
+  overflow_menu_tip_params["event_trigger"] =
+      "name:popup_menu_tip_triggered;comparator:==0;window:1825;"
+      "storage:1825";
+  overflow_menu_tip_params["event_lockout"] =
+      "name:overflow_menu_no_horizontal_scroll_or_action;comparator:>=2;window:"
+      "180;storage:360";
+
+  ScopedFeatureListHolder::GetInstance()
+      ->CreateList()
+      .InitAndEnableFeatureWithParameters(
+          feature_engagement::kIPHOverflowMenuTipFeature,
+          overflow_menu_tip_params);
+
+  return LoadFeatureEngagementTracker();
+}
+
 + (void)showTranslate {
   [chrome_test_util::HandlerForActiveBrowser() showTranslate];
 }
diff --git a/ios/chrome/browser/policy/OWNERS b/ios/chrome/browser/policy/OWNERS
index 27eb2a9..c18abb28 100644
--- a/ios/chrome/browser/policy/OWNERS
+++ b/ios/chrome/browser/policy/OWNERS
@@ -1,2 +1,3 @@
 rohitrao@chromium.org
+vincb@google.com
 file://components/policy/OWNERS
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
index 91b4764..c92423b 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -296,7 +296,7 @@
 // Coordinator for the QR scanner.
 @property(nonatomic, strong) QRScannerLegacyCoordinator* qrScannerCoordinator;
 
-// Coordinator for the QR scanner.
+// Coordinator for the popup menu.
 @property(nonatomic, strong) PopupMenuCoordinator* popupMenuCoordinator;
 
 // Coordinator for displaying the Reading List.
@@ -667,7 +667,7 @@
   self.popupMenuCoordinator.UIUpdater = _toolbarCoordinatorAdaptor;
   // Coordinator `start` is executed before setting it's `baseViewController`.
   // It is done intentionally, since this does not affecting the coordinator's
-  // behavior but helps command hanlders setup below.
+  // behavior but helps command handler setup below.
   [self.popupMenuCoordinator start];
 
   _primaryToolbarCoordinator.longPressDelegate = self.popupMenuCoordinator;
@@ -855,6 +855,11 @@
   self.printController =
       [[PrintController alloc] initWithBaseViewController:self.viewController];
 
+  // Help should only show in regular, non-incognito.
+  if (!self.browser->GetBrowserState()->IsOffTheRecord()) {
+    [self.popupMenuCoordinator startPopupMenuHelpCoordinator];
+  }
+
   /* NetExportCoordinator is created and started by a delegate method */
 
   /* passwordBreachCoordinator is created and started by a BrowserCommand */
diff --git a/ios/chrome/browser/ui/popup_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/BUILD.gn
index 5175ad1..d50f7ef2 100644
--- a/ios/chrome/browser/ui/popup_menu/BUILD.gn
+++ b/ios/chrome/browser/ui/popup_menu/BUILD.gn
@@ -10,6 +10,8 @@
     "popup_menu_action_handler_delegate.h",
     "popup_menu_coordinator.h",
     "popup_menu_coordinator.mm",
+    "popup_menu_help_coordinator.h",
+    "popup_menu_help_coordinator.mm",
     "popup_menu_mediator.h",
     "popup_menu_mediator.mm",
   ]
@@ -88,6 +90,8 @@
     "//ios/chrome/browser/ui/icons:action_icons",
     "//ios/chrome/browser/ui/icons:symbols",
     "//ios/chrome/browser/ui/list_model",
+    "//ios/chrome/browser/ui/main:layout_guide_scene_agent",
+    "//ios/chrome/browser/ui/main:scene_state_header",
     "//ios/chrome/browser/ui/ntp:metrics",
     "//ios/chrome/browser/ui/popup_menu:metrics_protocols",
     "//ios/chrome/browser/ui/popup_menu/cells",
@@ -203,6 +207,7 @@
     "//components/strings",
     "//components/version_info",
     "//ios/chrome/app/strings",
+    "//ios/chrome/browser/feature_engagement:eg_test_support+eg2",
     "//ios/chrome/browser/ui:feature_flags",
     "//ios/chrome/browser/ui/settings:constants",
     "//ios/chrome/test/earl_grey:eg_test_support+eg2",
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift
index 34b6703..56c7fbf 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_list.swift
@@ -61,6 +61,8 @@
 
   weak var metricsHandler: PopupMenuMetricsHandler?
 
+  var uiConfiguration: OverflowMenuUIConfiguration
+
   /// Tracks the list's current offset, to see when it scrolls.
   @State var listOffset: CGFloat = 0
 
@@ -105,6 +107,7 @@
           if layoutDirection == .rightToLeft {
             proxy.scrollTo(destinations.last?.destinationName)
           }
+          uiConfiguration.destinationListScreenFrame = geometry.frame(in: .global)
         }
       }
       .onPreferenceChange(ScrollViewLeadingOffset.self) { value in
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_ui_configuration.swift b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_ui_configuration.swift
index 0c777bf..e02bf5e 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_ui_configuration.swift
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_ui_configuration.swift
@@ -9,6 +9,9 @@
   @Published public var presentingViewControllerHorizontalSizeClass: UserInterfaceSizeClass
   @Published public var presentingViewControllerVerticalSizeClass: UserInterfaceSizeClass
 
+  /// The destination list's frame in screen coordinates.
+  public var destinationListScreenFrame: CGRect = .zero
+
   public init(
     presentingViewControllerHorizontalSizeClass: UIUserInterfaceSizeClass,
     presentingViewControllerVerticalSizeClass: UIUserInterfaceSizeClass
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_view.swift b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_view.swift
index f3b583a..462ff03 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_view.swift
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_view.swift
@@ -26,7 +26,8 @@
       spacing: 0
     ) {
       OverflowMenuDestinationList(
-        destinations: model.destinations, metricsHandler: metricsHandler
+        destinations: model.destinations, metricsHandler: metricsHandler,
+        uiConfiguration: uiConfiguration
       ).onPreferenceChange(
         DestinationVisibilityPreferenceKey.self
       ) {
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h
index f8d8e9ed..372866f 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h
@@ -34,6 +34,9 @@
 // Returns whether this coordinator is showing a popup menu.
 - (BOOL)isShowingPopupMenu;
 
+// Starts the popup menu's child help coordinator.
+- (void)startPopupMenuHelpCoordinator;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_POPUP_MENU_POPUP_MENU_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
index 67942cd..bbbea5a6 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -38,6 +38,7 @@
 #import "ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_swift.h"
 #import "ios/chrome/browser/ui/popup_menu/popup_menu_action_handler.h"
 #import "ios/chrome/browser/ui/popup_menu/popup_menu_constants.h"
+#import "ios/chrome/browser/ui/popup_menu/popup_menu_help_coordinator.h"
 #import "ios/chrome/browser/ui/popup_menu/popup_menu_mediator.h"
 #import "ios/chrome/browser/ui/popup_menu/popup_menu_metrics_handler.h"
 #import "ios/chrome/browser/ui/popup_menu/public/popup_menu_presenter.h"
@@ -106,6 +107,8 @@
 // Whether the user took an action on the tools menu while it was open.
 @property(nonatomic, assign) BOOL toolsMenuUserTookAction;
 
+@property(nonatomic, strong) PopupMenuHelpCoordinator* popupMenuHelpCoordinator;
+
 @end
 
 @implementation PopupMenuCoordinator
@@ -137,6 +140,7 @@
 }
 
 - (void)stop {
+  [self.popupMenuHelpCoordinator stop];
   [self.browser->GetCommandDispatcher() stopDispatchingToTarget:self];
   [self.overflowMenuMediator disconnect];
   self.overflowMenuMediator = nil;
@@ -151,6 +155,13 @@
   return self.presenter != nil;
 }
 
+- (void)startPopupMenuHelpCoordinator {
+  self.popupMenuHelpCoordinator = [[PopupMenuHelpCoordinator alloc]
+      initWithBaseViewController:self.baseViewController
+                         browser:self.browser];
+  [self.popupMenuHelpCoordinator start];
+}
+
 #pragma mark - PopupMenuCommands
 
 - (void)showNavigationHistoryBackPopupMenu {
@@ -419,6 +430,8 @@
                               self.baseViewController.traitCollection
                                   .verticalSizeClass];
 
+        self.popupMenuHelpCoordinator.uiConfiguration = uiConfiguration;
+
         UIViewController* menu = [OverflowMenuViewProvider
             makeViewControllerWithModel:self.overflowMenuMediator
                                             .overflowMenuModel
@@ -459,10 +472,15 @@
           ];
         }
 
+        __weak __typeof(self) weakSelf = self;
         [self.UIUpdater updateUIForMenuDisplayed:type];
-        [self.baseViewController presentViewController:menu
-                                              animated:YES
-                                            completion:nil];
+        [self.baseViewController
+            presentViewController:menu
+                         animated:YES
+                       completion:^{
+                         [weakSelf.popupMenuHelpCoordinator
+                             showOverflowMenuIPHInViewController:menu];
+                       }];
         return;
       }
     }
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_egtest.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_egtest.mm
index 8ab30ed..ed47b5c 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_egtest.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_egtest.mm
@@ -4,12 +4,14 @@
 
 #include "base/ios/ios_util.h"
 #include "base/strings/sys_string_conversions.h"
+#import "ios/chrome/browser/feature_engagement/feature_engagement_app_interface.h"
 #import "ios/chrome/browser/ui/popup_menu/popup_menu_constants.h"
 #include "ios/chrome/grit/ios_strings.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
 #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/web_http_server_chrome_test_case.h"
+#import "ios/testing/earl_grey/app_launch_manager.h"
 #import "ios/testing/earl_grey/earl_grey_test.h"
 #import "ios/web/public/test/http_server/http_server.h"
 #import "ios/web/public/test/http_server/http_server_util.h"
@@ -201,4 +203,32 @@
   [ChromeTestCase removeAnyOpenMenusAndInfoBars];
 }
 
+// Tests that the overflow menu IPH shows up when triggered.
+- (void)testOverflowMenuIPH {
+  if (![ChromeEarlGrey isNewOverflowMenuEnabled]) {
+    EARL_GREY_TEST_SKIPPED(
+        @"The overflow menu IPH only exists when the overflow menu is enabled.")
+  }
+  GREYAssert([FeatureEngagementAppInterface enableOverflowMenuTipTriggering],
+             @"Feature Engagement tracker did not load");
+
+  // Open and close tools menu twice with no action to trigger tooltip.
+  [ChromeEarlGreyUI openToolsMenu];
+  [ChromeEarlGreyUI closeToolsMenu];
+
+  [ChromeEarlGreyUI openToolsMenu];
+  [ChromeEarlGreyUI closeToolsMenu];
+
+  // Background and foreground the app, which should show tooltip.
+  [[AppLaunchManager sharedManager] backgroundAndForegroundApp];
+
+  [ChromeEarlGrey waitForSufficientlyVisibleElementWithMatcher:
+                      grey_accessibilityID(@"BubbleViewLabelIdentifier")];
+
+  // Open the tools menu and verify the second tooltip is visible.
+  [ChromeEarlGreyUI openToolsMenu];
+  [ChromeEarlGrey waitForSufficientlyVisibleElementWithMatcher:
+                      grey_accessibilityID(@"BubbleViewLabelIdentifier")];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_help_coordinator.h b/ios/chrome/browser/ui/popup_menu/popup_menu_help_coordinator.h
new file mode 100644
index 0000000..86d250ca
--- /dev/null
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_help_coordinator.h
@@ -0,0 +1,24 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// 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_POPUP_MENU_POPUP_MENU_HELP_COORDINATOR_H_
+#define IOS_CHROME_BROWSER_UI_POPUP_MENU_POPUP_MENU_HELP_COORDINATOR_H_
+
+#import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
+
+@class OverflowMenuUIConfiguration;
+
+// Coordinator for the popup menu help feature, educating users about the new
+// menu
+@interface PopupMenuHelpCoordinator : ChromeCoordinator
+
+@property(nonatomic, weak) OverflowMenuUIConfiguration* uiConfiguration;
+
+- (void)showPopupMenuButtonIPH;
+
+- (void)showOverflowMenuIPHInViewController:(UIViewController*)menu;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_POPUP_MENU_POPUP_MENU_HELP_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_help_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_help_coordinator.mm
new file mode 100644
index 0000000..572e43f
--- /dev/null
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_help_coordinator.mm
@@ -0,0 +1,273 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/popup_menu/popup_menu_help_coordinator.h"
+
+#import "base/threading/sequenced_task_runner_handle.h"
+#import "base/time/time.h"
+#import "components/feature_engagement/public/event_constants.h"
+#import "components/feature_engagement/public/feature_constants.h"
+#import "components/feature_engagement/public/tracker.h"
+#import "ios/chrome/browser/browser_state/chrome_browser_state.h"
+#import "ios/chrome/browser/feature_engagement/tracker_factory.h"
+#import "ios/chrome/browser/ui/bubble/bubble_view_controller_presenter.h"
+#import "ios/chrome/browser/ui/main/layout_guide_scene_agent.h"
+#import "ios/chrome/browser/ui/main/scene_state.h"
+#import "ios/chrome/browser/ui/main/scene_state_browser_agent.h"
+#import "ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_swift.h"
+#import "ios/chrome/browser/ui/util/layout_guide_names.h"
+#import "ios/chrome/browser/ui/util/uikit_ui_util.h"
+#import "ios/chrome/browser/ui/util/util_swift.h"
+#import "ios/chrome/grit/ios_chromium_strings.h"
+#import "ios/chrome/grit/ios_strings.h"
+#import "ui/base/l10n/l10n_util_mac.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+// Delay between the time the app launches, and the time the
+// menu button tip is shown.
+constexpr base::TimeDelta kMenuTipDelay = base::Seconds(1);
+}  // namespace
+
+@interface PopupMenuHelpCoordinator () <SceneStateObserver>
+
+// Bubble view controller presenter for popup menu tip.
+@property(nonatomic, strong)
+    BubbleViewControllerPresenter* popupMenuBubblePresenter;
+
+@property(nonatomic, strong)
+    BubbleViewControllerPresenter* overflowMenuBubblePresenter;
+
+// The browser state. May return null after the coordinator has been stopped
+// (thus the returned value must be checked for null).
+@property(nonatomic, readonly) ChromeBrowserState* browserState;
+
+// The layout guide center to use to coordinate views.
+@property(nonatomic, readonly) LayoutGuideCenter* layoutGuideCenter;
+
+// The layout guide installed in the base view controller on which to anchor the
+// potential IPH bubble.
+@property(nonatomic, strong) UILayoutGuide* layoutGuide;
+
+// Whether the user is still in the same session as when the popup menu IPH was
+// triggered
+@property(nonatomic, assign) BOOL inSessionWithPopupMenuIPH;
+
+// The tracker for feature engagement. May return null after the coordinator has
+// been stopped (thus the returned value must be checked for null).
+@property(nonatomic, readonly)
+    feature_engagement::Tracker* featureEngagementTracker;
+
+@end
+
+@implementation PopupMenuHelpCoordinator
+
+#pragma mark - Getters
+
+- (ChromeBrowserState*)browserState {
+  return self.browser ? self.browser->GetBrowserState() : nullptr;
+}
+
+- (LayoutGuideCenter*)layoutGuideCenter {
+  SceneState* sceneState =
+      SceneStateBrowserAgent::FromBrowser(self.browser)->GetSceneState();
+  LayoutGuideSceneAgent* layoutGuideSceneAgent =
+      [LayoutGuideSceneAgent agentFromScene:sceneState];
+  if (self.browserState && self.browserState->IsOffTheRecord()) {
+    return layoutGuideSceneAgent.incognitoLayoutGuideCenter;
+  } else {
+    return layoutGuideSceneAgent.layoutGuideCenter;
+  }
+}
+
+- (feature_engagement::Tracker*)featureEngagementTracker {
+  ChromeBrowserState* browserState = self.browserState;
+  if (!browserState)
+    return nullptr;
+  feature_engagement::Tracker* tracker =
+      feature_engagement::TrackerFactory::GetForBrowserState(browserState);
+  DCHECK(tracker);
+  return tracker;
+}
+
+#pragma mark - Public methods
+
+- (void)start {
+  SceneState* sceneState =
+      SceneStateBrowserAgent::FromBrowser(self.browser)->GetSceneState();
+  [sceneState addObserver:self];
+
+  self.layoutGuide =
+      [self.layoutGuideCenter makeLayoutGuideNamed:kToolsMenuGuide];
+  [self.baseViewController.view addLayoutGuide:self.layoutGuide];
+}
+
+- (void)stop {
+  SceneState* sceneState =
+      SceneStateBrowserAgent::FromBrowser(self.browser)->GetSceneState();
+  [sceneState removeObserver:self];
+}
+
+- (void)showPopupMenuButtonIPH {
+  [self showPopupMenuBubbleIfNecessary];
+}
+
+- (void)showOverflowMenuIPHInViewController:(UIViewController*)menu {
+  if (!self.inSessionWithPopupMenuIPH) {
+    return;
+  }
+
+  self.overflowMenuBubblePresenter = [self newOverflowMenuBubblePresenter];
+  // The overflow menu IPH should be horizontally centered, but beneath the
+  // destination list.
+  CGPoint anchorPoint = CGPointMake(
+      CGRectGetMidX(self.uiConfiguration.destinationListScreenFrame),
+      CGRectGetMaxY(self.uiConfiguration.destinationListScreenFrame));
+
+  if (![self.overflowMenuBubblePresenter canPresentInView:menu.view
+                                              anchorPoint:anchorPoint]) {
+    return;
+  }
+
+  self.inSessionWithPopupMenuIPH = NO;
+  [self.overflowMenuBubblePresenter presentInViewController:menu
+                                                       view:menu.view
+                                                anchorPoint:anchorPoint];
+}
+
+#pragma mark - Popup Menu Button Bubble/IPH methods
+
+- (BubbleViewControllerPresenter*)newPopupMenuBubblePresenter {
+  NSString* text = l10n_util::GetNSString(IDS_IOS_OVERFLOW_MENU_TIP);
+
+  // Prepare the dismissal callback.
+  __weak __typeof(self) weakSelf = self;
+  ProceduralBlockWithSnoozeAction dismissalCallback =
+      ^(feature_engagement::Tracker::SnoozeAction snoozeAction) {
+        [weakSelf popupMenuIPHDidDismissWithSnoozeAction:snoozeAction];
+      };
+
+  // Create the BubbleViewControllerPresenter.
+  BubbleArrowDirection arrowDirection =
+      IsSplitToolbarMode(self.baseViewController) ? BubbleArrowDirectionDown
+                                                  : BubbleArrowDirectionUp;
+  BubbleViewControllerPresenter* bubbleViewControllerPresenter =
+      [[BubbleViewControllerPresenter alloc]
+          initDefaultBubbleWithText:text
+                     arrowDirection:arrowDirection
+                          alignment:BubbleAlignmentTrailing
+               isLongDurationBubble:NO
+                  dismissalCallback:dismissalCallback];
+  bubbleViewControllerPresenter.voiceOverAnnouncement =
+      l10n_util::GetNSString(IDS_IOS_PASSWORD_SUGGESTIONS_TIP_VOICEOVER);
+  return bubbleViewControllerPresenter;
+}
+
+- (void)popupMenuIPHDidDismissWithSnoozeAction:
+    (feature_engagement::Tracker::SnoozeAction)snoozeAction {
+  feature_engagement::Tracker* tracker = self.featureEngagementTracker;
+  if (tracker) {
+    const base::Feature& feature =
+        feature_engagement::kIPHOverflowMenuTipFeature;
+    tracker->DismissedWithSnooze(feature, snoozeAction);
+  }
+  self.popupMenuBubblePresenter = nil;
+}
+
+- (void)showPopupMenuBubbleIfNecessary {
+  if (self.popupMenuBubblePresenter) {
+    return;
+  }
+
+  BubbleViewControllerPresenter* bubblePresenter =
+      [self newPopupMenuBubblePresenter];
+
+  // Get the anchor point for the bubble. In Split Toolbar Mode, the anchor
+  // button is at the bottom of the screen, so the bubble should be above it.
+  // When there's only one toolbar, the anchor button is at the top of the
+  // screen, so the bubble should be below it.
+  CGRect anchorFrame = self.layoutGuide.layoutFrame;
+  CGFloat anchorPointY = IsSplitToolbarMode(self.baseViewController)
+                             ? CGRectGetMinY(anchorFrame)
+                             : CGRectGetMaxY(anchorFrame);
+  CGPoint anchorPoint = CGPointMake(CGRectGetMidX(anchorFrame), anchorPointY);
+
+  // Discard if it doesn't fit in the view as it is currently shown.
+  if (![bubblePresenter canPresentInView:self.baseViewController.view
+                             anchorPoint:anchorPoint]) {
+    return;
+  }
+
+  // Early return if the engagement tracker won't display the IPH.
+  feature_engagement::Tracker* tracker = self.featureEngagementTracker;
+  const base::Feature& feature = feature_engagement::kIPHOverflowMenuTipFeature;
+  if (!tracker || !tracker->ShouldTriggerHelpUI(feature)) {
+    return;
+  }
+
+  // Present the bubble after the delay.
+  self.popupMenuBubblePresenter = bubblePresenter;
+  __weak __typeof(self) weakSelf = self;
+  base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
+      FROM_HERE, base::BindOnce(^{
+        [weakSelf presentPopupMenuBubbleAtAnchorPoint:anchorPoint];
+      }),
+      kMenuTipDelay);
+}
+
+// Actually presents the bubble.
+- (void)presentPopupMenuBubbleAtAnchorPoint:(CGPoint)anchorPoint {
+  self.inSessionWithPopupMenuIPH = YES;
+  [self.popupMenuBubblePresenter
+      presentInViewController:self.baseViewController
+                         view:self.baseViewController.view
+                  anchorPoint:anchorPoint];
+}
+
+#pragma mark - Overflow Menu Bubble methods
+
+- (BubbleViewControllerPresenter*)newOverflowMenuBubblePresenter {
+  NSString* text = l10n_util::GetNSString(IDS_IOS_OVERFLOW_MENU_CAROUSEL_TIP);
+
+  // Prepare the dismissal callback.
+  __weak __typeof(self) weakSelf = self;
+  ProceduralBlockWithSnoozeAction dismissalCallback =
+      ^(feature_engagement::Tracker::SnoozeAction snoozeAction) {
+        [weakSelf overflowMenuIPHDidDismissWithSnoozeAction:snoozeAction];
+      };
+
+  // Create the BubbleViewControllerPresenter.
+  BubbleArrowDirection arrowDirection = BubbleArrowDirectionUp;
+  BubbleViewControllerPresenter* bubbleViewControllerPresenter =
+      [[BubbleViewControllerPresenter alloc]
+          initDefaultBubbleWithText:text
+                     arrowDirection:arrowDirection
+                          alignment:BubbleAlignmentCenter
+               isLongDurationBubble:NO
+                  dismissalCallback:dismissalCallback];
+  bubbleViewControllerPresenter.voiceOverAnnouncement =
+      l10n_util::GetNSString(IDS_IOS_PASSWORD_SUGGESTIONS_TIP_VOICEOVER);
+  return bubbleViewControllerPresenter;
+}
+
+- (void)overflowMenuIPHDidDismissWithSnoozeAction:
+    (feature_engagement::Tracker::SnoozeAction)snoozeAction {
+  self.overflowMenuBubblePresenter = nil;
+}
+
+#pragma mark - SceneStateObserver
+
+- (void)sceneState:(SceneState*)sceneState
+    transitionedToActivationLevel:(SceneActivationLevel)level {
+  if (level <= SceneActivationLevelBackground) {
+    self.inSessionWithPopupMenuIPH = NO;
+  } else if (level >= SceneActivationLevelForegroundActive) {
+    [self showPopupMenuBubbleIfNecessary];
+  }
+}
+
+@end
diff --git a/ios/chrome/browser/ui/promos_manager/OWNERS b/ios/chrome/browser/ui/promos_manager/OWNERS
new file mode 100644
index 0000000..d0cdcc9
--- /dev/null
+++ b/ios/chrome/browser/ui/promos_manager/OWNERS
@@ -0,0 +1,3 @@
+bwwilliams@google.com
+gujen@google.com
+sebsg@chromium.org
diff --git a/media/base/audio_parameters.cc b/media/base/audio_parameters.cc
index a06134c..e1b84c1 100644
--- a/media/base/audio_parameters.cc
+++ b/media/base/audio_parameters.cc
@@ -6,11 +6,33 @@
 
 #include <sstream>
 
+#include "base/check_op.h"
 #include "media/base/audio_bus.h"
+#include "media/base/channel_layout.h"
 #include "media/base/limits.h"
 
 namespace media {
 
+namespace {
+
+int ComputeChannelCount(ChannelLayout channel_layout, int channels) {
+  if (channel_layout == CHANNEL_LAYOUT_DISCRETE) {
+    // TODO(1286281): Assert that channels is not 0 once the new constructors
+    // are used everywhere.
+    return channels;
+  } else if (channel_layout == CHANNEL_LAYOUT_5_1_4_DOWNMIX && channels != 0) {
+    // For CHANNEL_LAYOUT_5_1_4_DOWNMIX we can set a custom number of channels,
+    // but we are not forced to.
+    return channels;
+  }
+  const int calculated_channel_count =
+      ChannelLayoutToChannelCount(channel_layout);
+  DCHECK_EQ(calculated_channel_count, channels);
+  return calculated_channel_count;
+}
+
+}  // namespace
+
 static_assert(AudioBus::kChannelAlignment == kParametersAlignment,
               "Audio buffer parameters struct alignment not same as AudioBus");
 static_assert(sizeof(AudioInputBufferParameters) %
@@ -91,8 +113,57 @@
   return result.ValueOrDie();
 }
 
+ChannelLayoutConfig::ChannelLayoutConfig(const ChannelLayoutConfig& other) =
+    default;
+ChannelLayoutConfig& ChannelLayoutConfig::operator=(
+    const ChannelLayoutConfig& other) = default;
+ChannelLayoutConfig::~ChannelLayoutConfig() = default;
+
+ChannelLayoutConfig::ChannelLayoutConfig()
+    : ChannelLayoutConfig(
+          ChannelLayoutConfig::FromLayout<CHANNEL_LAYOUT_NONE>()) {}
+
+ChannelLayoutConfig::ChannelLayoutConfig(ChannelLayout channel_layout,
+                                         int channels)
+    : channel_layout_(channel_layout),
+      channels_(ComputeChannelCount(channel_layout, channels)) {}
+
+ChannelLayoutConfig ChannelLayoutConfig::Mono() {
+  return FromLayout<CHANNEL_LAYOUT_MONO>();
+}
+
+ChannelLayoutConfig ChannelLayoutConfig::Stereo() {
+  return FromLayout<CHANNEL_LAYOUT_STEREO>();
+}
+
+ChannelLayoutConfig ChannelLayoutConfig::Guess(int channels) {
+  return ChannelLayoutConfig(GuessChannelLayout(channels), channels);
+}
+
 AudioParameters::AudioParameters()
-    : AudioParameters(AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_NONE, 0, 0) {}
+    : AudioParameters(AUDIO_PCM_LINEAR,
+                      ChannelLayoutConfig::FromLayout<CHANNEL_LAYOUT_NONE>(),
+                      0,
+                      0) {}
+
+AudioParameters::AudioParameters(Format format,
+                                 ChannelLayoutConfig channel_layout_config,
+                                 int sample_rate,
+                                 int frames_per_buffer)
+    : latency_tag_(AudioLatency::LATENCY_COUNT) {
+  Reset(format, channel_layout_config, sample_rate, frames_per_buffer);
+}
+
+AudioParameters::AudioParameters(
+    Format format,
+    ChannelLayoutConfig channel_layout_config,
+    int sample_rate,
+    int frames_per_buffer,
+    const HardwareCapabilities& hardware_capabilities)
+    : latency_tag_(AudioLatency::LATENCY_COUNT),
+      hardware_capabilities_(hardware_capabilities) {
+  Reset(format, channel_layout_config, sample_rate, frames_per_buffer);
+}
 
 AudioParameters::AudioParameters(Format format,
                                  ChannelLayout channel_layout,
@@ -119,21 +190,28 @@
 AudioParameters& AudioParameters::operator=(const AudioParameters&) = default;
 
 void AudioParameters::Reset(Format format,
-                            ChannelLayout channel_layout,
+                            ChannelLayoutConfig channel_layout_config,
                             int sample_rate,
                             int frames_per_buffer) {
   format_ = format;
-  channel_layout_ = channel_layout;
-  channels_ = ChannelLayoutToChannelCount(channel_layout);
+  channel_layout_config_ = channel_layout_config;
   sample_rate_ = sample_rate;
   frames_per_buffer_ = frames_per_buffer;
   effects_ = NO_EFFECTS;
   mic_positions_.clear();
 }
 
+void AudioParameters::Reset(Format format,
+                            ChannelLayout channel_layout,
+                            int sample_rate,
+                            int frames_per_buffer) {
+  Reset(format, {channel_layout, ChannelLayoutToChannelCount(channel_layout)},
+        sample_rate, frames_per_buffer);
+}
+
 bool AudioParameters::IsValid() const {
-  return (channels_ > 0) && (channels_ <= media::limits::kMaxChannels) &&
-         (channel_layout_ > CHANNEL_LAYOUT_UNSUPPORTED) &&
+  return (channels() > 0) && (channels() <= media::limits::kMaxChannels) &&
+         (channel_layout() > CHANNEL_LAYOUT_UNSUPPORTED) &&
          (sample_rate_ >= media::limits::kMinSampleRate) &&
          (sample_rate_ <= media::limits::kMaxSampleRate) &&
          (frames_per_buffer_ > 0) &&
@@ -147,9 +225,9 @@
             media::limits::kMaxSamplesPerPacket) &&
            (hardware_capabilities_->max_frames_per_buffer >=
             hardware_capabilities_->min_frames_per_buffer))) &&
-         (channel_layout_ == CHANNEL_LAYOUT_DISCRETE ||
-          channel_layout_ == CHANNEL_LAYOUT_5_1_4_DOWNMIX ||
-          channels_ == ChannelLayoutToChannelCount(channel_layout_));
+         (channel_layout() == CHANNEL_LAYOUT_DISCRETE ||
+          channel_layout() == CHANNEL_LAYOUT_5_1_4_DOWNMIX ||
+          channels() == ChannelLayoutToChannelCount(channel_layout()));
 }
 
 std::string AudioParameters::AsHumanReadableString() const {
@@ -175,7 +253,7 @@
 }
 
 int AudioParameters::GetBytesPerFrame(SampleFormat fmt) const {
-  return channels_ * SampleFormatToBytesPerChannel(fmt);
+  return channels() * SampleFormatToBytesPerChannel(fmt);
 }
 
 double AudioParameters::GetMicrosecondsPerFrame() const {
@@ -190,8 +268,8 @@
 
 bool AudioParameters::Equals(const AudioParameters& other) const {
   return format_ == other.format() && sample_rate_ == other.sample_rate() &&
-         channel_layout_ == other.channel_layout() &&
-         channels_ == other.channels() &&
+         channel_layout() == other.channel_layout() &&
+         channels() == other.channels() &&
          frames_per_buffer_ == other.frames_per_buffer() &&
          effects_ == other.effects() && mic_positions_ == other.mic_positions_;
 }
@@ -215,13 +293,18 @@
          (hardware_capabilities_->bitstream_formats & format);
 }
 
+void AudioParameters::SetChannelLayoutConfig(ChannelLayout layout,
+                                             int channels) {
+  channel_layout_config_ = {layout, channels};
+}
+
 // static
 AudioParameters AudioParameters::UnavailableDeviceParams() {
   // Using 10 ms buffer since WebAudioMediaStreamSource::DeliverRebufferedAudio
   // deals incorrectly with reference time calculation if output buffer size
   // significantly differs from 10 ms used there, see http://crbug/701000.
   return media::AudioParameters(
-      media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO,
+      media::AudioParameters::AUDIO_FAKE, ChannelLayoutConfig::Stereo(),
       media::AudioParameters::kAudioCDSampleRate,
       media::AudioParameters::kAudioCDSampleRate / 100);
 }
diff --git a/media/base/audio_parameters.h b/media/base/audio_parameters.h
index dccb01b..2603e3f 100644
--- a/media/base/audio_parameters.h
+++ b/media/base/audio_parameters.h
@@ -112,6 +112,41 @@
 MEDIA_SHMEM_EXPORT uint32_t ComputeAudioOutputBufferSize(int channels,
                                                          int frames);
 
+// Channel count and ChannelLayout pair, with helper methods to enforce safe
+// construction.
+class MEDIA_SHMEM_EXPORT ChannelLayoutConfig {
+ public:
+  ChannelLayoutConfig(const ChannelLayoutConfig& other);
+  ChannelLayoutConfig& operator=(const ChannelLayoutConfig& other);
+  ChannelLayoutConfig();
+  ChannelLayoutConfig(ChannelLayout channel_layout, int channels);
+  ~ChannelLayoutConfig();
+
+  template <ChannelLayout layout>
+  static ChannelLayoutConfig FromLayout() {
+    return ChannelLayoutConfig(layout, ChannelLayoutToChannelCount(layout));
+  }
+
+  // For |CHANNEL_LAYOUT_DISCRETE|, we have to explicitly set the number of
+  // channels, so we need to use the normal constructor.
+  template <>
+  ChannelLayoutConfig FromLayout<CHANNEL_LAYOUT_DISCRETE>() = delete;
+
+  static ChannelLayoutConfig Mono();
+
+  static ChannelLayoutConfig Stereo();
+
+  static ChannelLayoutConfig Guess(int channels);
+
+  ChannelLayout channel_layout() const { return channel_layout_; }
+
+  int channels() const { return channels_; }
+
+ private:
+  ChannelLayout channel_layout_;  // Order of surround sound channels.
+  int channels_;                  // Number of channels.
+};
+
 class MEDIA_SHMEM_EXPORT AudioParameters {
  public:
   // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.media
@@ -189,6 +224,20 @@
   };
 
   AudioParameters();
+
+  AudioParameters(Format format,
+                  ChannelLayoutConfig channel_layout_config,
+                  int sample_rate,
+                  int frames_per_buffer);
+
+  AudioParameters(Format format,
+                  ChannelLayoutConfig channel_layout_config,
+                  int sample_rate,
+                  int frames_per_buffer,
+                  const HardwareCapabilities& hardware_capabilities);
+
+  // TODO(1286281): Remove these old constructors once the new constructors are
+  // used everywhere.
   AudioParameters(Format format,
                   ChannelLayout channel_layout,
                   int sample_rate,
@@ -203,6 +252,13 @@
 
   // Re-initializes all members except for |hardware_capabilities_|.
   void Reset(Format format,
+             ChannelLayoutConfig channel_layout_config,
+             int sample_rate,
+             int frames_per_buffer);
+
+  // TODO(1286281): Remove this old overload once the new version is used
+  // everywhere.
+  void Reset(Format format,
              ChannelLayout channel_layout,
              int sample_rate,
              int frames_per_buffer);
@@ -243,18 +299,27 @@
   void set_format(Format format) { format_ = format; }
   Format format() const { return format_; }
 
-  // A setter for channel_layout_ is intentionally excluded.
-  ChannelLayout channel_layout() const { return channel_layout_; }
+  void SetChannelLayoutConfig(ChannelLayout layout, int channels);
 
-  // The number of channels is usually computed from channel_layout_. Setting
-  // this explicitly is only required with CHANNEL_LAYOUT_DISCRETE.
-  void set_channels_for_discrete(int channels) {
-    DCHECK(channel_layout_ == CHANNEL_LAYOUT_DISCRETE ||
-           channel_layout_ == CHANNEL_LAYOUT_5_1_4_DOWNMIX ||
-           channels == ChannelLayoutToChannelCount(channel_layout_));
-    channels_ = channels;
+  const ChannelLayoutConfig& channel_layout_config() const {
+    return channel_layout_config_;
   }
-  int channels() const { return channels_; }
+
+  ChannelLayout channel_layout() const {
+    return channel_layout_config_.channel_layout();
+  }
+
+  // TODO(1286281): Remove this method once the new constructors are used
+  // everywhere. The number of channels is usually computed from
+  // channel_layout_. Setting this explicitly is only required with
+  // CHANNEL_LAYOUT_DISCRETE.
+  void set_channels_for_discrete(int channels) {
+    DCHECK(channel_layout() == CHANNEL_LAYOUT_DISCRETE ||
+           channel_layout() == CHANNEL_LAYOUT_5_1_4_DOWNMIX ||
+           channels == ChannelLayoutToChannelCount(channel_layout()));
+    SetChannelLayoutConfig(channel_layout(), channels);
+  }
+  int channels() const { return channel_layout_config_.channels(); }
 
   void set_sample_rate(int sample_rate) { sample_rate_ = sample_rate; }
   int sample_rate() const { return sample_rate_; }
@@ -294,9 +359,8 @@
 
  private:
   Format format_;                 // Format of the stream.
-  ChannelLayout channel_layout_;  // Order of surround sound channels.
-  int channels_;                  // Number of channels. Value set based on
-                                  // |channel_layout|.
+  ChannelLayoutConfig channel_layout_config_;  // The channel layout and the
+                                               // number of channels.
   int sample_rate_;               // Sampling frequency/rate.
   int frames_per_buffer_;         // Number of frames in a buffer.
   int effects_;                   // Bitmask using PlatformEffectsMask.
diff --git a/media/base/audio_parameters_unittest.cc b/media/base/audio_parameters_unittest.cc
index 021f044..4596beb 100644
--- a/media/base/audio_parameters_unittest.cc
+++ b/media/base/audio_parameters_unittest.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include "base/strings/string_number_conversions.h"
+#include "media/base/channel_layout.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace media {
@@ -36,6 +37,26 @@
   AudioParameters::Format expected_format =
       AudioParameters::AUDIO_PCM_LOW_LATENCY;
   int expected_channels = 6;
+  constexpr ChannelLayout expected_channel_layout = CHANNEL_LAYOUT_5_1;
+  int expected_rate = 44100;
+  int expected_samples = 880;
+
+  AudioParameters params(
+      expected_format,
+      ChannelLayoutConfig::FromLayout<expected_channel_layout>(), expected_rate,
+      expected_samples);
+
+  EXPECT_EQ(expected_format, params.format());
+  EXPECT_EQ(expected_channels, params.channels());
+  EXPECT_EQ(expected_channel_layout, params.channel_layout());
+  EXPECT_EQ(expected_rate, params.sample_rate());
+  EXPECT_EQ(expected_samples, params.frames_per_buffer());
+}
+
+TEST(AudioParameters, Constructor_OldParameterValues) {
+  AudioParameters::Format expected_format =
+      AudioParameters::AUDIO_PCM_LOW_LATENCY;
+  int expected_channels = 6;
   ChannelLayout expected_channel_layout = CHANNEL_LAYOUT_5_1;
   int expected_rate = 44100;
   int expected_samples = 880;
@@ -52,6 +73,24 @@
 
 TEST(AudioParameters, GetBytesPerBuffer) {
   EXPECT_EQ(100, AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+                                 ChannelLayoutConfig::Mono(), 1000, 100)
+                     .GetBytesPerBuffer(kSampleFormatU8));
+  EXPECT_EQ(200, AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+                                 ChannelLayoutConfig::Mono(), 1000, 100)
+                     .GetBytesPerBuffer(kSampleFormatS16));
+  EXPECT_EQ(200, AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+                                 ChannelLayoutConfig::Stereo(), 1000, 100)
+                     .GetBytesPerBuffer(kSampleFormatU8));
+  EXPECT_EQ(200, AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+                                 ChannelLayoutConfig::Mono(), 1000, 200)
+                     .GetBytesPerBuffer(kSampleFormatU8));
+  EXPECT_EQ(800, AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+                                 ChannelLayoutConfig::Stereo(), 1000, 200)
+                     .GetBytesPerBuffer(kSampleFormatS16));
+}
+
+TEST(AudioParameters, OldGetBytesPerBuffer) {
+  EXPECT_EQ(100, AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
                                  CHANNEL_LAYOUT_MONO, 1000, 100)
                      .GetBytesPerBuffer(kSampleFormatU8));
   EXPECT_EQ(200, AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
@@ -70,6 +109,57 @@
 
 TEST(AudioParameters, Compare) {
   AudioParameters values[] = {
+      AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+                      ChannelLayoutConfig::Mono(), 1000, 100),
+      AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+                      ChannelLayoutConfig::Mono(), 1000, 200),
+      AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+                      ChannelLayoutConfig::Mono(), 2000, 100),
+      AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+                      ChannelLayoutConfig::Mono(), 2000, 200),
+
+      AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+                      ChannelLayoutConfig::Stereo(), 1000, 100),
+      AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+                      ChannelLayoutConfig::Stereo(), 1000, 200),
+      AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+                      ChannelLayoutConfig::Stereo(), 2000, 100),
+      AudioParameters(AudioParameters::AUDIO_PCM_LINEAR,
+                      ChannelLayoutConfig::Stereo(), 2000, 200),
+
+      AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                      ChannelLayoutConfig::Mono(), 1000, 100),
+      AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                      ChannelLayoutConfig::Mono(), 1000, 200),
+      AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                      ChannelLayoutConfig::Mono(), 2000, 100),
+      AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                      ChannelLayoutConfig::Mono(), 2000, 200),
+
+      AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                      ChannelLayoutConfig::Stereo(), 1000, 100),
+      AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                      ChannelLayoutConfig::Stereo(), 1000, 200),
+      AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                      ChannelLayoutConfig::Stereo(), 2000, 100),
+      AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                      ChannelLayoutConfig::Stereo(), 2000, 200),
+  };
+
+  for (size_t i = 0; i < std::size(values); ++i) {
+    for (size_t j = 0; j < std::size(values); ++j) {
+      SCOPED_TRACE("i=" + base::NumberToString(i) +
+                   " j=" + base::NumberToString(j));
+      EXPECT_EQ(i < j, values[i] < values[j]);
+    }
+
+    // Verify that a value is never less than itself.
+    EXPECT_FALSE(values[i] < values[i]);
+  }
+}
+
+TEST(AudioParameters, OldCompare) {
+  AudioParameters values[] = {
       AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
                       1000, 100),
       AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
@@ -122,6 +212,19 @@
 TEST(AudioParameters, Constructor_ValidChannelCounts) {
   int expected_channels = 8;
   ChannelLayout expected_layout = CHANNEL_LAYOUT_DISCRETE;
+  ChannelLayoutConfig channel_layout_config(CHANNEL_LAYOUT_DISCRETE,
+                                            expected_channels);
+
+  AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                         channel_layout_config, 44100, 880);
+  EXPECT_EQ(expected_channels, params.channels());
+  EXPECT_EQ(expected_layout, params.channel_layout());
+  EXPECT_TRUE(params.IsValid());
+}
+
+TEST(AudioParameters, Constructor_OldValidChannelCounts) {
+  int expected_channels = 8;
+  ChannelLayout expected_layout = CHANNEL_LAYOUT_DISCRETE;
 
   AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
                          expected_layout, 44100, 880);
@@ -131,4 +234,45 @@
   EXPECT_TRUE(params.IsValid());
 }
 
+TEST(AudioParameters, Constructor_ValidChannelCountsFor514Downmix) {
+  int expected_channels = 7;
+  constexpr ChannelLayout expected_layout = CHANNEL_LAYOUT_5_1_4_DOWNMIX;
+  ChannelLayoutConfig channel_layout_config(expected_layout, expected_channels);
+
+  AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                         channel_layout_config, 44100, 880);
+  EXPECT_EQ(expected_channels, params.channels());
+  EXPECT_EQ(expected_layout, params.channel_layout());
+  EXPECT_TRUE(params.IsValid());
+
+  // We do not have to explicitly set the channels for this layout.
+  params.Reset(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+               ChannelLayoutConfig::FromLayout<expected_layout>(), 44100, 880);
+  EXPECT_EQ(6, params.channels());
+  EXPECT_EQ(expected_layout, params.channel_layout());
+  EXPECT_TRUE(params.IsValid());
+}
+
+TEST(AudioParameters, Constructor_CopyChannelLayoutConfig) {
+  int expected_channels = 8;
+  ChannelLayout expected_layout = CHANNEL_LAYOUT_DISCRETE;
+  ChannelLayoutConfig channel_layout_config(CHANNEL_LAYOUT_DISCRETE,
+                                            expected_channels);
+
+  AudioParameters params1(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                          channel_layout_config, 44100, 880);
+  AudioParameters params2(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                          params1.channel_layout_config(), 44100, 880);
+
+  EXPECT_EQ(expected_channels, params2.channels());
+  EXPECT_EQ(expected_layout, params2.channel_layout());
+  EXPECT_TRUE(params2.IsValid());
+}
+
+TEST(AudioParameters, ChannelLayoutConfig_Guess) {
+  ChannelLayoutConfig channel_layout_config = ChannelLayoutConfig::Guess(2);
+  EXPECT_EQ(CHANNEL_LAYOUT_STEREO, channel_layout_config.channel_layout());
+  EXPECT_EQ(2, channel_layout_config.channels());
+}
+
 }  // namespace media
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index b414115..38a2204 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -627,7 +627,7 @@
 // tab instead" button is shown for chrome.desktopCapture captures.
 const base::Feature kShareThisTabInsteadButtonGetDisplayMedia{
     "ShareThisTabInsteadButtonGetDisplayMedia",
-    base::FEATURE_DISABLED_BY_DEFAULT};
+    base::FEATURE_ENABLED_BY_DEFAULT};
 
 // If kShareThisTabInsteadButtonGetDisplayMedia is ENABLED, this flag controls
 // whether a "Share this tab instead" button should be enabled for
diff --git a/media/base/video_codecs.cc b/media/base/video_codecs.cc
index 21743dd..7577ed17 100644
--- a/media/base/video_codecs.cc
+++ b/media/base/video_codecs.cc
@@ -872,7 +872,8 @@
 }
 
 // The specification for Dolby Vision codec id strings can be found in Dolby
-// Vision streams within the MPEG-DASH format.
+// Vision streams within the MPEG-DASH format:
+// https://professional.dolby.com/siteassets/content-creation/dolby-vision-for-content-creators/dolbyvisioninmpegdashspecification_v2_0_public_20190107.pdf
 bool ParseDolbyVisionCodecId(const std::string& codec_id,
                              VideoCodecProfile* profile,
                              uint8_t* level_idc) {
@@ -954,7 +955,7 @@
   // Level string should be two digits.
   unsigned level_id = 0;
   if (elem[2].size() != 2 || !base::StringToUint(elem[2], &level_id) ||
-      level_id > 9 || level_id < 1) {
+      level_id > 13 || level_id < 1) {
     DVLOG(4) << __func__ << ": invalid format level_id=" << elem[2];
     return false;
   }
diff --git a/media/base/video_codecs_unittest.cc b/media/base/video_codecs_unittest.cc
index 0fd5f63..52f5cad 100644
--- a/media/base/video_codecs_unittest.cc
+++ b/media/base/video_codecs_unittest.cc
@@ -705,9 +705,17 @@
   EXPECT_FALSE(ParseDolbyVisionCodecId("dvhe.03.07", &profile, &level_id));
   EXPECT_FALSE(ParseDolbyVisionCodecId("dvhe.06.07", &profile, &level_id));
 
-  // Level should be numbers between 1 and 9.
+  // Level should be two digit number and in the range [01, 13].
   EXPECT_FALSE(ParseDolbyVisionCodecId("dvhe.04.00", &profile, &level_id));
-  EXPECT_FALSE(ParseDolbyVisionCodecId("dvhe.04.10", &profile, &level_id));
+  EXPECT_TRUE(ParseDolbyVisionCodecId("dvhe.04.01", &profile, &level_id));
+  EXPECT_EQ(level_id, 1);
+  EXPECT_TRUE(ParseDolbyVisionCodecId("dvhe.04.09", &profile, &level_id));
+  EXPECT_EQ(level_id, 9);
+  EXPECT_TRUE(ParseDolbyVisionCodecId("dvhe.04.10", &profile, &level_id));
+  EXPECT_EQ(level_id, 10);
+  EXPECT_TRUE(ParseDolbyVisionCodecId("dvhe.04.13", &profile, &level_id));
+  EXPECT_EQ(level_id, 13);
+  EXPECT_FALSE(ParseDolbyVisionCodecId("dvhe.04.14", &profile, &level_id));
   EXPECT_FALSE(ParseDolbyVisionCodecId("dvhe.04.20", &profile, &level_id));
   EXPECT_FALSE(ParseDolbyVisionCodecId("dvhe.04.99", &profile, &level_id));
 
@@ -725,6 +733,8 @@
   EXPECT_FALSE(ParseDolbyVisionCodecId("dvhe.5.7.", &profile, &level_id));
   EXPECT_FALSE(ParseDolbyVisionCodecId("dvhe.5.7..", &profile, &level_id));
   EXPECT_FALSE(ParseDolbyVisionCodecId("dvhe.5.7...", &profile, &level_id));
+  EXPECT_FALSE(ParseDolbyVisionCodecId("dvhe.05.7", &profile, &level_id));
+  EXPECT_FALSE(ParseDolbyVisionCodecId("dvhe.05.007", &profile, &level_id));
   EXPECT_FALSE(ParseDolbyVisionCodecId("dvhe..5", &profile, &level_id));
 #endif
 }
diff --git a/media/webrtc/audio_processor.cc b/media/webrtc/audio_processor.cc
index 24d694d0..aa8745b 100644
--- a/media/webrtc/audio_processor.cc
+++ b/media/webrtc/audio_processor.cc
@@ -556,14 +556,14 @@
   }
 
   AudioParameters params(
-      device_format.format(), channel_layout, device_format.sample_rate(),
+      device_format.format(), device_format.channel_layout_config(),
+      device_format.sample_rate(),
       GetCaptureBufferSize(
           audio_processing_settings.NeedWebrtcAudioProcessing(),
           device_format));
   params.set_effects(device_format.effects());
   if (channel_layout == CHANNEL_LAYOUT_DISCRETE) {
     DCHECK_LE(device_format.channels(), 2);
-    params.set_channels_for_discrete(device_format.channels());
   }
   DVLOG(1) << params.AsHumanReadableString();
   CHECK(params.IsValid());
@@ -591,9 +591,9 @@
 #endif
                                    : input_format.sample_rate();
 
-  media::ChannelLayout output_channel_layout;
+  media::ChannelLayoutConfig output_channel_layout_config;
   if (!need_webrtc_audio_processing) {
-    output_channel_layout = input_format.channel_layout();
+    output_channel_layout_config = input_format.channel_layout_config();
   } else if (settings.multi_channel_capture_processing) {
     // The number of output channels is equal to the number of input channels.
     // If the media stream audio processor receives stereo input it will
@@ -607,9 +607,9 @@
     // performing true stereo processing. There will be no need to change the
     // output format.
 
-    output_channel_layout = input_format.channel_layout();
+    output_channel_layout_config = input_format.channel_layout_config();
   } else {
-    output_channel_layout = media::CHANNEL_LAYOUT_MONO;
+    output_channel_layout_config = ChannelLayoutConfig::Mono();
   }
 
   // webrtc::AudioProcessing requires a 10 ms chunk size. We use this native
@@ -628,13 +628,9 @@
     output_frames = input_format.frames_per_buffer();
   }
 
-  media::AudioParameters output_format =
-      media::AudioParameters(input_format.format(), output_channel_layout,
-                             output_sample_rate, output_frames);
-  if (output_channel_layout == media::CHANNEL_LAYOUT_DISCRETE) {
-    // Explicitly set number of channels for discrete channel layouts.
-    output_format.set_channels_for_discrete(input_format.channels());
-  }
+  media::AudioParameters output_format = media::AudioParameters(
+      input_format.format(), output_channel_layout_config, output_sample_rate,
+      output_frames);
   return output_format;
 }
 }  // namespace media
diff --git a/media/webrtc/audio_processor_test.cc b/media/webrtc/audio_processor_test.cc
index a6f26e65..83c149f 100644
--- a/media/webrtc/audio_processor_test.cc
+++ b/media/webrtc/audio_processor_test.cc
@@ -97,7 +97,7 @@
  public:
   AudioProcessorTest()
       : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-                media::CHANNEL_LAYOUT_STEREO,
+                ChannelLayoutConfig::Stereo(),
                 48000,
                 480) {}
 
@@ -269,7 +269,7 @@
     SCOPED_TRACE(testing::Message() << "sample_rate=" << sample_rate);
     int buffer_size = sample_rate / 100;
     media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-                                  media::CHANNEL_LAYOUT_STEREO, sample_rate,
+                                  ChannelLayoutConfig::Stereo(), sample_rate,
                                   buffer_size);
     std::unique_ptr<AudioProcessor> audio_processor = AudioProcessor::Create(
         mock_capture_callback_.Get(), LogCallbackForTesting(), settings, params,
@@ -462,7 +462,7 @@
 
   media::AudioParameters input_params(
       media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-      media::CHANNEL_LAYOUT_STEREO, sample_rate, sample_rate / 100);
+      ChannelLayoutConfig::Stereo(), sample_rate, sample_rate / 100);
   AudioParameters output_params =
       AudioProcessor::GetDefaultOutputFormat(input_params, settings);
 
@@ -488,11 +488,11 @@
 TEST_F(AudioProcessorTest, DiscreteChannelLayout) {
   AudioProcessingSettings settings;
 
-  media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-                                media::CHANNEL_LAYOUT_DISCRETE, 48000, 480);
   // Test both 1 and 2 discrete channels.
   for (int channels = 1; channels <= 2; ++channels) {
-    params.set_channels_for_discrete(channels);
+    media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                                  {media::CHANNEL_LAYOUT_DISCRETE, channels},
+                                  48000, 480);
     std::unique_ptr<AudioProcessor> audio_processor = AudioProcessor::Create(
         mock_capture_callback_.Get(), LogCallbackForTesting(), settings, params,
         AudioProcessor::GetDefaultOutputFormat(params, settings));
@@ -585,7 +585,7 @@
   AudioProcessingSettings settings;
   // Set buffer size to 4 ms.
   media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-                                media::CHANNEL_LAYOUT_STEREO, 48000,
+                                ChannelLayoutConfig::Stereo(), 48000,
                                 48000 * 4 / 1000);
   std::unique_ptr<AudioProcessor> audio_processor = AudioProcessor::Create(
       mock_capture_callback.Get(), LogCallbackForTesting(), settings, params,
@@ -635,7 +635,7 @@
   AudioProcessingSettings settings;
   // Set buffer size to 35 ms.
   media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-                                media::CHANNEL_LAYOUT_STEREO, 48000,
+                                ChannelLayoutConfig::Stereo(), 48000,
                                 48000 * 35 / 1000);
   std::unique_ptr<AudioProcessor> audio_processor = AudioProcessor::Create(
       mock_capture_callback.Get(), LogCallbackForTesting(), settings, params,
@@ -675,7 +675,7 @@
   DisableDefaultSettings(settings);
   // Set buffer size to 4 ms.
   media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-                                media::CHANNEL_LAYOUT_STEREO, 48000,
+                                ChannelLayoutConfig::Stereo(), 48000,
                                 48000 * 4 / 1000);
   std::unique_ptr<AudioProcessor> audio_processor = AudioProcessor::Create(
       mock_capture_callback.Get(), LogCallbackForTesting(), settings, params,
@@ -712,7 +712,7 @@
   DisableDefaultSettings(settings);
   // Set buffer size to 35 ms.
   media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-                                media::CHANNEL_LAYOUT_STEREO, 48000,
+                                ChannelLayoutConfig::Stereo(), 48000,
                                 48000 * 35 / 1000);
   std::unique_ptr<AudioProcessor> audio_processor = AudioProcessor::Create(
       mock_capture_callback.Get(), LogCallbackForTesting(), settings, params,
diff --git a/net/cert/root_cert_list_generated.h b/net/cert/root_cert_list_generated.h
index 8f5f759..52ba92d 100644
--- a/net/cert/root_cert_list_generated.h
+++ b/net/cert/root_cert_list_generated.h
@@ -1130,6 +1130,13 @@
      278,
      true},
     {{
+         0x48, 0xA8, 0xA7, 0xEC, 0xD0, 0x3A, 0x83, 0xB2, 0x6A, 0xEC, 0x75,
+         0x74, 0xD0, 0x9D, 0x64, 0x53, 0xE9, 0x5F, 0x90, 0x36, 0x06, 0x34,
+         0xCE, 0x20, 0x4B, 0xCB, 0xD4, 0x73, 0x99, 0x7D, 0x4C, 0x05,
+     },
+     532,
+     false},
+    {{
          0x49, 0x05, 0x46, 0x66, 0x23, 0xAB, 0x41, 0x78, 0xBE, 0x92, 0xAC,
          0x5C, 0xBD, 0x65, 0x84, 0xF7, 0xA1, 0xE1, 0x7F, 0x27, 0x65, 0x2D,
          0x5A, 0x85, 0xAF, 0x89, 0x50, 0x4E, 0xA2, 0x39, 0xAA, 0xAA,
@@ -1375,6 +1382,13 @@
      440,
      true},
     {{
+         0x58, 0x1C, 0xC1, 0x58, 0x21, 0x16, 0x96, 0x94, 0xC3, 0x9C, 0x29,
+         0x91, 0xB5, 0x3E, 0x93, 0xAB, 0x94, 0x5A, 0x42, 0xB0, 0x76, 0x66,
+         0x17, 0x74, 0xC2, 0xEC, 0xF3, 0x8A, 0x33, 0x23, 0xAC, 0xEA,
+     },
+     540,
+     false},
+    {{
          0x58, 0x99, 0xD9, 0x13, 0xEA, 0xD1, 0x19, 0xB9, 0xCD, 0xB7, 0xBA,
          0x2F, 0x30, 0xEF, 0xE0, 0xDF, 0x68, 0xAD, 0x2C, 0xD2, 0x25, 0xBD,
          0xF4, 0x93, 0xE8, 0x32, 0x3A, 0x25, 0xAA, 0x4D, 0xBE, 0x23,
@@ -1585,6 +1599,13 @@
      126,
      true},
     {{
+         0x68, 0x1D, 0xC4, 0x82, 0xC2, 0x96, 0xC8, 0x40, 0x2C, 0x6E, 0xBB,
+         0x20, 0xE6, 0x83, 0x09, 0xA3, 0xBC, 0x84, 0x65, 0x23, 0xAE, 0x34,
+         0xB9, 0x84, 0xA8, 0x4E, 0xE6, 0x97, 0xA3, 0x31, 0x2D, 0xB7,
+     },
+     536,
+     false},
+    {{
          0x68, 0x27, 0x47, 0xF8, 0xBA, 0x62, 0x1B, 0x87, 0xCD, 0xD3, 0xBC,
          0x29, 0x5E, 0xD5, 0xCA, 0xBC, 0xE7, 0x22, 0xA1, 0xC0, 0xC0, 0x36,
          0x3D, 0x1D, 0x68, 0xB3, 0x89, 0x28, 0xD2, 0x78, 0x7F, 0x1E,
@@ -1620,6 +1641,13 @@
      499,
      true},
     {{
+         0x69, 0x3C, 0x9A, 0xA6, 0xB2, 0x45, 0xB3, 0xB0, 0x26, 0x16, 0x37,
+         0x75, 0x08, 0x63, 0xEA, 0xDB, 0x6C, 0x24, 0x8A, 0x16, 0xE5, 0x2D,
+         0x6F, 0x4B, 0xC9, 0x0C, 0x86, 0xBB, 0xF3, 0x2D, 0x70, 0x42,
+     },
+     522,
+     false},
+    {{
          0x6A, 0x43, 0x6B, 0x58, 0xD9, 0xD8, 0x30, 0xE8, 0xD5, 0xB8, 0xA6,
          0x42, 0x50, 0x5A, 0xD6, 0xB4, 0x14, 0x06, 0xAD, 0xCD, 0x68, 0x94,
          0xD9, 0x41, 0x4F, 0x7B, 0xE0, 0xA1, 0x46, 0x7B, 0xAD, 0xB7,
@@ -1634,6 +1662,13 @@
      421,
      true},
     {{
+         0x6A, 0x97, 0xB5, 0x1C, 0x82, 0x19, 0xE9, 0x3E, 0x5D, 0xEC, 0x64,
+         0xBA, 0xD5, 0x80, 0x6C, 0xDE, 0xB0, 0xF8, 0x35, 0x5B, 0xE4, 0x7E,
+         0x75, 0x70, 0x10, 0xB7, 0x02, 0x45, 0x6E, 0x01, 0xAA, 0xFD,
+     },
+     531,
+     false},
+    {{
          0x6B, 0x1A, 0x50, 0x5E, 0x02, 0x46, 0xF2, 0xF6, 0x0C, 0x49, 0x0F,
          0xF0, 0xC0, 0x97, 0xA7, 0xBE, 0x27, 0x21, 0x0C, 0xBB, 0x75, 0x00,
          0x23, 0x7F, 0x88, 0xB0, 0xCD, 0x48, 0x29, 0x8B, 0xC9, 0xB8,
@@ -1760,6 +1795,13 @@
      446,
      true},
     {{
+         0x76, 0x21, 0x95, 0xC2, 0x25, 0x58, 0x6E, 0xE6, 0xC0, 0x23, 0x74,
+         0x56, 0xE2, 0x10, 0x7D, 0xC5, 0x4F, 0x1E, 0xFC, 0x21, 0xF6, 0x1A,
+         0x79, 0x2E, 0xBD, 0x51, 0x59, 0x13, 0xCC, 0xE6, 0x83, 0x32,
+     },
+     535,
+     false},
+    {{
          0x76, 0xEE, 0x85, 0x90, 0x37, 0x4C, 0x71, 0x54, 0x37, 0xBB, 0xCA,
          0x6B, 0xBA, 0x60, 0x28, 0xEA, 0xDD, 0xE2, 0xDC, 0x6D, 0xBB, 0xB8,
          0xC3, 0xF6, 0x10, 0xE8, 0x51, 0xF1, 0x1D, 0x1A, 0xB7, 0xF5,
@@ -2299,6 +2341,13 @@
      259,
      true},
     {{
+         0x96, 0x35, 0x2D, 0x0A, 0xD8, 0x75, 0xC0, 0x27, 0xDB, 0x82, 0xD5,
+         0x99, 0xBA, 0xA8, 0xD4, 0x2E, 0x5C, 0x47, 0x26, 0x49, 0x98, 0x1E,
+         0xCE, 0xED, 0x3B, 0xFC, 0x65, 0xF4, 0xC8, 0x1F, 0xD5, 0xC1,
+     },
+     526,
+     false},
+    {{
          0x96, 0x47, 0x5B, 0x35, 0xAC, 0xB1, 0xC9, 0x30, 0x3A, 0x90, 0xBD,
          0x1D, 0xBF, 0x57, 0x41, 0x8F, 0x78, 0xE2, 0x9A, 0xF1, 0x1C, 0x4D,
          0xE8, 0xC8, 0xCB, 0xA2, 0xE5, 0xF9, 0x30, 0x9E, 0x38, 0xD4,
@@ -2467,6 +2516,13 @@
      407,
      true},
     {{
+         0xA0, 0x2F, 0xAF, 0xA1, 0x92, 0xC8, 0xCB, 0x81, 0xCB, 0x13, 0x41,
+         0x55, 0x4F, 0x9C, 0x05, 0xB7, 0x1C, 0xCA, 0x2A, 0x89, 0x0B, 0x0D,
+         0x12, 0x98, 0xD6, 0x83, 0x64, 0x7C, 0x96, 0x1E, 0xFB, 0xDF,
+     },
+     523,
+     false},
+    {{
          0xA1, 0x25, 0x74, 0xF4, 0xEB, 0x73, 0x95, 0xCC, 0x63, 0x0A, 0x15,
          0xFE, 0xC8, 0xDB, 0x1C, 0x7C, 0x82, 0x8F, 0x66, 0x69, 0x9D, 0x98,
          0x4C, 0x8C, 0x89, 0x7E, 0xCA, 0x44, 0xC8, 0x08, 0xF5, 0x5D,
@@ -2516,6 +2572,13 @@
      106,
      true},
     {{
+         0xA4, 0x95, 0xC8, 0xD1, 0x10, 0xE8, 0xB9, 0xE2, 0x00, 0xF3, 0x70,
+         0xAE, 0xDA, 0x3F, 0xF9, 0x2E, 0xE4, 0x3F, 0x8E, 0x3D, 0x4E, 0xC0,
+         0xDB, 0x1C, 0x0D, 0xC5, 0x8B, 0xD7, 0x62, 0x88, 0x0B, 0xA5,
+     },
+     529,
+     false},
+    {{
          0xA4, 0xB8, 0x9B, 0xB7, 0x06, 0x56, 0xEA, 0x49, 0x8F, 0x2D, 0x9E,
          0x00, 0xA4, 0x97, 0xFD, 0xB9, 0xDC, 0xD2, 0x0B, 0x81, 0xB8, 0x93,
          0x8E, 0x95, 0x2B, 0xBA, 0x2D, 0xF9, 0xF6, 0x57, 0x29, 0xC3,
@@ -2719,6 +2782,13 @@
      281,
      true},
     {{
+         0xAE, 0x7F, 0x96, 0x2C, 0xB9, 0xE6, 0xA7, 0xDB, 0xF7, 0xB8, 0x33,
+         0xFB, 0x18, 0xFA, 0x9B, 0x71, 0xA8, 0x91, 0x75, 0xDF, 0x94, 0x9C,
+         0x23, 0x2B, 0x6A, 0x9E, 0xF7, 0xCB, 0x3D, 0xF2, 0xBB, 0xFC,
+     },
+     525,
+     false},
+    {{
          0xAF, 0x11, 0x0F, 0x6B, 0x5A, 0xE8, 0xB7, 0x67, 0xEA, 0xC6, 0xE0,
          0xAA, 0x27, 0x3F, 0x38, 0x16, 0xE7, 0xA4, 0x0A, 0x64, 0x4E, 0xDA,
          0xCB, 0x43, 0x98, 0x14, 0x63, 0x56, 0xE7, 0x75, 0x09, 0xD6,
@@ -2775,6 +2845,13 @@
      72,
      true},
     {{
+         0xB1, 0x5A, 0xC9, 0x56, 0x12, 0x04, 0x75, 0x61, 0x24, 0xB9, 0xC4,
+         0xD3, 0xFE, 0x40, 0x6D, 0x93, 0x83, 0x3F, 0xF6, 0x66, 0x52, 0xF6,
+         0x7F, 0xBF, 0x13, 0x9F, 0x5B, 0xBF, 0x03, 0x0A, 0x0E, 0x64,
+     },
+     528,
+     false},
+    {{
          0xB1, 0x6C, 0xB1, 0xBA, 0x52, 0x9A, 0x39, 0xE2, 0xDF, 0xD5, 0x3B,
          0x3F, 0xF5, 0xA7, 0x9F, 0x19, 0x04, 0x61, 0x4D, 0x83, 0xE3, 0x13,
          0x04, 0xF0, 0x27, 0x8B, 0xB4, 0x0B, 0x38, 0xCF, 0x78, 0x24,
@@ -2901,6 +2978,13 @@
      178,
      false},
     {{
+         0xBB, 0x0C, 0xE7, 0x04, 0x03, 0x14, 0xA1, 0x43, 0xDC, 0xD1, 0x0E,
+         0x65, 0xCC, 0xAE, 0xEF, 0x70, 0x10, 0xE1, 0xB7, 0x84, 0xD1, 0x5D,
+         0x19, 0x5D, 0x77, 0xB5, 0x60, 0x19, 0x56, 0xBF, 0x9E, 0x3F,
+     },
+     541,
+     false},
+    {{
          0xBB, 0x41, 0x28, 0xEC, 0x96, 0x20, 0xF2, 0xD2, 0xA4, 0x9C, 0xE8,
          0xE2, 0xC4, 0xE2, 0x57, 0xAE, 0xBA, 0xD9, 0x3A, 0x0F, 0x11, 0xC5,
          0x6B, 0x5F, 0xA4, 0xB0, 0x0E, 0x23, 0x75, 0x9F, 0xA3, 0x9D,
@@ -2936,6 +3020,13 @@
      71,
      false},
     {{
+         0xBD, 0xAC, 0xCB, 0xF2, 0xE8, 0xB2, 0x7C, 0x0C, 0x02, 0xA6, 0x89,
+         0xEE, 0x86, 0x6C, 0x9B, 0x86, 0xEC, 0x04, 0x44, 0x2A, 0xFC, 0xDD,
+         0xDD, 0x5D, 0x4E, 0xC3, 0x6D, 0xEF, 0x21, 0xE7, 0x61, 0xDD,
+     },
+     539,
+     false},
+    {{
          0xBE, 0x32, 0x80, 0xC6, 0x86, 0x3C, 0x77, 0x0A, 0x33, 0xC9, 0x04,
          0x0B, 0xD9, 0x7D, 0x55, 0x40, 0xB2, 0x16, 0xD1, 0xD9, 0x1D, 0xB8,
          0xB0, 0x88, 0xCE, 0xAC, 0x11, 0x97, 0xDA, 0xE1, 0xD6, 0x60,
@@ -2992,6 +3083,13 @@
      124,
      false},
     {{
+         0xC2, 0xB3, 0xC3, 0x1A, 0x4A, 0x29, 0x85, 0x0A, 0xA8, 0xF3, 0xCF,
+         0x47, 0x2A, 0x11, 0x69, 0xFF, 0x71, 0xB4, 0x16, 0x57, 0x9F, 0x6A,
+         0x44, 0x82, 0xEC, 0x77, 0x44, 0xB8, 0x3D, 0xF9, 0x88, 0xAC,
+     },
+     533,
+     false},
+    {{
          0xC3, 0x72, 0xF6, 0xD1, 0x8E, 0xBE, 0xE5, 0xAA, 0x23, 0xD9, 0xE9,
          0x19, 0xF3, 0xE6, 0xBE, 0x98, 0x48, 0x8E, 0xC0, 0x16, 0x07, 0xDF,
          0x31, 0x62, 0xFC, 0x19, 0x2E, 0x4B, 0x13, 0x46, 0xAF, 0xB3,
@@ -3258,6 +3356,13 @@
      172,
      true},
     {{
+         0xD6, 0xEC, 0x63, 0x48, 0xA7, 0xC4, 0xD4, 0x2A, 0xC4, 0x8D, 0x9C,
+         0x43, 0x14, 0x5A, 0x8C, 0xD7, 0x19, 0x71, 0x36, 0x23, 0x63, 0x26,
+         0x7C, 0x66, 0x73, 0xA7, 0x7B, 0x8A, 0x85, 0x73, 0xA6, 0x6B,
+     },
+     530,
+     false},
+    {{
          0xD8, 0xFB, 0x33, 0xE3, 0x85, 0xC9, 0xC2, 0xDA, 0x72, 0x9A, 0x84,
          0x70, 0x6B, 0xA9, 0x27, 0xDC, 0xBB, 0x79, 0x27, 0x3E, 0x12, 0x2F,
          0xFD, 0x96, 0x73, 0x36, 0x3B, 0x70, 0xB7, 0xF3, 0x6C, 0xBB,
@@ -3328,6 +3433,13 @@
      236,
      true},
     {{
+         0xDE, 0x7B, 0x69, 0x32, 0xE9, 0xC4, 0x45, 0x82, 0xCE, 0x0D, 0xE0,
+         0x7A, 0xBD, 0xAB, 0x7E, 0xEA, 0x90, 0xC7, 0x5D, 0x6D, 0x2A, 0x07,
+         0x33, 0x1D, 0xF5, 0x7B, 0xD5, 0xCB, 0x88, 0x55, 0x3D, 0x13,
+     },
+     542,
+     false},
+    {{
          0xDF, 0x53, 0x0B, 0xAC, 0x9F, 0xCD, 0x91, 0x4C, 0x25, 0x2C, 0x2F,
          0xBD, 0xCE, 0xDD, 0xC6, 0x18, 0x3D, 0x4A, 0xE8, 0xC6, 0x80, 0xAD,
          0x65, 0xF0, 0x3E, 0x20, 0x48, 0x61, 0xDD, 0x7B, 0x1C, 0x73,
@@ -3335,6 +3447,13 @@
      313,
      true},
     {{
+         0xE0, 0x4A, 0x02, 0x2C, 0xE3, 0x2F, 0x4C, 0xCF, 0x2C, 0x7F, 0x60,
+         0x46, 0x28, 0x7B, 0x82, 0x8A, 0x32, 0xA9, 0x09, 0xF5, 0xE7, 0x51,
+         0x44, 0x7F, 0x83, 0xFD, 0x2C, 0x71, 0xF6, 0xFD, 0x81, 0x73,
+     },
+     524,
+     false},
+    {{
          0xE0, 0xC7, 0x80, 0xC6, 0x29, 0x90, 0x3E, 0x12, 0x6F, 0x1D, 0x91,
          0x95, 0x70, 0xDC, 0xE7, 0xC4, 0x96, 0xF8, 0x5F, 0x33, 0xAA, 0xE6,
          0x6B, 0x9A, 0x31, 0x47, 0xEE, 0x75, 0xF8, 0xD1, 0x62, 0x0A,
@@ -3349,6 +3468,13 @@
      369,
      true},
     {{
+         0xE1, 0x4E, 0x51, 0x89, 0x1F, 0x34, 0x92, 0x24, 0x3E, 0xEA, 0x61,
+         0x3B, 0xC2, 0xC8, 0x14, 0xD4, 0x72, 0x24, 0xB2, 0x24, 0xC5, 0x7D,
+         0x38, 0x16, 0x9E, 0x95, 0x8E, 0x30, 0xB3, 0xDE, 0xDE, 0xE4,
+     },
+     527,
+     false},
+    {{
          0xE1, 0x56, 0x44, 0x5F, 0xA2, 0x0C, 0x32, 0xAD, 0x00, 0x93, 0x7B,
          0x27, 0xD0, 0x96, 0xB8, 0x96, 0x3B, 0xCC, 0x86, 0x39, 0x50, 0x33,
          0x3A, 0x87, 0x7E, 0x68, 0xFA, 0x69, 0x70, 0x7A, 0x03, 0xAF,
@@ -3489,6 +3615,13 @@
      129,
      true},
     {{
+         0xF0, 0x01, 0x1F, 0x92, 0xFC, 0xF9, 0xBE, 0x36, 0xC7, 0xA5, 0xB3,
+         0x6E, 0x7B, 0xC8, 0x62, 0xAB, 0x20, 0xE9, 0x4E, 0xF3, 0x6F, 0xEA,
+         0x8A, 0x56, 0x1D, 0xB0, 0xA8, 0xD7, 0x75, 0x0C, 0x1F, 0x51,
+     },
+     537,
+     false},
+    {{
          0xF1, 0xC6, 0xBA, 0x67, 0x0C, 0xFC, 0x88, 0xE4, 0xDF, 0x52, 0x97,
          0x3C, 0xAE, 0x42, 0x0F, 0x0A, 0x08, 0x9D, 0xD4, 0x74, 0x14, 0x4F,
          0xE5, 0x80, 0x6C, 0x42, 0x00, 0x64, 0xE1, 0x59, 0x12, 0x29,
@@ -3629,6 +3762,13 @@
      158,
      true},
     {{
+         0xFC, 0x78, 0x43, 0x00, 0xEC, 0x8D, 0xF4, 0xD3, 0xD1, 0xBA, 0xD7,
+         0x63, 0x83, 0x51, 0x82, 0x91, 0x8D, 0x52, 0xA9, 0xFF, 0x02, 0x38,
+         0xBD, 0xF6, 0x95, 0xA1, 0xCD, 0x9B, 0xDB, 0x98, 0x32, 0x1C,
+     },
+     534,
+     false},
+    {{
          0xFC, 0xF7, 0xDA, 0x98, 0x36, 0x03, 0xE8, 0x88, 0x62, 0x03, 0x0D,
          0x96, 0x13, 0x7D, 0x8E, 0x13, 0x03, 0x1B, 0xAD, 0xFB, 0x4D, 0x56,
          0xC1, 0xFD, 0x4C, 0xAC, 0xC3, 0x39, 0xF6, 0xBD, 0xBB, 0x2A,
@@ -3664,6 +3804,13 @@
      110,
      false},
     {{
+         0xFE, 0xE8, 0xAF, 0x92, 0x91, 0x75, 0x68, 0x7F, 0x46, 0x38, 0xA3,
+         0xFC, 0x98, 0x3D, 0xB8, 0xEC, 0xD0, 0xE5, 0xE2, 0xA8, 0x3E, 0x73,
+         0x7F, 0x3F, 0xB7, 0x7B, 0x4C, 0x22, 0xFC, 0xBA, 0xC0, 0xA6,
+     },
+     538,
+     false},
+    {{
          0xFF, 0x34, 0x2F, 0xB6, 0xC4, 0xC8, 0xBD, 0x30, 0xA4, 0x70, 0x6F,
          0x73, 0x48, 0x95, 0x39, 0xF1, 0x9E, 0x6E, 0x48, 0xCC, 0x05, 0xF4,
          0x62, 0x54, 0x65, 0x4F, 0x66, 0x10, 0xDB, 0xC5, 0x40, 0xE9,
diff --git a/net/cookies/cookie_partition_key.cc b/net/cookies/cookie_partition_key.cc
index 52664b3e..7fe8e48 100644
--- a/net/cookies/cookie_partition_key.cc
+++ b/net/cookies/cookie_partition_key.cc
@@ -14,6 +14,18 @@
 #include "net/base/features.h"
 #include "net/cookies/cookie_constants.h"
 
+namespace {
+
+bool PartitionedCookiesEnabled(
+    const absl::optional<base::UnguessableToken>& nonce) {
+  return base::FeatureList::IsEnabled(net::features::kPartitionedCookies) ||
+         (base::FeatureList::IsEnabled(
+              net::features::kNoncedPartitionedCookies) &&
+          nonce);
+}
+
+}  // namespace
+
 namespace net {
 
 CookiePartitionKey::CookiePartitionKey() = default;
@@ -101,9 +113,7 @@
   // If PartitionedCookies is enabled, all partitioned cookies are allowed.
   // If NoncedPartitionedCookies is enabled, only partitioned cookies whose
   // partition key has a nonce are allowed.
-  if (!base::FeatureList::IsEnabled(features::kPartitionedCookies) &&
-      (!base::FeatureList::IsEnabled(features::kNoncedPartitionedCookies) ||
-       !nonce)) {
+  if (!PartitionedCookiesEnabled(nonce)) {
     return absl::nullopt;
   }
 
@@ -120,6 +130,16 @@
       net::CookiePartitionKey(*partition_key_site, nonce));
 }
 
+// static
+absl::optional<net::CookiePartitionKey>
+CookiePartitionKey::FromStorageKeyComponents(
+    const SchemefulSite& top_level_site,
+    const absl::optional<base::UnguessableToken>& nonce) {
+  if (!PartitionedCookiesEnabled(nonce))
+    return absl::nullopt;
+  return CookiePartitionKey::FromWire(top_level_site, nonce);
+}
+
 bool CookiePartitionKey::IsSerializeable() const {
   if (!base::FeatureList::IsEnabled(features::kPartitionedCookies)) {
     DLOG(WARNING) << "Attempting to serialize CookiePartitionKey when "
@@ -133,6 +153,9 @@
 
 std::ostream& operator<<(std::ostream& os, const CookiePartitionKey& cpk) {
   os << cpk.site();
+  if (cpk.nonce().has_value()) {
+    os << ",nonced";
+  }
   return os;
 }
 
diff --git a/net/cookies/cookie_partition_key.h b/net/cookies/cookie_partition_key.h
index 4b920323..ddd9591 100644
--- a/net/cookies/cookie_partition_key.h
+++ b/net/cookies/cookie_partition_key.h
@@ -92,6 +92,14 @@
     return absl::make_optional(CookiePartitionKey(true));
   }
 
+  // Create a new CookiePartitionKey from the components of a StorageKey.
+  // Forwards to FromWire, but unlike that method in this one the optional nonce
+  // argument has no default. It also checks that cookie partitioning is enabled
+  // before returning a valid key, which FromWire does not check.
+  static absl::optional<CookiePartitionKey> FromStorageKeyComponents(
+      const SchemefulSite& top_level_site,
+      const absl::optional<base::UnguessableToken>& nonce);
+
   const SchemefulSite& site() const { return site_; }
 
   bool from_script() const { return from_script_; }
diff --git a/net/data/ssl/root_stores/README.md b/net/data/ssl/root_stores/README.md
index 6cfefadc..c2515dce 100644
--- a/net/data/ssl/root_stores/README.md
+++ b/net/data/ssl/root_stores/README.md
@@ -96,3 +96,8 @@
 Additional restrictions upon trusted CAs are maintained as properties within
 the STL; however, these were not consulted, as they're not applicable to this
 use case.
+
+Tools that can help get this data:
+
+* https://github.com/robstradling/authroot.stl
+* https://github.com/zmap/rootfetch
diff --git a/net/data/ssl/root_stores/root_stores.json b/net/data/ssl/root_stores/root_stores.json
index 5edb8db..785e6bb 100644
--- a/net/data/ssl/root_stores/root_stores.json
+++ b/net/data/ssl/root_stores/root_stores.json
@@ -54,7 +54,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "007e452fd5cf838946696dfe37a2db2ef3991436d27bcbab45922053c15a87a8": [
       "windows/080328202117",
@@ -127,7 +128,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "00ab444abd6bdba33da8de569ac4ecde326d1be1a61442d5eec3975a0c243f04": [
       "windows/070201011524",
@@ -205,7 +207,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "016e1dcd5f78841bbebbae9ddea08c8d7ec54e698e95bb778ecdd1e10d8bf4f9": [
       "windows/181124234732",
@@ -223,6 +226,9 @@
       "windows/200226213356",
       "windows/200421004343"
     ],
+    "018e13f0772532cf809bd1b17281867283fc48c6e13be9c69812854a490c1b05": [
+      "windows/220719163622"
+    ],
     "02ed0eb28c14da45165c566791700d6451d7fb56f0b2ab1d3b8eb070e56edff5": [
       "android/android10-release",
       "android/android11-release",
@@ -330,7 +336,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "03458b6abeecc214953d97149af45391691de9f9cdcc2647863a3d67c95c243b": [
       "android/kitkat-cts-release",
@@ -494,7 +501,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "0378b202ccabba99a12e569a11a077db1edb39482061c75d0073059d9ab5b513": [
       "windows/071219233937",
@@ -604,7 +612,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "04048028bf1f2864d48f9ad4d83294366a828856553f3b14303f90147f5d40ef": [
       "android/android10-release",
@@ -731,7 +740,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "04acfb3b24793f300f67ef87e44dd72cb9b28b204f389a7cd5ae28785c7d42cd": [
       "macos/10.10.0",
@@ -819,7 +829,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "04f1bec36951bc1454a904ce32890c5da3cde1356b7900f6e62dfa2041ebad51": [
       "windows/170228174808",
@@ -850,7 +861,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "0536801fbb443b3e905fd6d70d8c81eb88551be8061299110d2b4f82e64cade1": [
       "windows/100719231554",
@@ -913,7 +925,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "058a40323ec8c46262c3052a5d357b91ac24d3da26351b3ff4407e99f7a4e9b4": [
       "windows/070201011524",
@@ -1173,7 +1186,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739": [
       "android/android10-release",
@@ -1502,7 +1516,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "075bfcca2d55ae6e35742c32afd0ca8ea4c958feefc23224999541c033d69c8d": [
       "windows/120125230451",
@@ -1556,7 +1571,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "0771920c8cb874d5c5a4dc0d6a51a2d495d38c4de2cd5b83d2a06faa051935f6": [
       "windows/121102212406",
@@ -1607,7 +1623,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "0791ca0749b20782aad3c7d7bd0cdfc9485835843eb2d7996009ce43ab6c6927": [
       "android/kitkat-cts-release",
@@ -1637,6 +1654,9 @@
       "mozilla/2.14",
       "mozilla/2.9"
     ],
+    "07cd9aa9064a9b94c6aef8fb784c1bbc1beda08acbe86878d781a39167626cf8": [
+      "windows/220719163622"
+    ],
     "08297a4047dba23680c731db6e317653ca7848e1bebd3a0b0179a707f92cf178": [
       "android/kitkat-cts-release",
       "android/kitkat-mr1-release",
@@ -1854,7 +1874,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "0b5eed4e846403cf55e065848440ed2a82758bf5b9aa1f253d4613cfa080ff3f": [
       "android/kitkat-cts-release",
@@ -1979,7 +2000,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "0c0b6b2bd1edd7b27fead157f8e846b335b784a39f06c47216c8746f64c5ceda": [
       "windows/140912180251",
@@ -2150,7 +2172,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "0c2cd63df7806fa399ede809116b575bf87989f06518f9808c860503178baf66": [
       "android/android10-release",
@@ -2330,7 +2353,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "0ed3ffab6c149c8b4e71058e8668d429abfda681c2fff508207641f0d751a3e5": [
       "macos/10.10.0",
@@ -2595,7 +2619,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "126bf01c1094d2f0ca2e352380b3c724294546ccc65597bef7f12d8a171f1984": [
       "macos/10.10.0",
@@ -2670,7 +2695,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "12d480c1a3c664781b99d9df0e9faf3f1cacee1b3c30c3123a337a4a454ffed2": [
       "windows/071219233937",
@@ -2873,7 +2899,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "1465fa205397b876faa6f0a9958e5590e40fcc7faa4fb7c2c8677521fb5fb658": [
       "android/android10-release",
@@ -3014,7 +3041,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "1501f89c5c4dcf36cf588a17c9fd7cfceb9ee01e8729be355e25de80eb6284b4": [
       "windows/160414222039",
@@ -3048,7 +3076,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "152a402bfcdf2cd548054d2275b39c7fca3ec0978078b0f0ea76e561a6c7433e": [
       "android/nougat-mr1-cts-release",
@@ -3116,7 +3145,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "1594cb5b826c315de3bc932c56895ff23a3a988b5dc1f034d214dfd858d89ee8": [
       "windows/070109202240",
@@ -3198,7 +3228,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "15f0ba00a3ac7af3ac884c072b1011a077bd77c097f40164b2f8598abd83860c": [
       "android/android10-release",
@@ -3426,7 +3457,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "1793927a0614549789adce2f8f34f7f0b66d0f3ae3a3b84d21ec15dbba4fadc7": [
       "android/android10-release",
@@ -3546,7 +3578,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "179fbc148a3dd00fd24ea13458cc43bfa7f59c8182d783a513f6ebec100c8924": [
       "android/android10-release",
@@ -3651,7 +3684,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "18ce6cfe7bf14e60b2e347b8dfe868cb31d02ebb3ada271569f50343b46db3a4": [
       "android/android10-release",
@@ -3722,7 +3756,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "18f1fc7f205df8adddeb7fe007dd57e3af375a9c4d8d73546bf4f1fed1e18d35": [
       "android/android10-release",
@@ -3863,7 +3898,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "19abcdff3a74402fa8f0ca206bf7fab0dffff3ae2bbd719584d21090a4353207": [
       "windows/170613190204",
@@ -3892,7 +3928,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "1a0d20445de5ba1862d19ef880858cbce50102b36e8f0a040c3c69e74522fe6e": [
       "windows/110919210309",
@@ -3948,7 +3985,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "1a2512cda6744abea11432a2fdc9f8c088db5a98c89e13352574cde4d9e80cdd": [
       "windows/140912180251",
@@ -3991,7 +4029,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "1aa980c8c0d316f25029978982f033cbb3a3f4188d669f2de6a8d84ee00a1575": [
       "windows/080328202117",
@@ -4135,7 +4174,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "1ba622b36325544ae922afc22ef9d367943794f6e16874f368a733c65c9d5279": [
       "windows/111018233154",
@@ -4273,7 +4313,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "1d4f0596fca2611d09f84c78f2ea565ef2eab9cfc272a1718bd336e6e0ae021a": [
       "windows/070109202240",
@@ -4365,7 +4406,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "1e49ac5dc69e86d0565da2c1305c419330b0b781bfec50e54a1b35af7fddd501": [
       "macos/10.11.0",
@@ -4449,7 +4491,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "1e51942b84fd467bf77d1c89da241c04254dc8f3ef4c22451fe7a89978bdcd4f": [
       "windows/160916174005",
@@ -4482,7 +4525,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "1e910b40c08184c0ca20468e824502ff2485163f77b03bb73296823f03885621": [
       "windows/111018233154",
@@ -4568,7 +4612,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "2193cfea381211a1aeaa2de984e630643a87160b1208118145eafb8e1bc69958": [
       "windows/170228174808",
@@ -4599,7 +4644,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "21db20123660bb2ed418205da11ee7a85a65e2bc6e55b5af7e7899c8a266d92e": [
       "android/kitkat-cts-release",
@@ -4723,7 +4769,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "229ccc196d32c98421cc119e78486eebef603aecd525c6b88b47abb740692b96": [
       "windows/150618202535",
@@ -4764,7 +4811,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "22a2c1f7bded704cc1e701b5f408c310880fe956b5de2a4a44f99c873a25a7c8": [
       "android/android10-release",
@@ -4821,7 +4869,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "22e0d11dc9207e16c92b2ee18cfdb2c2e940626847921fc528cedd2f7932f714": [
       "windows/070109202240",
@@ -4959,7 +5008,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "2399561127a57125de8cefea610ddf2fa078b5c8067f4e828290bfb860e84b3c": [
       "android/android10-release",
@@ -5087,7 +5137,11 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
+    ],
+    "242b69742fcb1e5b2abf98898b94572187544e5b4d9911786573621f6a74b82c": [
+      "windows/220719163622"
     ],
     "248302a977f40f7dd6a2b770586adfaac3eb1e85fd1a102dbd7863c72b8f8ef2": [
       "macos/10.10.0",
@@ -5125,7 +5179,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "2530cc8e98321502bad96f9b1fba1b099e2d299e0f4548bb914f363bc0d4531f": [
       "android/android10-release",
@@ -5191,7 +5246,8 @@
       "mozilla/2.9",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "2602d21e81277a83f6048128f61d794a06f474e1f75e49740a817c2666f62211": [
       "windows/070109202240",
@@ -5313,7 +5369,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "27995829fe6a7515c1bfe848f9c4761db16c225929257bf40d0894f29ea8baf2": [
       "android/nougat-mr1-cts-release",
@@ -5381,7 +5438,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "2834991cf677466d22baac3b0055e5b911d9a9e55f5b85ba02dc566782c30e8a": [
       "macos/10.10.0",
@@ -5507,7 +5565,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "2a8da2f8d23e0cd3b5871ecfb0f42276ca73230667f474eede71c5ee32cc3ec6": [
       "windows/160414222039",
@@ -5541,7 +5600,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "2a99f5bc1174b73cbb1d620884e01c34e51ccb3978da125f0e33268883bf4158": [
       "android/android10-release",
@@ -5635,7 +5695,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "2cabeafe37d06ca22aba7391c0033d25982952c453647349763a3ab5ad6ccf69": [
       "android/android10-release",
@@ -5673,7 +5734,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "2ce1cb0bf9d2f9e102993fbe215152c3b2dd0cabde1c68e5319b839154dbb7f5": [
       "android/android10-release",
@@ -5799,7 +5861,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "2d47437de17951215a12f3c58e51c729a58026ef1fcc0a5fb3d9dc012f600d19": [
       "android/kitkat-cts-release",
@@ -6050,7 +6113,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "2dfcbacadf22a6ff107a51fd3e8b9e17858028879b13f7c3b57b3e1bd2315809": [
       "windows/070109202240",
@@ -6091,7 +6155,8 @@
       "windows/150122021939"
     ],
     "2e44102ab58cb85419451c8e19d9acf3662cafbc614b6a53960a30f7d0e2eb41": [
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "2e7bf16cc22485a7bbe2aa8696750761b0ae39be3b2fe9d0cc6d4ef73491425c": [
       "android/android10-release",
@@ -6143,7 +6208,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "2f1062f8bf84e7eb83a0f64c98d891fbe2c811b17ffac0bce1a6dc9c7c3dcbb7": [
       "macos/10.9.0",
@@ -6325,7 +6391,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "31ad6648f8104138c738f39ea4320133393e3a18cc02296ef97c2ac9ef6731d0": [
       "android/android10-release",
@@ -6430,7 +6497,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "31eace9b4c9c71734a185680bc24866ca6cbd82b3cb61bcc8706261b59ce1073": [
       "windows/070109202240",
@@ -6672,7 +6740,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "341de98b1392abf7f4ab90a960cf25d4bd6ec65b9a51ce6ed067d00ec7ce9b7f": [
       "macos/10.10.0",
@@ -6726,7 +6795,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "34ff2a4409dc1383e9f8966e8adfe5719eba373fd0ad5e2f49f90ee07cf5d4c1": [
       "windows/190416222336",
@@ -6738,12 +6808,14 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "358df39d764af9e1b766e9c972df352ee15cfac227af6ad1d70e8e4a6edcba02": [
       "android/android12-release",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "35ae5bddd8f7ae635cffba5682a8f00b95f48462c7108ee9a0e5292b074aafb2": [
       "android/kitkat-cts-release",
@@ -6945,7 +7017,11 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
+    ],
+    "371a00dc0533b3721a7eeb40e8419e70799d2b0a0f2c1d80693165f7cec4ad75": [
+      "windows/220719163622"
     ],
     "37d51006c512eaab626421f1ec8c92013fc5f82ae98ee533eb4619b8deb4d06c": [
       "android/android10-release",
@@ -7085,7 +7161,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "37d8dc8af7867845da3344a6b1bade448d8a80e47b5579f96bf631768f9f30f6": [
       "windows/070201011524",
@@ -7373,7 +7450,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "3c4fb0b95ab8b30032f432b86f535fe172c185d0fd39865837cf36187fa6f428": [
       "android/android10-release",
@@ -7468,7 +7546,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "3c5f81fea5fab82c64bfa2eaecafcde8e077fc8620a7cae537163df36edbf378": [
       "android/android10-release",
@@ -7590,7 +7669,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "3ccc3ccfe45496d07b620dbf1328e8a1490018f48633c8a28a995ca60408b0be": [
       "windows/070109202240",
@@ -7669,7 +7749,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "3cfc3c14d1f684ff17e38c43ca440c00b967ec933e8bfe064ca1d72c90f2adb0": [
       "mozilla/2.10",
@@ -7808,7 +7889,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "3e9099b5015e8f486c00bcea9d111ee721faba355a89bcf1df69561e3dc6325c": [
       "android/android10-release",
@@ -7949,7 +8031,11 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
+    ],
+    "3f034bb5704d44b2d08545a02057de93ebf3905fce721acbc730c06ddaee904e": [
+      "windows/220719163622"
     ],
     "3f06e55681d496f5be169eb5389f9f2b8ff61e1708df6881724849cd5d27cb69": [
       "android/kitkat-cts-release",
@@ -7993,6 +8079,9 @@
       "windows/090825180842",
       "windows/091013033632"
     ],
+    "3f99cc474acfce4dfed58794665e478d1547739f2e780f1bb4ca9b133097d401": [
+      "windows/220719163622"
+    ],
     "3f9da4744ec9676cd38b530e500a463fbcb18165977ff0da6d5993c3fe5fab7c": [
       "windows/070201011524",
       "windows/070522004642",
@@ -8141,7 +8230,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "40f6af0346a99aa1cd1d555a4e9cce62c7f9634603ee406615833dc8c8d00367": [
       "android/android11-release",
@@ -8166,7 +8256,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "416b1f9e84e74c1d19b23d8d7191c6ad81246e641601f599132729f507beb3cc": [
       "windows/180518182443",
@@ -8188,7 +8279,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "417dcf3180f4ed1a3747acf1179316cd48cb05c5788435168aed98c98cdcb615": [
       "windows/121102212406",
@@ -8239,7 +8331,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "41c923866ab4cad6b7ad578081582e020797a6cbdf4fff78ce8396b38937d7f5": [
       "android/android10-release",
@@ -8378,7 +8471,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "41d4f6dcf130b9843a3b9a9530953e925fdd84e8b7aeb8f205b8fae39352617d": [
       "macos/10.10.0",
@@ -8528,7 +8622,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "4210f199499a9ac33c8de02ba6dbaa14408bdd8a6e324689c1922d069715a332": [
       "windows/100503224537",
@@ -8659,7 +8754,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161": [
       "android/android10-release",
@@ -8800,7 +8896,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "43df5774b03e7fef5fe40d931a7bedf1bb2e6b42738c4e6d3841103d3aa7f339": [
       "android/android10-release",
@@ -8928,7 +9025,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "43f257412d440d627476974f877da8f1fc2444565a367ae60eddc27a412531ae": [
       "macos/10.10.0",
@@ -9142,7 +9240,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "45140b3247eb9cc8c5b4f0d7b53091f73292089e6e5a63e2749dd3aca9198eda": [
       "android/android10-release",
@@ -9268,7 +9367,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "46273285615d96e52da9fc2ed8c036f10af3d9f6280f8d288706c52b2011b4da": [
       "windows/090501224247",
@@ -9336,7 +9436,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "46edc3689046d53a453fb3104ab80dcaec658b2660ea1629dd7e867990648716": [
       "android/android10-release",
@@ -9395,7 +9496,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "488e134f30c5db56b76473e608086842bf21af8ab3cd7ac67ebdf125d531834e": [
       "windows/090825180842",
@@ -9462,7 +9564,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "488fca189eaadf54a3f920ed39e587183ba512232999fae3e4a285fe98e298d1": [
       "windows/150122021939",
@@ -9582,7 +9685,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "49c8175a9815e08bef129a929de1bacad04e4db67a8c839293953e5031c81ca0": [
       "windows/070109202240",
@@ -9734,7 +9838,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "49f74f824f2e059fe99c98af3219ec0d9a004d1b64dd2fd1452616318ab806c0": [
       "windows/070109202240",
@@ -9774,6 +9879,9 @@
       "windows/140912180251",
       "windows/150122021939"
     ],
+    "4b009c1034494f9ab56bba3ba1d62731fc4d20d8955adcec10a925607261e338": [
+      "windows/220719163622"
+    ],
     "4b03f45807ad70f21bfc2cae71c9fde4604c064cf5ffb686bae5dbaad7fdd34c": [
       "android/android10-release",
       "android/android11-release",
@@ -9899,7 +10007,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "4b22d5a6aec99f3cdb79aa5ec06838479cd5ecba7164f7f22dc1d65f63d85708": [
       "android/lollipop-cts-release",
@@ -9958,7 +10067,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "4bdb7418bdf7ffe33ba0884afa7c0c61fd85a153972f65f7d01cb3ec7eb4073c": [
       "windows/070109202240",
@@ -10052,7 +10162,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "4d2491414cfe956746ec4cefa6cf6f72e28a1329432f9d8a907ac4cb5dadc15a": [
       "android/android10-release",
@@ -10152,7 +10263,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "4d9ebb28825c9643ab15d54e5f9614f13cb3e95de3cf4eac971301f320f9226e": [
       "windows/090825180842",
@@ -10219,7 +10331,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "4dbb0157a691fa7382289d65c0332ddb1dcb640b40ad10f010a43e20f3afed1e": [
       "windows/070109202240",
@@ -10297,6 +10410,9 @@
       "windows/140912180251",
       "windows/150122021939"
     ],
+    "4fa3126d8d3a11d1c4855a4f807cbad6cf919d3a5a88b03bea2c6372d93c40c9": [
+      "windows/220719163622"
+    ],
     "4ff460d54b9c86dabfbcfc5712e0400d2bed3fbc4d4fbdaa86e06adcd2a9ad7a": [
       "android/android10-release",
       "android/android11-release",
@@ -10403,7 +10519,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "507941c74460a0b47086220d4e9932572ab5d1b5bbcb8980ab1cb17651a844d2": [
       "android/kitkat-cts-release",
@@ -10519,7 +10636,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "513b2cecb810d4cde5dd85391adfc6c2dd60d87bb736d2b521484aa47a0ebef6": [
       "android/android10-release",
@@ -10646,7 +10764,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "51847c8cbd2e9a72c91e292d2ae247d7de1e3fd270547a20ef7d610f38b8842c": [
       "macos/10.10.0",
@@ -10849,7 +10968,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "53dfdfa4e297fcfe07594e8c62d5b8ab06b32c7549f38a163094fd6429d5da43": [
       "macos/10.10.0",
@@ -10917,7 +11037,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "54455f7129c20b1447c418f997168f24c58fc5023bf5da5be2eb6e1dd8902ed5": [
       "android/android10-release",
@@ -10969,7 +11090,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "54ae8a683fe2d78ff1ef0e0b3f58425092953ba08c67fe4a95595d1cebcdcb30": [
       "windows/140912180251",
@@ -11057,7 +11179,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "552f7bdcf1a7af9e6ce672017f4f12abf77240c78e761ac203d1d9d20ac89988": [
       "android/android10-release",
@@ -11162,7 +11285,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "5533a0401f612c688ebce5bf53f2ec14a734eb178bfae00e50e85dae6723078a": [
       "windows/131003230417",
@@ -11209,13 +11333,18 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "554153b13d2cf9ddb753bfbe1a4e0ae08d0aa4187058fe60a2b862b2e4b87bcb": [
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
+    ],
+    "5546a52504fba74f61ffd4890067529ade3b9c9d07e502592831ccda9b369fd3": [
+      "windows/220719163622"
     ],
     "55903859c8c0c3ebb8759ece4e2557225ff5758bbd38ebd48276601e1bd58097": [
       "android/android12-release",
@@ -11228,7 +11357,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "55926084ec963a64b96e2abe01ce0ba86a64fbfebcc7aab5afc155b37fd76066": [
       "android/android10-release",
@@ -11343,7 +11473,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "5607e260163f49c8ea4175a1c0a53b13195cb7d07845611e943a2ff507036834": [
       "windows/070522004642",
@@ -11420,7 +11551,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "568d6905a2c88708a4b3025190edcfedb1974a606a13c6e5290fcb2ae63edab5": [
       "android/android10-release",
@@ -11546,7 +11678,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "56c77128d98c18d91b4cfdffbc25ee9103d4758ea2abad826a90f3457d460eb4": [
       "android/nougat-mr1-cts-release",
@@ -11819,7 +11952,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "59b3829f1ff443344958fae8bff621b684c848cfbf7ead6b63a6ca50f2794f89": [
       "macos/10.11.0",
@@ -11903,7 +12037,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "5a1b5d6bc65523b40a6deffa45b48e4288ae8dd86dd70a5b858d4a5affc94f71": [
       "windows/071219233937",
@@ -12001,7 +12136,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "5a885db19c01d912c5759388938cafbbdf031ab2d48e91ee15589b42971d039c": [
       "android/android10-release",
@@ -12057,7 +12193,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "5ab4fcdb180b5b6af0d262a2375a2c77d25602015d96648756611e2e78c53ad3": [
       "windows/180926205955",
@@ -12075,7 +12212,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "5adfa25013bed3710831572de51c4b9a21171c00313249c4cb4719d37fbb8d20": [
       "windows/160916174005",
@@ -12108,7 +12246,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "5b1d9d24de0afea8b35ba04a1c3e25d0812cdf7c4625de0a89af9fe4bbd1bb15": [
       "windows/110919210309",
@@ -12303,7 +12442,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "5cc3d78e4e1d5e45547a04e6873e64f90cf9536d1ccc2ef800f355c4c5fd70fd": [
       "android/android10-release",
@@ -12397,7 +12537,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "5d56499be4d2e08bcfcad08a3e38723d50503bde706948e42f55603019e528ae": [
       "android/android10-release",
@@ -12494,7 +12635,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "5e3571f33f45a7df1537a68b5ffb9e036af9d2f5bc4c9717130dc43d7175aac7": [
       "windows/070201011524",
@@ -12571,7 +12713,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "5edb7ac43b82a06a8761e8d7be4979ebf2611f7dd79bf91c1c6b566a219ed766": [
       "android/android10-release",
@@ -12699,7 +12842,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "5f0b62eab5e353ea6521651658fbb65359f443280a4afbd104d77d10f9f04c07": [
       "android/kitkat-cts-release",
@@ -12909,7 +13053,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "606223d9db80df3939601e74b7e828e2800cce4273f76f276aa62db0a8e3b6c1": [
       "windows/071219233937",
@@ -12955,7 +13100,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "614fd18da1490560cdad1196e2492ab7062eab1a67b3a30f1d0585a7d6ba6824": [
       "windows/070109202240",
@@ -13250,7 +13396,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "62f240278c564c4dd8bf7d9d4f6f366ea894d22f5f34d989a983acec2fffed50": [
       "android/kitkat-cts-release",
@@ -13412,7 +13559,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "63343abfb89a6a03ebb57e9b3f5fa7be7c4f5c756f3017b3a8c488c3653e9179": [
       "macos/10.10.0",
@@ -13494,7 +13642,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "657cfe2fa73faa38462571f332a2363a46fce7020951710702cdfbb6eeda3305": [
       "android/android12-release",
@@ -13521,7 +13670,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "6639d13cab85df1ad9a23c443b3a60901e2b138d456fa71183578108884ec6bf": [
       "macos/10.10.0",
@@ -13989,7 +14139,11 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
+    ],
+    "69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470": [
+      "windows/220719163622"
     ],
     "69ddd7ea90bb57c93e135dc85ea6fcd5480b603239bdc454fc758b2a26cf7f79": [
       "android/android10-release",
@@ -14116,7 +14270,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "69fac9bd55fb0ac78d53bbee5cf1d597989fd0aaab20a25151bdf1733ee7d122": [
       "android/kitkat-cts-release",
@@ -14265,6 +14420,9 @@
       "windows/200111003235",
       "windows/200226213356"
     ],
+    "6b328085625318aa50d173c98d8bda09d57e27413d114cf787a0f5d06c030cf6": [
+      "windows/220719163622"
+    ],
     "6b9c08e86eb0f767cfad65cd98b62149e5494a67f5845e7bd1ed019f27b86bd6": [
       "android/android10-release",
       "android/android11-release",
@@ -14343,7 +14501,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "6baf50ae3467eff3c35fefdc76a02a97fab6267723eda91e99f1b3dc2b28f82e": [
       "windows/090825180842",
@@ -14541,7 +14700,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "6cc05041e6445e74696c4cfbc9f80f543b7eabbb44b4ce6f787c6a9971c42f17": [
       "android/android10-release",
@@ -14610,7 +14770,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "6ccfd302fc44bf4599329b9750878ea44e7e8566564bcbd586169762dd10c74e": [
       "windows/130626232015",
@@ -14802,7 +14963,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "6dea86a1e66620a040c3c5943cb215d2ca87fb6ac09b59707e29d2facbd66b4e": [
       "android/kitkat-mr1-release",
@@ -14831,6 +14993,9 @@
       "windows/150122021939",
       "windows/150220201450"
     ],
+    "6e0bff069a26994c15de2c4888cc54af84882e5495b7fbf66be9ccffec7489f6": [
+      "windows/220719163622"
+    ],
     "6e5e93ae867fd3e3e78304e054d1a6aeaed0295d58c0e3fc4c9ffe310a3488cc": [
       "windows/070109202240",
       "windows/070201011524",
@@ -15053,7 +15218,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "6f2bc4cb632c24eae6782c0f39758932d1e1dc9b3e070f9303073fff38b288e2": [
       "macos/10.9.0"
@@ -15167,7 +15333,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "6fff78e400a70c11011cd85977c459fb5af96a3df0540820d0f4b8607875e58f": [
       "macos/10.10.0",
@@ -15324,7 +15491,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "70b922bfda0e3f4a342e4ee22d579ae598d071cc5ec9c30f123680340388aea5": [
       "macos/10.10.0",
@@ -15396,7 +15564,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "71cca5391f9e794b04802530b363e121da8a3043bb26662fea4dca7fc951a4bd": [
       "android/android10-release",
@@ -15440,7 +15609,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "7286ce249fe9e32bd4752257c17cd8f6991a9c1e6f1a3cc73304ed023e6ae4eb": [
       "windows/131003230417",
@@ -15487,7 +15657,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "730b619eaa759863c65360b7412e1457eca96844ef2f16d91fcf2efe46a647e9": [
       "windows/070109202240",
@@ -15597,7 +15768,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "73c176434f1bc6d5adf45b0e76e727287c8de57616c1e6e6141a2b2cbc7d8e4c": [
       "android/android10-release",
@@ -15738,7 +15910,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "7431e5f4c3c1ce4690774f0b61e05440883ba9a01ed00ba6abd7806ed3b118cf": [
       "android/android10-release",
@@ -15879,7 +16052,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "744b1147b4a9a69c32785e9e37c3323241ef29f63e76f1603d6761a783d8a0fe": [
       "windows/150122021939",
@@ -16122,7 +16296,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "767c955a76412c89af688e90a1c70f556cfd6b6025dbea10416d7eb6831f8c40": [
       "android/kitkat-cts-release",
@@ -16263,7 +16438,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "77407312c63a153d5bc00b4e51759cdfdac237dc2a33b67946e98e9bfa680ae3": [
       "android/kitkat-cts-release",
@@ -16455,7 +16631,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "781d64dfa77b00f2c006700b1fda86bf68b865a603c7a656f92e90c042ca2873": [
       "windows/080328202117",
@@ -16831,7 +17008,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "7af6ea9f753a1e709bd64d0beb867c11e8c295a56e24a6e0471459dccdaa1558": [
       "macos/10.11.0",
@@ -16915,7 +17093,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "7afc9d01a62f03a2de9637936d4afe68090d2de18d03f29c88cfb0b1ba63587f": [
       "macos/10.10.0",
@@ -17148,7 +17327,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "7d2bf3489ebc9ad3448b8b0827715a3cbfe3d523e3b56a9b5fc1d2a2da2f20fe": [
       "windows/100503224537",
@@ -17212,7 +17392,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "7d3b465a6014e526c0affcee2127d2311727ad811c26842d006af37306cc80bd": [
       "android/kitkat-cts-release",
@@ -17446,7 +17627,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "7f12cd5f7e5e290ec7d85179d5b72c20a5be7508ffdb5bf81ab9684a7fc9f667": [
       "android/kitkat-cts-release",
@@ -17651,7 +17833,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "81c2568503eb3be5eec366653960e6d1be9448915e4605b793fbeb34ccb2470f": [
       "windows/120223022238",
@@ -17819,7 +18002,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "83ce3c1229688a593d485f81973c0f9195431eda37cc5e36430e79c7a888638b": [
       "android/kitkat-cts-release",
@@ -17908,7 +18092,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "847df6a78497943f27fc72eb93f9a637320a02b561d0a91b09e87a7807ed7c61": [
       "windows/110919210309",
@@ -18000,7 +18185,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "85666a562ee0be5ce925c1d8890a6f76a87ec16d4d7d5f29ea7419cf20123b69": [
       "android/android10-release",
@@ -18057,7 +18243,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "85a0dd7dd720adb7ff05f83d542b209dc7ff4528f7d677b18389fea5e5c49e86": [
       "android/android10-release",
@@ -18197,7 +18384,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "85e0dfae3e55a843195f8b08c8349050e4689372f6e133ad0d199af96e95cc08": [
       "windows/070109202240",
@@ -18355,7 +18543,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "86a1ecba089c4a8d3bbe2734c612ba341d813e043cf9e8a862cd5c57a36bbe6b": [
       "android/android11-release",
@@ -18380,7 +18569,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "87c678bfb8b25f38f7e97b336956bbcf144bbacaa53647e61a2325bc1055316b": [
       "android/kitkat-cts-release",
@@ -18527,7 +18717,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "885de64c340e3ea70658f01e1145f957fcda27aabeea1ab9faa9fdb0102d4077": [
       "windows/070109202240",
@@ -18708,7 +18899,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "88f438dcf8ffd1fa8f429115ffe5f82ae1e06e0c70c375faad717b34a49e7265": [
       "android/android12-release",
@@ -18722,7 +18914,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "894ce6ddb012cb3f736954668de63f436080e95f17b7a81bd924eb21bee9e440": [
       "windows/071219233937",
@@ -18796,7 +18989,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "894ebc0b23da2a50c0186b7f8f25ef1f6b2935af32a94584ef80aaf877a3a06e": [
       "macos/10.10.0",
@@ -18979,7 +19173,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "8a968aadd88b20519672a452a3d6e31eacb71c26bcaf65b32f9793bf2ffa54a9": [
       "macos/10.10.0",
@@ -18994,7 +19189,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "8b3fdb151af759c566143e07c950ede4f9e8c7cf808453d33bcb78e52a400af9": [
       "windows/130420010442",
@@ -19043,7 +19239,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "8b45da1c06f791eb0cabf26be588f5fb23165c2e614bf885562d0dce50b29b02": [
       "android/nougat-cts-release",
@@ -19092,7 +19289,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "8ba1bd9c88efb3947e60ebe21137f81df7f09994cef27f097055018b8194c634": [
       "windows/140912180251",
@@ -19411,7 +19609,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "8da084fcf99ce07722f89b3205939806fa5cb811e1c813f6a108c7d336b3408e": [
       "android/kitkat-cts-release",
@@ -19711,7 +19910,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "8f1ecdaf29bcd56eddd6b5d56a07fcac2b74d4bcd179179144a0365c27dcf14b": [
       "windows/121102212406",
@@ -19816,7 +20016,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "8f9e2751dcd574e9ba90e744ea92581fd0af640ae86ac1ce2198c90f96b44823": [
       "windows/070109202240",
@@ -19999,7 +20200,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "90f3e05396995ff20922c44592db62d7845e1bf64aef512cca75bc669caa2479": [
       "windows/070702210503",
@@ -20192,7 +20394,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "92a9d9833fe1944db366e8bfae7a95b6480c2d6c6c2a1be65d4236b608fca1bb": [
       "macos/10.10.0",
@@ -20442,7 +20645,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "940ef46536713d8e2eb4b501e80b6abd8eb4e9928dba44784ce7d7e98595dfe8": [
       "macos/10.9.0"
@@ -20467,7 +20671,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "956057517ff3bb35049342288c1c9dce852daca652b465e9747253b5f93b1f5e": [
       "windows/070109202240",
@@ -20535,7 +20740,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "959dc5880c457cd92e5447aaa5609db09ed47bd02c17a0edefdc819e756c74e5": [
       "macos/10.10.0",
@@ -20730,7 +20936,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "97552015f5ddfc3c8788c006944555408894450084f100867086bc1a2bb58dc8": [
       "android/android12-release",
@@ -20743,7 +20950,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "978cd966f2faa07ba7aa9500d9c02e9d77f2cdada6ad6ba74af4b91c66593c50": [
       "android/kitkat-cts-release",
@@ -20860,7 +21068,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "9806ab8509e2f35e192f275f0c308b9409b42512f90c659598c22be613962272": [
       "windows/070109202240",
@@ -21043,7 +21252,11 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
+    ],
+    "9a296a5182d1d451a2e37f439b74daafa267523329f90f9a0d2007c334e23c9a": [
+      "windows/220719163622"
     ],
     "9a6ec012e1a7da9dbe34194d478ad7c0db1822fb071df12981496ed104384113": [
       "android/android10-release",
@@ -21125,7 +21338,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "9a73929a500f1a0bf49dcb046e8039169696557345e9f813f10ff9380db22695": [
       "macos/10.10.0",
@@ -21296,7 +21510,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "9b14e8f5f6ea167666e76dcd6becc190861d5e8970b99a9470f0231236049704": [
       "windows/131003230417",
@@ -21347,7 +21562,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "9cefb0cb7b74e642932532831e0dc8f4d68ad414261fc3f474b795e72a164e57": [
       "windows/150618202535",
@@ -21388,7 +21604,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "9d190b2e314566685be8a889e27aa8c7d7ae1d8aaddba3c1ecf9d24863cd34b9": [
       "macos/10.10.0",
@@ -21659,7 +21876,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "a040929a02ce53b4acf4f2ffc6981ce4496f755e6d45fe0b2a692bcd52523f36": [
       "android/android10-release",
@@ -21729,7 +21947,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "a0459b9f63b22559f5fa5d4c6db3f9f72ff19342033578f073bf1d1b46cbb912": [
       "android/android10-release",
@@ -21840,7 +22059,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "a1339d33281a0b56e557d3d32b1ce7f9367eb094bd5fa72a7e5004c8ded7cafe": [
       "android/android10-release",
@@ -21895,7 +22115,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "a1a86d04121eb87f027c66f53303c28e5739f943fc84b38ad6af009035dd9457": [
       "macos/10.13.1",
@@ -22066,7 +22287,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "a22dba681e97376e2d397d728aae3a9b6296b9fdba60bc2e11f647f2c675fb37": [
       "android/kitkat-cts-release",
@@ -22191,7 +22413,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "a31f093053bd12c1f5c3c6efd498023fd2914d7758d05d698ce084b50626e0e5": [
       "macos/10.10.0",
@@ -22327,7 +22550,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "a3d7435a18c46b23b6a4f8929cd59050c9168b03a7fad532626f297cac5356e4": [
       "windows/110919210309",
@@ -22383,7 +22607,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "a4310d50af18a6447190372a86afaf8b951ffb431d837f1e5688b45971ed1557": [
       "android/android10-release",
@@ -22503,7 +22728,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "a45ede3bbbf09c8ae15c72efc07268d693a21c996fd51e67ca079460fd6d8873": [
       "android/android10-release",
@@ -22943,7 +23169,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "a798a1c70e9b6d50eaa5724a26fac7991848edc61bf48d79816bcafb66972128": [
       "windows/070109202240",
@@ -23067,7 +23294,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "aad9ceed5aa6b1cea28596a8e4e1abed9386d6ebc9d4aad9acde0fa36ba069d0": [
       "macos/10.10.0",
@@ -23149,7 +23377,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "ab7036365c7154aa29c2c29f5d4191163b162a2225011357d56d07ffa7bc1f72": [
       "macos/10.10.0",
@@ -23249,7 +23478,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "ad016f958050e0e7e46fae7dcc50197ed8e3ff0a4b262e5ddcdb3edddc7d6578": [
       "windows/100503224537",
@@ -23313,7 +23543,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "ad7539e5cdc985fa95244055a9202d63460ec921467d034cfdbe87ec6d00fedc": [
       "windows/130626232015",
@@ -23458,7 +23689,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "ae92e90000541a9ebc101b70b6c33a62f5a53a55ba815e81d31abddf03507f5d": [
       "windows/070109202240",
@@ -24078,7 +24310,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "b2259996fff735ab35014ef63f3d413190079dd03a0962432635a8695f995305": [
       "windows/100927165108",
@@ -24229,7 +24462,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "b3c962d34019fb38ab9fe9c62399742ab26c43c2d18ce3f2b13c14321e52964b": [
       "windows/070109202240",
@@ -24534,7 +24768,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "b5bd2cb79cbd1907298d6bdf4842e516d8c78fa6fc96d25f71af814e16cc245e": [
       "windows/080828200829",
@@ -24605,7 +24840,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "b6191a50d0c3977f7da99bcdaac86a227daeb9679ec70ba3b0c9d92271c170d3": [
       "android/android10-release",
@@ -24879,7 +25115,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "b7a7ec419454411761225ecf30d99585f851356077bf83274b11588fd05521b8": [
       "macos/10.9.0"
@@ -25006,7 +25243,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "b8bbe523bfca3b11d50f73f7f10b3ec8ec958aa1dc86f66d9541907ff1a110ef": [
       "windows/090203164005",
@@ -25241,7 +25479,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "bc23f98a313cb92de3bbfc3a5a9f4461ac39494c4ae15a9e9df131e99b73019a": [
       "android/kitkat-cts-release",
@@ -25317,7 +25556,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "bcdd8df4276366d7ff4b688dc81500d8e98252c049c8ff1e8c82f2baec9d5c16": [
       "windows/070109202240",
@@ -25489,7 +25729,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "bd81ce3b4f6591d11a67b5fc7a47fdef25521bf9aa4e18b9e3df2e34a7803be8": [
       "android/kitkat-cts-release",
@@ -25657,10 +25898,12 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "beb00b30839b9bc32c32e4447905950641f26421b15ed089198b518ae2ea1b99": [
-      "android/android12-release"
+      "android/android12-release",
+      "windows/220719163622"
     ],
     "bebce57dcb85f60a93bfa5019edb1a294bf6d81f82d9b4e71f502f0b15a1fc08": [
       "windows/160916174005",
@@ -25793,7 +26036,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "bf0feefb9e3a581ad5f9e9db7589985743d261085c4d314f6f5d7259aa421612": [
       "android/android10-release",
@@ -25992,7 +26236,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "bfff8fd04433487d6a8aa60c1a29767a9fc2bbb05e420f713a13b992891d3893": [
       "android/android10-release",
@@ -26056,7 +26301,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "c0a6f4dc63a24bfdcf54ef2a6a082a0a72de35803e2ff5ff527ae5d87206dfd5": [
       "android/android10-release",
@@ -26190,7 +26436,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "c0c05a8d8da55eaf27aa9b910b0a6ef0d8bbded346928db872e182c2073e9802": [
       "macos/10.10.0",
@@ -26280,6 +26527,9 @@
       "windows/150820181119",
       "windows/151119231843"
     ],
+    "c1468cf2254e6004b24696aba209d1a30ba6e2dff68a9a4e32c6ab414f90c8d9": [
+      "windows/220719163622"
+    ],
     "c1727f3b673e6ae7f12f23d789a7be38b918223ef6911c592da1f583444a547e": [
       "windows/171121202507",
       "windows/180122185731",
@@ -26305,7 +26555,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "c1b12f480020336e5b04f520bc19c2e2e10ab42c9d9235f05cbec33ffa4d4dea": [
       "windows/070109202240",
@@ -26524,7 +26775,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "c1cf0b52096435e3f1b71daaec455a2311c8404f5583a9e213c69d857d943305": [
       "android/kitkat-mr1-release",
@@ -26594,7 +26846,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "c2157309d9aee17bf34f4df5e88dbaeba57e0361eb814cbc239f4d54d329a38d": [
       "windows/140912180251",
@@ -26639,7 +26892,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "c2959db8339e8dbcf6409ca92a66c49fd2e32494940a901143bd7eb72827dec2": [
       "windows/070109202240",
@@ -26751,7 +27005,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "c34c5df53080078ffe45b21a7f600469917204f4f0293f1d7209393e5265c04f": [
       "windows/150723231635",
@@ -26791,7 +27046,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "c3846bf24b9e93ca64274c0ec67c1ecc5e024ffcacd2d74019350e81fe546ae4": [
       "android/android10-release",
@@ -26932,7 +27188,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "c38dcb38959393358691ea4d4f3ce495ce748996e64ed1891d897a0fc4dd55c6": [
       "android/kitkat-mr1-release",
@@ -27040,7 +27297,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "c470cf547e2302b977fb29dd71a89a7b6c1f60777b0329f56017f328bf4f6be6": [
       "android/kitkat-cts-release",
@@ -27249,7 +27507,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "c57bacf238f9336c3dfba62d12bcf5823603e5842c44e62f5448cc7e5f4cad59": [
       "macos/10.9.0"
@@ -27257,7 +27516,8 @@
     "c741f70f4b2a8d88bf2e71c14122ef53ef10eba0cfa5e64cfa20f418853073e0": [
       "android/android12-release",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "c766a9bef2d4071c863a31aa4920e813b2d198608cb7b7cfe21143b836df09ea": [
       "android/kitkat-cts-release",
@@ -27370,7 +27630,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "c795ff8ff20c966688f064a1e091421d3110a3456c17ec2404b998738741f622": [
       "windows/150618202535",
@@ -27411,7 +27672,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "c7ba6567de93a798ae1faa791e712d378fae1f93c4397fea441bb7cbe6fd5995": [
       "android/kitkat-cts-release",
@@ -27504,7 +27766,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "ca2d82a08677072f8ab6764ff035676cfe3e5e325e012172df3f92096db79b85": [
       "android/kitkat-cts-release",
@@ -27800,7 +28063,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "caca93b9d23d2b6fa76e8b8471931e0df3ec6f63af3cdbb936c41954a1872326": [
       "windows/180619172254",
@@ -27926,7 +28190,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "cb627d18b58ad56dde331a30456bc65c601a4e9b18dedcea08e7daaa07815ff0": [
       "macos/10.10.0",
@@ -28091,7 +28356,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "cbb5af185e942a2402f9eacbc0ed5bb876eea3c1223623d00447e4f3ba554b65": [
       "macos/10.10.0",
@@ -28124,6 +28390,9 @@
       "macos/10.9.4",
       "macos/10.9.5"
     ],
+    "cbb9c44d84b8043e1050ea31a69f514955d7bfd2e2c6b49301019ad61d9f5058": [
+      "windows/220719163622"
+    ],
     "cbd8ed38d4a2d677d453d70dd8890af4f6374cba6299943f1ab3a6936c6fd795": [
       "windows/091029013045",
       "windows/100503224537",
@@ -28333,7 +28602,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "cd201256fe5ced0bfff8df595fff36b1416d5313a999f532ef4a9915df96dee0": [
       "windows/090825180842",
@@ -28400,7 +28670,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "cd808284cf746ff2fd6eb58aa1d59c4ad4b3ca56fdc6274a8926a7835f32313d": [
       "macos/10.10.0",
@@ -28636,7 +28907,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "cf56ff46a4a186109dd96584b5eeb58a510c4275b0e5f94f40bbae865e19f673": [
       "android/kitkat-cts-release",
@@ -28724,7 +28996,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "d1c339ea2784eb870f934fc5634e4aa9ad5505016401f26465d37a574663359f": [
       "macos/10.10.0",
@@ -28808,7 +29081,11 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
+    ],
+    "d3ed3fc40ad26b52e001e1e18f4b9449529deb75a81d5eb680d7b62db23ba96d": [
+      "windows/220719163622"
     ],
     "d40e9c86cd8fe468c1776959f49ea774fa548684b6c406f3909261f4dce2575c": [
       "android/android10-release",
@@ -28863,7 +29140,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "d41d829e8c1659822af93fce62bffcde264fc84e8b950c5ff275d052354695a3": [
       "android/kitkat-cts-release",
@@ -29001,7 +29279,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "d487a56f83b07482e85e963394c1ecc2c9e51d0903ee946b02c301581ed99e16": [
       "android/nougat-cts-release",
@@ -29050,7 +29329,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "d48d3d23eedb50a459e55197601c27774b9d7b18c94d5a059511a10250b93168": [
       "android/android10-release",
@@ -29092,7 +29372,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "d68f7730b1ec2b3fb698c96d76540c9997415a25737dcd61d44960db77d2723d": [
       "macos/10.9.0"
@@ -29154,7 +29435,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "d7a7a0fb5d7e2731d771e9484ebcdef71d5f0c3e0a2948782bc83ee0ea699ef4": [
       "android/android10-release",
@@ -29295,7 +29577,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "d7ba3f4ff8ad05633451470dda3378a3491b90005e5c687d2b68d53647cfdd66": [
       "windows/170922155710",
@@ -29323,7 +29606,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "d80fef910ae3f104723b045cec2d019f441ce6213adf156791e70c1790110a31": [
       "windows/150618202535",
@@ -29363,7 +29647,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "d8e0febc1db2e38d00940f37d27d41344d993e734b99d5656d9778d4d8143624": [
       "android/kitkat-cts-release",
@@ -29489,7 +29774,11 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
+    ],
+    "d95d0e8eda79525bf9beb11b14d2100d3294985f0c62d9fabd9cd999eccb7b1d": [
+      "windows/220719163622"
     ],
     "d95fea3ca4eedce74cd76e75fc6d1ff62c441f0fa8bc77f034b19e5db258015d": [
       "android/kitkat-cts-release",
@@ -29580,7 +29869,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "da98f640194df128c7888bc8e3479a9dd31795ff087c649052fbafb02eaef184": [
       "macos/10.10.0",
@@ -29610,7 +29900,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "dd6936fe21f8f077c123a1a521c12224f72255b73e03a7260693e8a24b0fa389": [
       "android/android10-release",
@@ -29734,7 +30025,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "ddbf149733bc2bf8a09d7f012b01a6dea11d7bae26713783ef6407a2495bf189": [
       "windows/170228174808",
@@ -29765,7 +30057,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "ddff53ecd7743b60bb7b2795ff5732fa785f9a14df1120fb40a38cf84ca2a566": [
       "windows/070201011524",
@@ -29843,7 +30136,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "de1af143ffa160cf5fa86abfe577291633dc264da12c863c5738bea4afbb2cdb": [
       "windows/200421004343"
@@ -29969,7 +30263,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "e17890ee09a3fbf4f48b9c414a17d637b7a50647e9bc752322727fcc1742a911": [
       "android/kitkat-cts-release",
@@ -30123,7 +30418,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "e28097721a8cab8880af80fdef8902b1f15bc7473ad68ec22991257a910d9ea2": [
       "windows/190723222703",
@@ -30131,7 +30427,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "e28393773da845a679f2080cc7fb44a3b7a1c3792cb7eb7729fdcb6a8d99aea7": [
       "android/kitkat-cts-release",
@@ -30219,7 +30516,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "e3268f6106ba8b665a1a962ddea1459d2a46972f1f2440329b390b895749ad45": [
       "macos/10.10.3",
@@ -30316,7 +30614,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "e389360d0fdbaeb3d250584b4730314e222f39c156a020144e8d960561791506": [
       "android/kitkat-cts-release",
@@ -30517,7 +30816,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "e3efb6118a92e3b858fd806f690e31d46b95ca1bd756da2b3037fe2f87cc9137": [
       "macos/10.9.0",
@@ -30525,6 +30825,9 @@
       "macos/10.9.4",
       "macos/10.9.5"
     ],
+    "e46a392204a8dca342a71c1ca9a60c9185b9a930370120c3b9c7e3856f0d8f3b": [
+      "windows/220719163622"
+    ],
     "e4c73430d7a5b50925df43370a0d216e9a79b9d6db8373a0c69eb1cc31c7c52a": [
       "android/kitkat-cts-release",
       "android/kitkat-mr1-release",
@@ -30874,6 +31177,9 @@
       "windows/150723231635",
       "windows/150820181119"
     ],
+    "e6be68ce06fe0da0c140f1aeb00b67b636c5eea9422088929362375ce086db39": [
+      "windows/220719163622"
+    ],
     "e6e4a951ecbf7d8edc01bc873f7b6fd35868bdb10ed786f3a1b1ee16d8cec3e9": [
       "windows/070702210503",
       "windows/070821012656",
@@ -30948,7 +31254,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "e74fbda55bd564c473a36b441aa799c8a68e077440e8288b9fa1e50e4bbaca11": [
       "windows/170228174808",
@@ -30979,7 +31286,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "e75e72ed9f560eec6eb4800073a43fc3ad19195a392282017895974a99026b6c": [
       "android/android10-release",
@@ -31120,7 +31428,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "e7685634efacf69ace939a6b255b7b4fabef42935b50a265acb5cb6027e44e70": [
       "macos/10.10.0",
@@ -31204,7 +31513,11 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
+    ],
+    "e778f0f095fe843729cd1a0082179e5314a9c291442805e1fb1d8fb6b8886c3a": [
+      "windows/220719163622"
     ],
     "e793c9b02fd8aa13e21c31228accb08119643b749c898964b1746d46c3d4cbd2": [
       "android/android10-release",
@@ -31312,7 +31625,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "e873d4082a7b4632934f48a5cc1ee500932f661e56c3467c5c84d31447476b0c": [
       "windows/070109202240",
@@ -31632,7 +31946,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "eac0220c5c9fecc5121d3720872d06707b5266be25d4ebb56ab804bbbf85fe03": [
       "macos/10.10.0",
@@ -31856,7 +32171,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "eb7e05aa58e7bd328a282bf8867033f3c035342b516ee85c01673dffffbbfe58": [
       "windows/090203164005",
@@ -31925,7 +32241,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "ebc5570c29018c4d67b1aa127baf12f703b4611ebc17b7dab5573894179b93fa": [
       "android/android10-release",
@@ -31982,7 +32299,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "ebd41040e4bb3ec742c9e381d31ef2a41a48b6685c96e7cef3c1df6cd4331c99": [
       "android/android10-release",
@@ -32117,7 +32435,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "ebf3c02a8789b1fb7d511995d663b72906d913ce0d5e10568a8a77e2586167e7": [
       "android/kitkat-cts-release",
@@ -32408,7 +32727,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "eec5496b988ce98625b934092eec2908bed0b0f316c2d4730c84eaf1f3d34881": [
       "android/android10-release",
@@ -32522,7 +32842,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "eefca888db442cea1f03fac5de5b1af210ae03f5e1658ddb880c645e78624546": [
       "windows/091013033632",
@@ -32675,7 +32996,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "efb5157e9c66caa1dcc63c9fac0127cde83b7a426c4579b7b43a41ba46a56deb": [
       "windows/111018233154",
@@ -32914,7 +33236,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "f015ce3cc239bfef064be9f1d2c417e1a0264a0a94be1f0c8d121864eb6949cc": [
       "windows/190723222703",
@@ -32922,7 +33245,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "f09b122c7114f4a09bd4ea4f4a99d558b46e4c25cd81140d29c05613914c3841": [
       "android/kitkat-cts-release",
@@ -33019,7 +33343,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "f1b13f5c9a326403b0f31bbe7699cd17c7d1c0b981586dd1a7b219c52508fe99": [
       "windows/070702210503",
@@ -33095,7 +33420,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "f1c1b50ae5a20dd8030ec9f6bc24823dd367b5255759b4e71b61fce9f7375d73": [
       "android/android10-release",
@@ -33236,7 +33562,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "f1f3cc207a6d47947b8cb9c30422229de0d71fb867e0b9a3eda08e0e1736bc28": [
       "windows/070109202240",
@@ -33317,7 +33644,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "f356bea244b7a91eb35d53ca9ad7864ace018e2d35d5f8f96ddf68a6f41aa474": [
       "android/android10-release",
@@ -33422,7 +33750,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "f375e2f77a108bacc4234894a9af308edeca1acd8fbde0e7aaa9634e9daf7e1c": [
       "windows/091029013045",
@@ -33584,7 +33913,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "f4c149551a3013a35bc7bffe17a7f3449bc1ab5b5a0ae74b06c23b90004c0104": [
       "android/kitkat-cts-release",
@@ -33825,7 +34155,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "f9e67d336c51002ac054c632022d66dda2e7e3fff10ad061ed31d8bbb410cfb2": [
       "android/android10-release",
@@ -33966,7 +34297,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "fabcf5197cdd7f458ac33832d3284021db2425fd6bea7a2e69b7486e8f51f9cc": [
       "macos/10.10.0",
@@ -34041,7 +34373,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "fad540811afae0dc767cdf6572a088fa3ce8493dd82b3b869a67d10aab4e8124": [
       "windows/170419224008",
@@ -34071,7 +34404,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "fb47d92a9909fd4fa9bec02737543e1f3514ced747407a8d9cfa397b0915067c": [
       "windows/120223022238",
@@ -34124,7 +34458,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "fc0a0fe27c9dc13c81238a5913a1daf8184168beb7e5a4512a771fd4f453651d": [
       "windows/070109202240",
@@ -34189,7 +34524,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "fcbfe2886206f72b27593c8b070297e12d769ed10ed7930705a8098effc14d17": [
       "android/kitkat-cts-release",
@@ -34297,7 +34633,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "fd73dad31c644ff1b43bef0ccdda96710b9cd9875eca7e31707af3e96d522bbd": [
       "android/android10-release",
@@ -34414,7 +34751,8 @@
       "windows/191029183108",
       "windows/200111003235",
       "windows/200226213356",
-      "windows/200421004343"
+      "windows/200421004343",
+      "windows/220719163622"
     ],
     "fe7114d07a147759891ff37b4f53eb43568296bc3bf89bc12cafb186985ef28d": [
       "windows/071219233937",
@@ -34490,6 +34828,9 @@
       "windows/200226213356",
       "windows/200421004343"
     ],
+    "fe7696573855773e37a95e7ad4d9cc96c30157c15d31765ba9b15704e1ae78fd": [
+      "windows/220719163622"
+    ],
     "fe863d0822fe7a2353fa484d5924e875656d3dc9fb58771f6f616f9d571bc592": [
       "macos/10.10.0",
       "macos/10.10.3",
@@ -34711,7 +35052,7 @@
       "windows/151119231843"
     ]
   },
-  "last_spki_id": 521,
+  "last_spki_id": 542,
   "spkis": {
     "004124ad6037fd5f3319e7a23d4d9c811f5598d66c4754155b0aaa9e8f00621f": {
       "fingerprints": [
@@ -35784,6 +36125,12 @@
       "id": 278,
       "legacy": true
     },
+    "48a8a7ecd03a83b26aec7574d09d6453e95f90360634ce204bcbd473997d4c05": {
+      "fingerprints": [
+        "5546a52504fba74f61ffd4890067529ade3b9c9d07e502592831ccda9b369fd3"
+      ],
+      "id": 532
+    },
     "4905466623ab4178be92ac5cbd6584f7a1e17f27652d5a85af89504ea239aaaa": {
       "fingerprints": [
         "37d51006c512eaab626421f1ec8c92013fc5f82ae98ee533eb4619b8deb4d06c"
@@ -36017,6 +36364,12 @@
       "id": 440,
       "legacy": true
     },
+    "581cc15821169694c39c2991b53e93ab945a42b076661774c2ecf38a3323acea": {
+      "fingerprints": [
+        "4b009c1034494f9ab56bba3ba1d62731fc4d20d8955adcec10a925607261e338"
+      ],
+      "id": 540
+    },
     "5899d913ead119b9cdb7ba2f30efe0df68ad2cd225bdf493e8323a25aa4dbe23": {
       "fingerprints": [
         "d7ba3f4ff8ad05633451470dda3378a3491b90005e5c687d2b68d53647cfdd66"
@@ -36219,6 +36572,12 @@
       "id": 126,
       "legacy": true
     },
+    "681dc482c296c8402c6ebb20e68309a3bc846523ae34b984a84ee697a3312db7": {
+      "fingerprints": [
+        "fe7696573855773e37a95e7ad4d9cc96c30157c15d31765ba9b15704e1ae78fd"
+      ],
+      "id": 536
+    },
     "682747f8ba621b87cdd3bc295ed5cabce722a1c0c0363d1d68b38928d2787f1e": {
       "fingerprints": [
         "2cabeafe37d06ca22aba7391c0033d25982952c453647349763a3ab5ad6ccf69"
@@ -36254,6 +36613,12 @@
       "id": 499,
       "legacy": true
     },
+    "693c9aa6b245b3b0261637750863eadb6c248a16e52d6f4bc90c86bbf32d7042": {
+      "fingerprints": [
+        "d95d0e8eda79525bf9beb11b14d2100d3294985f0c62d9fabd9cd999eccb7b1d"
+      ],
+      "id": 522
+    },
     "6a436b58d9d830e8d5b8a642505ad6b41406adcd6894d9414f7be0a1467badb7": {
       "fingerprints": [
         "05d38c2a70bfc500ccb0cb509159b46b065c6ac9cb42d2e6f16167841434572a"
@@ -36268,6 +36633,12 @@
       "id": 421,
       "legacy": true
     },
+    "6a97b51c8219e93e5dec64bad5806cdeb0f8355be47e757010b702456e01aafd": {
+      "fingerprints": [
+        "371a00dc0533b3721a7eeb40e8419e70799d2b0a0f2c1d80693165f7cec4ad75"
+      ],
+      "id": 531
+    },
     "6b1a505e0246f2f60c490ff0c097a7be27210cbb7500237f88b0cd48298bc9b8": {
       "fingerprints": [
         "2a99f5bc1174b73cbb1d620884e01c34e51ccb3978da125f0e33268883bf4158"
@@ -36388,6 +36759,12 @@
       "id": 446,
       "legacy": true
     },
+    "762195c225586ee6c0237456e2107dc54f1efc21f61a792ebd515913cce68332": {
+      "fingerprints": [
+        "69729b8e15a86efc177a57afb7171dfc64add28c2fca8cf1507e34453ccb1470"
+      ],
+      "id": 535
+    },
     "76ee8590374c715437bbca6bba6028eadde2dc6dbbb8c3f610e851f11d1ab7f5": {
       "fingerprints": [
         "43df5774b03e7fef5fe40d931a7bedf1bb2e6b42738c4e6d3841103d3aa7f339"
@@ -36904,6 +37281,12 @@
       "id": 259,
       "legacy": true
     },
+    "96352d0ad875c027db82d599baa8d42e5c472649981eceed3bfc65f4c81fd5c1": {
+      "fingerprints": [
+        "6e0bff069a26994c15de2c4888cc54af84882e5495b7fbf66be9ccffec7489f6"
+      ],
+      "id": 526
+    },
     "96475b35acb1c9303a90bd1dbf57418f78e29af11c4de8c8cba2e5f9309e38d4": {
       "fingerprints": [
         "b04d708f1ae0456265dd1b66907a2691a28680b853e031df3df9083af71614d7"
@@ -37070,6 +37453,12 @@
       "id": 407,
       "legacy": true
     },
+    "a02fafa192c8cb81cb1341554f9c05b71cca2a890b0d1298d683647c961efbdf": {
+      "fingerprints": [
+        "018e13f0772532cf809bd1b17281867283fc48c6e13be9c69812854a490c1b05"
+      ],
+      "id": 523
+    },
     "a12574f4eb7395cc630a15fec8db1c7c828f66699d984c8c897eca44c808f55d": {
       "fingerprints": [
         "c499f6cecc5da4d61f14ed0405270c5249d0e79615b0da42659ed2d7ffef8a40"
@@ -37118,6 +37507,12 @@
       "id": 106,
       "legacy": true
     },
+    "a495c8d110e8b9e200f370aeda3ff92ee43f8e3d4ec0db1c0dc58bd762880ba5": {
+      "fingerprints": [
+        "e46a392204a8dca342a71c1ca9a60c9185b9a930370120c3b9c7e3856f0d8f3b"
+      ],
+      "id": 529
+    },
     "a4b89bb70656ea498f2d9e00a497fdb9dcd20b81b8938e952bba2df9f65729c3": {
       "fingerprints": [
         "5a1b5d6bc65523b40a6deffa45b48e4288ae8dd86dd70a5b858d4a5affc94f71"
@@ -37318,6 +37713,12 @@
       "id": 281,
       "legacy": true
     },
+    "ae7f962cb9e6a7dbf7b833fb18fa9b71a89175df949c232b6a9ef7cb3df2bbfc": {
+      "fingerprints": [
+        "4fa3126d8d3a11d1c4855a4f807cbad6cf919d3a5a88b03bea2c6372d93c40c9"
+      ],
+      "id": 525
+    },
     "af110f6b5ae8b767eac6e0aa273f3816e7a40a644edacb4398146356e77509d6": {
       "fingerprints": [
         "46273285615d96e52da9fc2ed8c036f10af3d9f6280f8d288706c52b2011b4da"
@@ -37374,6 +37775,12 @@
       "id": 72,
       "legacy": true
     },
+    "b15ac9561204756124b9c4d3fe406d93833ff66652f67fbf139f5bbf030a0e64": {
+      "fingerprints": [
+        "07cd9aa9064a9b94c6aef8fb784c1bbc1beda08acbe86878d781a39167626cf8"
+      ],
+      "id": 528
+    },
     "b16cb1ba529a39e2dfd53b3ff5a79f1904614d83e31304f0278bb40b38cf7824": {
       "fingerprints": [
         "0771920c8cb874d5c5a4dc0d6a51a2d495d38c4de2cd5b83d2a06faa051935f6"
@@ -37498,6 +37905,12 @@
       ],
       "id": 178
     },
+    "bb0ce7040314a143dcd10e65ccaeef7010e1b784d15d195d77b5601956bf9e3f": {
+      "fingerprints": [
+        "d3ed3fc40ad26b52e001e1e18f4b9449529deb75a81d5eb680d7b62db23ba96d"
+      ],
+      "id": 541
+    },
     "bb4128ec9620f2d2a49ce8e2c4e257aebad93a0f11c56b5fa4b00e23759fa39d": {
       "fingerprints": [
         "bf0feefb9e3a581ad5f9e9db7589985743d261085c4d314f6f5d7259aa421612"
@@ -37529,6 +37942,12 @@
       ],
       "id": 71
     },
+    "bdaccbf2e8b27c0c02a689ee866c9b86ec04442afcdddd5d4ec36def21e761dd": {
+      "fingerprints": [
+        "c1468cf2254e6004b24696aba209d1a30ba6e2dff68a9a4e32c6ab414f90c8d9"
+      ],
+      "id": 539
+    },
     "be3280c6863c770a33c9040bd97d5540b216d1d91db8b088ceac1197dae1d660": {
       "fingerprints": [
         "5ab4fcdb180b5b6af0d262a2375a2c77d25602015d96648756611e2e78c53ad3"
@@ -37584,6 +38003,12 @@
       ],
       "id": 124
     },
+    "c2b3c31a4a29850aa8f3cf472a1169ff71b416579f6a4482ec7744b83df988ac": {
+      "fingerprints": [
+        "242b69742fcb1e5b2abf98898b94572187544e5b4d9911786573621f6a74b82c"
+      ],
+      "id": 533
+    },
     "c372f6d18ebee5aa23d9e919f3e6be98488ec01607df3162fc192e4b1346afb3": {
       "fingerprints": [
         "ac7f7862e685c7a7d9826a58ea32d183d4893fcc8f8fd6d900c9769a987e77f0"
@@ -37841,6 +38266,12 @@
       "id": 172,
       "legacy": true
     },
+    "d6ec6348a7c4d42ac48d9c43145a8cd71971362363267c6673a77b8a8573a66b": {
+      "fingerprints": [
+        "e6be68ce06fe0da0c140f1aeb00b67b636c5eea9422088929362375ce086db39"
+      ],
+      "id": 530
+    },
     "d8fb33e385c9c2da729a84706ba927dcbb79273e122ffd9673363b70b7f36cbb": {
       "fingerprints": [
         "8c4edfd04348f322969e7e29a4cd4dca004655061c16e1b076422ef342ad630e"
@@ -37910,6 +38341,12 @@
       "id": 236,
       "legacy": true
     },
+    "de7b6932e9c44582ce0de07abdab7eea90c75d6d2a07331df57bd5cb88553d13": {
+      "fingerprints": [
+        "6b328085625318aa50d173c98d8bda09d57e27413d114cf787a0f5d06c030cf6"
+      ],
+      "id": 542
+    },
     "df530bac9fcd914c252c2fbdceddc6183d4ae8c680ad65f03e204861dd7b1c73": {
       "fingerprints": [
         "885de64c340e3ea70658f01e1145f957fcda27aabeea1ab9faa9fdb0102d4077"
@@ -37917,6 +38354,12 @@
       "id": 313,
       "legacy": true
     },
+    "e04a022ce32f4ccf2c7f6046287b828a32a909f5e751447f83fd2c71f6fd8173": {
+      "fingerprints": [
+        "cbb9c44d84b8043e1050ea31a69f514955d7bfd2e2c6b49301019ad61d9f5058"
+      ],
+      "id": 524
+    },
     "e0c780c629903e126f1d919570dce7c496f85f33aae66b9a3147ee75f8d1620a": {
       "fingerprints": [
         "416b1f9e84e74c1d19b23d8d7191c6ad81246e641601f599132729f507beb3cc"
@@ -37931,6 +38374,12 @@
       "id": 369,
       "legacy": true
     },
+    "e14e51891f3492243eea613bc2c814d47224b224c57d38169e958e30b3dedee4": {
+      "fingerprints": [
+        "3f034bb5704d44b2d08545a02057de93ebf3905fce721acbc730c06ddaee904e"
+      ],
+      "id": 527
+    },
     "e156445fa20c32ad00937b27d096b8963bcc863950333a877e68fa69707a03af": {
       "fingerprints": [
         "54b4fc43d44aa4ca9fc03ca7e9949fbae267a064d02da21852412a381b5d1537"
@@ -38070,6 +38519,12 @@
       "id": 129,
       "legacy": true
     },
+    "f0011f92fcf9be36c7a5b36e7bc862ab20e94ef36fea8a561db0a8d7750c1f51": {
+      "fingerprints": [
+        "e778f0f095fe843729cd1a0082179e5314a9c291442805e1fb1d8fb6b8886c3a"
+      ],
+      "id": 537
+    },
     "f1c6ba670cfc88e4df52973cae420f0a089dd474144fe5806c420064e1591229": {
       "fingerprints": [
         "7d05ebb682339f8c9451ee094eebfefa7953a114edb2f44949452fab7d2fc185"
@@ -38208,6 +38663,12 @@
       "id": 158,
       "legacy": true
     },
+    "fc784300ec8df4d3d1bad763835182918d52a9ff0238bdf695a1cd9bdb98321c": {
+      "fingerprints": [
+        "3f99cc474acfce4dfed58794665e478d1547739f2e780f1bb4ca9b133097d401"
+      ],
+      "id": 534
+    },
     "fcf7da983603e88862030d96137d8e13031badfb4d56c1fd4cacc339f6bdbb2a": {
       "fingerprints": [
         "7d3b465a6014e526c0affcee2127d2311727ad811c26842d006af37306cc80bd"
@@ -38241,6 +38702,12 @@
       ],
       "id": 110
     },
+    "fee8af929175687f4638a3fc983db8ecd0e5e2a83e737f3fb77b4c22fcbac0a6": {
+      "fingerprints": [
+        "9a296a5182d1d451a2e37f439b74daafa267523329f90f9a0d2007c334e23c9a"
+      ],
+      "id": 538
+    },
     "ff342fb6c4c8bd30a4706f73489539f19e6e48cc05f46254654f6610dbc540e9": {
       "fingerprints": [
         "eec5496b988ce98625b934092eec2908bed0b0f316c2d4730c84eaf1f3d34881"
@@ -38255,4 +38722,4 @@
       "legacy": true
     }
   }
-}
+}
\ No newline at end of file
diff --git a/remoting/android/remoting_apk_tmpl.gni b/remoting/android/remoting_apk_tmpl.gni
index 112c265e..f38cd2c 100644
--- a/remoting/android/remoting_apk_tmpl.gni
+++ b/remoting/android/remoting_apk_tmpl.gni
@@ -19,11 +19,7 @@
       if (!defined(proguard_configs)) {
         proguard_configs = []
       }
-      proguard_configs += [
-        "//remoting/android/proguard.flags",
-        "//base/android/proguard/chromium_apk.flags",
-        "//base/android/proguard/chromium_code.flags",
-      ]
+      proguard_configs += [ "//remoting/android/proguard.flags" ]
     }
 
     android_manifest = "$root_gen_dir/remoting/android/AndroidManifest.xml"
diff --git a/services/network/public/mojom/socket_broker.mojom b/services/network/public/mojom/socket_broker.mojom
index 14fafb6..d3ac344 100644
--- a/services/network/public/mojom/socket_broker.mojom
+++ b/services/network/public/mojom/socket_broker.mojom
@@ -5,6 +5,7 @@
 module network.mojom;
 
 import "services/network/public/mojom/address_family.mojom";
+import "services/network/public/mojom/transferable_socket.mojom";
 
 // Interface to broker socket creation in the browser.
 // Used on Windows and Android as a sandboxed network service
@@ -13,5 +14,5 @@
   // Creates an unconnected TCP socket. Returns the
   // SocketDescriptor and the net::Error.
   CreateTcpSocket(AddressFamily address_family)
-      => (handle<platform>? created_socket, int32 rv);
+      => (TransferableSocket created_socket, int32 rv);
 };
diff --git a/services/network/tcp_client_socket_brokered.cc b/services/network/tcp_client_socket_brokered.cc
index 9458fd5..eae8283 100644
--- a/services/network/tcp_client_socket_brokered.cc
+++ b/services/network/tcp_client_socket_brokered.cc
@@ -12,6 +12,7 @@
 #include "net/socket/tcp_client_socket.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/brokered_client_socket_factory.h"
+#include "services/network/public/cpp/transferable_socket.h"
 
 namespace network {
 
@@ -104,7 +105,7 @@
 
 void TCPClientSocketBrokered ::DidCompleteCreate(
     net::CompletionOnceCallback callback,
-    mojo::PlatformHandle fd,
+    network::TransferableSocket socket,
     int result) {
   if (result != net::OK) {
     std::move(callback).Run(result);
@@ -119,7 +120,7 @@
 #if BUILDFLAG(IS_WIN)
   tcp_socket->Open(addresses_.begin()->GetFamily());
 #else
-  tcp_socket->AdoptUnconnectedSocket(fd.ReleaseFD());
+  tcp_socket->AdoptUnconnectedSocket(socket.TakeSocket());
 #endif
 
   // TODO(liza): Pass through the NetworkHandle.
diff --git a/services/network/tcp_client_socket_brokered.h b/services/network/tcp_client_socket_brokered.h
index 958ce30..b90d7ea 100644
--- a/services/network/tcp_client_socket_brokered.h
+++ b/services/network/tcp_client_socket_brokered.h
@@ -29,6 +29,7 @@
 namespace network {
 
 class BrokeredClientSocketFactory;
+class TransferableSocket;
 
 // A client socket used exclusively with a socket broker. Currently intended for
 // Windows and Android only. Not intended to be used by non-brokered
@@ -104,7 +105,7 @@
   void DidCompleteConnect(net::CompletionOnceCallback callback, int result);
 
   void DidCompleteCreate(net::CompletionOnceCallback callback,
-                         mojo::PlatformHandle fd,
+                         network::TransferableSocket socket,
                          int result);
 
   // The list of addresses we should try in order to establish a connection.
diff --git a/services/network/test/test_socket_broker_impl.cc b/services/network/test/test_socket_broker_impl.cc
index 3e159e8..7cb46c3 100644
--- a/services/network/test/test_socket_broker_impl.cc
+++ b/services/network/test/test_socket_broker_impl.cc
@@ -12,6 +12,7 @@
 #include "net/log/net_log_source.h"
 #include "net/socket/socket_descriptor.h"
 #include "net/socket/tcp_socket.h"
+#include "services/network/public/cpp/transferable_socket.h"
 
 #if !BUILDFLAG(IS_WIN)
 #include <netinet/in.h>
@@ -29,13 +30,14 @@
 void TestSocketBrokerImpl::CreateTcpSocket(net::AddressFamily address_family,
                                            CreateTcpSocketCallback callback) {
   if (is_mock_socket_test_) {
-    std::move(callback).Run(mojo::PlatformHandle(), net::ERR_CONNECTION_FAILED);
+    std::move(callback).Run(network::TransferableSocket(),
+                            net::ERR_CONNECTION_FAILED);
     return;
   }
 
 // TODO(https://crbug.com/1311014): Open and release raw socket on Windows.
 #if BUILDFLAG(IS_WIN)
-  std::move(callback).Run(mojo::PlatformHandle(), net::OK);
+  std::move(callback).Run(network::TransferableSocket(), net::OK);
 #else
   base::ScopedFD socket(net::CreatePlatformSocket(
       net::ConvertAddressFamily(address_family), SOCK_STREAM,
@@ -47,7 +49,9 @@
     rv = net::MapSystemError(errno);
     socket.reset();
   }
-  std::move(callback).Run(mojo::PlatformHandle(std::move(socket)), rv);
+  std::move(callback).Run(
+      network::TransferableSocket(base::kNullProcessHandle, socket.release()),
+      rv);
 #endif
 }
 
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 10d40fe..45b60d6a 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -5800,21 +5800,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5272.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "dimension_sets": [
@@ -5827,7 +5827,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "isolate_profile_data": true,
@@ -5965,21 +5965,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5272.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "dimension_sets": [
@@ -5991,7 +5991,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "args": [
@@ -6111,21 +6111,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5272.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "dimension_sets": [
@@ -6137,7 +6137,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "isolate_profile_data": true,
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index b666eea2..bfeafce 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -99395,21 +99395,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5272.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -99417,7 +99417,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "isolate_profile_data": true,
@@ -99530,28 +99530,28 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5272.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "args": [
@@ -99651,28 +99651,28 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5272.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "isolate_profile_data": true,
@@ -101004,20 +101004,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5272.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "dimension_sets": [
@@ -101031,7 +101031,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "merge": {
@@ -101169,20 +101169,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5272.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "dimension_sets": [
@@ -101195,7 +101195,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "args": [
@@ -101315,20 +101315,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5272.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "dimension_sets": [
@@ -101341,7 +101341,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "merge": {
@@ -102848,20 +102848,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5272.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "dimension_sets": [
@@ -102875,7 +102875,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "merge": {
@@ -103013,20 +103013,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5272.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "dimension_sets": [
@@ -103039,7 +103039,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "args": [
@@ -103159,20 +103159,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5272.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "dimension_sets": [
@@ -103185,7 +103185,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "merge": {
@@ -103970,20 +103970,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5272.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "dimension_sets": [
@@ -103996,7 +103996,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       }
     ]
   },
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 6c92725..c166932 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -20863,21 +20863,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5272.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "dimension_sets": [
@@ -20890,7 +20890,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "isolate_profile_data": true,
@@ -21028,21 +21028,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5272.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "dimension_sets": [
@@ -21054,7 +21054,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "args": [
@@ -21174,21 +21174,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5272.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 107.0.5273.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v107.0.5272.0",
-              "revision": "version:107.0.5272.0"
+              "location": "lacros_version_skew_tests_v107.0.5273.0",
+              "revision": "version:107.0.5273.0"
             }
           ],
           "dimension_sets": [
@@ -21200,7 +21200,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 107.0.5272.0"
+        "variant_id": "Lacros version skew testing ash 107.0.5273.0"
       },
       {
         "isolate_profile_data": true,
diff --git a/testing/buildbot/tryserver.blink.json b/testing/buildbot/tryserver.blink.json
index 4393e969..7d7e5fd4 100644
--- a/testing/buildbot/tryserver.blink.json
+++ b/testing/buildbot/tryserver.blink.json
@@ -99,6 +99,84 @@
       }
     ]
   },
+  "mac11.0.arm64-blink-rel": {
+    "isolated_scripts": [
+      {
+        "args": [
+          "--num-retries=3",
+          "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json",
+          "--git-revision=${got_revision}"
+        ],
+        "check_flakiness_for_new_tests": false,
+        "isolate_name": "blink_web_tests",
+        "merge": {
+          "args": [
+            "--verbose"
+          ],
+          "script": "//third_party/blink/tools/merge_web_test_results.py"
+        },
+        "name": "blink_web_tests",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true
+        },
+        "results_handler": "layout tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "os": "Mac-11"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 5
+        },
+        "test_id_prefix": "ninja://:blink_web_tests/"
+      },
+      {
+        "args": [
+          "--num-retries=3",
+          "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json",
+          "--git-revision=${got_revision}"
+        ],
+        "check_flakiness_for_new_tests": false,
+        "isolate_name": "blink_wpt_tests",
+        "merge": {
+          "args": [
+            "--verbose"
+          ],
+          "script": "//third_party/blink/tools/merge_web_test_results.py"
+        },
+        "name": "blink_wpt_tests",
+        "precommit_args": [
+          "--gerrit-issue=${patch_issue}",
+          "--gerrit-patchset=${patch_set}",
+          "--buildbucket-id=${buildbucket_build_id}"
+        ],
+        "resultdb": {
+          "enable": true
+        },
+        "results_handler": "layout tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "os": "Mac-11"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 7
+        },
+        "test_id_prefix": "ninja://:blink_wpt_tests/"
+      }
+    ]
+  },
   "mac12.0-blink-rel": {
     "isolated_scripts": [
       {
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index c482868..b0e3f38 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -22,15 +22,15 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5272.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v107.0.5273.0/test_ash_chrome',
     ],
-    'identifier': 'Lacros version skew testing ash 107.0.5272.0',
+    'identifier': 'Lacros version skew testing ash 107.0.5273.0',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v107.0.5272.0',
-          'revision': 'version:107.0.5272.0',
+          'location': 'lacros_version_skew_tests_v107.0.5273.0',
+          'revision': 'version:107.0.5273.0',
         },
       ],
     },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index c927bd7..cf1d296a 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -6721,6 +6721,14 @@
           'isolated_scripts': 'chromium_web_tests_and_wpt_webdriver_isolated_scripts',
         },
       },
+      'mac11.0.arm64-blink-rel': {
+        'mixins': [
+          'mac_11_arm64',
+        ],
+        'test_suites': {
+          'isolated_scripts': 'chromium_webkit_isolated_scripts',
+        },
+      },
       'mac12.0-blink-rel': {
         'mixins': [
           'mac_12_x64',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 016cae65..a114eaa 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1889,7 +1889,6 @@
                         "allowed_websites": "",
                         "cache_size": "6",
                         "check_eligibility_after_pagehide": "true",
-                        "enable_same_site": "true",
                         "file_system_api_supported": "true",
                         "foreground_cache_size": "2",
                         "grace_period_to_finish_loading_in_seconds": "60",
@@ -1923,7 +1922,6 @@
                         "cache_size": "6",
                         "check_eligibility_after_pagehide": "true",
                         "content_injection_supported": "true",
-                        "enable_same_site": "true",
                         "extension_message_supported": "true",
                         "file_system_api_supported": "true",
                         "foreground_cache_size": "2",
diff --git a/third_party/blink/common/storage_key/storage_key.cc b/third_party/blink/common/storage_key/storage_key.cc
index ac389881..10248ad 100644
--- a/third_party/blink/common/storage_key/storage_key.cc
+++ b/third_party/blink/common/storage_key/storage_key.cc
@@ -439,6 +439,12 @@
   return false;
 }
 
+const absl::optional<net::CookiePartitionKey> StorageKey::ToCookiePartitionKey()
+    const {
+  return net::CookiePartitionKey::FromStorageKeyComponents(top_level_site_,
+                                                           nonce_);
+}
+
 bool operator==(const StorageKey& lhs, const StorageKey& rhs) {
   return std::tie(lhs.origin_, lhs.top_level_site_, lhs.nonce_,
                   lhs.ancestor_chain_bit_) ==
diff --git a/third_party/blink/common/storage_key/storage_key_unittest.cc b/third_party/blink/common/storage_key/storage_key_unittest.cc
index 2f66e63..f8336b4 100644
--- a/third_party/blink/common/storage_key/storage_key_unittest.cc
+++ b/third_party/blink/common/storage_key/storage_key_unittest.cc
@@ -697,4 +697,86 @@
   }
 }
 
+TEST(StorageKeyTest, ToCookiePartitionKey) {
+  struct TestCase {
+    const StorageKey storage_key;
+    const absl::optional<net::CookiePartitionKey> expected;
+  };
+
+  auto nonce = base::UnguessableToken::Create();
+
+  {  // Cookie partitioning disabled.
+    base::test::ScopedFeatureList scope_feature_list;
+    scope_feature_list.InitWithFeatures(
+        {net::features::kThirdPartyStoragePartitioning},
+        {net::features::kPartitionedCookies,
+         net::features::kNoncedPartitionedCookies});
+
+    TestCase test_cases[] = {
+        {StorageKey(url::Origin::Create(GURL("https://www.example.com"))),
+         absl::nullopt},
+        {StorageKey::CreateForTesting(
+             url::Origin::Create(GURL("https://www.foo.com")),
+             url::Origin::Create(GURL("https://www.bar.com"))),
+         absl::nullopt},
+        {StorageKey::CreateWithNonce(
+             url::Origin::Create(GURL("https://www.example.com")), nonce),
+         absl::nullopt},
+    };
+    for (const auto& test_case : test_cases) {
+      EXPECT_EQ(test_case.expected,
+                test_case.storage_key.ToCookiePartitionKey());
+    }
+  }
+
+  {
+    // Nonced partitioned cookies enabled only.
+    base::test::ScopedFeatureList scope_feature_list;
+    scope_feature_list.InitWithFeatures(
+        {net::features::kThirdPartyStoragePartitioning,
+         net::features::kNoncedPartitionedCookies},
+        {net::features::kPartitionedCookies});
+
+    TestCase test_cases[] = {
+        {StorageKey(url::Origin::Create(GURL("https://www.example.com"))),
+         absl::nullopt},
+        {StorageKey::CreateWithNonce(
+             url::Origin::Create(GURL("https://www.example.com")), nonce),
+         net::CookiePartitionKey::FromURLForTesting(GURL("https://example.com"),
+                                                    nonce)},
+    };
+    for (const auto& test_case : test_cases) {
+      EXPECT_EQ(test_case.expected,
+                test_case.storage_key.ToCookiePartitionKey());
+    }
+  }
+
+  {  // Cookie partitioning enabled.
+    base::test::ScopedFeatureList scope_feature_list;
+    scope_feature_list.InitWithFeatures(
+        {net::features::kThirdPartyStoragePartitioning,
+         net::features::kPartitionedCookies},
+        {});
+
+    TestCase test_cases[] = {
+        {StorageKey(url::Origin::Create(GURL("https://www.example.com"))),
+         net::CookiePartitionKey::FromURLForTesting(
+             GURL("https://www.example.com"))},
+        {StorageKey::CreateForTesting(
+             url::Origin::Create(GURL("https://www.foo.com")),
+             url::Origin::Create(GURL("https://www.bar.com"))),
+         net::CookiePartitionKey::FromURLForTesting(
+             GURL("https://subdomain.bar.com"))},
+        {StorageKey::CreateWithNonce(
+             url::Origin::Create(GURL("https://www.example.com")), nonce),
+         net::CookiePartitionKey::FromURLForTesting(
+             GURL("https://www.example.com"), nonce)},
+    };
+    for (const auto& test_case : test_cases) {
+      EXPECT_EQ(test_case.expected,
+                test_case.storage_key.ToCookiePartitionKey());
+    }
+  }
+}
+
 }  // namespace blink
diff --git a/third_party/blink/public/common/storage_key/storage_key.h b/third_party/blink/public/common/storage_key/storage_key.h
index c7d79d5..376578c 100644
--- a/third_party/blink/public/common/storage_key/storage_key.h
+++ b/third_party/blink/public/common/storage_key/storage_key.h
@@ -12,6 +12,7 @@
 #include "base/unguessable_token.h"
 #include "net/base/isolation_info.h"
 #include "net/base/schemeful_site.h"
+#include "net/cookies/cookie_partition_key.h"
 #include "net/cookies/site_for_cookies.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/common_export.h"
@@ -178,6 +179,10 @@
     return storage_key;
   }
 
+  // Cast a storage key to a cookie partition key. If cookie partitioning is not
+  // enabled, then it will always return nullopt.
+  const absl::optional<net::CookiePartitionKey> ToCookiePartitionKey() const;
+
  private:
   // This enum represents the different type of encodable partitioning
   // attributes.
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni
index 93f64af..0a26a2ce 100644
--- a/third_party/blink/renderer/bindings/generated_in_core.gni
+++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -709,8 +709,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_scale.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_scope_rule.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_scope_rule.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_scroll_timeline_rule.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_scroll_timeline_rule.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_skew.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_skew.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_skew_x.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_core.gni b/third_party/blink/renderer/bindings/idl_in_core.gni
index eee0541..7f162b10 100644
--- a/third_party/blink/renderer/bindings/idl_in_core.gni
+++ b/third_party/blink/renderer/bindings/idl_in_core.gni
@@ -57,7 +57,6 @@
           "//third_party/blink/renderer/core/css/css_rule.idl",
           "//third_party/blink/renderer/core/css/css_rule_list.idl",
           "//third_party/blink/renderer/core/css/css_scope_rule.idl",
-          "//third_party/blink/renderer/core/css/css_scroll_timeline_rule.idl",
           "//third_party/blink/renderer/core/css/css_style_declaration.idl",
           "//third_party/blink/renderer/core/css/css_style_rule.idl",
           "//third_party/blink/renderer/core/css/css_style_sheet.idl",
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 ddda0b3..1a4fd8e5 100644
--- a/third_party/blink/renderer/core/animation/css/css_animations.cc
+++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -452,20 +452,6 @@
   return &element_animations->CssAnimations().PendingUpdate();
 }
 
-// The source element must be a previous inclusive sibling of one of
-// subject's inclusive ancestors.
-bool IsPreviousSiblingAncestor(Node* source, Node* subject) {
-  DCHECK(subject);
-
-  for (Node* prev = subject; prev; prev = prev->previousSibling()) {
-    if (source == prev)
-      return true;
-  }
-
-  Node* parent = subject->ParentOrShadowHostNode();
-  return parent && IsPreviousSiblingAncestor(source, parent);
-}
-
 }  // namespace
 
 const CSSAnimations::TimelineData* CSSAnimations::GetTimelineData(
@@ -573,24 +559,8 @@
     return nullptr;
   }
   if (style_timeline.IsName()) {
-    // First, look for timelines created by 'scroll-timeline' properties.
-    if (CSSScrollTimeline* timeline = FindPreviousSiblingAncestorTimeline(
-            style_timeline.GetName().GetValue(), element, &update)) {
-      return timeline;
-    }
-    // Otherwise, look for timelines created by @scroll-timeline.
-    // TODO(crbug.com/1317765): Remove support for @scroll-timeline.
-    CSSScrollTimeline* timeline = document.GetStyleEngine().FindScrollTimeline(
-        style_timeline.GetName().GetValue());
-    if (!timeline)
-      return nullptr;
-    // This currently enforces the lookup rules from the new scroll timeline API
-    // on @scroll-timelines. This makes transitioning to the new API easier.
-    if (timeline->source() &&
-        !IsPreviousSiblingAncestor(timeline->source(), element)) {
-      return nullptr;
-    }
-    return timeline;
+    return FindPreviousSiblingAncestorTimeline(
+        style_timeline.GetName().GetValue(), element, &update);
   }
   DCHECK(style_timeline.IsScroll());
   return ComputeScrollFunctionTimeline(element, style_timeline.GetScroll());
diff --git a/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc b/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc
index b8b90bd..89a6f087 100644
--- a/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc
+++ b/third_party/blink/renderer/core/animation/css/css_scroll_timeline.cc
@@ -4,13 +4,6 @@
 
 #include "third_party/blink/renderer/core/animation/css/css_scroll_timeline.h"
 
-#include "third_party/blink/renderer/core/animation/document_animations.h"
-#include "third_party/blink/renderer/core/css/css_function_value.h"
-#include "third_party/blink/renderer/core/css/css_id_selector_value.h"
-#include "third_party/blink/renderer/core/css/css_identifier_value.h"
-#include "third_party/blink/renderer/core/css/css_value_list.h"
-#include "third_party/blink/renderer/core/css/style_engine.h"
-#include "third_party/blink/renderer/core/css/style_rule.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 
@@ -18,61 +11,6 @@
 
 namespace {
 
-bool IsIdentifier(const CSSValue* value, CSSValueID value_id) {
-  if (const auto* ident = DynamicTo<CSSIdentifierValue>(value))
-    return ident->GetValueID() == value_id;
-  return false;
-}
-
-bool IsAuto(const CSSValue* value) {
-  return IsIdentifier(value, CSSValueID::kAuto);
-}
-
-bool IsNone(const CSSValue* value) {
-  return IsIdentifier(value, CSSValueID::kNone);
-}
-
-const cssvalue::CSSIdSelectorValue* GetIdSelectorValue(const CSSValue* value) {
-  if (const auto* selector = DynamicTo<CSSFunctionValue>(value)) {
-    if (selector->FunctionType() != CSSValueID::kSelector)
-      return nullptr;
-    DCHECK_EQ(selector->length(), 1u);
-    return DynamicTo<cssvalue::CSSIdSelectorValue>(selector->Item(0));
-  }
-  return nullptr;
-}
-
-absl::optional<Element*> ComputeScrollSource(Document& document,
-                                             const CSSValue* value) {
-  if (const auto* id = GetIdSelectorValue(value))
-    return document.getElementById(id->Id());
-  if (IsNone(value))
-    return nullptr;
-  DCHECK(!value || IsAuto(value));
-  // TODO(crbug.com/1189101): Respond when the scrolling element changes.
-  return absl::nullopt;
-}
-
-ScrollTimeline::ScrollDirection ComputeScrollDirection(const CSSValue* value) {
-  CSSValueID value_id = CSSValueID::kAuto;
-
-  if (const auto* identifier = DynamicTo<CSSIdentifierValue>(value))
-    value_id = identifier->GetValueID();
-
-  switch (value_id) {
-    case CSSValueID::kInline:
-      return ScrollTimeline::ScrollDirection::kInline;
-    case CSSValueID::kHorizontal:
-      return ScrollTimeline::ScrollDirection::kHorizontal;
-    case CSSValueID::kVertical:
-      return ScrollTimeline::ScrollDirection::kVertical;
-    case CSSValueID::kAuto:
-    case CSSValueID::kBlock:
-    default:
-      return ScrollTimeline::ScrollDirection::kBlock;
-  }
-}
-
 ScrollTimeline::ScrollDirection ComputeScrollDirection(TimelineAxis axis) {
   using ScrollDirection = ScrollTimeline::ScrollDirection;
 
@@ -91,54 +29,8 @@
   return ScrollDirection::kBlock;
 }
 
-class ElementReferenceObserver : public IdTargetObserver {
- public:
-  ElementReferenceObserver(Document* document,
-                           const AtomicString& id,
-                           CSSScrollTimeline* timeline)
-      : IdTargetObserver(document->GetIdTargetObserverRegistry(), id),
-        document_(document),
-        timeline_(timeline) {}
-
-  void Trace(Visitor* visitor) const override {
-    visitor->Trace(timeline_);
-    visitor->Trace(document_);
-    IdTargetObserver::Trace(visitor);
-  }
-
- private:
-  void IdTargetChanged() override {
-    if (timeline_)
-      document_->GetStyleEngine().ScrollTimelineInvalidated(*timeline_);
-  }
-  Member<Document> document_;
-  WeakMember<CSSScrollTimeline> timeline_;
-};
-
-HeapVector<Member<IdTargetObserver>> CreateElementReferenceObservers(
-    Document* document,
-    StyleRuleScrollTimeline* rule,
-    CSSScrollTimeline* timeline) {
-  HeapVector<Member<IdTargetObserver>> observers;
-
-  if (const auto* id = GetIdSelectorValue(rule->GetSource())) {
-    observers.push_back(MakeGarbageCollected<ElementReferenceObserver>(
-        document, id->Id(), timeline));
-  }
-
-  return observers;
-}
-
 }  // anonymous namespace
 
-CSSScrollTimeline::Options::Options(Document& document,
-                                    StyleRuleScrollTimeline& rule)
-    : reference_type_(ScrollTimeline::ReferenceType::kSource),
-      reference_element_(ComputeScrollSource(document, rule.GetSource())),
-      direction_(ComputeScrollDirection(rule.GetOrientation())),
-      name_(rule.GetName()),
-      rule_(&rule) {}
-
 CSSScrollTimeline::Options::Options(
     Document& document,
     ScrollTimeline::ReferenceType reference_type,
@@ -148,8 +40,7 @@
     : reference_type_(reference_type),
       reference_element_(reference_element),
       direction_(ComputeScrollDirection(axis)),
-      name_(name),
-      rule_(nullptr) {}
+      name_(name) {}
 
 CSSScrollTimeline::CSSScrollTimeline(Document* document, Options&& options)
     : ScrollTimeline(document,
@@ -157,45 +48,14 @@
                      options.reference_element_.value_or(
                          document->ScrollingElementNoLayout()),
                      options.direction_),
-      name_(options.name_),
-      rule_(options.rule_) {
+      name_(options.name_) {
   SnapshotState();
 }
 
 bool CSSScrollTimeline::Matches(const Options& options) const {
   return (GetReferenceType() == options.reference_type_) &&
          (ReferenceElement() == options.reference_element_) &&
-         (GetOrientation() == options.direction_) && (name_ == options.name_) &&
-         (rule_ == options.rule_);
-}
-
-void CSSScrollTimeline::AnimationAttached(Animation* animation) {
-  if (rule_) {
-    if (!HasAnimations())
-      SetObservers(CreateElementReferenceObservers(GetDocument(), rule_, this));
-  }
-  ScrollTimeline::AnimationAttached(animation);
-}
-
-void CSSScrollTimeline::AnimationDetached(Animation* animation) {
-  ScrollTimeline::AnimationDetached(animation);
-  if (rule_) {
-    if (!HasAnimations())
-      SetObservers(HeapVector<Member<IdTargetObserver>>());
-  }
-}
-
-void CSSScrollTimeline::Trace(Visitor* visitor) const {
-  visitor->Trace(rule_);
-  visitor->Trace(observers_);
-  ScrollTimeline::Trace(visitor);
-}
-
-void CSSScrollTimeline::SetObservers(
-    HeapVector<Member<IdTargetObserver>> observers) {
-  for (IdTargetObserver* observer : observers_)
-    observer->Unregister();
-  observers_ = std::move(observers);
+         (GetOrientation() == options.direction_) && (name_ == options.name_);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h b/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h
index 3644700..649926c 100644
--- a/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h
+++ b/third_party/blink/renderer/core/animation/css/css_scroll_timeline.h
@@ -8,25 +8,21 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/renderer/core/animation/scroll_timeline.h"
 #include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/dom/id_target_observer.h"
+#include "third_party/blink/renderer/core/style/computed_style_constants.h"
 
 namespace blink {
 
 class Document;
 class Element;
-class StyleRuleScrollTimeline;
 
 // A CSSScrollTimeline is like a ScrollTimeline, except it originates from
-// an @scroll-timeline rule.
+// the scroll-timeline-* properties.
 class CORE_EXPORT CSSScrollTimeline : public ScrollTimeline {
  public:
   struct Options {
     STACK_ALLOCATED();
 
    public:
-    // TODO(crbug.com/1317765): Remove this constructor.
-    Options(Document&, StyleRuleScrollTimeline&);
-
     Options(Document&,
             ScrollTimeline::ReferenceType reference_type,
             absl::optional<Element*> reference_element,
@@ -40,34 +36,19 @@
     absl::optional<Element*> reference_element_;
     ScrollTimeline::ScrollDirection direction_;
     AtomicString name_;
-    StyleRuleScrollTimeline* rule_;
   };
 
   CSSScrollTimeline(Document*, Options&&);
 
   const AtomicString& Name() const { return name_; }
 
-  StyleRuleScrollTimeline* GetRule() const { return rule_; }
-
   bool Matches(const Options&) const;
 
   // AnimationTimeline implementation.
   bool IsCSSScrollTimeline() const override { return true; }
-  void AnimationAttached(Animation*) override;
-  void AnimationDetached(Animation*) override;
-
-  // If a CSSScrollTimeline matching |options| already exists, return that
-  // timeline. Otherwise returns nullptr.
-  static CSSScrollTimeline* FindMatchingTimeline(const Options&);
-
-  void Trace(Visitor*) const override;
 
  private:
-  void SetObservers(HeapVector<Member<IdTargetObserver>>);
-
   AtomicString name_;
-  Member<StyleRuleScrollTimeline> rule_;
-  HeapVector<Member<IdTargetObserver>> observers_;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/animation/css/css_scroll_timeline_test.cc b/third_party/blink/renderer/core/animation/css/css_scroll_timeline_test.cc
index 3f941c78c..57d2884 100644
--- a/third_party/blink/renderer/core/animation/css/css_scroll_timeline_test.cc
+++ b/third_party/blink/renderer/core/animation/css/css_scroll_timeline_test.cc
@@ -27,160 +27,37 @@
  public:
   CSSScrollTimelineTest() : ScopedCSSScrollTimelineForTest(true) {}
 
-  bool HasObservers(const AtomicString& id) {
-    return GetDocument().GetIdTargetObserverRegistry().HasObservers(id);
-  }
-
   DocumentAnimations& GetDocumentAnimations() const {
     return GetDocument().GetDocumentAnimations();
   }
-
-  void SimulateFrame() {
-    auto new_time = GetAnimationClock().CurrentTime() + base::Milliseconds(100);
-    GetPage().Animator().ServiceScriptedAnimations(new_time);
-  }
 };
 
-TEST_F(CSSScrollTimelineTest, IdObserverElementRemoval) {
-  ASSERT_FALSE(HasObservers("scroller"));
-
-  SetBodyInnerHTML(R"HTML(
-    <style>
-      @keyframes anim {
-        from { width: 100px; }
-        to { width: 200px; }
-      }
-      @scroll-timeline timeline {
-        source: selector(#scroller);
-      }
-      div {
-        animation: anim 10s;
-        animation-timeline: timeline;
-      }
-    </style>
-    <div id=element1></div>
-    <div id=element2></div>
-  )HTML");
-
-  EXPECT_TRUE(HasObservers("scroller"));
-
-  Element* element1 = GetDocument().getElementById("element1");
-  Element* element2 = GetDocument().getElementById("element2");
-  ASSERT_TRUE(element1);
-  ASSERT_TRUE(element2);
-
-  element1->remove();
-  SimulateFrame();
-  UpdateAllLifecyclePhasesForTest();
-  ThreadState::Current()->CollectAllGarbageForTesting();
-  EXPECT_TRUE(HasObservers("scroller"));
-
-  element2->remove();
-  SimulateFrame();
-  UpdateAllLifecyclePhasesForTest();
-  ThreadState::Current()->CollectAllGarbageForTesting();
-  EXPECT_FALSE(HasObservers("scroller"));
-}
-
-TEST_F(CSSScrollTimelineTest, IdObserverRuleInsertion) {
-  ASSERT_FALSE(HasObservers("scroller1"));
-  ASSERT_FALSE(HasObservers("scroller2"));
-  ASSERT_FALSE(HasObservers("scroller3"));
-  ASSERT_FALSE(HasObservers("redefined"));
-
-  SetBodyInnerHTML(R"HTML(
-    <style>
-      @keyframes anim {
-        from { width: 100px; }
-        to { width: 200px; }
-      }
-      @scroll-timeline timeline1 {
-        source: selector(#scroller1);
-      }
-      @scroll-timeline timeline2 {
-        source: selector(#scroller2);
-      }
-      div {
-        animation: anim 10s;
-      }
-      #element1 {
-        animation-timeline: timeline1;
-      }
-      #element2 {
-        animation-timeline: timeline2;
-      }
-    </style>
-    <div id=element1></div>
-    <div id=element2></div>
-    <div id=element3></div>
-  )HTML");
-
-  EXPECT_TRUE(HasObservers("scroller1"));
-  EXPECT_TRUE(HasObservers("scroller2"));
-
-  Element* element1 = GetDocument().getElementById("element1");
-  Element* element2 = GetDocument().getElementById("element2");
-  ASSERT_TRUE(element1);
-  ASSERT_TRUE(element2);
-
-  // Insert a <style> element which redefines timeline2, and also
-  // creates an additional timeline (timeline3).
-  auto* style_element = MakeGarbageCollected<HTMLStyleElement>(
-      GetDocument(), CreateElementFlags());
-  style_element->setTextContent(R"CSS(
-      @scroll-timeline timeline2 {
-        source: selector(#redefined);
-      }
-      @scroll-timeline timeline3 {
-        source: selector(#scroller3);
-      }
-      #element3 {
-        animation-timeline: timeline3;
-      }
-  )CSS");
-  GetDocument().body()->AppendChild(style_element);
-  UpdateAllLifecyclePhasesForTest();
-  ThreadState::Current()->CollectAllGarbageForTesting();
-  EXPECT_TRUE(HasObservers("scroller1"));
-  EXPECT_FALSE(HasObservers("scroller2"));
-  EXPECT_TRUE(HasObservers("scroller3"));
-  EXPECT_TRUE(HasObservers("redefined"));
-
-  // Remove the <style> element again.
-  style_element->remove();
-  UpdateAllLifecyclePhasesForTest();
-  ThreadState::Current()->CollectAllGarbageForTesting();
-  EXPECT_TRUE(HasObservers("scroller1"));
-  EXPECT_TRUE(HasObservers("scroller2"));
-  EXPECT_FALSE(HasObservers("scroller3"));
-  EXPECT_FALSE(HasObservers("redefined"));
-}
-
 TEST_F(CSSScrollTimelineTest, SharedTimelines) {
   SetBodyInnerHTML(R"HTML(
     <style>
       @keyframes anim1 { to { top: 200px; } }
       @keyframes anim2 { to { left: 200px; } }
       @keyframes anim3 { to { right: 200px; } }
-      @scroll-timeline timeline1 {
-        source: selector(#scroller);
-      }
-      @scroll-timeline timeline2 {
-        source: selector(#scroller);
-      }
-      #scroller {
+      .scroller {
         height: 100px;
         overflow: scroll;
       }
-      #scroller > div {
+      .scroller > div {
         height: 200px;
       }
+      #scroller1 {
+        scroll-timeline: timeline1;
+      }
+      #scroller2 {
+        scroll-timeline: timeline2;
+      }
     </style>
-    <div id=scroller><div></div></div>
+    <div id=scroller1 class=scroller><div></div></div>
+    <div id=scroller2 class=scroller><div></div></div>
     <main id=main></main>
   )HTML");
-  // #scroller etc is created in a separate lifecycle phase to ensure that
-  // we get a layout box for #scroller before the animations are started.
+  // #scroller[1,2] etc is created in a separate lifecycle phase to ensure that
+  // we get a layout box for #scroller[1,2] before the animations are started.
 
   Element* main = GetDocument().getElementById("main");
   ASSERT_TRUE(main);
@@ -227,14 +104,10 @@
         from { color: green; }
         to { color: green; }
       }
-      @scroll-timeline timeline {
-        source: selector(#scroller);
-        start: auto;
-        end: auto;
-      }
       #scroller {
         height: 100px;
         overflow: scroll;
+        scroll-timeline: timeline;
       }
       #scroller > div {
         height: 200px;
@@ -274,25 +147,22 @@
 
 class AnimationTriggeringDelegate : public ResizeObserver::Delegate {
  public:
-  explicit AnimationTriggeringDelegate(Element* style_element)
-      : style_element_(style_element) {}
+  explicit AnimationTriggeringDelegate(Element* scroller_element)
+      : scroller_element_(scroller_element) {}
 
   void OnResize(
       const HeapVector<Member<ResizeObserverEntry>>& entries) override {
-    style_element_->setTextContent(R"CSS(
-      @scroll-timeline timeline {
-        source: selector(#scroller);
-      }
-    )CSS");
+    scroller_element_->SetInlineStyleProperty(CSSPropertyID::kScrollTimeline,
+                                              "timeline");
   }
 
   void Trace(Visitor* visitor) const override {
     ResizeObserver::Delegate::Trace(visitor);
-    visitor->Trace(style_element_);
+    visitor->Trace(scroller_element_);
   }
 
  private:
-  Member<Element> style_element_;
+  Member<Element> scroller_element_;
 };
 
 }  // namespace
@@ -329,16 +199,12 @@
   scroller->setAttribute(blink::html_names::kIdAttr, "scroller");
   scroller->AppendChild(MakeGarbageCollected<HTMLDivElement>(GetDocument()));
 
-  Element* style = MakeGarbageCollected<HTMLStyleElement>(GetDocument(),
-                                                          CreateElementFlags());
-
   Element* main = GetDocument().getElementById("main");
   ASSERT_TRUE(main);
-  main->AppendChild(style);
   main->AppendChild(scroller);
   main->AppendChild(element);
 
-  auto* delegate = MakeGarbageCollected<AnimationTriggeringDelegate>(style);
+  auto* delegate = MakeGarbageCollected<AnimationTriggeringDelegate>(scroller);
   ResizeObserver* observer =
       ResizeObserver::Create(GetDocument().domWindow(), delegate);
   observer->observe(element);
@@ -357,11 +223,8 @@
       from { z-index: 100; }
       to { z-index: 100; }
     }
-    @scroll-timeline timeline {
-      source: auto;
-    }
     #element {
-      animation: anim 10s timeline forwards;
+      animation: anim 10s forwards scroll(root);
     }
     </style>
     <div id=element></div>
diff --git a/third_party/blink/renderer/core/css/build.gni b/third_party/blink/renderer/core/css/build.gni
index 63ad61f..61f25ca 100644
--- a/third_party/blink/renderer/core/css/build.gni
+++ b/third_party/blink/renderer/core/css/build.gni
@@ -95,8 +95,6 @@
   "css_cyclic_variable_value.h",
   "css_default_style_sheets.cc",
   "css_default_style_sheets.h",
-  "css_element_offset_value.cc",
-  "css_element_offset_value.h",
   "css_font_face.cc",
   "css_font_face.h",
   "css_font_face_rule.cc",
@@ -133,8 +131,6 @@
   "css_grid_template_areas_value.h",
   "css_grouping_rule.cc",
   "css_grouping_rule.h",
-  "css_id_selector_value.cc",
-  "css_id_selector_value.h",
   "css_identifier_value.cc",
   "css_identifier_value.h",
   "css_image_generator_value.cc",
@@ -233,8 +229,6 @@
   "css_rule_list.h",
   "css_scope_rule.cc",
   "css_scope_rule.h",
-  "css_scroll_timeline_rule.cc",
-  "css_scroll_timeline_rule.h",
   "css_scroll_value.cc",
   "css_scroll_value.h",
   "css_segmented_font_face.cc",
@@ -700,11 +694,9 @@
   "counter_style_map_test.cc",
   "counter_style_test.cc",
   "css_computed_style_declaration_test.cc",
-  "css_element_offset_value_test.cc",
   "css_font_face_source_test.cc",
   "css_font_family_webkit_prefix_test.cc",
   "css_gradient_value_test.cc",
-  "css_id_selector_value_test.cc",
   "css_image_value_test.cc",
   "css_invalid_variable_value_test.cc",
   "css_light_dark_value_pair_test.cc",
diff --git a/third_party/blink/renderer/core/css/css_element_offset_value.cc b/third_party/blink/renderer/core/css/css_element_offset_value.cc
deleted file mode 100644
index 2cfcd28..0000000
--- a/third_party/blink/renderer/core/css/css_element_offset_value.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// 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/css/css_element_offset_value.h"
-#include "base/memory/values_equivalent.h"
-#include "third_party/blink/renderer/core/css/css_function_value.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-namespace cssvalue {
-
-CSSElementOffsetValue::CSSElementOffsetValue(const CSSValue* target,
-                                             const CSSValue* edge,
-                                             const CSSValue* threshold)
-    : CSSValue(kElementOffsetClass),
-      target_(target),
-      edge_(edge),
-      threshold_(threshold) {
-  DCHECK(target && target->IsFunctionValue() &&
-         To<CSSFunctionValue>(*target).FunctionType() == CSSValueID::kSelector);
-  DCHECK(!edge || edge->IsIdentifierValue());
-  DCHECK(!threshold || threshold->IsNumericLiteralValue());
-}
-
-String CSSElementOffsetValue::CustomCSSText() const {
-  StringBuilder result;
-  result.Append(target_->CssText());
-  if (edge_) {
-    result.Append(' ');
-    result.Append(edge_->CssText());
-  }
-  if (threshold_) {
-    result.Append(' ');
-    result.Append(threshold_->CssText());
-  }
-  return result.ReleaseString();
-}
-
-bool CSSElementOffsetValue::Equals(const CSSElementOffsetValue& other) const {
-  return base::ValuesEquivalent(target_, other.target_) &&
-         base::ValuesEquivalent(edge_, other.edge_) &&
-         base::ValuesEquivalent(threshold_, other.threshold_);
-}
-
-void CSSElementOffsetValue::TraceAfterDispatch(blink::Visitor* visitor) const {
-  CSSValue::TraceAfterDispatch(visitor);
-  visitor->Trace(target_);
-  visitor->Trace(edge_);
-  visitor->Trace(threshold_);
-}
-
-}  // namespace cssvalue
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_element_offset_value.h b/third_party/blink/renderer/core/css/css_element_offset_value.h
deleted file mode 100644
index f8720ca..0000000
--- a/third_party/blink/renderer/core/css/css_element_offset_value.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// 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_CSS_CSS_ELEMENT_OFFSET_VALUE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_ELEMENT_OFFSET_VALUE_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/css/css_value.h"
-#include "third_party/blink/renderer/platform/wtf/casting.h"
-
-namespace blink {
-namespace cssvalue {
-
-// https://drafts.csswg.org/scroll-animations-1/#typedef-element-offset
-class CORE_EXPORT CSSElementOffsetValue : public CSSValue {
- public:
-  CSSElementOffsetValue(const CSSValue* target,
-                        const CSSValue* edge,
-                        const CSSValue* threshold);
-
-  const CSSValue* Target() const { return target_; }
-  const CSSValue* Edge() const { return edge_; }
-  const CSSValue* Threshold() const { return threshold_; }
-
-  String CustomCSSText() const;
-  bool Equals(const CSSElementOffsetValue&) const;
-  void TraceAfterDispatch(blink::Visitor*) const;
-
- private:
-  Member<const CSSValue> target_;
-  Member<const CSSValue> edge_;
-  Member<const CSSValue> threshold_;
-};
-
-}  // namespace cssvalue
-
-template <>
-struct DowncastTraits<cssvalue::CSSElementOffsetValue> {
-  static bool AllowFrom(const CSSValue& value) {
-    return value.IsElementOffsetValue();
-  }
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_ELEMENT_OFFSET_VALUE_H_
diff --git a/third_party/blink/renderer/core/css/css_element_offset_value_test.cc b/third_party/blink/renderer/core/css/css_element_offset_value_test.cc
deleted file mode 100644
index e86e38b..0000000
--- a/third_party/blink/renderer/core/css/css_element_offset_value_test.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// 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/css/css_element_offset_value.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
-#include "third_party/blink/renderer/core/css/css_function_value.h"
-#include "third_party/blink/renderer/core/css/css_id_selector_value.h"
-#include "third_party/blink/renderer/core/css/css_identifier_value.h"
-#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-using CSSElementOffsetValue = cssvalue::CSSElementOffsetValue;
-using CSSIdSelectorValue = cssvalue::CSSIdSelectorValue;
-
-namespace {
-
-CSSValue* MakeSelectorFunction(String id) {
-  auto* function =
-      MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kSelector);
-  function->Append(*MakeGarbageCollected<CSSIdSelectorValue>(id));
-  return function;
-}
-
-CSSValue* MakeEdge(CSSValueID edge) {
-  return CSSIdentifierValue::Create(edge);
-}
-
-CSSValue* MakeThreshold(double threshold) {
-  return CSSNumericLiteralValue::Create(threshold,
-                                        CSSPrimitiveValue::UnitType::kNumber);
-}
-
-CSSElementOffsetValue* MakeOffset(String id,
-                                  absl::optional<CSSValueID> edge,
-                                  absl::optional<double> threshold) {
-  return MakeGarbageCollected<CSSElementOffsetValue>(
-      MakeSelectorFunction(id), edge ? MakeEdge(*edge) : nullptr,
-      threshold ? MakeThreshold(*threshold) : nullptr);
-}
-
-}  // namespace
-
-TEST(CSSElementOffsetValueTest, Accessors) {
-  auto* offset = MakeOffset("foo", CSSValueID::kEnd, 2.0);
-  ASSERT_TRUE(offset);
-  ASSERT_TRUE(offset->Target());
-  ASSERT_TRUE(offset->Edge());
-  ASSERT_TRUE(offset->Threshold());
-
-  EXPECT_EQ("selector(#foo)", offset->Target()->CssText());
-  EXPECT_EQ("end", offset->Edge()->CssText());
-  EXPECT_EQ("2", offset->Threshold()->CssText());
-}
-
-TEST(CSSElementOffsetValueTest, Equals) {
-  EXPECT_EQ(*MakeOffset("foo", CSSValueID::kEnd, 2.0),
-            *MakeOffset("foo", CSSValueID::kEnd, 2.0));
-  EXPECT_EQ(*MakeOffset("foo", absl::nullopt, absl::nullopt),
-            *MakeOffset("foo", absl::nullopt, absl::nullopt));
-  EXPECT_NE(*MakeOffset("foo", CSSValueID::kEnd, 2.0),
-            *MakeOffset("bar", CSSValueID::kEnd, 2.0));
-  EXPECT_NE(*MakeOffset("foo", CSSValueID::kEnd, 2.0),
-            *MakeOffset("foo", CSSValueID::kStart, 2.0));
-  EXPECT_NE(*MakeOffset("foo", CSSValueID::kEnd, 2.0),
-            *MakeOffset("foo", CSSValueID::kEnd, 1.0));
-}
-
-TEST(CSSElementOffsetValueTest, CustomCSSText) {
-  EXPECT_EQ("selector(#foo) end 2",
-            MakeOffset("foo", CSSValueID::kEnd, 2.0)->CustomCSSText());
-  EXPECT_EQ(
-      "selector(#foo) end",
-      MakeOffset("foo", CSSValueID::kEnd, absl::nullopt)->CustomCSSText());
-  EXPECT_EQ("selector(#foo) 2",
-            MakeOffset("foo", absl::nullopt, 2.0)->CustomCSSText());
-  EXPECT_EQ("selector(#foo)",
-            MakeOffset("foo", absl::nullopt, absl::nullopt)->CustomCSSText());
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_id_selector_value.cc b/third_party/blink/renderer/core/css/css_id_selector_value.cc
deleted file mode 100644
index a9dcd2e..0000000
--- a/third_party/blink/renderer/core/css/css_id_selector_value.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// 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/css/css_id_selector_value.h"
-
-#include "third_party/blink/renderer/core/css/css_markup.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-namespace cssvalue {
-
-CSSIdSelectorValue::CSSIdSelectorValue(const String& id)
-    : CSSValue(kIdSelectorClass), id_(id) {}
-
-String CSSIdSelectorValue::CustomCSSText() const {
-  StringBuilder builder;
-  builder.Append('#');
-  SerializeIdentifier(id_, builder);
-  return builder.ReleaseString();
-}
-
-void CSSIdSelectorValue::TraceAfterDispatch(blink::Visitor* visitor) const {
-  CSSValue::TraceAfterDispatch(visitor);
-}
-
-}  // namespace cssvalue
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_id_selector_value.h b/third_party/blink/renderer/core/css/css_id_selector_value.h
deleted file mode 100644
index 9ca65ac..0000000
--- a/third_party/blink/renderer/core/css/css_id_selector_value.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// 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_CSS_CSS_ID_SELECTOR_VALUE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_ID_SELECTOR_VALUE_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/css/css_value.h"
-#include "third_party/blink/renderer/platform/wtf/casting.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-namespace cssvalue {
-
-class CORE_EXPORT CSSIdSelectorValue : public CSSValue {
- public:
-  explicit CSSIdSelectorValue(const String&);
-
-  const AtomicString& Id() const { return id_; }
-
-  String CustomCSSText() const;
-
-  bool Equals(const CSSIdSelectorValue& other) const {
-    return id_ == other.id_;
-  }
-
-  void TraceAfterDispatch(blink::Visitor*) const;
-
- private:
-  AtomicString id_;
-};
-
-}  // namespace cssvalue
-
-template <>
-struct DowncastTraits<cssvalue::CSSIdSelectorValue> {
-  static bool AllowFrom(const CSSValue& value) {
-    return value.IsIdSelectorValue();
-  }
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_ID_SELECTOR_VALUE_H_
diff --git a/third_party/blink/renderer/core/css/css_id_selector_value_test.cc b/third_party/blink/renderer/core/css/css_id_selector_value_test.cc
deleted file mode 100644
index c4e23d8d..0000000
--- a/third_party/blink/renderer/core/css/css_id_selector_value_test.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// 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/css/css_id_selector_value.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-using CSSIdSelectorValue = cssvalue::CSSIdSelectorValue;
-
-TEST(CSSIdSelectorValueTest, Id) {
-  EXPECT_EQ("test", MakeGarbageCollected<CSSIdSelectorValue>("test")->Id());
-}
-
-TEST(CSSIdSelectorValueTest, Equals) {
-  EXPECT_EQ(*MakeGarbageCollected<CSSIdSelectorValue>("foo"),
-            *MakeGarbageCollected<CSSIdSelectorValue>("foo"));
-  EXPECT_NE(*MakeGarbageCollected<CSSIdSelectorValue>("foo"),
-            *MakeGarbageCollected<CSSIdSelectorValue>("bar"));
-  EXPECT_NE(*MakeGarbageCollected<CSSIdSelectorValue>("bar"),
-            *MakeGarbageCollected<CSSIdSelectorValue>("foo"));
-}
-
-TEST(CSSIdSelectorValueTest, CustomCSSText) {
-  EXPECT_EQ("#foo",
-            MakeGarbageCollected<CSSIdSelectorValue>("foo")->CustomCSSText());
-  // The identifier part must follow the serialization rules of:
-  // https://drafts.csswg.org/cssom/#serialize-an-identifier
-  EXPECT_EQ("#\\31 23",
-            MakeGarbageCollected<CSSIdSelectorValue>("123")->CustomCSSText());
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_rule.h b/third_party/blink/renderer/core/css/css_rule.h
index ce34b69..9a8de61 100644
--- a/third_party/blink/renderer/core/css/css_rule.h
+++ b/third_party/blink/renderer/core/css/css_rule.h
@@ -67,14 +67,13 @@
 
     // Values for internal use, not web-exposed:
     kPropertyRule = 16,
-    kScrollTimelineRule = 17,
-    kContainerRule = 18,
-    kLayerBlockRule = 19,
-    kLayerStatementRule = 20,
-    kFontPaletteValuesRule = 21,
-    kScopeRule = 22,
-    kPositionFallbackRule = 23,
-    kTryRule = 24,
+    kContainerRule = 17,
+    kLayerBlockRule = 18,
+    kLayerStatementRule = 19,
+    kFontPaletteValuesRule = 20,
+    kScopeRule = 21,
+    kPositionFallbackRule = 22,
+    kTryRule = 23,
   };
 
   virtual Type GetType() const = 0;
diff --git a/third_party/blink/renderer/core/css/css_scroll_timeline_rule.cc b/third_party/blink/renderer/core/css/css_scroll_timeline_rule.cc
deleted file mode 100644
index 347fc16..0000000
--- a/third_party/blink/renderer/core/css/css_scroll_timeline_rule.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// 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/css/css_scroll_timeline_rule.h"
-
-#include "third_party/blink/renderer/core/css/css_markup.h"
-#include "third_party/blink/renderer/core/css/style_rule.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
-
-namespace blink {
-
-CSSScrollTimelineRule::CSSScrollTimelineRule(
-    StyleRuleScrollTimeline* scroll_timeline_rule,
-    CSSStyleSheet* sheet)
-    : CSSRule(sheet), scroll_timeline_rule_(scroll_timeline_rule) {}
-
-CSSScrollTimelineRule::~CSSScrollTimelineRule() = default;
-
-String CSSScrollTimelineRule::cssText() const {
-  StringBuilder builder;
-  builder.Append("@scroll-timeline ");
-  SerializeIdentifier(name(), builder);
-  builder.Append(" { ");
-  if (const CSSValue* source = scroll_timeline_rule_->GetSource()) {
-    builder.Append("source: ");
-    builder.Append(source->CssText());
-    builder.Append("; ");
-  }
-  if (const CSSValue* orientation = scroll_timeline_rule_->GetOrientation()) {
-    builder.Append("orientation: ");
-    builder.Append(orientation->CssText());
-    builder.Append("; ");
-  }
-  if (const CSSValue* start = scroll_timeline_rule_->GetStart()) {
-    builder.Append("start: ");
-    builder.Append(start->CssText());
-    builder.Append("; ");
-  }
-  if (const CSSValue* end = scroll_timeline_rule_->GetEnd()) {
-    builder.Append("end: ");
-    builder.Append(end->CssText());
-    builder.Append("; ");
-  }
-  builder.Append("}");
-  return builder.ReleaseString();
-}
-
-void CSSScrollTimelineRule::Reattach(StyleRuleBase* rule) {
-  DCHECK(rule);
-  scroll_timeline_rule_ = To<StyleRuleScrollTimeline>(rule);
-}
-
-String CSSScrollTimelineRule::name() const {
-  return scroll_timeline_rule_->GetName();
-}
-
-String CSSScrollTimelineRule::source() const {
-  if (const CSSValue* source = scroll_timeline_rule_->GetSource())
-    return source->CssText();
-  return "none";
-}
-
-String CSSScrollTimelineRule::orientation() const {
-  if (const CSSValue* orientation = scroll_timeline_rule_->GetOrientation())
-    return orientation->CssText();
-  return "auto";
-}
-
-String CSSScrollTimelineRule::start() const {
-  if (const CSSValue* start = scroll_timeline_rule_->GetStart())
-    return start->CssText();
-  return "auto";
-}
-
-String CSSScrollTimelineRule::end() const {
-  if (const CSSValue* end = scroll_timeline_rule_->GetEnd())
-    return end->CssText();
-  return "auto";
-}
-
-void CSSScrollTimelineRule::Trace(Visitor* visitor) const {
-  visitor->Trace(scroll_timeline_rule_);
-  CSSRule::Trace(visitor);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_scroll_timeline_rule.h b/third_party/blink/renderer/core/css/css_scroll_timeline_rule.h
deleted file mode 100644
index 80c1203..0000000
--- a/third_party/blink/renderer/core/css/css_scroll_timeline_rule.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// 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_CSS_CSS_SCROLL_TIMELINE_RULE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_SCROLL_TIMELINE_RULE_H_
-
-#include "third_party/blink/renderer/core/css/css_rule.h"
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/heap/member.h"
-#include "third_party/blink/renderer/platform/wtf/casting.h"
-
-namespace blink {
-
-class StyleRuleScrollTimeline;
-
-class CSSScrollTimelineRule final : public CSSRule {
-  DEFINE_WRAPPERTYPEINFO();
-
- public:
-  CSSScrollTimelineRule(StyleRuleScrollTimeline*, CSSStyleSheet*);
-  ~CSSScrollTimelineRule() override;
-
-  String cssText() const override;
-  void Reattach(StyleRuleBase*) override;
-
-  String name() const;
-  String source() const;
-  String orientation() const;
-  String start() const;
-  String end() const;
-
-  void Trace(Visitor*) const override;
-
- private:
-  CSSRule::Type GetType() const override { return kScrollTimelineRule; }
-
-  Member<StyleRuleScrollTimeline> scroll_timeline_rule_;
-};
-
-template <>
-struct DowncastTraits<CSSScrollTimelineRule> {
-  static bool AllowFrom(const CSSRule& rule) {
-    return rule.GetType() == CSSRule::kScrollTimelineRule;
-  }
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_SCROLL_TIMELINE_RULE_H_
diff --git a/third_party/blink/renderer/core/css/css_scroll_timeline_rule.idl b/third_party/blink/renderer/core/css/css_scroll_timeline_rule.idl
deleted file mode 100644
index 5e5115d5..0000000
--- a/third_party/blink/renderer/core/css/css_scroll_timeline_rule.idl
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-[
-    Exposed=Window,
-    RuntimeEnabled=CSSScrollTimeline
-] interface CSSScrollTimelineRule : CSSRule {
-    readonly attribute CSSOMString name;
-    readonly attribute CSSOMString source;
-    readonly attribute CSSOMString orientation;
-    readonly attribute CSSOMString start;
-    readonly attribute CSSOMString end;
-};
diff --git a/third_party/blink/renderer/core/css/css_value.cc b/third_party/blink/renderer/core/css/css_value.cc
index d9923dd..5ec2ab8 100644
--- a/third_party/blink/renderer/core/css/css_value.cc
+++ b/third_party/blink/renderer/core/css/css_value.cc
@@ -38,7 +38,6 @@
 #include "third_party/blink/renderer/core/css/css_custom_ident_value.h"
 #include "third_party/blink/renderer/core/css/css_custom_property_declaration.h"
 #include "third_party/blink/renderer/core/css/css_cyclic_variable_value.h"
-#include "third_party/blink/renderer/core/css/css_element_offset_value.h"
 #include "third_party/blink/renderer/core/css/css_font_face_src_value.h"
 #include "third_party/blink/renderer/core/css/css_font_family_value.h"
 #include "third_party/blink/renderer/core/css/css_font_feature_value.h"
@@ -49,7 +48,6 @@
 #include "third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h"
 #include "third_party/blink/renderer/core/css/css_grid_integer_repeat_value.h"
 #include "third_party/blink/renderer/core/css/css_grid_template_areas_value.h"
-#include "third_party/blink/renderer/core/css/css_id_selector_value.h"
 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
 #include "third_party/blink/renderer/core/css/css_image_set_value.h"
 #include "third_party/blink/renderer/core/css/css_image_value.h"
@@ -298,12 +296,8 @@
         return CompareCSSValues<CSSCyclicVariableValue>(*this, other);
       case kLightDarkValuePairClass:
         return CompareCSSValues<CSSLightDarkValuePair>(*this, other);
-      case kIdSelectorClass:
-        return CompareCSSValues<cssvalue::CSSIdSelectorValue>(*this, other);
       case kScrollClass:
         return CompareCSSValues<cssvalue::CSSScrollValue>(*this, other);
-      case kElementOffsetClass:
-        return CompareCSSValues<cssvalue::CSSElementOffsetValue>(*this, other);
       case kRatioClass:
         return CompareCSSValues<cssvalue::CSSRatioValue>(*this, other);
     }
@@ -436,12 +430,8 @@
       return To<CSSCyclicVariableValue>(this)->CustomCSSText();
     case kLightDarkValuePairClass:
       return To<CSSLightDarkValuePair>(this)->CustomCSSText();
-    case kIdSelectorClass:
-      return To<cssvalue::CSSIdSelectorValue>(this)->CustomCSSText();
     case kScrollClass:
       return To<cssvalue::CSSScrollValue>(this)->CustomCSSText();
-    case kElementOffsetClass:
-      return To<cssvalue::CSSElementOffsetValue>(this)->CustomCSSText();
     case kRatioClass:
       return To<cssvalue::CSSRatioValue>(this)->CustomCSSText();
   }
@@ -640,15 +630,9 @@
     case kLightDarkValuePairClass:
       To<CSSLightDarkValuePair>(this)->~CSSLightDarkValuePair();
       return;
-    case kIdSelectorClass:
-      To<cssvalue::CSSIdSelectorValue>(this)->~CSSIdSelectorValue();
-      return;
     case kScrollClass:
       To<cssvalue::CSSScrollValue>(this)->~CSSScrollValue();
       return;
-    case kElementOffsetClass:
-      To<cssvalue::CSSElementOffsetValue>(this)->~CSSElementOffsetValue();
-      return;
     case kRatioClass:
       To<cssvalue::CSSRatioValue>(this)->~CSSRatioValue();
       return;
@@ -847,15 +831,9 @@
     case kLightDarkValuePairClass:
       To<CSSLightDarkValuePair>(this)->TraceAfterDispatch(visitor);
       return;
-    case kIdSelectorClass:
-      To<cssvalue::CSSIdSelectorValue>(this)->TraceAfterDispatch(visitor);
-      return;
     case kScrollClass:
       To<cssvalue::CSSScrollValue>(this)->TraceAfterDispatch(visitor);
       return;
-    case kElementOffsetClass:
-      To<cssvalue::CSSElementOffsetValue>(this)->TraceAfterDispatch(visitor);
-      return;
     case kRatioClass:
       To<cssvalue::CSSRatioValue>(this)->TraceAfterDispatch(visitor);
       return;
diff --git a/third_party/blink/renderer/core/css/css_value.h b/third_party/blink/renderer/core/css/css_value.h
index 2f1db63..d5daeeb0 100644
--- a/third_party/blink/renderer/core/css/css_value.h
+++ b/third_party/blink/renderer/core/css/css_value.h
@@ -181,11 +181,7 @@
   bool IsLightDarkValuePair() const {
     return class_type_ == kLightDarkValuePairClass;
   }
-  bool IsIdSelectorValue() const { return class_type_ == kIdSelectorClass; }
   bool IsScrollValue() const { return class_type_ == kScrollClass; }
-  bool IsElementOffsetValue() const {
-    return class_type_ == kElementOffsetClass;
-  }
   bool IsRatioValue() const { return class_type_ == kRatioClass; }
 
   bool HasFailedOrCanceledSubresources() const;
@@ -218,9 +214,7 @@
     kURIClass,
     kValuePairClass,
     kLightDarkValuePairClass,
-    kIdSelectorClass,
     kScrollClass,
-    kElementOffsetClass,
     kRatioClass,
 
     // Basic shape classes.
diff --git a/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.cc b/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.cc
index 41d913f..16f53f4 100644
--- a/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.cc
+++ b/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.cc
@@ -6,7 +6,6 @@
 
 #include "third_party/blink/renderer/core/css/css_custom_property_declaration.h"
 #include "third_party/blink/renderer/core/css/css_font_face_src_value.h"
-#include "third_party/blink/renderer/core/css/css_id_selector_value.h"
 #include "third_party/blink/renderer/core/css/css_string_value.h"
 #include "third_party/blink/renderer/core/css/css_unicode_range_value.h"
 #include "third_party/blink/renderer/core/css/css_value.h"
@@ -283,21 +282,6 @@
   return values;
 }
 
-CSSValue* ConsumeScrollTimelineSource(CSSParserTokenRange& range) {
-  if (auto* selector_function =
-          css_parsing_utils::ConsumeSelectorFunction(range)) {
-    return selector_function;
-  }
-  return css_parsing_utils::ConsumeIdent<CSSValueID::kAuto, CSSValueID::kNone>(
-      range);
-}
-
-CSSValue* ConsumeScrollTimelineOrientation(CSSParserTokenRange& range) {
-  return css_parsing_utils::ConsumeIdent<
-      CSSValueID::kAuto, CSSValueID::kBlock, CSSValueID::kInline,
-      CSSValueID::kHorizontal, CSSValueID::kVertical>(range);
-}
-
 CSSValue* ConsumeDescriptor(StyleRule::RuleType rule_type,
                             AtRuleDescriptorID id,
                             const CSSTokenizedValue& tokenized_value,
@@ -314,8 +298,6 @@
       return Parser::ParseAtPropertyDescriptor(id, tokenized_value, context);
     case StyleRule::kCounterStyle:
       return Parser::ParseAtCounterStyleDescriptor(id, range, context);
-    case StyleRule::kScrollTimeline:
-      return Parser::ParseAtScrollTimelineDescriptor(id, range, context);
     case StyleRule::kCharset:
     case StyleRule::kContainer:
     case StyleRule::kStyle:
@@ -475,35 +457,6 @@
   return parsed_value;
 }
 
-CSSValue* AtRuleDescriptorParser::ParseAtScrollTimelineDescriptor(
-    AtRuleDescriptorID id,
-    CSSParserTokenRange& range,
-    const CSSParserContext& context) {
-  CSSValue* parsed_value = nullptr;
-
-  range.ConsumeWhitespace();
-
-  switch (id) {
-    case AtRuleDescriptorID::Source:
-      parsed_value = ConsumeScrollTimelineSource(range);
-      break;
-    case AtRuleDescriptorID::Orientation:
-      parsed_value = ConsumeScrollTimelineOrientation(range);
-      break;
-    case AtRuleDescriptorID::Start:
-    case AtRuleDescriptorID::End:
-      parsed_value = css_parsing_utils::ConsumeScrollOffset(range, context);
-      break;
-    default:
-      break;
-  }
-
-  if (!parsed_value || !range.AtEnd())
-    return nullptr;
-
-  return parsed_value;
-}
-
 bool AtRuleDescriptorParser::ParseAtRule(
     StyleRule::RuleType rule_type,
     AtRuleDescriptorID id,
diff --git a/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h b/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h
index 6d43ca0ef..7f28818 100644
--- a/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h
+++ b/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h
@@ -43,9 +43,6 @@
   static CSSValue* ParseAtFontPaletteValuesDescriptor(AtRuleDescriptorID,
                                                       CSSParserTokenRange&,
                                                       const CSSParserContext&);
-  static CSSValue* ParseAtScrollTimelineDescriptor(AtRuleDescriptorID,
-                                                   CSSParserTokenRange&,
-                                                   const CSSParserContext&);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
index 4b66fba..97560b9 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
+++ b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
@@ -650,8 +650,6 @@
         return ConsumePageRule(stream);
       case kCSSAtRuleProperty:
         return ConsumePropertyRule(stream);
-      case kCSSAtRuleScrollTimeline:
-        return ConsumeScrollTimelineRule(stream);
       case kCSSAtRuleScope:
         return ConsumeScopeRule<UseArena>(stream);
       case kCSSAtRuleCounterStyle:
@@ -1119,36 +1117,6 @@
       name, CreateCSSPropertyValueSet(parsed_properties_, context_->Mode()));
 }
 
-StyleRuleScrollTimeline* CSSParserImpl::ConsumeScrollTimelineRule(
-    CSSParserTokenStream& stream) {
-  wtf_size_t prelude_offset_start = stream.LookAheadOffset();
-  CSSParserTokenRange prelude = ConsumeAtRulePrelude(stream);
-  wtf_size_t prelude_offset_end = stream.LookAheadOffset();
-  if (!ConsumeEndOfPreludeForAtRuleWithBlock(stream))
-    return nullptr;
-  CSSParserTokenStream::BlockGuard guard(stream);
-
-  if (!RuntimeEnabledFeatures::CSSScrollTimelineEnabled())
-    return nullptr;
-
-  const CSSParserToken& name_token = prelude.ConsumeIncludingWhitespace();
-  if (!prelude.AtEnd())
-    return nullptr;
-  if (!css_parsing_utils::IsTimelineName(name_token))
-    return nullptr;
-  String name = name_token.Value().ToString();
-
-  if (observer_) {
-    observer_->StartRuleHeader(StyleRule::kScrollTimeline,
-                               prelude_offset_start);
-    observer_->EndRuleHeader(prelude_offset_end);
-  }
-
-  ConsumeDeclarationList(stream, StyleRule::kScrollTimeline);
-  return MakeGarbageCollected<StyleRuleScrollTimeline>(
-      name, CreateCSSPropertyValueSet(parsed_properties_, context_->Mode()));
-}
-
 template <bool UseArena>
 StyleRuleBase* CSSParserImpl::ConsumeScopeRule(CSSParserTokenStream& stream) {
   DCHECK(RuntimeEnabledFeatures::CSSScopeEnabled());
@@ -1435,7 +1403,6 @@
       rule_type == StyleRule::kContainer ||
       rule_type == StyleRule::kCounterStyle ||
       rule_type == StyleRule::kFontPaletteValues ||
-      rule_type == StyleRule::kScrollTimeline ||
       rule_type == StyleRule::kKeyframe || rule_type == StyleRule::kScope ||
       rule_type == StyleRule::kTry;
   bool use_observer = observer_ && is_observer_rule_type;
@@ -1517,8 +1484,7 @@
   if (rule_type == StyleRule::kFontFace ||
       rule_type == StyleRule::kFontPaletteValues ||
       rule_type == StyleRule::kProperty ||
-      rule_type == StyleRule::kCounterStyle ||
-      rule_type == StyleRule::kScrollTimeline) {
+      rule_type == StyleRule::kCounterStyle) {
     if (important)  // Invalid
       return;
     atrule_id = lhs.ParseAsAtRuleDescriptorID();
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_impl.h b/third_party/blink/renderer/core/css/parser/css_parser_impl.h
index 1284e7c..187b6e8 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_impl.h
+++ b/third_party/blink/renderer/core/css/parser/css_parser_impl.h
@@ -191,7 +191,6 @@
   StyleRulePage* ConsumePageRule(CSSParserTokenStream&);
   StyleRuleProperty* ConsumePropertyRule(CSSParserTokenStream&);
   StyleRuleCounterStyle* ConsumeCounterStyleRule(CSSParserTokenStream&);
-  StyleRuleScrollTimeline* ConsumeScrollTimelineRule(CSSParserTokenStream&);
   template <bool UseArena>
   StyleRuleBase* ConsumeScopeRule(CSSParserTokenStream&);
   template <bool UseArena>
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_impl_test.cc b/third_party/blink/renderer/core/css/parser/css_parser_impl_test.cc
index cac765b..b746ae9 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_impl_test.cc
+++ b/third_party/blink/renderer/core/css/parser/css_parser_impl_test.cc
@@ -179,25 +179,6 @@
   EXPECT_EQ(test_css_parser_observer.rule_body_end_, 19u);
 }
 
-TEST(CSSParserImplTest, AtScrollTimelineOffsets) {
-  ScopedCSSScrollTimelineForTest scoped_feature(true);
-
-  String sheet_text = "@scroll-timeline test { }";
-  auto* context = MakeGarbageCollected<CSSParserContext>(
-      kHTMLStandardMode, SecureContextMode::kInsecureContext);
-  auto* style_sheet = MakeGarbageCollected<StyleSheetContents>(context);
-  TestCSSParserObserver test_css_parser_observer;
-  CSSParserImpl::ParseStyleSheetForInspector(sheet_text, context, style_sheet,
-                                             test_css_parser_observer);
-  EXPECT_EQ(style_sheet->ChildRules().size(), 1u);
-  EXPECT_EQ(test_css_parser_observer.rule_type_,
-            StyleRule::RuleType::kScrollTimeline);
-  EXPECT_EQ(test_css_parser_observer.rule_header_start_, 17u);
-  EXPECT_EQ(test_css_parser_observer.rule_header_end_, 22u);
-  EXPECT_EQ(test_css_parser_observer.rule_body_start_, 23u);
-  EXPECT_EQ(test_css_parser_observer.rule_body_end_, 24u);
-}
-
 TEST(CSSParserImplTest, AtCounterStyleOffsets) {
   String sheet_text = "@counter-style test { }";
   auto* context = MakeGarbageCollected<CSSParserContext>(
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
index 15907e5..cee5ed7 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -16,7 +16,6 @@
 #include "third_party/blink/renderer/core/css/css_content_distribution_value.h"
 #include "third_party/blink/renderer/core/css/css_crossfade_value.h"
 #include "third_party/blink/renderer/core/css/css_custom_ident_value.h"
-#include "third_party/blink/renderer/core/css/css_element_offset_value.h"
 #include "third_party/blink/renderer/core/css/css_font_family_value.h"
 #include "third_party/blink/renderer/core/css/css_font_feature_value.h"
 #include "third_party/blink/renderer/core/css/css_font_style_range_value.h"
@@ -25,7 +24,6 @@
 #include "third_party/blink/renderer/core/css/css_grid_auto_repeat_value.h"
 #include "third_party/blink/renderer/core/css/css_grid_integer_repeat_value.h"
 #include "third_party/blink/renderer/core/css/css_grid_template_areas_value.h"
-#include "third_party/blink/renderer/core/css/css_id_selector_value.h"
 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
 #include "third_party/blink/renderer/core/css/css_image_set_value.h"
 #include "third_party/blink/renderer/core/css/css_image_value.h"
@@ -1369,29 +1367,6 @@
       url_string, context.CompleteURL(url_string));
 }
 
-CSSValue* ConsumeSelectorFunction(CSSParserTokenRange& range) {
-  if (range.Peek().FunctionId() != CSSValueID::kSelector)
-    return nullptr;
-  auto block = ConsumeFunction(range);
-  if (auto* id_value = ConsumeIdSelector(block)) {
-    if (!block.AtEnd())
-      return nullptr;
-    auto* selector_function =
-        MakeGarbageCollected<CSSFunctionValue>(CSSValueID::kSelector);
-    selector_function->Append(*id_value);
-    return selector_function;
-  }
-  return nullptr;
-}
-
-CSSValue* ConsumeIdSelector(CSSParserTokenRange& range) {
-  if (!IsHashIdentifier(range.Peek()))
-    return nullptr;
-  auto token = range.ConsumeIncludingWhitespace();
-  return MakeGarbageCollected<cssvalue::CSSIdSelectorValue>(
-      token.Value().ToString());
-}
-
 static int ClampRGBComponent(const CSSPrimitiveValue& value) {
   double result = value.GetDoubleValue();
   if (value.IsPercentage()) {
@@ -3184,46 +3159,6 @@
          IsCustomIdent<CSSValueID::kNone>(token.Id());
 }
 
-CSSValue* ConsumeScrollOffset(CSSParserTokenRange& range,
-                              const CSSParserContext& context) {
-  if (IdentMatches<CSSValueID::kAuto>(range.Peek().Id()))
-    return ConsumeIdent(range);
-  CSSParserContext::ParserModeOverridingScope scope(context, kHTMLStandardMode);
-  if (auto* element_offset = ConsumeElementOffset(range, context))
-    return element_offset;
-  CSSValue* value = ConsumeLengthOrPercent(
-      range, context, CSSPrimitiveValue::ValueRange::kNonNegative);
-  if (!range.AtEnd())
-    return nullptr;
-  return value;
-}
-
-namespace {
-
-// https://drafts.csswg.org/scroll-animations-1/#typedef-element-offset-edge
-CSSValue* ConsumeElementOffsetEdge(CSSParserTokenRange& range) {
-  return ConsumeIdent<CSSValueID::kStart, CSSValueID::kEnd>(range);
-}
-
-}  // namespace
-
-// https://drafts.csswg.org/scroll-animations-1/#typedef-element-offset
-CSSValue* ConsumeElementOffset(CSSParserTokenRange& range,
-                               const CSSParserContext& context) {
-  CSSValue* target = ConsumeSelectorFunction(range);
-  if (!target)
-    return nullptr;
-  CSSValue* edge = ConsumeElementOffsetEdge(range);
-  CSSValue* threshold = ConsumeNumber(
-      range, context, CSSPrimitiveValue::ValueRange::kNonNegative);
-  // Edge and threshold may appear in any order.
-  edge = edge ? edge : ConsumeElementOffsetEdge(range);
-  if (!range.AtEnd())
-    return nullptr;
-  return MakeGarbageCollected<cssvalue::CSSElementOffsetValue>(target, edge,
-                                                               threshold);
-}
-
 CSSValue* ConsumeSelfPositionOverflowPosition(
     CSSParserTokenRange& range,
     IsPositionKeyword is_position_keyword) {
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.h b/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
index dd806aa..fccda35 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
@@ -163,8 +163,6 @@
                                   const CSSParserContext&);
 cssvalue::CSSURIValue* ConsumeUrl(CSSParserTokenRange&,
                                   const CSSParserContext&);
-CSSValue* ConsumeSelectorFunction(CSSParserTokenRange&);
-CORE_EXPORT CSSValue* ConsumeIdSelector(CSSParserTokenRange&);
 
 CORE_EXPORT CSSValue* ConsumeColor(CSSParserTokenRange&,
                                    const CSSParserContext&,
@@ -292,8 +290,6 @@
 // https://drafts.csswg.org/scroll-animations-1/#typedef-timeline-name
 bool IsTimelineName(const CSSParserToken&);
 
-CSSValue* ConsumeScrollOffset(CSSParserTokenRange&, const CSSParserContext&);
-CSSValue* ConsumeElementOffset(CSSParserTokenRange&, const CSSParserContext&);
 CSSValue* ConsumeSelfPositionOverflowPosition(CSSParserTokenRange&,
                                               IsPositionKeyword);
 CSSValue* ConsumeSimplifiedDefaultPosition(CSSParserTokenRange&,
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils_test.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils_test.cc
index 96245fe..d363ce6 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils_test.cc
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils_test.cc
@@ -19,7 +19,6 @@
 using css_parsing_utils::AtDelimiter;
 using css_parsing_utils::AtIdent;
 using css_parsing_utils::ConsumeAngle;
-using css_parsing_utils::ConsumeIdSelector;
 using css_parsing_utils::ConsumeIfDelimiter;
 using css_parsing_utils::ConsumeIfIdent;
 
@@ -45,65 +44,6 @@
   EXPECT_TRUE(css_parsing_utils::IsCSSWideKeyword("revert"));
 }
 
-TEST(CSSParsingUtilsTest, ConsumeIdSelector) {
-  {
-    String text = "#foo";
-    auto tokens = CSSTokenizer(text).TokenizeToEOF();
-    CSSParserTokenRange range(tokens);
-    EXPECT_EQ("#foo", ConsumeIdSelector(range)->CssText());
-  }
-  {
-    String text = "#bar  ";
-    auto tokens = CSSTokenizer(text).TokenizeToEOF();
-    CSSParserTokenRange range(tokens);
-    EXPECT_EQ("#bar", ConsumeIdSelector(range)->CssText());
-    EXPECT_TRUE(range.AtEnd())
-        << "ConsumeIdSelector cleans up trailing whitespace";
-  }
-
-  {
-    String text = "#123";
-    auto tokens = CSSTokenizer(text).TokenizeToEOF();
-    CSSParserTokenRange range(tokens);
-    ASSERT_TRUE(range.Peek().GetType() == kHashToken &&
-                range.Peek().GetHashTokenType() == kHashTokenUnrestricted);
-    EXPECT_FALSE(ConsumeIdSelector(range))
-        << "kHashTokenUnrestricted is not a valid <id-selector>";
-  }
-  {
-    String text = "#";
-    auto tokens = CSSTokenizer(text).TokenizeToEOF();
-    CSSParserTokenRange range(tokens);
-    EXPECT_FALSE(ConsumeIdSelector(range));
-  }
-  {
-    String text = " #foo";
-    auto tokens = CSSTokenizer(text).TokenizeToEOF();
-    CSSParserTokenRange range(tokens);
-    EXPECT_FALSE(ConsumeIdSelector(range))
-        << "ConsumeIdSelector does not accept preceding whitespace";
-    EXPECT_EQ(kWhitespaceToken, range.Peek().GetType());
-  }
-  {
-    String text = "foo";
-    auto tokens = CSSTokenizer(text).TokenizeToEOF();
-    CSSParserTokenRange range(tokens);
-    EXPECT_FALSE(ConsumeIdSelector(range));
-  }
-  {
-    String text = "##";
-    auto tokens = CSSTokenizer(text).TokenizeToEOF();
-    CSSParserTokenRange range(tokens);
-    EXPECT_FALSE(ConsumeIdSelector(range));
-  }
-  {
-    String text = "10px";
-    auto tokens = CSSTokenizer(text).TokenizeToEOF();
-    CSSParserTokenRange range(tokens);
-    EXPECT_FALSE(ConsumeIdSelector(range));
-  }
-}
-
 double ConsumeAngleValue(String target) {
   auto tokens = CSSTokenizer(target).TokenizeToEOF();
   CSSParserTokenRange range(tokens);
diff --git a/third_party/blink/renderer/core/css/rule_set.cc b/third_party/blink/renderer/core/css/rule_set.cc
index ab6ca46c..e6d57fb 100644
--- a/third_party/blink/renderer/core/css/rule_set.cc
+++ b/third_party/blink/renderer/core/css/rule_set.cc
@@ -486,11 +486,6 @@
   font_palette_values_rules_.push_back(rule);
 }
 
-void RuleSet::AddScrollTimelineRule(StyleRuleScrollTimeline* rule) {
-  need_compaction_ = true;
-  scroll_timeline_rules_.push_back(rule);
-}
-
 void RuleSet::AddPositionFallbackRule(StyleRulePositionFallback* rule) {
   need_compaction_ = true;
   position_fallback_rules_.push_back(rule);
@@ -538,10 +533,6 @@
                    DynamicTo<StyleRuleCounterStyle>(rule)) {
       counter_style_rule->SetCascadeLayer(cascade_layer);
       AddCounterStyleRule(counter_style_rule);
-    } else if (auto* scroll_timeline_rule =
-                   DynamicTo<StyleRuleScrollTimeline>(rule)) {
-      scroll_timeline_rule->SetCascadeLayer(cascade_layer);
-      AddScrollTimelineRule(scroll_timeline_rule);
     } else if (auto* position_fallback_rule =
                    DynamicTo<StyleRulePositionFallback>(rule)) {
       // TODO(crbug.com/1309178): Handle interaction with cascade layers.
@@ -867,7 +858,6 @@
   keyframes_rules_.ShrinkToFit();
   property_rules_.ShrinkToFit();
   counter_style_rules_.ShrinkToFit();
-  scroll_timeline_rules_.ShrinkToFit();
   position_fallback_rules_.ShrinkToFit();
   layer_intervals_.ShrinkToFit();
 
@@ -971,7 +961,6 @@
   visitor->Trace(keyframes_rules_);
   visitor->Trace(property_rules_);
   visitor->Trace(counter_style_rules_);
-  visitor->Trace(scroll_timeline_rules_);
   visitor->Trace(position_fallback_rules_);
   visitor->Trace(media_query_set_results_);
   visitor->Trace(implicit_outer_layer_);
diff --git a/third_party/blink/renderer/core/css/rule_set.h b/third_party/blink/renderer/core/css/rule_set.h
index 171946b..5ce318d 100644
--- a/third_party/blink/renderer/core/css/rule_set.h
+++ b/third_party/blink/renderer/core/css/rule_set.h
@@ -425,10 +425,6 @@
       const {
     return font_palette_values_rules_;
   }
-  const HeapVector<Member<StyleRuleScrollTimeline>>& ScrollTimelineRules()
-      const {
-    return scroll_timeline_rules_;
-  }
   const HeapVector<Member<StyleRulePositionFallback>>& PositionFallbackRules()
       const {
     return position_fallback_rules_;
@@ -519,7 +515,6 @@
   void AddFontFaceRule(StyleRuleFontFace*);
   void AddKeyframesRule(StyleRuleKeyframes*);
   void AddPropertyRule(StyleRuleProperty*);
-  void AddScrollTimelineRule(StyleRuleScrollTimeline*);
   void AddCounterStyleRule(StyleRuleCounterStyle*);
   void AddFontPaletteValuesRule(StyleRuleFontPaletteValues*);
   void AddPositionFallbackRule(StyleRulePositionFallback*);
@@ -609,7 +604,6 @@
   HeapVector<Member<StyleRuleKeyframes>> keyframes_rules_;
   HeapVector<Member<StyleRuleProperty>> property_rules_;
   HeapVector<Member<StyleRuleCounterStyle>> counter_style_rules_;
-  HeapVector<Member<StyleRuleScrollTimeline>> scroll_timeline_rules_;
   HeapVector<Member<StyleRulePositionFallback>> position_fallback_rules_;
   HeapVector<MediaQuerySetResult> media_query_set_results_;
 
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc
index 845b27fc..2039b29 100644
--- a/third_party/blink/renderer/core/css/style_engine.cc
+++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -570,7 +570,6 @@
   UpdateViewport();
   UpdateActiveStyleSheets();
   UpdateGlobalRuleSet();
-  UpdateTimelines();
 }
 
 const ActiveStyleSheetVector StyleEngine::ActiveStyleSheetsForInspector() {
@@ -1935,10 +1934,9 @@
   kKeyframesRules = 1 << 1,
   kFullRecalcRules = 1 << 2,
   kPropertyRules = 1 << 3,
-  kScrollTimelineRules = 1 << 4,
-  kCounterStyleRules = 1 << 5,
-  kLayerRules = 1 << 6,
-  kFontPaletteValuesRules = 1 << 7,
+  kCounterStyleRules = 1 << 4,
+  kLayerRules = 1 << 5,
+  kFontPaletteValuesRules = 1 << 6,
 };
 
 const unsigned kRuleSetFlagsAll = ~0u;
@@ -1959,8 +1957,6 @@
       flags |= kPropertyRules;
     if (!rule_set->CounterStyleRules().IsEmpty())
       flags |= kCounterStyleRules;
-    if (!rule_set->ScrollTimelineRules().IsEmpty())
-      flags |= kScrollTimelineRules;
     if (rule_set->HasCascadeLayers())
       flags |= kLayerRules;
   }
@@ -2002,8 +1998,8 @@
   initial_data_ = nullptr;
 }
 
-// A miniature CascadeMap for cascading @property and @scroll-timeline
-// at-rules according to their origin, cascade layer order and position.
+// A miniature CascadeMap for cascading @property at-rules according to their
+// origin, cascade layer order and position.
 class StyleEngine::AtRuleCascadeMap {
   STACK_ALLOCATED();
 
@@ -2138,20 +2134,13 @@
     MarkCounterStylesNeedUpdate();
   }
 
-  if (changed_rule_flags &
-      (kPropertyRules | kScrollTimelineRules | kFontPaletteValuesRules)) {
+  if (changed_rule_flags & (kPropertyRules | kFontPaletteValuesRules)) {
     if (changed_rule_flags & kPropertyRules) {
       ClearPropertyRules();
       AtRuleCascadeMap cascade_map(GetDocument());
       AddPropertyRulesFromSheets(cascade_map, new_style_sheets,
                                  true /* is_user_style */);
     }
-    if (changed_rule_flags & kScrollTimelineRules) {
-      ClearScrollTimelineRules();
-      AtRuleCascadeMap cascade_map(GetDocument());
-      AddScrollTimelineRulesFromSheets(cascade_map, new_style_sheets,
-                                       true /* is_user_style */);
-    }
 
     if (changed_rule_flags & kFontPaletteValuesRules) {
       font_palette_values_rule_map_.clear();
@@ -2188,13 +2177,11 @@
                                  (changed_rule_flags & kFontFaceRules) &&
                                  tree_scope.RootNode().IsDocumentNode();
   bool rebuild_at_property_registry = false;
-  bool rebuild_at_scroll_timeline_map = false;
   bool rebuild_at_font_palette_values_map = false;
   ScopedStyleResolver* scoped_resolver = tree_scope.GetScopedStyleResolver();
   if (scoped_resolver && scoped_resolver->NeedsAppendAllSheets()) {
     rebuild_font_face_cache = true;
     rebuild_at_property_registry = true;
-    rebuild_at_scroll_timeline_map = true;
     rebuild_at_font_palette_values_map = true;
     change = kActiveSheetsChanged;
   }
@@ -2263,20 +2250,6 @@
     }
   }
 
-  if ((changed_rule_flags & kScrollTimelineRules) ||
-      rebuild_at_scroll_timeline_map) {
-    // @scroll-timeline rules are currently not allowed in shadow trees.
-    // https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule
-    if (tree_scope.RootNode().IsDocumentNode()) {
-      ClearScrollTimelineRules();
-      AtRuleCascadeMap cascade_map(GetDocument());
-      AddScrollTimelineRulesFromSheets(cascade_map, active_user_style_sheets_,
-                                       true /* is_user_style */);
-      AddScrollTimelineRulesFromSheets(cascade_map, new_style_sheets,
-                                       false /* is_user_style */);
-    }
-  }
-
   if ((changed_rule_flags & kFontPaletteValuesRules) ||
       rebuild_at_font_palette_values_map) {
     // TODO(https://crbug.com1296114): Support @font-palette-values in shadow
@@ -2393,17 +2366,6 @@
     resolver_->InvalidateMatchedPropertiesCache();
 }
 
-void StyleEngine::ScrollTimelinesChanged() {
-  MarkAllElementsForStyleRecalc(StyleChangeReasonForTracing::Create(
-      style_change_reason::kScrollTimeline));
-  // We currently rely on marking at least one element for recalc in order
-  // to clean the timelines_need_update_ flag. (Otherwise the timelines
-  // will just remain dirty). Hence, if we in the future remove the call
-  // to mark elements for recalc, we would need to call
-  // ScheduleLayoutTreeUpdateIfNeeded to ensure that we reach UpdateTimelines.
-  timelines_need_update_ = true;
-}
-
 void StyleEngine::NodeWillBeRemoved(Node& node) {
   if (auto* element = DynamicTo<Element>(node)) {
     pending_invalidations_.RescheduleSiblingInvalidationsAsDescendants(
@@ -2461,11 +2423,6 @@
   PropertyRegistration::RemoveDeclaredProperties(GetDocument());
 }
 
-void StyleEngine::ClearScrollTimelineRules() {
-  scroll_timeline_rule_map_.clear();
-  ScrollTimelinesChanged();
-}
-
 void StyleEngine::AddPropertyRulesFromSheets(
     AtRuleCascadeMap& cascade_map,
     const ActiveStyleSheetVector& sheets,
@@ -2476,16 +2433,6 @@
   }
 }
 
-void StyleEngine::AddScrollTimelineRulesFromSheets(
-    AtRuleCascadeMap& cascade_map,
-    const ActiveStyleSheetVector& sheets,
-    bool is_user_style) {
-  for (const ActiveStyleSheet& active_sheet : sheets) {
-    if (RuleSet* rule_set = active_sheet.second)
-      AddScrollTimelineRules(cascade_map, *rule_set, is_user_style);
-  }
-}
-
 void StyleEngine::AddFontPaletteValuesRulesFromSheets(
     const ActiveStyleSheetVector& sheets) {
   for (const ActiveStyleSheet& active_sheet : sheets) {
@@ -2574,23 +2521,6 @@
   }
 }
 
-void StyleEngine::AddScrollTimelineRules(AtRuleCascadeMap& cascade_map,
-                                         const RuleSet& rule_set,
-                                         bool is_user_style) {
-  const HeapVector<Member<StyleRuleScrollTimeline>> scroll_timeline_rules =
-      rule_set.ScrollTimelineRules();
-  if (scroll_timeline_rules.IsEmpty())
-    return;
-  for (const auto& rule : scroll_timeline_rules) {
-    auto priority =
-        cascade_map.GetPriority(is_user_style, rule->GetCascadeLayer());
-    if (!cascade_map.AddAndCascade(rule->GetName(), priority))
-      continue;
-    scroll_timeline_rule_map_.Set(rule->GetName(), rule);
-  }
-  ScrollTimelinesChanged();
-}
-
 StyleRuleKeyframes* StyleEngine::KeyframeStylesForAnimation(
     const AtomicString& animation_name) {
   if (keyframes_rule_map_.IsEmpty())
@@ -2618,51 +2548,6 @@
   return it->value.Get();
 }
 
-void StyleEngine::UpdateTimelines() {
-  if (!timelines_need_update_)
-    return;
-  timelines_need_update_ = false;
-
-  HeapHashMap<AtomicString, Member<CSSScrollTimeline>> timelines;
-
-  for (const auto& it : scroll_timeline_rule_map_) {
-    const AtomicString& name = it.key;
-
-    CSSScrollTimeline::Options options(GetDocument(), *it.value);
-
-    // Check if we can re-use existing timeline.
-    CSSScrollTimeline* existing_timeline = FindScrollTimeline(name);
-    if (existing_timeline && existing_timeline->Matches(options)) {
-      timelines.Set(name, existing_timeline);
-      continue;
-    }
-
-    // Create a new timeline.
-    auto* timeline = MakeGarbageCollected<CSSScrollTimeline>(
-        &GetDocument(), std::move(options));
-    // It is not allowed for a style update to create timelines that
-    // needs timing updates (i.e.
-    // AnimationTimeline::NeedsAnimationTimingUpdate() must return false).
-    // Servicing animations after creation preserves this invariant by ensuring
-    // the last-update time of the timeline is equal to the current time.
-    timeline->ServiceAnimations(kTimingUpdateOnDemand);
-    timelines.Set(name, timeline);
-  }
-
-  std::swap(scroll_timeline_map_, timelines);
-}
-
-CSSScrollTimeline* StyleEngine::FindScrollTimeline(const AtomicString& name) {
-  DCHECK(!timelines_need_update_);
-  auto it = scroll_timeline_map_.find(name);
-  return it != scroll_timeline_map_.end() ? it->value : nullptr;
-}
-
-void StyleEngine::ScrollTimelineInvalidated(CSSScrollTimeline& timeline) {
-  timelines_need_update_ = true;
-  timeline.InvalidateEffectTargetStyle();
-}
-
 DocumentStyleEnvironmentVariables& StyleEngine::EnsureEnvironmentVariables() {
   if (!environment_variables_) {
     environment_variables_ = DocumentStyleEnvironmentVariables::Create(
@@ -3375,8 +3260,6 @@
   visitor->Trace(keyframes_rule_map_);
   visitor->Trace(font_palette_values_rule_map_);
   visitor->Trace(user_counter_style_map_);
-  visitor->Trace(scroll_timeline_rule_map_);
-  visitor->Trace(scroll_timeline_map_);
   visitor->Trace(user_cascade_layer_map_);
   visitor->Trace(inspector_style_sheet_);
   visitor->Trace(document_style_sheet_collection_);
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h
index d69d367f..bfc16eae 100644
--- a/third_party/blink/renderer/core/css/style_engine.h
+++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -74,7 +74,6 @@
 class CounterStyleMap;
 class CSSFontSelector;
 class CSSPropertyValueSet;
-class CSSScrollTimeline;
 class CSSStyleSheet;
 class CSSValue;
 class Document;
@@ -95,7 +94,6 @@
 class StyleResolverStats;
 class StyleRuleFontFace;
 class StyleRuleFontPaletteValues;
-class StyleRuleScrollTimeline;
 class StyleRuleKeyframes;
 class StyleRuleUsageTracker;
 class StyleSheet;
@@ -440,13 +438,6 @@
 
   void EnvironmentVariableChanged();
 
-  // Called when the set of @scroll-timeline rules changes. E.g. if a new
-  // @scroll-timeline rule was inserted.
-  //
-  // Not to be confused with ScrollTimelineInvalidated, which is called when
-  // elements *referenced* by @scroll-timeline rules change.
-  void ScrollTimelinesChanged();
-
   void MarkAllElementsForStyleRecalc(const StyleChangeReasonForTracing& reason);
   void MarkViewportStyleDirty();
   bool IsViewportStyleDirty() const { return viewport_style_dirty_; }
@@ -467,18 +458,6 @@
       AtomicString palette_name,
       AtomicString font_family);
 
-  void UpdateTimelines();
-
-  CSSScrollTimeline* FindScrollTimeline(const AtomicString& name);
-
-  // Called when information a @scroll-timeline depends on changes, e.g.
-  // when we have source:selector(#foo), and the element referenced by
-  // #foo changes.
-  //
-  // Not to be confused with ScrollTimelinesChanged, which is called when
-  // @scroll-timeline rules themselves change.
-  void ScrollTimelineInvalidated(CSSScrollTimeline&);
-
   CounterStyleMap* GetUserCounterStyleMap() { return user_counter_style_map_; }
   const CounterStyle& FindCounterStyleAcrossScopes(const AtomicString&,
                                                    const TreeScope*) const;
@@ -675,16 +654,12 @@
 
   void ClearKeyframeRules();
   void ClearPropertyRules();
-  void ClearScrollTimelineRules();
 
   class AtRuleCascadeMap;
 
   void AddPropertyRulesFromSheets(AtRuleCascadeMap&,
                                   const ActiveStyleSheetVector&,
                                   bool is_user_style);
-  void AddScrollTimelineRulesFromSheets(AtRuleCascadeMap&,
-                                        const ActiveStyleSheetVector&,
-                                        bool is_user_style);
   void AddFontPaletteValuesRulesFromSheets(
       const ActiveStyleSheetVector& sheets);
 
@@ -694,9 +669,6 @@
   void AddUserKeyframeStyle(StyleRuleKeyframes*);
   void AddFontPaletteValuesRules(const RuleSet& rule_set);
   void AddPropertyRules(AtRuleCascadeMap&, const RuleSet&, bool is_user_style);
-  void AddScrollTimelineRules(AtRuleCascadeMap&,
-                              const RuleSet&,
-                              bool is_user_style);
   bool UserKeyframeStyleShouldOverride(
       const StyleRuleKeyframes* new_rule,
       const StyleRuleKeyframes* existing_rule) const;
@@ -805,7 +777,6 @@
   bool viewport_style_dirty_{false};
   bool fonts_need_update_{false};
   bool counter_styles_need_update_{false};
-  bool timelines_need_update_{false};
 
   // Set to true if we allow marking style dirty from style recalc. Ideally, we
   // should get rid of this, but we keep track of where we allow it with
@@ -874,10 +845,6 @@
 
   Member<CounterStyleMap> user_counter_style_map_;
 
-  HeapHashMap<AtomicString, Member<StyleRuleScrollTimeline>>
-      scroll_timeline_rule_map_;
-  HeapHashMap<AtomicString, Member<CSSScrollTimeline>> scroll_timeline_map_;
-
   Member<CascadeLayerMap> user_cascade_layer_map_;
 
   scoped_refptr<DocumentStyleEnvironmentVariables> environment_variables_;
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc
index e5f6c01..c9e2dc4 100644
--- a/third_party/blink/renderer/core/css/style_engine_test.cc
+++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -142,13 +142,6 @@
     return ListMarker::Get(marker)->GetTextChild(*marker).GetText();
   }
 
-  StyleRuleScrollTimeline* FindScrollTimelineRule(AtomicString name) {
-    CSSScrollTimeline* timeline = GetStyleEngine().FindScrollTimeline(name);
-    if (!timeline)
-      return nullptr;
-    return timeline->GetRule();
-  }
-
   void SimulateFrame() {
     auto new_time = GetAnimationClock().CurrentTime() + base::Milliseconds(100);
     GetPage().Animator().ServiceScriptedAnimations(new_time);
@@ -3183,23 +3176,6 @@
   EXPECT_TRUE(GetDocument().IsUseCounted(WebFeature::kCSSAtRuleProperty));
 }
 
-TEST_F(StyleEngineTest, AtScrollTimelineUseCount) {
-  ScopedCSSScrollTimelineForTest scoped_feature(true);
-
-  GetDocument().body()->setInnerHTML("<div>No @scroll-timline</div>");
-  UpdateAllLifecyclePhases();
-  EXPECT_FALSE(
-      GetDocument().IsUseCounted(WebFeature::kCSSAtRuleScrollTimeline));
-
-  GetDocument().body()->setInnerHTML(R"HTML(
-    <style>
-      @scroll-timeline foo { }
-    </style>
-  )HTML");
-  UpdateAllLifecyclePhases();
-  EXPECT_TRUE(GetDocument().IsUseCounted(WebFeature::kCSSAtRuleScrollTimeline));
-}
-
 TEST_F(StyleEngineTest, CSSMatchMediaUnknownUseCounter) {
   ScopedCSSMediaQueries4ForTest media_queries_4_flag(false);
 
@@ -3496,46 +3472,6 @@
   EXPECT_EQ("30px", ComputedValue(GetDocument().body(), "--y")->CssText());
 }
 
-TEST_F(StyleEngineTest, AtScrollTimelineInUserOrigin) {
-  ScopedCSSScrollTimelineForTest scoped_feature(true);
-
-  // @scroll-timeline in the user origin:
-  InjectSheet("user1", WebCssOrigin::kUser, R"CSS(
-    @scroll-timeline timeline1 {
-      source: selector(#scroller1);
-    }
-  )CSS");
-  UpdateAllLifecyclePhases();
-  StyleRuleScrollTimeline* rule1 = FindScrollTimelineRule("timeline1");
-  ASSERT_TRUE(rule1);
-  ASSERT_TRUE(rule1->GetSource());
-  EXPECT_EQ("selector(#scroller1)", rule1->GetSource()->CssText());
-
-  // @scroll-timeline in the author origin (should win over user origin)
-  InjectSheet("author", WebCssOrigin::kAuthor, R"CSS(
-    @scroll-timeline timeline1 {
-      source: selector(#scroller2);
-    }
-  )CSS");
-  UpdateAllLifecyclePhases();
-  StyleRuleScrollTimeline* rule2 = FindScrollTimelineRule("timeline1");
-  ASSERT_TRUE(rule2);
-  ASSERT_TRUE(rule2->GetSource());
-  EXPECT_EQ("selector(#scroller2)", rule2->GetSource()->CssText());
-
-  // An additional @scroll-timeline in the user origin:
-  InjectSheet("user2", WebCssOrigin::kUser, R"CSS(
-    @scroll-timeline timeline2 {
-      source: selector(#scroller3);
-    }
-  )CSS");
-  UpdateAllLifecyclePhases();
-  StyleRuleScrollTimeline* rule3 = FindScrollTimelineRule("timeline2");
-  ASSERT_TRUE(rule3);
-  ASSERT_TRUE(rule3->GetSource());
-  EXPECT_EQ("selector(#scroller3)", rule3->GetSource()->CssText());
-}
-
 // https://crbug.com/1050564
 TEST_F(StyleEngineTest, MediaAttributeChangeUpdatesFontCacheVersion) {
   GetDocument().body()->setInnerHTML(R"HTML(
@@ -4996,125 +4932,6 @@
   EXPECT_EQ(100, target->OffsetWidth());
 }
 
-TEST_F(StyleEngineTest, UserScrollTimelineOverrideWithCascadeLayers) {
-  ScopedCSSScrollTimelineForTest scroll_timeline_enabled(true);
-
-  auto* user_sheet = MakeGarbageCollected<StyleSheetContents>(
-      MakeGarbageCollected<CSSParserContext>(GetDocument()));
-  user_sheet->ParseString(R"CSS(
-    @layer base, override;
-
-    #scroller {
-      overflow: hidden;
-      width: 100px;
-      height: 100px;
-    }
-
-    #scroll-contents {
-      height: 200px;
-      width: 300px;
-    }
-
-    @keyframes expand {
-      from { width: 100px; }
-      to { width: 200px; }
-    }
-
-    #target {
-      animation: expand 10s linear;
-      animation-timeline: timeline;
-      height: 100px;
-    }
-
-    @layer override {
-      @scroll-timeline timeline {
-        source: selector(#scroller);
-        orientation: block;
-      }
-    }
-
-    @layer base {
-      @scroll-timeline timeline {
-        source: selector(#scroller);
-        orientation: inline;
-      }
-    }
-  )CSS");
-  StyleSheetKey key("user");
-  GetStyleEngine().InjectSheet(key, user_sheet, WebCssOrigin::kUser);
-
-  GetDocument().body()->setInnerHTML(
-      "<div id=scroller><div id=scroll-contents></div></div>"
-      "<div id=target></div>");
-
-  Element* scroller = GetDocument().getElementById("scroller");
-  scroller->setScrollTop(25);
-  UpdateAllLifecyclePhases();
-
-  Element* target = GetDocument().getElementById("target");
-  EXPECT_EQ(125, target->OffsetWidth());
-}
-
-TEST_F(StyleEngineTest, UserAndAuthorScrollTimelineOverrideWithCascadeLayers) {
-  ScopedCSSScrollTimelineForTest scroll_timeline_enabled(true);
-
-  auto* user_sheet = MakeGarbageCollected<StyleSheetContents>(
-      MakeGarbageCollected<CSSParserContext>(GetDocument()));
-  user_sheet->ParseString(R"CSS(
-    @layer base, override;
-
-    #scroller {
-      overflow: hidden;
-      width: 100px;
-      height: 100px;
-    }
-
-    #scroll-contents {
-      height: 200px;
-    }
-
-    @keyframes expand {
-      from { width: 100px; }
-      to { width: 200px; }
-    }
-
-    @layer override {
-      @scroll-timeline timeline {
-        source: selector(#scroller);
-        orientation: inline;
-      }
-    }
-  )CSS");
-  StyleSheetKey key("user");
-  GetStyleEngine().InjectSheet(key, user_sheet, WebCssOrigin::kUser);
-
-  GetDocument().body()->setInnerHTML(R"HTML(
-    <style>
-      @scroll-timeline timeline {
-        source: selector(#scroller);
-        orientation: block;
-      }
-
-      #target {
-        animation: expand 10s linear;
-        animation-timeline: timeline;
-        height: 100px;
-      }
-    </style>
-    <div id=scroller><div id=scroll-contents></div></div>
-    <div id=target></div>
-  )HTML");
-
-  Element* scroller = GetDocument().getElementById("scroller");
-  scroller->setScrollTop(25);
-  UpdateAllLifecyclePhases();
-
-  // User-defined scroll timelines should not override author-defined
-  // scroll timelines regardless of cascade layers.
-  Element* target = GetDocument().getElementById("target");
-  EXPECT_EQ(125, target->OffsetWidth());
-}
-
 TEST_F(StyleEngineSimTest, UserFontFaceOverrideWithCascadeLayers) {
   SimRequest main_resource("https://example.com", "text/html");
   SimSubresourceRequest ahem_resource("https://example.com/ahem.woff2",
diff --git a/third_party/blink/renderer/core/css/style_rule.cc b/third_party/blink/renderer/core/css/style_rule.cc
index f52bcf4..d3085c9 100644
--- a/third_party/blink/renderer/core/css/style_rule.cc
+++ b/third_party/blink/renderer/core/css/style_rule.cc
@@ -37,7 +37,6 @@
 #include "third_party/blink/renderer/core/css/css_position_fallback_rule.h"
 #include "third_party/blink/renderer/core/css/css_property_rule.h"
 #include "third_party/blink/renderer/core/css/css_scope_rule.h"
-#include "third_party/blink/renderer/core/css/css_scroll_timeline_rule.h"
 #include "third_party/blink/renderer/core/css/css_style_rule.h"
 #include "third_party/blink/renderer/core/css/css_supports_rule.h"
 #include "third_party/blink/renderer/core/css/css_try_rule.h"
@@ -97,9 +96,6 @@
     case kMedia:
       To<StyleRuleMedia>(this)->TraceAfterDispatch(visitor);
       return;
-    case kScrollTimeline:
-      To<StyleRuleScrollTimeline>(this)->TraceAfterDispatch(visitor);
-      return;
     case kScope:
       To<StyleRuleScope>(this)->TraceAfterDispatch(visitor);
       return;
@@ -166,9 +162,6 @@
     case kMedia:
       To<StyleRuleMedia>(this)->~StyleRuleMedia();
       return;
-    case kScrollTimeline:
-      To<StyleRuleScrollTimeline>(this)->~StyleRuleScrollTimeline();
-      return;
     case kScope:
       To<StyleRuleScope>(this)->~StyleRuleScope();
       return;
@@ -226,8 +219,6 @@
       return To<StyleRuleFontPaletteValues>(this)->Copy();
     case kMedia:
       return To<StyleRuleMedia>(this)->Copy();
-    case kScrollTimeline:
-      return To<StyleRuleScrollTimeline>(this)->Copy();
     case kScope:
       return To<StyleRuleScope>(this)->Copy();
     case kSupports:
@@ -294,10 +285,6 @@
       rule = MakeGarbageCollected<CSSMediaRule>(To<StyleRuleMedia>(self),
                                                 parent_sheet);
       break;
-    case kScrollTimeline:
-      rule = MakeGarbageCollected<CSSScrollTimelineRule>(
-          To<StyleRuleScrollTimeline>(self), parent_sheet);
-      break;
     case kScope:
       rule = MakeGarbageCollected<CSSScopeRule>(To<StyleRuleScope>(self),
                                                 parent_sheet);
@@ -520,28 +507,6 @@
   StyleRuleBase::TraceAfterDispatch(visitor);
 }
 
-StyleRuleScrollTimeline::StyleRuleScrollTimeline(
-    const String& name,
-    const CSSPropertyValueSet* properties)
-    : StyleRuleBase(kScrollTimeline),
-      name_(name),
-      source_(properties->GetPropertyCSSValue(CSSPropertyID::kSource)),
-      orientation_(
-          properties->GetPropertyCSSValue(CSSPropertyID::kOrientation)),
-      start_(properties->GetPropertyCSSValue(CSSPropertyID::kStart)),
-      end_(properties->GetPropertyCSSValue(CSSPropertyID::kEnd)) {}
-
-void StyleRuleScrollTimeline::TraceAfterDispatch(
-    blink::Visitor* visitor) const {
-  visitor->Trace(source_);
-  visitor->Trace(orientation_);
-  visitor->Trace(start_);
-  visitor->Trace(end_);
-  visitor->Trace(layer_);
-
-  StyleRuleBase::TraceAfterDispatch(visitor);
-}
-
 StyleRuleScope::StyleRuleScope(const StyleScope& style_scope,
                                HeapVector<Member<StyleRuleBase>>& adopt_rules)
     : StyleRuleGroup(kScope, adopt_rules), style_scope_(&style_scope) {}
diff --git a/third_party/blink/renderer/core/css/style_rule.h b/third_party/blink/renderer/core/css/style_rule.h
index d56a0002..62e4c8d 100644
--- a/third_party/blink/renderer/core/css/style_rule.h
+++ b/third_party/blink/renderer/core/css/style_rule.h
@@ -62,7 +62,6 @@
     kContainer,
     kCounterStyle,
     kScope,
-    kScrollTimeline,
     kSupports,
     kViewport,
     kPositionFallback,
@@ -94,7 +93,6 @@
   bool IsPropertyRule() const { return GetType() == kProperty; }
   bool IsStyleRule() const { return GetType() == kStyle; }
   bool IsScopeRule() const { return GetType() == kScope; }
-  bool IsScrollTimelineRule() const { return GetType() == kScrollTimeline; }
   bool IsSupportsRule() const { return GetType() == kSupports; }
   bool IsViewportRule() const { return GetType() == kViewport; }
   bool IsImportRule() const { return GetType() == kImport; }
@@ -345,35 +343,6 @@
   Member<const CascadeLayer> layer_;
 };
 
-class CORE_EXPORT StyleRuleScrollTimeline : public StyleRuleBase {
- public:
-  StyleRuleScrollTimeline(const String& name, const CSSPropertyValueSet*);
-  StyleRuleScrollTimeline(const StyleRuleScrollTimeline&) = default;
-
-  StyleRuleScrollTimeline* Copy() const {
-    return MakeGarbageCollected<StyleRuleScrollTimeline>(*this);
-  }
-
-  void TraceAfterDispatch(blink::Visitor*) const;
-
-  const AtomicString& GetName() const { return name_; }
-  const CSSValue* GetSource() const { return source_; }
-  const CSSValue* GetOrientation() const { return orientation_; }
-  const CSSValue* GetStart() const { return start_; }
-  const CSSValue* GetEnd() const { return end_; }
-
-  void SetCascadeLayer(const CascadeLayer* layer) { layer_ = layer; }
-  const CascadeLayer* GetCascadeLayer() const { return layer_; }
-
- private:
-  AtomicString name_;
-  Member<const CSSValue> source_;
-  Member<const CSSValue> orientation_;
-  Member<const CSSValue> start_;
-  Member<const CSSValue> end_;
-  Member<const CascadeLayer> layer_;
-};
-
 class CORE_EXPORT StyleRuleGroup : public StyleRuleBase {
  public:
   const HeapVector<Member<StyleRuleBase>>& ChildRules() const {
@@ -590,13 +559,6 @@
 };
 
 template <>
-struct DowncastTraits<StyleRuleScrollTimeline> {
-  static bool AllowFrom(const StyleRuleBase& rule) {
-    return rule.IsScrollTimelineRule();
-  }
-};
-
-template <>
 struct DowncastTraits<StyleRuleScope> {
   static bool AllowFrom(const StyleRuleBase& rule) {
     return rule.IsScopeRule();
diff --git a/third_party/blink/renderer/core/css/style_rule_test.cc b/third_party/blink/renderer/core/css/style_rule_test.cc
index 157c00a4..9be871b5 100644
--- a/third_party/blink/renderer/core/css/style_rule_test.cc
+++ b/third_party/blink/renderer/core/css/style_rule_test.cc
@@ -12,67 +12,6 @@
 
 class StyleRuleTest : public PageTestBase {};
 
-// Verifies that a StyleRuleScrollTimeline can be accessed even if
-// the runtime flag CSSScrollTimeline is disabled.
-//
-// Note that this test can be removed when the CSSScrollTimeline flag is
-// removed.
-TEST_F(StyleRuleTest, StyleRuleScrollTimelineGettersWithoutFeature) {
-  ScopedCSSScrollTimelineForTest scoped_disable_feature(false);
-
-  StyleRuleBase* base_rule = nullptr;
-
-  {
-    ScopedCSSScrollTimelineForTest scoped_enable_feature(true);
-    base_rule = css_test_helpers::ParseRule(GetDocument(), R"CSS(
-        @scroll-timeline timeline {
-          source: selector(#foo);
-          start: 1px;
-          end: 2px;
-        }
-      )CSS");
-  }
-
-  ASSERT_TRUE(base_rule);
-  const auto* rule = To<StyleRuleScrollTimeline>(base_rule);
-
-  // Don't crash:
-  EXPECT_FALSE(rule->GetName().IsEmpty());
-  EXPECT_TRUE(rule->GetSource());
-  EXPECT_TRUE(rule->GetStart());
-  EXPECT_TRUE(rule->GetEnd());
-}
-
-TEST_F(StyleRuleTest, StyleRuleScrollTimelineCopy) {
-  ScopedCSSScrollTimelineForTest scoped_feature(true);
-
-  auto* base_rule = css_test_helpers::ParseRule(GetDocument(), R"CSS(
-      @scroll-timeline timeline {
-        source: selector(#foo);
-        start: 1px;
-        end: 2px;
-      }
-    )CSS");
-
-  ASSERT_TRUE(base_rule);
-  auto* base_copy = base_rule->Copy();
-
-  EXPECT_NE(base_rule, base_copy);
-  EXPECT_EQ(base_rule->GetType(), base_copy->GetType());
-
-  auto* rule = DynamicTo<StyleRuleScrollTimeline>(base_rule);
-  auto* copy = DynamicTo<StyleRuleScrollTimeline>(base_copy);
-
-  ASSERT_TRUE(rule);
-  ASSERT_TRUE(copy);
-
-  EXPECT_EQ(rule->GetName(), copy->GetName());
-  EXPECT_EQ(rule->GetSource(), copy->GetSource());
-  EXPECT_EQ(rule->GetOrientation(), copy->GetOrientation());
-  EXPECT_EQ(rule->GetStart(), copy->GetStart());
-  EXPECT_EQ(rule->GetEnd(), copy->GetEnd());
-}
-
 TEST_F(StyleRuleTest, StyleRulePropertyCopy) {
   auto* base_rule = css_test_helpers::ParseRule(GetDocument(), R"CSS(
       @property --foo {
diff --git a/third_party/blink/renderer/core/css/style_sheet_contents.cc b/third_party/blink/renderer/core/css/style_sheet_contents.cc
index dc7acf7..1cf3115 100644
--- a/third_party/blink/renderer/core/css/style_sheet_contents.cc
+++ b/third_party/blink/renderer/core/css/style_sheet_contents.cc
@@ -597,7 +597,6 @@
       case StyleRuleBase::kKeyframes:
       case StyleRuleBase::kKeyframe:
       case StyleRuleBase::kLayerStatement:
-      case StyleRuleBase::kScrollTimeline:
       case StyleRuleBase::kSupports:
       case StyleRuleBase::kViewport:
       case StyleRuleBase::kFontPaletteValues:
diff --git a/third_party/blink/renderer/core/frame/frame_serializer.cc b/third_party/blink/renderer/core/frame/frame_serializer.cc
index ca21cbe..c71cd987 100644
--- a/third_party/blink/renderer/core/frame/frame_serializer.cc
+++ b/third_party/blink/renderer/core/frame/frame_serializer.cc
@@ -460,7 +460,6 @@
     case CSSRule::kPropertyRule:
     case CSSRule::kKeyframesRule:
     case CSSRule::kKeyframeRule:
-    case CSSRule::kScrollTimelineRule:
     case CSSRule::kNamespaceRule:
     case CSSRule::kViewportRule:
     case CSSRule::kLayerStatementRule:
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc
index da5775f..bb0d971 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.cc
+++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -4111,6 +4111,8 @@
   if (!speech_synthesis_) {
     speech_synthesis_ =
         SpeechSynthesisBase::Create(*(GetDocument().domWindow()));
+    speech_synthesis_->SetOnSpeakingCompletedCallback(WTF::BindRepeating(
+        &HTMLMediaElement::OnSpeakingCompleted, WrapWeakPersistent(this)));
   }
   return speech_synthesis_;
 }
@@ -4337,6 +4339,11 @@
       GetDocument().GetTaskRunner(TaskType::kInternalMedia));
 }
 
+void HTMLMediaElement::OnSpeakingCompleted() {
+  if (paused())
+    Play();
+}
+
 void HTMLMediaElement::Trace(Visitor* visitor) const {
   visitor->Trace(audio_source_node_);
   visitor->Trace(speech_synthesis_);
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.h b/third_party/blink/renderer/core/html/media/html_media_element.h
index 971bd46..0caf69d40 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.h
+++ b/third_party/blink/renderer/core/html/media/html_media_element.h
@@ -507,6 +507,10 @@
   virtual void OnLoadStarted() {}
   virtual void OnLoadFinished() {}
 
+  // Handles playing of media element when audio descriptions are finished
+  // speaking.
+  void OnSpeakingCompleted();
+
   void SetShowPosterFlag(bool value);
 
   void SetReadyState(ReadyState);
diff --git a/third_party/blink/renderer/core/html/track/cue_timeline.cc b/third_party/blink/renderer/core/html/track/cue_timeline.cc
index 5224710c..dfe956d 100644
--- a/third_party/blink/renderer/core/html/track/cue_timeline.cc
+++ b/third_party/blink/renderer/core/html/track/cue_timeline.cc
@@ -359,8 +359,11 @@
       media_element.ScheduleEvent(
           CreateEventWithTarget(event_name, task.second.Get()));
       if (features::IsTextBasedAudioDescriptionEnabled()) {
-        if (is_enter_event)
+        if (is_enter_event) {
           cue->OnEnter(MediaElement());
+        } else {
+          cue->OnExit(MediaElement());
+        }
       }
     }
   }
diff --git a/third_party/blink/renderer/core/html/track/text_track_cue.h b/third_party/blink/renderer/core/html/track/text_track_cue.h
index beb666c7..e220e0bc 100644
--- a/third_party/blink/renderer/core/html/track/text_track_cue.h
+++ b/third_party/blink/renderer/core/html/track/text_track_cue.h
@@ -81,10 +81,11 @@
   // already been added.
   virtual void UpdateDisplay(HTMLDivElement& container) = 0;
 
-  // Called when entering the cue on the timeline in cue_timeline.cc
-  // (cf. the 'enter' event). Handles enter event behavior
+  // Called when entering or exiting the cue on the timeline in cue_timeline.cc
+  // (cf. the 'enter' and 'exit' events). Handles enter and exit event behavior
   // for spoken cues.
   virtual void OnEnter(HTMLMediaElement& video) = 0;
+  virtual void OnExit(HTMLMediaElement& video) = 0;
 
   // Marks the nodes of the display tree as past or future relative to
   // movieTime. If |updateDisplay| has not been called there is no display
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc b/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc
index 378f1f3c..c9e5f3a 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc
@@ -753,6 +753,13 @@
   video.SpeechSynthesis()->Speak(text_);
 }
 
+void VTTCue::OnExit(HTMLMediaElement& video) {
+  if (!track()->IsSpokenKind())
+    return;
+  if (video.SpeechSynthesis()->Speaking())
+    video.pause();
+}
+
 void VTTCue::UpdateDisplay(HTMLDivElement& container) {
   DCHECK(track() && track()->IsRendered() && IsActive());
 
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h b/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h
index c14abdd4..660d126 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h
@@ -136,7 +136,12 @@
 
   DocumentFragment* getCueAsHTML();
 
+  // Handles the entrance and exit of cues for description-tagged tracks.
+  // OnEnter begins speaking the cue. OnExit pauses the video to let the
+  // description finish, if the cue is still being spoken at the specified end
+  // time.
   void OnEnter(HTMLMediaElement& video) override;
+  void OnExit(HTMLMediaElement& video) override;
 
   void UpdateDisplay(HTMLDivElement& container) override;
 
diff --git a/third_party/blink/renderer/core/speech/speech_synthesis_base.cc b/third_party/blink/renderer/core/speech/speech_synthesis_base.cc
index f962758..b58d461b 100644
--- a/third_party/blink/renderer/core/speech/speech_synthesis_base.cc
+++ b/third_party/blink/renderer/core/speech/speech_synthesis_base.cc
@@ -21,4 +21,14 @@
   return create_function_(window);
 }
 
+void SpeechSynthesisBase::SetOnSpeakingCompletedCallback(
+    OnSpeakingCompletedCallback callback) {
+  on_speaking_completed_callback_ = std::move(callback);
+}
+
+void SpeechSynthesisBase::HandleSpeakingCompleted() {
+  if (!on_speaking_completed_callback_.is_null())
+    on_speaking_completed_callback_.Run();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/speech/speech_synthesis_base.h b/third_party/blink/renderer/core/speech/speech_synthesis_base.h
index 14d33f9..fef81b1 100644
--- a/third_party/blink/renderer/core/speech/speech_synthesis_base.h
+++ b/third_party/blink/renderer/core/speech/speech_synthesis_base.h
@@ -16,6 +16,8 @@
 // in /core. /core is where all audio description handling occurs.
 class CORE_EXPORT SpeechSynthesisBase : public GarbageCollectedMixin {
  public:
+  using OnSpeakingCompletedCallback = base::RepeatingCallback<void()>;
+
   SpeechSynthesisBase(const SpeechSynthesisBase&) = delete;
   SpeechSynthesisBase& operator=(const SpeechSynthesisBase&) = delete;
   ~SpeechSynthesisBase() = default;
@@ -41,6 +43,15 @@
   // Overridden in speech_synthesis.cc.
   virtual void Speak(const String& text) = 0;
   virtual void Cancel() = 0;
+  virtual void Pause() = 0;
+  virtual void Resume() = 0;
+  virtual bool Speaking() const = 0;
+
+  void SetOnSpeakingCompletedCallback(OnSpeakingCompletedCallback callback);
+
+  // Calls on_speaking_completed_callback_ when audio description is finished
+  // speaking. Run in SpeechSynthesis::HandleSpeakingCompleted.
+  void HandleSpeakingCompleted();
 
  protected:
   SpeechSynthesisBase() = default;
@@ -49,6 +60,9 @@
   // Creates a SpeechSynthesis object returned as type SpeechSynthesisBase for
   // use in /core.
   static SpeechSynthesisBaseCreateFunction create_function_;
+
+  // Restarts the video once if it was paused by VTTCue::OnExit.
+  OnSpeakingCompletedCallback on_speaking_completed_callback_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/breakout_box/pushable_media_stream_audio_source.cc b/third_party/blink/renderer/modules/breakout_box/pushable_media_stream_audio_source.cc
index 827fdd6..e91edf8 100644
--- a/third_party/blink/renderer/modules/breakout_box/pushable_media_stream_audio_source.cc
+++ b/third_party/blink/renderer/modules/breakout_box/pushable_media_stream_audio_source.cc
@@ -135,9 +135,10 @@
       params.format() != media::AudioParameters::AUDIO_PCM_LOW_LATENCY ||
       last_channels_ != channel_count || last_sample_rate_ != sample_rate ||
       last_frames_ != frame_count) {
-    SetFormat(media::AudioParameters(
-        media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-        media::GuessChannelLayout(channel_count), sample_rate, frame_count));
+    SetFormat(
+        media::AudioParameters(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
+                               media::ChannelLayoutConfig::Guess(channel_count),
+                               sample_rate, frame_count));
     last_channels_ = channel_count;
     last_sample_rate_ = sample_rate;
     last_frames_ = frame_count;
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc
index c62496ce..37c0b54 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc
+++ b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc
@@ -512,26 +512,6 @@
   return nullptr;
 }
 
-// Abort an ongoing PublicKeyCredential create() or get() operation.
-void AbortPublicKeyRequest(ScriptState* script_state) {
-  if (!script_state->ContextIsValid())
-    return;
-
-  auto* authenticator =
-      CredentialManagerProxy::From(script_state)->Authenticator();
-  authenticator->Cancel();
-}
-
-// Abort an ongoing OtpCredential get() operation.
-void AbortOtpRequest(ScriptState* script_state) {
-  if (!script_state->ContextIsValid())
-    return;
-
-  auto* webotp_service =
-      CredentialManagerProxy::From(script_state)->WebOTPService();
-  webotp_service->Abort();
-}
-
 // Abort an ongoing FederatedCredential login() operation.
 void AbortIdentityCredentialRequest(ScriptState* script_state) {
   if (!script_state->ContextIsValid())
@@ -630,6 +610,7 @@
 
 void OnMakePublicKeyCredentialComplete(
     std::unique_ptr<ScopedPromiseResolver> scoped_resolver,
+    AbortSignal* signal,
     RequiredOriginType required_origin_type,
     AuthenticatorStatus status,
     MakeCredentialAuthenticatorResponsePtr credential,
@@ -638,8 +619,14 @@
   AssertSecurityRequirementsBeforeResponse(resolver, required_origin_type);
   if (status != AuthenticatorStatus::SUCCESS) {
     DCHECK(!credential);
-    resolver->Reject(
-        AuthenticatorStatusToDOMException(status, dom_exception_details));
+    if (signal && signal->aborted()) {
+      auto* script_state = resolver->GetScriptState();
+      ScriptState::Scope script_state_scope(script_state);
+      resolver->Reject(signal->reason(script_state));
+    } else {
+      resolver->Reject(
+          AuthenticatorStatusToDOMException(status, dom_exception_details));
+    }
     return;
   }
   DCHECK(credential);
@@ -715,6 +702,7 @@
 
 void OnSaveCredentialIdForPaymentExtension(
     std::unique_ptr<ScopedPromiseResolver> scoped_resolver,
+    AbortSignal* signal,
     MakeCredentialAuthenticatorResponsePtr credential,
     PaymentCredentialStorageStatus storage_status) {
   auto status = AuthenticatorStatus::SUCCESS;
@@ -724,13 +712,14 @@
     credential = nullptr;
   }
   OnMakePublicKeyCredentialComplete(
-      std::move(scoped_resolver),
+      std::move(scoped_resolver), signal,
       RequiredOriginType::kSecureWithPaymentPermissionPolicy, status,
       std::move(credential), /*dom_exception_details=*/nullptr);
 }
 
 void OnMakePublicKeyCredentialWithPaymentExtensionComplete(
     std::unique_ptr<ScopedPromiseResolver> scoped_resolver,
+    AbortSignal* signal,
     const String& rp_id_for_payment_extension,
     const WTF::Vector<uint8_t>& user_id_for_payment_extension,
     AuthenticatorStatus status,
@@ -743,8 +732,14 @@
   AssertSecurityRequirementsBeforeResponse(resolver, required_origin_type);
   if (status != AuthenticatorStatus::SUCCESS) {
     DCHECK(!credential);
-    resolver->Reject(
-        AuthenticatorStatusToDOMException(status, dom_exception_details));
+    if (signal && signal->aborted()) {
+      auto* script_state = resolver->GetScriptState();
+      ScriptState::Scope script_state_scope(script_state);
+      resolver->Reject(signal->reason(script_state));
+    } else {
+      resolver->Reject(
+          AuthenticatorStatusToDOMException(status, dom_exception_details));
+    }
     return;
   }
 
@@ -757,11 +752,12 @@
       std::move(user_id_for_payment_extension),
       WTF::Bind(&OnSaveCredentialIdForPaymentExtension,
                 std::make_unique<ScopedPromiseResolver>(resolver),
-                std::move(credential)));
+                WrapPersistent(signal), std::move(credential)));
 }
 
 void OnGetAssertionComplete(
     std::unique_ptr<ScopedPromiseResolver> scoped_resolver,
+    AbortSignal* signal,
     AuthenticatorStatus status,
     GetAssertionAuthenticatorResponsePtr credential,
     WebAuthnDOMExceptionDetailsPtr dom_exception_details) {
@@ -831,11 +827,18 @@
     return;
   }
   DCHECK(!credential);
-  resolver->Reject(
-      AuthenticatorStatusToDOMException(status, dom_exception_details));
+  if (signal && signal->aborted()) {
+    auto* script_state = resolver->GetScriptState();
+    ScriptState::Scope script_state_scope(script_state);
+    resolver->Reject(signal->reason(script_state));
+  } else {
+    resolver->Reject(
+        AuthenticatorStatusToDOMException(status, dom_exception_details));
+  }
 }
 
 void OnSmsReceive(ScriptPromiseResolver* resolver,
+                  AbortSignal* signal,
                   base::TimeTicks start_time,
                   mojom::blink::SmsStatus status,
                   const String& otp) {
@@ -852,8 +855,14 @@
     return;
   }
   if (status == mojom::blink::SmsStatus::kAborted) {
-    resolver->Reject(MakeGarbageCollected<DOMException>(
-        DOMExceptionCode::kAbortError, "OTP retrieval was aborted."));
+    if (signal && signal->aborted()) {
+      auto* script_state = resolver->GetScriptState();
+      ScriptState::Scope script_state_scope(script_state);
+      resolver->Reject(signal->reason(script_state));
+    } else {
+      resolver->Reject(MakeGarbageCollected<DOMException>(
+          DOMExceptionCode::kAbortError, "OTP retrieval was aborted."));
+    }
     return;
   }
   if (status == mojom::blink::SmsStatus::kCancelled) {
@@ -947,6 +956,58 @@
 
 const char CredentialsContainer::kSupplementName[] = "CredentialsContainer";
 
+class CredentialsContainer::OtpRequestAbortAlgorithm final
+    : public AbortSignal::Algorithm {
+ public:
+  explicit OtpRequestAbortAlgorithm(ScriptState* script_state)
+      : script_state_(script_state) {}
+  ~OtpRequestAbortAlgorithm() override = default;
+
+  // Abort an ongoing OtpCredential get() operation.
+  void Run() override {
+    if (!script_state_->ContextIsValid())
+      return;
+
+    auto* webotp_service =
+        CredentialManagerProxy::From(script_state_)->WebOTPService();
+    webotp_service->Abort();
+  }
+
+  void Trace(Visitor* visitor) const override {
+    visitor->Trace(script_state_);
+    Algorithm::Trace(visitor);
+  }
+
+ private:
+  Member<ScriptState> script_state_;
+};
+
+class CredentialsContainer::PublicKeyRequestAbortAlgorithm final
+    : public AbortSignal::Algorithm {
+ public:
+  explicit PublicKeyRequestAbortAlgorithm(ScriptState* script_state)
+      : script_state_(script_state) {}
+  ~PublicKeyRequestAbortAlgorithm() override = default;
+
+  // Abort an ongoing PublicKeyCredential create() or get() operation.
+  void Run() override {
+    if (!script_state_->ContextIsValid())
+      return;
+
+    auto* authenticator =
+        CredentialManagerProxy::From(script_state_)->Authenticator();
+    authenticator->Cancel();
+  }
+
+  void Trace(Visitor* visitor) const override {
+    visitor->Trace(script_state_);
+    Algorithm::Trace(visitor);
+  }
+
+ private:
+  Member<ScriptState> script_state_;
+};
+
 CredentialsContainer* CredentialsContainer::credentials(Navigator& navigator) {
   CredentialsContainer* credentials =
       Supplement<Navigator>::From<CredentialsContainer>(navigator);
@@ -1112,14 +1173,14 @@
               "Ignoring unknown publicKey.userVerification value"));
     }
 
-    if (options->hasSignal()) {
-      if (options->signal()->aborted()) {
-        resolver->Reject(MakeGarbageCollected<DOMException>(
-            DOMExceptionCode::kAbortError, "Request has been aborted."));
+    auto* signal = options->getSignalOr(nullptr);
+    if (signal) {
+      if (signal->aborted()) {
+        resolver->Reject(signal->reason(script_state));
         return promise;
       }
-      options->signal()->AddAlgorithm(
-          WTF::Bind(&AbortPublicKeyRequest, WrapPersistent(script_state)));
+      signal->AddAlgorithm(
+          MakeGarbageCollected<PublicKeyRequestAbortAlgorithm>(script_state));
     }
 
     bool is_conditional_ui_request =
@@ -1146,7 +1207,8 @@
       authenticator->GetAssertion(
           std::move(mojo_options),
           WTF::Bind(&OnGetAssertionComplete,
-                    std::make_unique<ScopedPromiseResolver>(resolver)));
+                    std::make_unique<ScopedPromiseResolver>(resolver),
+                    WrapPersistent(signal)));
     } else {
       resolver->Reject(MakeGarbageCollected<DOMException>(
           DOMExceptionCode::kNotSupportedError,
@@ -1163,19 +1225,20 @@
       return promise;
     }
 
-    if (options->hasSignal()) {
-      if (options->signal()->aborted()) {
-        resolver->Reject(MakeGarbageCollected<DOMException>(
-            DOMExceptionCode::kAbortError, "Request has been aborted."));
+    auto* signal = options->getSignalOr(nullptr);
+    if (signal) {
+      if (signal->aborted()) {
+        resolver->Reject(signal->reason(script_state));
         return promise;
       }
-      options->signal()->AddAlgorithm(
-          WTF::Bind(&AbortOtpRequest, WrapPersistent(script_state)));
+      signal->AddAlgorithm(
+          MakeGarbageCollected<OtpRequestAbortAlgorithm>(script_state));
     }
 
     auto* webotp_service =
         CredentialManagerProxy::From(script_state)->WebOTPService();
     webotp_service->Receive(WTF::Bind(&OnSmsReceive, WrapPersistent(resolver),
+                                      WrapPersistent(signal),
                                       base::TimeTicks::Now()));
 
     UseCounter::Count(context, WebFeature::kWebOTP);
@@ -1516,14 +1579,14 @@
     }
   }
 
-  if (options->hasSignal()) {
-    if (options->signal()->aborted()) {
-      resolver->Reject(MakeGarbageCollected<DOMException>(
-          DOMExceptionCode::kAbortError, "Request has been aborted."));
+  auto* signal = options->getSignalOr(nullptr);
+  if (signal) {
+    if (signal->aborted()) {
+      resolver->Reject(signal->reason(script_state));
       return promise;
     }
-    options->signal()->AddAlgorithm(
-        WTF::Bind(&AbortPublicKeyRequest, WrapPersistent(script_state)));
+    signal->AddAlgorithm(
+        MakeGarbageCollected<PublicKeyRequestAbortAlgorithm>(script_state));
   }
 
   if (options->publicKey()->hasAttestation() &&
@@ -1642,14 +1705,14 @@
           std::move(mojo_options),
           WTF::Bind(&OnMakePublicKeyCredentialWithPaymentExtensionComplete,
                     std::make_unique<ScopedPromiseResolver>(resolver),
-                    rp_id_for_payment_extension,
+                    WrapPersistent(signal), rp_id_for_payment_extension,
                     std::move(user_id_for_payment_extension)));
     } else {
       authenticator->MakeCredential(
           std::move(mojo_options),
           WTF::Bind(&OnMakePublicKeyCredentialComplete,
                     std::make_unique<ScopedPromiseResolver>(resolver),
-                    required_origin_type));
+                    WrapPersistent(signal), required_origin_type));
     }
   }
 
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.h b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.h
index 86ee9e87..395c6736 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.h
+++ b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.h
@@ -40,6 +40,10 @@
   ScriptPromise preventSilentAccess(ScriptState*);
 
   void Trace(Visitor*) const override;
+
+ private:
+  class OtpRequestAbortAlgorithm;
+  class PublicKeyRequestAbortAlgorithm;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/speech/speech_synthesis.cc b/third_party/blink/renderer/modules/speech/speech_synthesis.cc
index dba51b2..9478154 100644
--- a/third_party/blink/renderer/modules/speech/speech_synthesis.cc
+++ b/third_party/blink/renderer/modules/speech/speech_synthesis.cc
@@ -128,7 +128,7 @@
       .Record(GetSupplementable()->UkmRecorder());
 }
 
-bool SpeechSynthesis::speaking() const {
+bool SpeechSynthesis::Speaking() const {
   // If we have a current speech utterance, then that means we're assumed to be
   // in a speaking state. This state is independent of whether the utterance
   // happens to be paused.
@@ -190,7 +190,7 @@
     mojom_synthesis->Cancel();
 }
 
-void SpeechSynthesis::pause() {
+void SpeechSynthesis::Pause() {
   if (is_paused_)
     return;
 
@@ -199,7 +199,7 @@
     mojom_synthesis->Pause();
 }
 
-void SpeechSynthesis::resume() {
+void SpeechSynthesis::Resume() {
   if (!CurrentSpeechUtterance())
     return;
 
@@ -273,6 +273,9 @@
     bool error_occurred) {
   DCHECK(utterance);
 
+  // Special handling for audio descriptions.
+  SpeechSynthesisBase::HandleSpeakingCompleted();
+
   bool should_start_speaking = false;
   // If the utterance that completed was the one we're currently speaking,
   // remove it from the queue and start speaking the next one.
diff --git a/third_party/blink/renderer/modules/speech/speech_synthesis.h b/third_party/blink/renderer/modules/speech/speech_synthesis.h
index e87e8c88..257ad51 100644
--- a/third_party/blink/renderer/modules/speech/speech_synthesis.h
+++ b/third_party/blink/renderer/modules/speech/speech_synthesis.h
@@ -62,17 +62,20 @@
   explicit SpeechSynthesis(LocalDOMWindow&);
 
   bool pending() const;
-  bool speaking() const;
+  bool speaking() const { return Speaking(); }
   bool paused() const;
 
   // SpeechSynthesisBase
   void Speak(const String&) override;
   void Cancel() override;
+  void Pause() override;
+  void Resume() override;
+  bool Speaking() const override;
 
   void speak(ScriptState*, SpeechSynthesisUtterance*);
   void cancel() { Cancel(); }
-  void pause();
-  void resume();
+  void pause() { Pause(); }
+  void resume() { Resume(); }
 
   const HeapVector<Member<SpeechSynthesisVoice>>& getVoices();
 
diff --git a/third_party/blink/renderer/platform/image-decoders/jxl/jxl_image_decoder.cc b/third_party/blink/renderer/platform/image-decoders/jxl/jxl_image_decoder.cc
index 73660d22..588b963 100644
--- a/third_party/blink/renderer/platform/image-decoders/jxl/jxl_image_decoder.cc
+++ b/third_party/blink/renderer/platform/image-decoders/jxl/jxl_image_decoder.cc
@@ -153,25 +153,23 @@
   }
 
   DCHECK_LE(num_decoded_frames_, frame_buffer_cache_.size());
+
   if (num_decoded_frames_ > index &&
       frame_buffer_cache_[index].GetStatus() == ImageFrame::kFrameComplete) {
     // Frame already complete
     return;
   }
+
   if ((index < num_decoded_frames_) && dec_) {
     // An animation frame that already has been decoded, but does not have
-    // status ImageFrame::kFrameComplete, was requested.
-    // This can mean two things:
-    // (1) an earlier animation frame was purged but is to be re-decoded now.
-    // Rewind the decoder and skip to the requested frame.
-    // (2) During progressive decoding the frame has the status
-    // ImageFrame::kFramePartial.
+    // status ImageFrame::kFrameComplete, was requested. This means an earlier
+    // animation frame was purged but is to be re-decoded now. Rewind the
+    // decoder and skip to the requested frame.
     JxlDecoderRewind(dec_.get());
     offset_ = 0;
     // No longer subscribe to JXL_DEC_BASIC_INFO or JXL_DEC_COLOR_ENCODING.
     if (JXL_DEC_SUCCESS !=
-        JxlDecoderSubscribeEvents(
-            dec_.get(), JXL_DEC_FULL_IMAGE | JXL_DEC_FRAME_PROGRESSION)) {
+        JxlDecoderSubscribeEvents(dec_.get(), JXL_DEC_FULL_IMAGE)) {
       SetFailed();
       return;
     }
@@ -183,18 +181,13 @@
     dec_ = JxlDecoderMake(nullptr);
     // Subscribe to color encoding event even when only getting size, because
     // SetSize must be called after SetEmbeddedColorProfile
-    const int events = JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING |
-                       JXL_DEC_FULL_IMAGE | JXL_DEC_FRAME_PROGRESSION;
+    const int events =
+        JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING | JXL_DEC_FULL_IMAGE;
 
     if (JXL_DEC_SUCCESS != JxlDecoderSubscribeEvents(dec_.get(), events)) {
       SetFailed();
       return;
     }
-    if (JXL_DEC_SUCCESS !=
-        JxlDecoderSetProgressiveDetail(dec_.get(), JxlProgressiveDetail::kDC)) {
-      SetFailed();
-      return;
-    }
   } else {
     offset_ -= JxlDecoderReleaseInput(dec_.get());
   }
@@ -230,23 +223,6 @@
         size_t jxl_size = 0;
         if (!ReadBytes(remaining, &offset_, &segment_, &reader, &jxl_data,
                        &jxl_size)) {
-          if (IsAllDataReceived()) {
-            // Happens only if a partial image file was transferred, otherwise
-            // status will be JXL_DEC_FULL_IMAGE or JXL_DEC_SUCCESS. In
-            // this case we flush one more time in order to get the progressive
-            // image plus everything known so far. The progressive image was not
-            // flushed when status was JXL_DEC_FRAME_PROGRESSION because all
-            // data seemed to have been received (not knowing then that it was
-            // only a partial file).
-            if (JXL_DEC_SUCCESS != JxlDecoderFlushImage(dec_.get())) {
-              DVLOG(1) << "JxlDecoderSetImageOutCallback failed";
-              SetFailed();
-              return;
-            }
-            ImageFrame& frame = frame_buffer_cache_[num_decoded_frames_ - 1];
-            frame.SetPixelsChanged(true);
-            frame.SetStatus(ImageFrame::kFramePartial);
-          }
           return;
         }
 
@@ -492,21 +468,6 @@
         }
         break;
       }
-      case JXL_DEC_FRAME_PROGRESSION: {
-        if (IsAllDataReceived()) {
-          break;
-        } else {
-          if (JXL_DEC_SUCCESS != JxlDecoderFlushImage(dec_.get())) {
-            DVLOG(1) << "JxlDecoderSetImageOutCallback failed";
-            SetFailed();
-            return;
-          }
-          ImageFrame& frame = frame_buffer_cache_[num_decoded_frames_ - 1];
-          frame.SetPixelsChanged(true);
-          frame.SetStatus(ImageFrame::kFramePartial);
-          break;
-        }
-      }
       case JXL_DEC_FULL_IMAGE: {
         ImageFrame& frame = frame_buffer_cache_[num_decoded_frames_ - 1];
         frame.SetPixelsChanged(true);
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_audio_test.cc b/third_party/blink/renderer/platform/mediastream/media_stream_audio_test.cc
index 2d7b4c0b..5212590d 100644
--- a/third_party/blink/renderer/platform/mediastream/media_stream_audio_test.cc
+++ b/third_party/blink/renderer/platform/mediastream/media_stream_audio_test.cc
@@ -100,7 +100,7 @@
       if (!audio_bus_ || audio_bus_->frames() != buffer_size) {
         MediaStreamAudioSource::SetFormat(media::AudioParameters(
             media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-            media::CHANNEL_LAYOUT_MONO, kSampleRate, buffer_size));
+            media::ChannelLayoutConfig::Mono(), kSampleRate, buffer_size));
         audio_bus_ = media::AudioBus::Create(1, buffer_size);
       }
 
@@ -301,8 +301,8 @@
 
   // Check that the audio parameters propagated to the track and sink.
   const media::AudioParameters expected_params(
-      media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO,
-      kSampleRate, kBufferSize);
+      media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
+      media::ChannelLayoutConfig::Mono(), kSampleRate, kBufferSize);
   EXPECT_TRUE(expected_params.Equals(track()->GetOutputFormat()));
   EXPECT_TRUE(expected_params.Equals(sink.params()));
 
@@ -365,8 +365,8 @@
   while (!sink.params().IsValid())
     base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
   const media::AudioParameters expected_params(
-      media::AudioParameters::AUDIO_PCM_LOW_LATENCY, media::CHANNEL_LAYOUT_MONO,
-      kSampleRate, kBufferSize);
+      media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
+      media::ChannelLayoutConfig::Mono(), kSampleRate, kBufferSize);
   EXPECT_TRUE(expected_params.Equals(track()->GetOutputFormat()));
   EXPECT_TRUE(expected_params.Equals(sink.params()));
 
diff --git a/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.cc b/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.cc
index 829c1f4f..bb437da 100644
--- a/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.cc
+++ b/third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.cc
@@ -44,10 +44,8 @@
   // running on.
   fifo_.Reset(sample_rate / 100);
   media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
-                                channel_layout, sample_rate,
-                                fifo_.frames_per_buffer());
-  // Take care of the discrete channel layout case.
-  params.set_channels_for_discrete(number_of_channels);
+                                {channel_layout, number_of_channels},
+                                sample_rate, fifo_.frames_per_buffer());
   MediaStreamAudioSource::SetFormat(params);
 
   if (!wrapper_bus_ || wrapper_bus_->channels() != params.channels())
diff --git a/third_party/blink/web_tests/FlagSpecificConfig b/third_party/blink/web_tests/FlagSpecificConfig
index 16feebe..97dd2336 100644
--- a/third_party/blink/web_tests/FlagSpecificConfig
+++ b/third_party/blink/web_tests/FlagSpecificConfig
@@ -16,10 +16,6 @@
     "args": ["--disable-site-isolation-trials"]
   },
   {
-    "name": "enable-back-forward-cache-same-site",
-    "args": ["--enable-features=BackForwardCache:enable_same_site/true"]
-  },
-  {
     "name": "enable-blink-heap-concurrent-marking",
     "args": ["--enable-features=BlinkHeapConcurrentMarking"]
   },
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 750171c..82ec6b8 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -6851,5 +6851,9 @@
 # TODO(crbug.com/1358147): Re-enable this test
 virtual/plz-dedicated-worker/external/wpt/resource-timing/no-entries-for-cross-origin-css-fetched-memory-cache.sub.html [ Skip ]
 
+# Disable step failure trigger flaky tests   
+crbug.com/1351571 [ Mac12-arm64 ] http/tests/devtools/persistence/automapping-bind-committed-network-sourcecode.js [ Failure Timeout Pass ]
+crbug.com/1358333 [ Mac10.15 ] external/wpt/webmessaging/event.origin.sub.htm [ Failure Pass ]
+
 # Sheriff 2022-08-31
 crbug.com/1306304 [ Mac ] plugins/multiple-plugins.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/otpcredential-get-basics.https.html b/third_party/blink/web_tests/external/wpt/credential-management/otpcredential-get-basics.https.html
index c0cac166..3907f854 100644
--- a/third_party/blink/web_tests/external/wpt/credential-management/otpcredential-get-basics.https.html
+++ b/third_party/blink/web_tests/external/wpt/credential-management/otpcredential-get-basics.https.html
@@ -66,4 +66,12 @@
     {otp: {transport: ["sms"]}, signal: signal}));
 }, 'Should abort request');
 
+promise_test(async t => {
+  const controller = new AbortController();
+  const signal = controller.signal;
+
+  controller.abort('CustomError');
+  await promise_rejects_exactly(t, 'CustomError', navigator.credentials.get(
+    {otp: {transport: ["sms"]}, signal: signal}));
+}, 'Should abort request with reason');
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https-expected.txt b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https-expected.txt
index d3dd35b..f9c50fc4 100644
--- a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https-expected.txt
@@ -5,6 +5,8 @@
 PASS Payment credential requires userVerification to be "required", not "discouraged".
 PASS Payment credential does not allow residentKey to be "discouraged".
 PASS Payment credential requires authenticatorAttachment to be "platform", not "cross-platform".
+PASS Payment credential abort without reason
+PASS Payment credential abort reason with Error
 PASS Clean up the test environment
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https.html b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https.html
index 7a370aa..b93822c 100644
--- a/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https.html
+++ b/third_party/blink/web_tests/external/wpt/secure-payment-confirmation/enrollment.https.html
@@ -41,6 +41,19 @@
       .runTest('Payment credential does not allow residentKey to be "discouraged".', "NotSupportedError");
   new CreatePaymentCredentialsTest({authenticatorAttachment: 'cross-platform'})
       .runTest('Payment credential requires authenticatorAttachment to be "platform", not "cross-platform".', "NotSupportedError");
+
+  // abort creates
+  let abortController = new AbortController();
+  abortController.abort();
+  new CreatePaymentCredentialsTest()
+      .modify("options.signal", abortController.signal)
+      .runTest("Payment credential abort without reason", "AbortError");
+
+  abortController = new AbortController();
+  abortController.abort(new Error('error'));
+  new CreatePaymentCredentialsTest()
+      .modify("options.signal", abortController.signal)
+      .runTest("Payment credential abort reason with Error", Error);
 }, {
   protocol: 'ctap2_1',
   transport: 'internal',
diff --git a/third_party/blink/web_tests/external/wpt/webauthn/createcredential-abort.https.html b/third_party/blink/web_tests/external/wpt/webauthn/createcredential-abort.https.html
new file mode 100644
index 0000000..d175e66
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webauthn/createcredential-abort.https.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebAuthn navigator.credentials.create() abort Tests</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src=helpers.js></script>
+<body></body>
+<script>
+"use strict";
+
+virtualAuthenticatorPromiseTest(async t => {
+  const abortController = new AbortController();
+  const signal = abortController.signal;
+  abortController.abort();
+  const promise = createCredential({
+    options: {
+      signal: signal,
+    }
+  });
+  return promise_rejects_dom(t, "AbortError", promise);
+}, {
+  protocol: "ctap1/u2f",
+  transport: "usb",
+  isUserConsenting: false,
+}, "navigator.credentials.create() after abort without reason");
+
+virtualAuthenticatorPromiseTest(async t => {
+  const abortController = new AbortController();
+  const signal = abortController.signal;
+  const promise = createCredential({
+    options: {
+      signal: signal,
+    }
+  });
+  abortController.abort();
+  return promise_rejects_dom(t, "AbortError", promise);
+}, {
+  protocol: "ctap1/u2f",
+  transport: "usb",
+  isUserConsenting: false,
+}, "navigator.credentials.create() before abort without reason");
+
+virtualAuthenticatorPromiseTest(async t => {
+  const abortController = new AbortController();
+  const signal = abortController.signal;
+  abortController.abort("CustomError");
+  const promise = createCredential({
+    options: {
+      signal: signal,
+    }
+  });
+  return promise_rejects_exactly(t, "CustomError", promise);
+}, {
+  protocol: "ctap1/u2f",
+  transport: "usb",
+  isUserConsenting: false,
+}, "navigator.credentials.create() after abort reason");
+
+virtualAuthenticatorPromiseTest(async t => {
+  const abortController = new AbortController();
+  const signal = abortController.signal;
+  const promise = createCredential({
+    options: {
+      signal: signal,
+    }
+  });
+  abortController.abort("CustomError");
+  return promise_rejects_exactly(t, "CustomError", promise);
+}, {
+  protocol: "ctap1/u2f",
+  transport: "usb",
+  isUserConsenting: false,
+}, "navigator.credentials.create() before abort reason");
+
+virtualAuthenticatorPromiseTest(async t => {
+  const abortController = new AbortController();
+  const signal = abortController.signal;
+  abortController.abort(new Error('error'));
+  const promise = createCredential({
+    options: {
+      signal: signal,
+    }
+  });
+  return promise_rejects_js(t, Error, promise);
+}, {
+  protocol: "ctap1/u2f",
+  transport: "usb",
+  isUserConsenting: false,
+}, "navigator.credentials.create() after abort reason with Error");
+
+virtualAuthenticatorPromiseTest(async t => {
+  const abortController = new AbortController();
+  const signal = abortController.signal;
+  const promise = createCredential({
+    options: {
+      signal: signal,
+    }
+  });
+  abortController.abort(new Error('error'));
+  return promise_rejects_js(t, Error, promise);
+}, {
+  protocol: "ctap1/u2f",
+  transport: "usb",
+  isUserConsenting: false,
+}, "navigator.credentials.create() before abort reason with Error");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/webauthn/getcredential-abort.https.html b/third_party/blink/web_tests/external/wpt/webauthn/getcredential-abort.https.html
new file mode 100644
index 0000000..958f65d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webauthn/getcredential-abort.https.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebAuthn navigator.credentials.get() abort Tests</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=helpers.js></script>
+<body></body>
+<script>
+"use strict";
+
+const getParams = {
+    publicKey: {
+        id: 'id',
+        challenge: new Uint8Array(),
+    }
+};
+
+promise_test(async t => {
+    const abortController = new AbortController();
+    abortController.abort();
+    getParams.signal = abortController.signal;
+    const promise = navigator.credentials.get(getParams);
+    return promise_rejects_dom(t, "AbortError", promise);
+}, "navigator.credentials.get() after abort without reason");
+
+promise_test(async t => {
+    const abortController = new AbortController();
+    getParams.signal = abortController.signal;
+    const promise = navigator.credentials.get(getParams);
+    abortController.abort();
+    return promise_rejects_dom(t, "AbortError", promise);
+}, "navigator.credentials.get() before abort without reason");
+
+promise_test(async t => {
+    const abortController = new AbortController();
+    abortController.abort("CustomError");
+    getParams.signal = abortController.signal;
+    const promise = navigator.credentials.get(getParams);
+    return promise_rejects_exactly(t, "CustomError", promise);
+}, "navigator.credentials.get() after abort reason");
+
+promise_test(async t => {
+    const abortController = new AbortController();
+    getParams.signal = abortController.signal;
+    const promise = navigator.credentials.get(getParams);
+    abortController.abort("CustomError");
+    return promise_rejects_exactly(t, "CustomError", promise);
+}, "navigator.credentials.get() before abort reason");
+
+promise_test(async t => {
+    const abortController = new AbortController();
+    abortController.abort(new Error('error'));
+    getParams.signal = abortController.signal;
+    const promise = navigator.credentials.get(getParams);
+    return promise_rejects_js(t, Error, promise);
+}, "navigator.credentials.get() after abort reason with Error");
+
+promise_test(async t => {
+    const abortController = new AbortController();
+    getParams.signal = abortController.signal;
+    const promise = navigator.credentials.get(getParams);
+    abortController.abort(new Error('error'));
+    return promise_rejects_js(t, Error, promise);
+}, "navigator.credentials.get() before abort reason with Error");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/webauthn/helpers.js b/third_party/blink/web_tests/external/wpt/webauthn/helpers.js
index 4fb1904b..efe3537 100644
--- a/third_party/blink/web_tests/external/wpt/webauthn/helpers.js
+++ b/third_party/blink/web_tests/external/wpt/webauthn/helpers.js
@@ -341,7 +341,7 @@
 
 function extendObject(dst, src) {
     Object.keys(src).forEach(function(key) {
-        if (isSimpleObject(src[key])) {
+        if (isSimpleObject(src[key]) && !isAbortSignal(src[key])) {
             dst[key] ||= {};
             extendObject(dst[key], src[key]);
         } else {
@@ -356,6 +356,10 @@
         !(o instanceof ArrayBuffer));
 }
 
+function isAbortSignal(o) {
+    return (o instanceof AbortSignal);
+}
+
 /**
  * CreateCredentialTest
  *
diff --git a/third_party/blink/web_tests/images/jxl/progressive-expected.png b/third_party/blink/web_tests/images/jxl/progressive-expected.png
deleted file mode 100644
index 23927820..0000000
--- a/third_party/blink/web_tests/images/jxl/progressive-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/images/jxl/progressive.html b/third_party/blink/web_tests/images/jxl/progressive.html
deleted file mode 100644
index 00cd4e4..0000000
--- a/third_party/blink/web_tests/images/jxl/progressive.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body>
-<img src="../resources/jxl/partial_cat.jxl">
-</body>
-</html>
diff --git a/third_party/blink/web_tests/images/resources/jxl/README.md b/third_party/blink/web_tests/images/resources/jxl/README.md
index 9a5d3543..b5f00e7 100644
--- a/third_party/blink/web_tests/images/resources/jxl/README.md
+++ b/third_party/blink/web_tests/images/resources/jxl/README.md
@@ -14,7 +14,6 @@
 animated.gif
 jxl/3x3.png
 jxl/3x3a.png
-cat.jpg
 ```
 Then we run:
 ```
@@ -73,7 +72,4 @@
 for i in $(seq 0 9); do J=$(printf '%03d' $i); convert -fill black -size 500x500 -font 'Courier' -pointsize 72 -gravity center label:$J $J.png; done
 convert -delay 20 *.png count.gif
 cjxl count.gif count.jxl
-
-cjxl --lossless_jpeg 0 --group_order 1 --distance 1 cat.jpg cat.jxl
-dd bs=1 count=30000 if=cat.jxl of=partial_cat.jxl
 ```
diff --git a/third_party/blink/web_tests/images/resources/jxl/cat.jxl b/third_party/blink/web_tests/images/resources/jxl/cat.jxl
deleted file mode 100644
index 8cb444cc..0000000
--- a/third_party/blink/web_tests/images/resources/jxl/cat.jxl
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/images/resources/jxl/partial_cat.jxl b/third_party/blink/web_tests/images/resources/jxl/partial_cat.jxl
deleted file mode 100644
index 065cf1f..0000000
--- a/third_party/blink/web_tests/images/resources/jxl/partial_cat.jxl
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/images/jxl/progressive-expected.png b/third_party/blink/web_tests/platform/linux/images/jxl/progressive-expected.png
deleted file mode 100644
index 23927820..0000000
--- a/third_party/blink/web_tests/platform/linux/images/jxl/progressive-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/jxl/progressive-expected.png b/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/jxl/progressive-expected.png
deleted file mode 100644
index 502e198..0000000
--- a/third_party/blink/web_tests/platform/linux/virtual/exotic-color-space/images/jxl/progressive-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/gpu-rasterization/images/jxl/progressive-expected.png b/third_party/blink/web_tests/platform/linux/virtual/gpu-rasterization/images/jxl/progressive-expected.png
deleted file mode 100644
index 3f15d66f..0000000
--- a/third_party/blink/web_tests/platform/linux/virtual/gpu-rasterization/images/jxl/progressive-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/jxl-enabled/images/jxl/progressive-expected.png b/third_party/blink/web_tests/platform/linux/virtual/jxl-enabled/images/jxl/progressive-expected.png
deleted file mode 100644
index d4d3290c..0000000
--- a/third_party/blink/web_tests/platform/linux/virtual/jxl-enabled/images/jxl/progressive-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/images/jxl/progressive-expected.png b/third_party/blink/web_tests/platform/mac/images/jxl/progressive-expected.png
deleted file mode 100644
index 23927820..0000000
--- a/third_party/blink/web_tests/platform/mac/images/jxl/progressive-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/jxl/progressive-expected.png b/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/jxl/progressive-expected.png
deleted file mode 100644
index 910cb6a..0000000
--- a/third_party/blink/web_tests/platform/mac/virtual/exotic-color-space/images/jxl/progressive-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/gpu-rasterization/images/jxl/progressive-expected.png b/third_party/blink/web_tests/platform/mac/virtual/gpu-rasterization/images/jxl/progressive-expected.png
deleted file mode 100644
index 224837d..0000000
--- a/third_party/blink/web_tests/platform/mac/virtual/gpu-rasterization/images/jxl/progressive-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/jxl-enabled/images/jxl/progressive-expected.png b/third_party/blink/web_tests/platform/mac/virtual/jxl-enabled/images/jxl/progressive-expected.png
deleted file mode 100644
index d4d3290c..0000000
--- a/third_party/blink/web_tests/platform/mac/virtual/jxl-enabled/images/jxl/progressive-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/exotic-color-space/images/jxl/progressive-expected.png b/third_party/blink/web_tests/virtual/exotic-color-space/images/jxl/progressive-expected.png
deleted file mode 100644
index 910cb6a..0000000
--- a/third_party/blink/web_tests/virtual/exotic-color-space/images/jxl/progressive-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/gpu-rasterization/images/jxl/progressive-expected.png b/third_party/blink/web_tests/virtual/gpu-rasterization/images/jxl/progressive-expected.png
deleted file mode 100644
index 224837d..0000000
--- a/third_party/blink/web_tests/virtual/gpu-rasterization/images/jxl/progressive-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/jxl-enabled/images/jxl/progressive-expected.png b/third_party/blink/web_tests/virtual/jxl-enabled/images/jxl/progressive-expected.png
deleted file mode 100644
index 5562a70e..0000000
--- a/third_party/blink/web_tests/virtual/jxl-enabled/images/jxl/progressive-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index 8368e04..6ab75a0d 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -914,14 +914,6 @@
 interface CSSScopeRule : CSSConditionRule
     attribute @@toStringTag
     method constructor
-interface CSSScrollTimelineRule : CSSRule
-    attribute @@toStringTag
-    getter end
-    getter name
-    getter orientation
-    getter source
-    getter start
-    method constructor
 interface CSSSkew : CSSTransformComponent
     attribute @@toStringTag
     getter ax
diff --git a/third_party/ipcz/src/BUILD.gn b/third_party/ipcz/src/BUILD.gn
index 78187739..4e9af9f 100644
--- a/third_party/ipcz/src/BUILD.gn
+++ b/third_party/ipcz/src/BUILD.gn
@@ -244,6 +244,8 @@
   ]
   sources = [
     "ipcz/api_object.cc",
+    "ipcz/atomic_queue_state.cc",
+    "ipcz/atomic_queue_state.h",
     "ipcz/block_allocator.cc",
     "ipcz/block_allocator_pool.cc",
     "ipcz/block_allocator_pool.h",
@@ -270,6 +272,7 @@
     "ipcz/message_macros/message_params_declaration_macros.h",
     "ipcz/message_macros/message_params_declaration_macros.h",
     "ipcz/message_macros/undef_message_macros.h",
+    "ipcz/monitored_atomic.h",
     "ipcz/node.cc",
     "ipcz/node_connector.cc",
     "ipcz/node_link.cc",
@@ -385,6 +388,7 @@
     "remote_portal_test.cc",
     "trap_test.cc",
     "util/ref_counted_test.cc",
+    "util/safe_math_test.cc",
     "util/stack_trace_test.cc",
   ]
 
diff --git a/third_party/ipcz/src/ipcz/atomic_queue_state.cc b/third_party/ipcz/src/ipcz/atomic_queue_state.cc
new file mode 100644
index 0000000..ee4a947
--- /dev/null
+++ b/third_party/ipcz/src/ipcz/atomic_queue_state.cc
@@ -0,0 +1,38 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ipcz/atomic_queue_state.h"
+
+#include <cstdint>
+
+#include "ipcz/monitored_atomic.h"
+#include "third_party/abseil-cpp/absl/base/macros.h"
+
+namespace ipcz {
+
+AtomicQueueState::AtomicQueueState() noexcept = default;
+
+AtomicQueueState::QueryResult AtomicQueueState::Query(
+    const MonitorSelection& monitors) {
+  return {
+      .num_parcels_consumed =
+          num_parcels_consumed_.Query({.monitor = monitors.monitor_parcels}),
+      .num_bytes_consumed =
+          num_bytes_consumed_.Query({.monitor = monitors.monitor_bytes}),
+  };
+}
+
+bool AtomicQueueState::Update(const UpdateValue& value) {
+  ABSL_ASSERT(value.num_parcels_consumed <=
+              MonitoredAtomic<uint64_t>::kMaxValue);
+  ABSL_ASSERT(value.num_bytes_consumed <= MonitoredAtomic<uint64_t>::kMaxValue);
+  const bool parcels_were_monitored =
+      num_parcels_consumed_.UpdateValueAndResetMonitor(
+          value.num_parcels_consumed);
+  const bool bytes_were_monitored =
+      num_bytes_consumed_.UpdateValueAndResetMonitor(value.num_bytes_consumed);
+  return parcels_were_monitored || bytes_were_monitored;
+}
+
+}  // namespace ipcz
diff --git a/third_party/ipcz/src/ipcz/atomic_queue_state.h b/third_party/ipcz/src/ipcz/atomic_queue_state.h
new file mode 100644
index 0000000..5f78282
--- /dev/null
+++ b/third_party/ipcz/src/ipcz/atomic_queue_state.h
@@ -0,0 +1,75 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IPCZ_SRC_IPCZ_ATOMIC_QUEUE_STATE_
+#define IPCZ_SRC_IPCZ_ATOMIC_QUEUE_STATE_
+
+#include <cstdint>
+#include <type_traits>
+
+#include "ipcz/monitored_atomic.h"
+
+namespace ipcz {
+
+// AtomicQueueState holds some trivial data about how much of a router's inbound
+// parcel sequence has been consumed so far.
+//
+// Note that the fields herein are not strictly synchronized. If a queue
+// accumulates a 4k parcel and an 8k parcel which are both then consumed by the
+// application, the remote sender may observe `num_parcels_consumed` at 0, then
+// 1, then 2; and they may observe `num_bytes_consumed` at 0, then 4k, and then
+// 12k; the ordering of those individual progressions is guaranteed, but there's
+// no guarantee that an observer will see `num_parcels_consumed` as 1 at the
+// same time they see `num_bytes_consumed` as 4k.
+class alignas(8) AtomicQueueState {
+ public:
+  AtomicQueueState() noexcept;
+
+  // Performs a best-effort query of the most recently visible value on both
+  // fields and returns them as a QueryResult. `monitors` determines whether
+  // each field will be atomically marked for monitoring at the same time its
+  // value is retrieved.
+  struct QueryResult {
+    MonitoredAtomic<uint64_t>::State num_parcels_consumed;
+    MonitoredAtomic<uint64_t>::State num_bytes_consumed;
+  };
+  struct MonitorSelection {
+    bool monitor_parcels;
+    bool monitor_bytes;
+  };
+  QueryResult Query(const MonitorSelection& monitors);
+
+  // Updates both fields with new values, resetting any monitor bit that may
+  // have been set on either one. If either field had a monitor bit set prior to
+  // this update, this returns true. Otherwise it returns false.
+  struct UpdateValue {
+    uint64_t num_parcels_consumed;
+    uint64_t num_bytes_consumed;
+  };
+  bool Update(const UpdateValue& value);
+
+ private:
+  // The number of parcels consumed from the router's inbound parcel queue,
+  // either by the application reading from its portal, or by ipcz proxying them
+  // onward to another router.
+  MonitoredAtomic<uint64_t> num_parcels_consumed_{0};
+
+  // The total number of bytes of data consumed from the router's inbound parcel
+  // queue. This is the sum of the data size of all parcels covered by
+  // `consumed_sequence_length`, plus any bytes already consumed from the
+  // next parcel in sequence if it's been partially consumed..
+  MonitoredAtomic<uint64_t> num_bytes_consumed_{0};
+};
+
+// This must remain stable at 16 bytes in size, as it's part of shared memory
+// layouts. Trivial copyability is also required as a proxy condition to prevent
+// changes which might break that usage (e.g. introduction of a non-trivial
+// destructor.)
+static_assert(sizeof(AtomicQueueState) == 16, "Invalid AtomicQueueState size");
+static_assert(std::is_trivially_copyable_v<AtomicQueueState>,
+              "AtomicQueueState must be trivially copyable");
+
+}  // namespace ipcz
+
+#endif  // IPCZ_SRC_IPCZ_ATOMIC_QUEUE_STATE_
diff --git a/third_party/ipcz/src/ipcz/local_router_link.cc b/third_party/ipcz/src/ipcz/local_router_link.cc
index e675a57..fe89ecae 100644
--- a/third_party/ipcz/src/ipcz/local_router_link.cc
+++ b/third_party/ipcz/src/ipcz/local_router_link.cc
@@ -94,6 +94,10 @@
   return &state_->link_state();
 }
 
+void LocalRouterLink::WaitForLinkStateAsync(std::function<void()> callback) {
+  callback();
+}
+
 Ref<Router> LocalRouterLink::GetLocalPeer() {
   return state_->GetRouter(side_.opposite());
 }
@@ -125,25 +129,18 @@
   }
 }
 
-size_t LocalRouterLink::GetParcelCapacityInBytes(const IpczPutLimits& limits) {
-  return state_->GetRouter(side_.opposite())->GetInboundCapacityInBytes(limits);
+AtomicQueueState* LocalRouterLink::GetPeerQueueState() {
+  return &state_->link_state().GetQueueState(side_.opposite());
 }
 
-RouterLinkState::QueueState LocalRouterLink::GetPeerQueueState() {
-  return state_->link_state().GetQueueState(side_.opposite());
+AtomicQueueState* LocalRouterLink::GetLocalQueueState() {
+  return &state_->link_state().GetQueueState(side_);
 }
 
-bool LocalRouterLink::UpdateInboundQueueState(size_t num_parcels,
-                                              size_t num_bytes) {
-  return state_->link_state().UpdateQueueState(side_, num_parcels, num_bytes);
-}
-
-void LocalRouterLink::NotifyDataConsumed() {
-  state_->GetRouter(side_.opposite())->NotifyPeerConsumedData();
-}
-
-bool LocalRouterLink::EnablePeerMonitoring(bool enable) {
-  return state_->link_state().SetSideIsMonitoringPeer(side_, enable);
+void LocalRouterLink::SnapshotPeerQueueState() {
+  if (Ref<Router> receiver = state_->GetRouter(side_.opposite())) {
+    receiver->SnapshotPeerQueueState();
+  }
 }
 
 void LocalRouterLink::AcceptRouteDisconnected() {
diff --git a/third_party/ipcz/src/ipcz/local_router_link.h b/third_party/ipcz/src/ipcz/local_router_link.h
index 5122308..bf23ed4 100644
--- a/third_party/ipcz/src/ipcz/local_router_link.h
+++ b/third_party/ipcz/src/ipcz/local_router_link.h
@@ -35,6 +35,7 @@
   // RouterLink:
   LinkType GetType() const override;
   RouterLinkState* GetLinkState() const override;
+  void WaitForLinkStateAsync(std::function<void()> callback) override;
   Ref<Router> GetLocalPeer() override;
   RemoteRouterLink* AsRemoteRouterLink() override;
   void AllocateParcelData(size_t num_bytes,
@@ -43,11 +44,9 @@
   void AcceptParcel(Parcel& parcel) override;
   void AcceptRouteClosure(SequenceNumber sequence_length) override;
   void AcceptRouteDisconnected() override;
-  size_t GetParcelCapacityInBytes(const IpczPutLimits& limits) override;
-  RouterLinkState::QueueState GetPeerQueueState() override;
-  bool UpdateInboundQueueState(size_t num_parcels, size_t num_bytes) override;
-  void NotifyDataConsumed() override;
-  bool EnablePeerMonitoring(bool enable) override;
+  AtomicQueueState* GetPeerQueueState() override;
+  AtomicQueueState* GetLocalQueueState() override;
+  void SnapshotPeerQueueState() override;
   void MarkSideStable() override;
   bool TryLockForBypass(const NodeName& bypass_request_source) override;
   bool TryLockForClosure() override;
diff --git a/third_party/ipcz/src/ipcz/monitored_atomic.h b/third_party/ipcz/src/ipcz/monitored_atomic.h
new file mode 100644
index 0000000..b271e0b
--- /dev/null
+++ b/third_party/ipcz/src/ipcz/monitored_atomic.h
@@ -0,0 +1,76 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IPCZ_SRC_IPCZ_MONITORED_VALUE_H_
+#define IPCZ_SRC_IPCZ_MONITORED_VALUE_H_
+
+#include <atomic>
+#include <type_traits>
+
+namespace ipcz {
+
+// MonitoredAtomic is a trivial wrapper around around an atomic unsigned
+// integral value, with the high bit reserved for primitive communication
+// between one producer and any number of concurrent consumers of the value.
+//
+// Consumers can atomically query the value while simultaneously signaling that
+// they want to be notified about the next time the value changes. Producers can
+// atomically update the value while simulataneously querying (and resetting)
+// the consumer's interest in being notified about the change.
+template <typename T>
+class MonitoredAtomic {
+  static_assert(std::is_integral_v<T> && std::is_unsigned_v<T>,
+                "MonitoredAtomic requires an unsigned integral type");
+
+ public:
+  struct State {
+    T value;
+    bool monitored;
+  };
+
+  static constexpr T kMaxValue = std::numeric_limits<T>::max() >> 1;
+  static constexpr T kMonitorBit = kMaxValue + 1;
+
+  MonitoredAtomic() noexcept = default;
+  explicit MonitoredAtomic(T value) noexcept : value_(value) {}
+
+  // Returns a best-effort snapshot of the most recent underlying value. If
+  // `monitor` is true in `options`, then the stored value is also atomically
+  // flagged for monitoring.
+  struct QueryOptions {
+    bool monitor;
+  };
+  State Query(const QueryOptions& options) {
+    T value = value_.load(std::memory_order_relaxed);
+    while (options.monitor && !IsMonitored(value) &&
+           !value_.compare_exchange_weak(value, Monitored(value),
+                                         std::memory_order_release,
+                                         std::memory_order_relaxed)) {
+    }
+    return {.value = Unmonitored(value), .monitored = IsMonitored(value)};
+  }
+
+  // Stores a new underlying value, resetting the monitor bit if it was set.
+  // Returns a boolean indicating whether the monitor bit was set.
+  [[nodiscard]] bool UpdateValueAndResetMonitor(T value) {
+    T old_value = value_.load(std::memory_order_relaxed);
+    while (value != old_value &&
+           !value_.compare_exchange_weak(old_value, value,
+                                         std::memory_order_release,
+                                         std::memory_order_relaxed)) {
+    }
+    return IsMonitored(old_value);
+  }
+
+ private:
+  static bool IsMonitored(T value) { return (value & kMonitorBit) != 0; }
+  static T Monitored(T value) { return value | kMonitorBit; }
+  static T Unmonitored(T value) { return value & kMaxValue; }
+
+  std::atomic<T> value_{0};
+};
+
+}  // namespace ipcz
+
+#endif  // IPCZ_SRC_IPCZ_MONITORED_VALUE_H_
diff --git a/third_party/ipcz/src/ipcz/node_link.cc b/third_party/ipcz/src/ipcz/node_link.cc
index 1835fcc4..697fa759 100644
--- a/third_party/ipcz/src/ipcz/node_link.cc
+++ b/third_party/ipcz/src/ipcz/node_link.cc
@@ -626,9 +626,9 @@
       sublink->router_link->GetType());
 }
 
-bool NodeLink::OnNotifyDataConsumed(msg::NotifyDataConsumed& notify) {
-  if (Ref<Router> router = GetRouter(notify.params().sublink)) {
-    router->NotifyPeerConsumedData();
+bool NodeLink::OnSnapshotPeerQueueState(msg::SnapshotPeerQueueState& snapshot) {
+  if (Ref<Router> router = GetRouter(snapshot.params().sublink)) {
+    router->SnapshotPeerQueueState();
   }
   return true;
 }
diff --git a/third_party/ipcz/src/ipcz/node_link.h b/third_party/ipcz/src/ipcz/node_link.h
index 2b9bf42..c1ecee1 100644
--- a/third_party/ipcz/src/ipcz/node_link.h
+++ b/third_party/ipcz/src/ipcz/node_link.h
@@ -241,7 +241,7 @@
       msg::AcceptParcelDriverObjects& accept) override;
   bool OnRouteClosed(msg::RouteClosed& route_closed) override;
   bool OnRouteDisconnected(msg::RouteDisconnected& route_disconnected) override;
-  bool OnNotifyDataConsumed(msg::NotifyDataConsumed& notify) override;
+  bool OnSnapshotPeerQueueState(msg::SnapshotPeerQueueState& snapshot) override;
   bool OnBypassPeer(msg::BypassPeer& bypass) override;
   bool OnAcceptBypassLink(msg::AcceptBypassLink& accept) override;
   bool OnStopProxying(msg::StopProxying& stop) override;
diff --git a/third_party/ipcz/src/ipcz/node_messages_generator.h b/third_party/ipcz/src/ipcz/node_messages_generator.h
index 65bc189..99749d6b 100644
--- a/third_party/ipcz/src/ipcz/node_messages_generator.h
+++ b/third_party/ipcz/src/ipcz/node_messages_generator.h
@@ -323,9 +323,9 @@
   IPCZ_MSG_PARAM(SublinkId, sublink)
 IPCZ_MSG_END()
 
-// Notifies a Router that the other side of its route has consumed some parcels
-// or parcel data from its inbound queue.
-IPCZ_MSG_BEGIN(NotifyDataConsumed, IPCZ_MSG_ID(24), IPCZ_MSG_VERSION(0))
+// Notifies a router that it may be interested in a recent change to its outward
+// peer's visible queue state.
+IPCZ_MSG_BEGIN(SnapshotPeerQueueState, IPCZ_MSG_ID(24), IPCZ_MSG_VERSION(0))
   // Identifies the router to receive this message.
   IPCZ_MSG_PARAM(SublinkId, sublink)
 IPCZ_MSG_END()
diff --git a/third_party/ipcz/src/ipcz/parcel_queue.cc b/third_party/ipcz/src/ipcz/parcel_queue.cc
index 8ddaedc..746861a3 100644
--- a/third_party/ipcz/src/ipcz/parcel_queue.cc
+++ b/third_party/ipcz/src/ipcz/parcel_queue.cc
@@ -16,7 +16,7 @@
   ABSL_ASSERT(p.data_size() >= num_bytes_consumed);
   ABSL_ASSERT(p.num_objects() >= handles.size());
   p.Consume(num_bytes_consumed, handles);
-  ReduceNextElementSize(num_bytes_consumed);
+  PartiallyConsumeNextElement(num_bytes_consumed);
   if (p.empty()) {
     Parcel discarded;
     const bool ok = Pop(discarded);
diff --git a/third_party/ipcz/src/ipcz/remote_router_link.cc b/third_party/ipcz/src/ipcz/remote_router_link.cc
index e35a1b9..d52abeb 100644
--- a/third_party/ipcz/src/ipcz/remote_router_link.cc
+++ b/third_party/ipcz/src/ipcz/remote_router_link.cc
@@ -72,10 +72,19 @@
   // SetLinkState() must be called with an addressable fragment only once.
   ABSL_ASSERT(link_state_.load(std::memory_order_acquire) == nullptr);
 
-  // The release when storing `link_state_` is balanced by an acquire in
-  // GetLinkState().
   link_state_fragment_ = std::move(state);
-  link_state_.store(link_state_fragment_.get(), std::memory_order_release);
+
+  std::vector<std::function<void()>> callbacks;
+  {
+    absl::MutexLock lock(&mutex_);
+    // This store-release is balanced by a load-acquire in GetLinkState().
+    link_state_.store(link_state_fragment_.get(), std::memory_order_release);
+    link_state_callbacks_.swap(callbacks);
+  }
+
+  for (auto& callback : callbacks) {
+    callback();
+  }
 
   // If this side of the link was already marked stable before the
   // RouterLinkState was available, `side_is_stable_` will be true. In that
@@ -98,6 +107,18 @@
   return link_state_.load(std::memory_order_acquire);
 }
 
+void RemoteRouterLink::WaitForLinkStateAsync(std::function<void()> callback) {
+  {
+    absl::MutexLock lock(&mutex_);
+    if (!link_state_.load(std::memory_order_relaxed)) {
+      link_state_callbacks_.push_back(std::move(callback));
+      return;
+    }
+  }
+
+  callback();
+}
+
 Ref<Router> RemoteRouterLink::GetLocalPeer() {
   return nullptr;
 }
@@ -275,50 +296,24 @@
   node_link()->Transmit(route_closed);
 }
 
-size_t RemoteRouterLink::GetParcelCapacityInBytes(const IpczPutLimits& limits) {
-  if (limits.max_queued_bytes == 0 || limits.max_queued_parcels == 0) {
-    return 0;
-  }
-
-  RouterLinkState* state = GetLinkState();
-  if (!state) {
-    // This is only a best-effort estimate. With no link state yet, err on the
-    // side of more data flow.
-    return limits.max_queued_bytes;
-  }
-
-  const RouterLinkState::QueueState peer_queue =
-      state->GetQueueState(side_.opposite());
-  if (peer_queue.num_parcels >= limits.max_queued_parcels ||
-      peer_queue.num_bytes >= limits.max_queued_bytes) {
-    return 0;
-  }
-
-  return limits.max_queued_bytes - peer_queue.num_bytes;
-}
-
-RouterLinkState::QueueState RemoteRouterLink::GetPeerQueueState() {
+AtomicQueueState* RemoteRouterLink::GetPeerQueueState() {
   if (auto* state = GetLinkState()) {
-    return state->GetQueueState(side_.opposite());
+    return &state->GetQueueState(side_.opposite());
   }
-  return {.num_parcels = 0, .num_bytes = 0};
+  return nullptr;
 }
 
-bool RemoteRouterLink::UpdateInboundQueueState(size_t num_parcels,
-                                               size_t num_bytes) {
-  RouterLinkState* state = GetLinkState();
-  return state && state->UpdateQueueState(side_, num_parcels, num_bytes);
+AtomicQueueState* RemoteRouterLink::GetLocalQueueState() {
+  if (auto* state = GetLinkState()) {
+    return &state->GetQueueState(side_);
+  }
+  return nullptr;
 }
 
-void RemoteRouterLink::NotifyDataConsumed() {
-  msg::NotifyDataConsumed notify;
-  notify.params().sublink = sublink_;
-  node_link()->Transmit(notify);
-}
-
-bool RemoteRouterLink::EnablePeerMonitoring(bool enable) {
-  RouterLinkState* state = GetLinkState();
-  return state && state->SetSideIsMonitoringPeer(side_, enable);
+void RemoteRouterLink::SnapshotPeerQueueState() {
+  msg::SnapshotPeerQueueState snapshot;
+  snapshot.params().sublink = sublink_;
+  node_link()->Transmit(snapshot);
 }
 
 void RemoteRouterLink::AcceptRouteDisconnected() {
diff --git a/third_party/ipcz/src/ipcz/remote_router_link.h b/third_party/ipcz/src/ipcz/remote_router_link.h
index 0eddf33..7982ec4 100644
--- a/third_party/ipcz/src/ipcz/remote_router_link.h
+++ b/third_party/ipcz/src/ipcz/remote_router_link.h
@@ -6,6 +6,8 @@
 #define IPCZ_SRC_IPCZ_REMOTE_ROUTER_LINK_H_
 
 #include <atomic>
+#include <functional>
+#include <vector>
 
 #include "ipcz/fragment_ref.h"
 #include "ipcz/link_side.h"
@@ -13,6 +15,7 @@
 #include "ipcz/router_link.h"
 #include "ipcz/router_link_state.h"
 #include "ipcz/sublink_id.h"
+#include "third_party/abseil-cpp/absl/synchronization/mutex.h"
 #include "util/ref_counted.h"
 
 namespace ipcz {
@@ -51,6 +54,7 @@
   // RouterLink:
   LinkType GetType() const override;
   RouterLinkState* GetLinkState() const override;
+  void WaitForLinkStateAsync(std::function<void()> callback) override;
   Ref<Router> GetLocalPeer() override;
   RemoteRouterLink* AsRemoteRouterLink() override;
   void AllocateParcelData(size_t num_bytes,
@@ -59,11 +63,9 @@
   void AcceptParcel(Parcel& parcel) override;
   void AcceptRouteClosure(SequenceNumber sequence_length) override;
   void AcceptRouteDisconnected() override;
-  size_t GetParcelCapacityInBytes(const IpczPutLimits& limits) override;
-  RouterLinkState::QueueState GetPeerQueueState() override;
-  bool UpdateInboundQueueState(size_t num_parcels, size_t num_bytes) override;
-  void NotifyDataConsumed() override;
-  bool EnablePeerMonitoring(bool enable) override;
+  AtomicQueueState* GetPeerQueueState() override;
+  AtomicQueueState* GetLocalQueueState() override;
+  void SnapshotPeerQueueState() override;
   void MarkSideStable() override;
   bool TryLockForBypass(const NodeName& bypass_request_source) override;
   bool TryLockForClosure() override;
@@ -118,6 +120,11 @@
   // that value indefinitely, so any non-null value loaded from this field is
   // safe to dereference for the duration of the RemoteRouterLink's lifetime.
   std::atomic<RouterLinkState*> link_state_{nullptr};
+
+  // Set of callbacks to be invoked as soon as this link has a RouterLinkState.
+  absl::Mutex mutex_;
+  std::vector<std::function<void()>> link_state_callbacks_
+      ABSL_GUARDED_BY(mutex_);
 };
 
 }  // namespace ipcz
diff --git a/third_party/ipcz/src/ipcz/router.cc b/third_party/ipcz/src/ipcz/router.cc
index eae86db2..2a59bdf 100644
--- a/third_party/ipcz/src/ipcz/router.cc
+++ b/third_party/ipcz/src/ipcz/router.cc
@@ -9,6 +9,7 @@
 #include <cstring>
 #include <utility>
 
+#include "ipcz/atomic_queue_state.h"
 #include "ipcz/ipcz.h"
 #include "ipcz/local_router_link.h"
 #include "ipcz/node_link.h"
@@ -96,6 +97,12 @@
 
 void Router::QueryStatus(IpczPortalStatus& status) {
   absl::MutexLock lock(&mutex_);
+  AtomicQueueState::QueryResult result;
+  if (auto* state = GetPeerQueueState()) {
+    result = state->Query({.monitor_parcels = false, .monitor_bytes = false});
+  }
+
+  UpdateStatusForPeerQueueState(result);
   const size_t size = std::min(status.size, status_.size);
   memcpy(&status, &status_, size);
   status.size = size;
@@ -136,7 +143,8 @@
         outbound_parcels_.GetCurrentSequenceLength();
     parcel.set_sequence_number(sequence_number);
     if (outward_edge_.primary_link() &&
-        outbound_parcels_.MaybeSkipSequenceNumber(sequence_number)) {
+        outbound_parcels_.SkipElement(sequence_number,
+                                      parcel.data_view().size())) {
       link = outward_edge_.primary_link();
     } else {
       // If there are no unsent parcels ahead of this one in the outbound
@@ -205,42 +213,27 @@
     return 0;
   }
 
-  size_t num_queued_bytes = 0;
-  Ref<RouterLink> link;
-  {
-    absl::MutexLock lock(&mutex_);
-    if (outbound_parcels_.GetNumAvailableElements() >=
-        limits.max_queued_parcels) {
-      return 0;
-    }
-    if (outbound_parcels_.GetTotalAvailableElementSize() >
-        limits.max_queued_bytes) {
-      return 0;
-    }
+  SnapshotPeerQueueState();
 
-    num_queued_bytes = outbound_parcels_.GetTotalAvailableElementSize();
-    link = outward_edge_.primary_link();
-  }
-
-  size_t link_capacity =
-      link ? link->GetParcelCapacityInBytes(limits) : limits.max_queued_bytes;
-  if (link_capacity <= num_queued_bytes) {
-    return 0;
-  }
-
-  return link_capacity - num_queued_bytes;
-}
-
-size_t Router::GetInboundCapacityInBytes(const IpczPutLimits& limits) {
   absl::MutexLock lock(&mutex_);
-  const size_t num_queued_parcels = inbound_parcels_.GetNumAvailableElements();
-  const size_t num_queued_bytes =
-      inbound_parcels_.GetTotalAvailableElementSize();
-  if (num_queued_bytes >= limits.max_queued_bytes ||
-      num_queued_parcels >= limits.max_queued_parcels) {
+  if (status_.num_remote_parcels >= limits.max_queued_parcels ||
+      status_.num_remote_bytes >= limits.max_queued_bytes) {
     return 0;
   }
-  return limits.max_queued_bytes - num_queued_bytes;
+
+  if (outbound_parcels_.GetNumAvailableElements() >=
+      limits.max_queued_parcels - status_.num_remote_parcels) {
+    return 0;
+  }
+
+  const size_t num_bytes_pending =
+      outbound_parcels_.GetTotalAvailableElementSize();
+  const size_t available_capacity =
+      limits.max_queued_bytes - status_.num_remote_bytes;
+  if (num_bytes_pending >= available_capacity) {
+    return 0;
+  }
+  return available_capacity - num_bytes_pending;
 }
 
 bool Router::AcceptInboundParcel(Parcel& parcel) {
@@ -260,12 +253,6 @@
       status_.num_local_bytes = inbound_parcels_.GetTotalAvailableElementSize();
       traps_.UpdatePortalStatus(status_, TrapSet::UpdateReason::kNewLocalParcel,
                                 dispatcher);
-
-      const Ref<RouterLink>& outward_link = outward_edge_.primary_link();
-      if (outward_link && outward_link->GetType().is_central()) {
-        outward_link->UpdateInboundQueueState(status_.num_local_parcels,
-                                              status_.num_local_bytes);
-      }
     }
   }
 
@@ -316,6 +303,8 @@
         if (inbound_parcels_.IsSequenceFullyConsumed()) {
           status_.flags |= IPCZ_PORTAL_STATUS_DEAD;
         }
+        status_.num_remote_bytes = 0;
+        status_.num_remote_parcels = 0;
         traps_.UpdatePortalStatus(status_, TrapSet::UpdateReason::kPeerClosed,
                                   dispatcher);
       }
@@ -369,6 +358,8 @@
       if (inbound_parcels_.IsSequenceFullyConsumed()) {
         status_.flags |= IPCZ_PORTAL_STATUS_DEAD;
       }
+      status_.num_remote_parcels = 0;
+      status_.num_remote_bytes = 0;
       traps_.UpdatePortalStatus(status_, TrapSet::UpdateReason::kPeerClosed,
                                 dispatcher);
     }
@@ -386,27 +377,50 @@
   return true;
 }
 
-void Router::NotifyPeerConsumedData() {
+void Router::SnapshotPeerQueueState() {
   TrapEventDispatcher dispatcher;
-  {
-    absl::MutexLock lock(&mutex_);
-    const Ref<RouterLink>& outward_link = outward_edge_.primary_link();
-    if (!outward_link || !outward_link->GetType().is_central() ||
-        inward_edge_) {
-      return;
-    }
-
-    const RouterLinkState::QueueState peer_state =
-        outward_link->GetPeerQueueState();
-    status_.num_remote_parcels = peer_state.num_parcels;
-    status_.num_remote_bytes = peer_state.num_bytes;
-    traps_.UpdatePortalStatus(status_, TrapSet::UpdateReason::kRemoteActivity,
-                              dispatcher);
-
-    if (!traps_.need_remote_state()) {
-      outward_link->EnablePeerMonitoring(false);
-    }
+  absl::ReleasableMutexLock lock(&mutex_);
+  Ref<RouterLink> outward_link = outward_edge_.primary_link();
+  if (!outward_link || !outward_link->GetType().is_central() || inward_edge_) {
+    return;
   }
+
+  AtomicQueueState* peer_state = outward_link->GetPeerQueueState();
+  if (!peer_state) {
+    lock.Release();
+    // Try again after we have RouterLinkState access.
+    outward_link->WaitForLinkStateAsync(
+        [self = WrapRefCounted(this)] { self->SnapshotPeerQueueState(); });
+    return;
+  }
+
+  // Start with a cheaper snapshot, which may be good enough.
+  const AtomicQueueState::QueryResult state =
+      peer_state->Query({.monitor_parcels = false, .monitor_bytes = false});
+  UpdateStatusForPeerQueueState(state);
+  traps_.UpdatePortalStatus(status_, TrapSet::UpdateReason::kRemoteActivity,
+                            dispatcher);
+  if (!traps_.need_remote_state()) {
+    return;
+  }
+
+  const bool monitor_sequence_length =
+      traps_.need_remote_parcels() && !state.num_parcels_consumed.monitored;
+  const bool monitor_num_bytes =
+      traps_.need_remote_bytes() && !state.num_bytes_consumed.monitored;
+  if (!monitor_sequence_length && !monitor_num_bytes) {
+    return;
+  }
+
+  // We have at least one trap interested in remote queue state, the caller
+  // requested monitoring, and the state isn't currently being monitored. Take
+  // another snapshot, this time flipping any appropriate monitor bits.
+  UpdateStatusForPeerQueueState(peer_state->Query({
+      .monitor_parcels = traps_.need_remote_parcels(),
+      .monitor_bytes = traps_.need_remote_bytes(),
+  }));
+  traps_.UpdatePortalStatus(status_, TrapSet::UpdateReason::kRemoteActivity,
+                            dispatcher);
 }
 
 IpczResult Router::GetNextInboundParcel(IpczGetFlags flags,
@@ -459,17 +473,13 @@
     }
     traps_.UpdatePortalStatus(
         status_, TrapSet::UpdateReason::kLocalParcelConsumed, dispatcher);
-
-    const Ref<RouterLink>& outward_link = outward_edge_.primary_link();
-    if (outward_link && outward_link->GetType().is_central() &&
-        outward_link->UpdateInboundQueueState(status_.num_local_parcels,
-                                              status_.num_local_bytes)) {
-      link_to_notify = outward_link;
+    if (RefreshLocalQueueState()) {
+      link_to_notify = outward_edge_.primary_link();
     }
   }
 
   if (link_to_notify) {
-    link_to_notify->NotifyDataConsumed();
+    link_to_notify->SnapshotPeerQueueState();
   }
   return IPCZ_RESULT_OK;
 }
@@ -533,17 +543,13 @@
     }
     traps_.UpdatePortalStatus(
         status_, TrapSet::UpdateReason::kLocalParcelConsumed, dispatcher);
-
-    const Ref<RouterLink>& outward_link = outward_edge_.primary_link();
-    if (outward_link && outward_link->GetType().is_central() &&
-        outward_link->UpdateInboundQueueState(status_.num_local_parcels,
-                                              status_.num_local_bytes)) {
-      link_to_notify = outward_link;
+    if (RefreshLocalQueueState()) {
+      link_to_notify = outward_edge_.primary_link();
     }
   }
 
   if (link_to_notify) {
-    link_to_notify->NotifyDataConsumed();
+    link_to_notify->SnapshotPeerQueueState();
   }
 
   return IPCZ_RESULT_OK;
@@ -554,46 +560,42 @@
                         uint64_t context,
                         IpczTrapConditionFlags* satisfied_condition_flags,
                         IpczPortalStatus* status) {
-  const bool need_remote_state =
-      (conditions.flags & (IPCZ_TRAP_BELOW_MAX_REMOTE_PARCELS |
-                           IPCZ_TRAP_BELOW_MAX_REMOTE_BYTES)) != 0;
-  {
-    absl::MutexLock lock(&mutex_);
-    const Ref<RouterLink>& outward_link = outward_edge_.primary_link();
-    if (need_remote_state) {
-      status_.num_remote_parcels = outbound_parcels_.GetNumAvailableElements();
-      status_.num_remote_bytes =
-          outbound_parcels_.GetTotalAvailableElementSize();
+  absl::MutexLock lock(&mutex_);
 
-      if (outward_link && outward_link->GetType().is_central()) {
-        const RouterLinkState::QueueState peer_state =
-            outward_link->GetPeerQueueState();
-        status_.num_remote_parcels =
-            SaturatedAdd(status_.num_remote_parcels,
-                         static_cast<size_t>(peer_state.num_parcels));
-        status_.num_remote_bytes =
-            SaturatedAdd(status_.num_remote_bytes,
-                         static_cast<size_t>(peer_state.num_bytes));
+  const bool need_remote_parcels =
+      (conditions.flags & IPCZ_TRAP_BELOW_MAX_REMOTE_PARCELS) != 0;
+  const bool need_remote_bytes =
+      (conditions.flags & IPCZ_TRAP_BELOW_MAX_REMOTE_BYTES) != 0;
+  if (need_remote_parcels || need_remote_bytes) {
+    if (AtomicQueueState* peer_state = GetPeerQueueState()) {
+      const AtomicQueueState::QueryResult state =
+          peer_state->Query({.monitor_parcels = false, .monitor_bytes = false});
+      UpdateStatusForPeerQueueState(state);
+
+      // If the status already meets some conditions and would block trap
+      // installation, OR if it's already being monitored for changes, we can
+      // just go ahead and install the trap. Otherwise we have to re-query and
+      // set any monitoring bits ourselves.
+      const bool monitor_parcels =
+          need_remote_parcels && !state.num_parcels_consumed.monitored;
+      const bool monitor_bytes =
+          need_remote_bytes && !state.num_bytes_consumed.monitored;
+      if (!TrapSet::GetSatisfiedConditions(conditions, status_) &&
+          (monitor_parcels || monitor_bytes)) {
+        UpdateStatusForPeerQueueState(
+            peer_state->Query({.monitor_parcels = need_remote_parcels,
+                               .monitor_bytes = need_remote_bytes}));
       }
-    }
-
-    const bool already_monitoring_remote_state = traps_.need_remote_state();
-    IpczResult result = traps_.Add(conditions, handler, context, status_,
-                                   satisfied_condition_flags, status);
-    if (result != IPCZ_RESULT_OK || !need_remote_state) {
-      return result;
-    }
-
-    if (!already_monitoring_remote_state) {
-      outward_link->EnablePeerMonitoring(true);
+    } else {
+      status_.num_remote_parcels =
+          outbound_parcels_.GetCurrentSequenceLength().value();
+      status_.num_remote_bytes = saturated_cast<size_t>(
+          outbound_parcels_.GetTotalElementSizeQueuedSoFar());
     }
   }
 
-  // Safeguard against races between remote state changes and the new trap being
-  // installed above. Only reached if the new trap monitors remote state.
-  ABSL_ASSERT(need_remote_state);
-  NotifyPeerConsumedData();
-  return IPCZ_RESULT_OK;
+  return traps_.Add(conditions, handler, context, status_,
+                    satisfied_condition_flags, status);
 }
 
 IpczResult Router::MergeRoute(const Ref<Router>& other) {
@@ -638,12 +640,16 @@
   auto router = MakeRefCounted<Router>();
   {
     absl::MutexLock lock(&router->mutex_);
-    router->outbound_parcels_.ResetInitialSequenceNumber(
-        descriptor.next_outgoing_sequence_number);
-    router->inbound_parcels_.ResetInitialSequenceNumber(
-        descriptor.next_incoming_sequence_number);
+    router->outbound_parcels_.ResetSequence(
+        descriptor.next_outgoing_sequence_number,
+        descriptor.num_bytes_produced);
+    router->inbound_parcels_.ResetSequence(
+        descriptor.next_incoming_sequence_number,
+        descriptor.num_bytes_consumed);
     if (descriptor.peer_closed) {
       router->status_.flags |= IPCZ_PORTAL_STATUS_PEER_CLOSED;
+      router->status_.num_remote_parcels = 0;
+      router->status_.num_remote_bytes = 0;
       if (!router->inbound_parcels_.SetFinalSequenceLength(
               descriptor.closed_peer_sequence_length)) {
         return nullptr;
@@ -690,8 +696,12 @@
 
     descriptor.next_outgoing_sequence_number =
         outbound_parcels_.GetCurrentSequenceLength();
+    descriptor.num_bytes_produced =
+        outbound_parcels_.total_consumed_element_size();
     descriptor.next_incoming_sequence_number =
         inbound_parcels_.current_sequence_number();
+    descriptor.num_bytes_consumed =
+        inbound_parcels_.total_consumed_element_size();
 
     // Initialize an inward edge but with no link yet. This ensures that we
     // don't look like a terminal router while waiting for a link to be set,
@@ -1120,6 +1130,8 @@
   bool inward_link_decayed = false;
   bool outward_link_decayed = false;
   bool dropped_last_decaying_link = false;
+  bool snapshot_peer_queue_state = false;
+  bool peer_needs_local_state_update = false;
   ParcelsToFlush parcels_to_flush;
   {
     absl::MutexLock lock(&mutex_);
@@ -1132,6 +1144,8 @@
     decaying_inward_link =
         inward_edge_ ? inward_edge_->decaying_link() : nullptr;
     on_central_link = outward_link && outward_link->GetType().is_central();
+    snapshot_peer_queue_state = on_central_link && traps_.need_remote_state();
+    peer_needs_local_state_update = on_central_link && RefreshLocalQueueState();
     if (bridge_) {
       // Bridges have either a primary link or decaying link, but never both.
       bridge_link = bridge_->primary_link() ? bridge_->primary_link()
@@ -1274,6 +1288,14 @@
     return;
   }
 
+  if (snapshot_peer_queue_state) {
+    SnapshotPeerQueueState();
+  }
+
+  if (peer_needs_local_state_update) {
+    outward_link->SnapshotPeerQueueState();
+  }
+
   if (!dropped_last_decaying_link && behavior != kForceProxyBypassAttempt) {
     // No relevant state changes, so there are no new bypass opportunities.
     return;
@@ -1288,6 +1310,72 @@
   }
 }
 
+AtomicQueueState* Router::GetPeerQueueState() {
+  if (!outward_edge_.primary_link()) {
+    return nullptr;
+  }
+
+  if (!outward_edge_.primary_link()->GetType().is_central()) {
+    return nullptr;
+  }
+
+  return outward_edge_.primary_link()->GetPeerQueueState();
+}
+
+bool Router::RefreshLocalQueueState() {
+  const Ref<RouterLink>& outward_link = outward_edge_.primary_link();
+  if (!outward_link) {
+    return false;
+  }
+
+  auto* state = outward_link->GetLocalQueueState();
+  if (!state) {
+    return false;
+  }
+
+  const uint64_t num_parcels_consumed =
+      inbound_parcels_.current_sequence_number().value();
+  const uint64_t num_bytes_consumed =
+      inbound_parcels_.total_consumed_element_size();
+  if (last_queue_update_ &&
+      last_queue_update_->num_parcels_consumed == num_parcels_consumed &&
+      last_queue_update_->num_bytes_consumed == num_bytes_consumed) {
+    // If our current status doesn't differ in some way from the last time we
+    // updated the local AtomicQueueState, there's nothing to do.
+    return false;
+  }
+
+  last_queue_update_ = AtomicQueueState::UpdateValue{
+      .num_parcels_consumed = num_parcels_consumed,
+      .num_bytes_consumed = num_bytes_consumed,
+  };
+  return state->Update(*last_queue_update_);
+}
+
+void Router::UpdateStatusForPeerQueueState(
+    const AtomicQueueState::QueryResult& state) {
+  // The consumed amounts should never exceed produced amounts. If they do,
+  // treat them as zero.
+  const uint64_t num_parcels_produced =
+      outbound_parcels_.GetCurrentSequenceLength().value();
+  uint64_t num_parcels_consumed = 0;
+  if (state.num_parcels_consumed.value <= num_parcels_produced) {
+    num_parcels_consumed = state.num_parcels_consumed.value;
+  }
+
+  const uint64_t num_bytes_produced =
+      outbound_parcels_.GetTotalElementSizeQueuedSoFar();
+  uint64_t num_bytes_consumed = 0;
+  if (state.num_bytes_consumed.value <= num_bytes_produced) {
+    num_bytes_consumed = state.num_bytes_consumed.value;
+  }
+
+  status_.num_remote_parcels =
+      saturated_cast<size_t>(num_parcels_produced - num_parcels_consumed);
+  status_.num_remote_bytes =
+      saturated_cast<size_t>(num_bytes_produced - num_bytes_consumed);
+}
+
 bool Router::MaybeStartSelfBypass() {
   Ref<RemoteRouterLink> remote_inward_link;
   Ref<RemoteRouterLink> remote_outward_link;
diff --git a/third_party/ipcz/src/ipcz/router.h b/third_party/ipcz/src/ipcz/router.h
index 092e7a6..8bdecad2 100644
--- a/third_party/ipcz/src/ipcz/router.h
+++ b/third_party/ipcz/src/ipcz/router.h
@@ -23,6 +23,7 @@
 
 namespace ipcz {
 
+class AtomicQueueState;
 class NodeLink;
 class RemoteRouterLink;
 struct RouterLinkState;
@@ -131,9 +132,9 @@
   bool AcceptRouteClosureFrom(LinkType link_type,
                               SequenceNumber sequence_length);
 
-  // Informs this router that its outward peer consumed some inbound parcels or
-  // parcel data.
-  void NotifyPeerConsumedData();
+  // Queries the remote peer's queue state and performs any local state upates
+  // needed to reflect it.
+  void SnapshotPeerQueueState();
 
   // Accepts notification from a link bound to this Router that some node along
   // the route (in the direction of that link) has been disconnected, e.g. due
@@ -315,6 +316,23 @@
  private:
   ~Router() override;
 
+  // Returns a handle to the outward peer's queue state, if available. Otherwise
+  // returns null.
+  AtomicQueueState* GetPeerQueueState() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+
+  // Updates the AtomicQueueState shared with this Router's outward peer, based
+  // on the current portal status. Any monitor bit set by the remote peer is
+  // reset, and this returns the value of that bit prior to the reset. If this
+  // returns true, the caller is responsible for notifying the remote peer about
+  // a state change.
+  [[nodiscard]] bool RefreshLocalQueueState()
+      ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+
+  // Updates this Router's status to reflect how many parcels and total bytes of
+  // parcel data remain on the remote peer's inbound queue.
+  void UpdateStatusForPeerQueueState(const AtomicQueueState::QueryResult& state)
+      ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+
   // Attempts to initiate bypass of this router by its peers, and ultimately to
   // remove this router from its route.
   //
@@ -377,6 +395,11 @@
   // this router, iff this is a terminal router.
   IpczPortalStatus status_ ABSL_GUARDED_BY(mutex_) = {sizeof(status_)};
 
+  // A local cache of the most recently stored value for our own local
+  // AtomicQueueState.
+  absl::optional<AtomicQueueState::UpdateValue> last_queue_update_
+      ABSL_GUARDED_BY(mutex_);
+
   // A set of traps installed via a controlling portal where applicable. These
   // traps are notified about any interesting state changes within the router.
   TrapSet traps_ ABSL_GUARDED_BY(mutex_);
diff --git a/third_party/ipcz/src/ipcz/router_descriptor.h b/third_party/ipcz/src/ipcz/router_descriptor.h
index 2e472ed..75ff93e 100644
--- a/third_party/ipcz/src/ipcz/router_descriptor.h
+++ b/third_party/ipcz/src/ipcz/router_descriptor.h
@@ -40,9 +40,15 @@
   // this router.
   SequenceNumber next_outgoing_sequence_number;
 
+  // The total number of outgoing bytes produced by the router's portal so far.
+  uint64_t num_bytes_produced;
+
   // The SequenceNumber of the next inbound parcel expected by this router.
   SequenceNumber next_incoming_sequence_number;
 
+  // The total number of incoming bytes consumed from router's portal so far.
+  uint64_t num_bytes_consumed;
+
   // Indicates that the other end of the route is already known to be closed.
   // In this case sending any new outbound parcels from this router would be
   // pointless, but there may still be in-flight parcels to receive from the
diff --git a/third_party/ipcz/src/ipcz/router_link.h b/third_party/ipcz/src/ipcz/router_link.h
index fb5ae27..0889eba 100644
--- a/third_party/ipcz/src/ipcz/router_link.h
+++ b/third_party/ipcz/src/ipcz/router_link.h
@@ -5,6 +5,12 @@
 #ifndef IPCZ_SRC_IPCZ_ROUTER_LINK_H_
 #define IPCZ_SRC_IPCZ_ROUTER_LINK_H_
 
+#include <cstddef>
+#include <functional>
+#include <string>
+#include <utility>
+
+#include "ipcz/atomic_queue_state.h"
 #include "ipcz/fragment_ref.h"
 #include "ipcz/link_type.h"
 #include "ipcz/node_name.h"
@@ -39,6 +45,10 @@
   // returns null.
   virtual RouterLinkState* GetLinkState() const = 0;
 
+  // Runs `callback` as soon as this RouterLink has a RouterLinkState. If the
+  // link already has a RouterLinkState then `callback` is invoked immediately.
+  virtual void WaitForLinkStateAsync(std::function<void()> callback) = 0;
+
   // Returns the Router on the other end of this link, if this is a
   // LocalRouterLink. Otherwise returns null.
   virtual Ref<Router> GetLocalPeer() = 0;
@@ -72,30 +82,18 @@
   // delivery of any further parcels.
   virtual void AcceptRouteDisconnected() = 0;
 
-  // Returns a best-effort estimation of how much new parcel data can be
-  // transmitted across the link before one or more limits described by `limits`
-  // would be exceeded on the receiving portal.
-  virtual size_t GetParcelCapacityInBytes(const IpczPutLimits& limits) = 0;
+  // Returns the AtomicQueueState for the other side of this link if available.
+  // Otherwise returns null.
+  virtual AtomicQueueState* GetPeerQueueState() = 0;
 
-  // Returns a best-effort snapshot of the last known state of the inbound
-  // parcel queue on the other side of this link. This is only meaningful for
-  // central links.
-  virtual RouterLinkState::QueueState GetPeerQueueState() = 0;
+  // Returns the AtomicQueueState for this side of the link if available.
+  // Otherwise returns null.
+  virtual AtomicQueueState* GetLocalQueueState() = 0;
 
-  // Updates the QueueState for this side of the link, returning true if and
-  // only if the other side wants to be notified about the update.
-  virtual bool UpdateInboundQueueState(size_t num_parcels,
-                                       size_t num_bytes) = 0;
-
-  // Notifies the other side that this side has consumed some parcels or parcel
-  // data from its inbound queue. Should only be called on central links when
-  // the other side has expressed interest in such notifications.
-  virtual void NotifyDataConsumed() = 0;
-
-  // Controls whether the caller's side of the link is interested in being
-  // notified about data consumption on the opposite side of the link. Returns
-  // the previous value of this bit.
-  virtual bool EnablePeerMonitoring(bool enable) = 0;
+  // Notifies the other side that this side has updated its visible queue state
+  // in some way which may be interesting to them. This should be called
+  // sparingly to avoid redundant IPC traffic and redundant idle wakes.
+  virtual void SnapshotPeerQueueState() = 0;
 
   // Signals that this side of the link is in a stable state suitable for one
   // side or the other to lock the link, either for bypass or closure
diff --git a/third_party/ipcz/src/ipcz/router_link_state.cc b/third_party/ipcz/src/ipcz/router_link_state.cc
index 70e842d..cf5223fb 100644
--- a/third_party/ipcz/src/ipcz/router_link_state.cc
+++ b/third_party/ipcz/src/ipcz/router_link_state.cc
@@ -125,38 +125,8 @@
   return true;
 }
 
-RouterLinkState::QueueState RouterLinkState::GetQueueState(
-    LinkSide side) const {
-  return {
-      .num_parcels = SelectBySide(side, num_parcels_on_a, num_parcels_on_b)
-                         .load(std::memory_order_relaxed),
-      .num_bytes = SelectBySide(side, num_bytes_on_a, num_bytes_on_b)
-                       .load(std::memory_order_relaxed),
-  };
-}
-
-bool RouterLinkState::UpdateQueueState(LinkSide side,
-                                       size_t num_parcels,
-                                       size_t num_bytes) {
-  StoreSaturated(SelectBySide(side, num_parcels_on_a, num_parcels_on_b),
-                 num_parcels);
-  StoreSaturated(SelectBySide(side, num_bytes_on_a, num_bytes_on_b), num_bytes);
-  const uint32_t other_side_monitoring_this_side =
-      SelectBySide(side, kSideBMonitoringSideA, kSideAMonitoringSideB);
-  return (status.load(std::memory_order_relaxed) &
-          other_side_monitoring_this_side) != 0;
-}
-
-bool RouterLinkState::SetSideIsMonitoringPeer(LinkSide side,
-                                              bool is_monitoring) {
-  const uint32_t monitoring_bit =
-      SelectBySide(side, kSideAMonitoringSideB, kSideBMonitoringSideA);
-  uint32_t expected = kStable;
-  while (!status.compare_exchange_weak(expected, expected | monitoring_bit,
-                                       std::memory_order_relaxed,
-                                       std::memory_order_relaxed)) {
-  }
-  return (expected & monitoring_bit) != 0;
+AtomicQueueState& RouterLinkState::GetQueueState(LinkSide side) {
+  return SelectBySide(side, side_a_queue_state, side_b_queue_state);
 }
 
 }  // namespace ipcz
diff --git a/third_party/ipcz/src/ipcz/router_link_state.h b/third_party/ipcz/src/ipcz/router_link_state.h
index 0d1ae54e..1154b919 100644
--- a/third_party/ipcz/src/ipcz/router_link_state.h
+++ b/third_party/ipcz/src/ipcz/router_link_state.h
@@ -9,6 +9,7 @@
 #include <cstdint>
 #include <type_traits>
 
+#include "ipcz/atomic_queue_state.h"
 #include "ipcz/ipcz.h"
 #include "ipcz/link_side.h"
 #include "ipcz/node_name.h"
@@ -62,13 +63,6 @@
   static constexpr Status kLockedBySideA = 1 << 4;
   static constexpr Status kLockedBySideB = 1 << 5;
 
-  // Set if the link on either side A or B wishes to be notified when parcels
-  // or parcel data are consumed by the other side. In practice these are only
-  // set when a router has a trap installed to monitor such conditions, which
-  // applications may leverage to e.g. implement a back-pressure mechanism.
-  static constexpr Status kSideAMonitoringSideB = 1 << 6;
-  static constexpr Status kSideBMonitoringSideA = 1 << 7;
-
   std::atomic<Status> status{kUnstable};
 
   // In a situation with three routers A-B-C and a central link between A and
@@ -78,16 +72,14 @@
   // validate that C is an appropriate source of such a bypass request.
   NodeName allowed_bypass_request_source;
 
-  // These fields approximate the number of parcels and data bytes received and
-  // queued for retrieval on each side of this link. Values here are saturated
-  // if the actual values would exceed the max uint32_t value.
-  std::atomic<uint32_t> num_parcels_on_a{0};
-  std::atomic<uint32_t> num_bytes_on_a{0};
-  std::atomic<uint32_t> num_parcels_on_b{0};
-  std::atomic<uint32_t> num_bytes_on_b{0};
+  // An approximation of the queue state on each side of the link. These are
+  // used both for best-effort querying of remote conditions as well as for
+  // reliable synchronization against remote activity.
+  AtomicQueueState side_a_queue_state;
+  AtomicQueueState side_b_queue_state;
 
   // More reserved slots, padding out this structure to 64 bytes.
-  uint32_t reserved1[6] = {0};
+  uint32_t reserved1[2] = {0};
 
   bool is_locked_by(LinkSide side) const {
     Status s = status.load(std::memory_order_relaxed);
@@ -124,24 +116,9 @@
   // still unstable.
   bool ResetWaitingBit(LinkSide side);
 
-  // Returns a snapshot of the inbound parcel queue state on the given side of
+  // Returns a view of the inbound parcel queue state for the given `side` of
   // this link.
-  struct QueueState {
-    uint32_t num_parcels;
-    uint32_t num_bytes;
-  };
-  QueueState GetQueueState(LinkSide side) const;
-
-  // Updates the queue state for the given side of this link. Values which
-  // exceed 2**32-1 are clamped to that value. Returns true if and only if the
-  // opposite side of the link wants to be notified about this update.
-  bool UpdateQueueState(LinkSide side, size_t num_parcels, size_t num_bytes);
-
-  // Sets an appropriate bit to indicate whether the router on the given side of
-  // this link should notify the opposite side after consuming inbound parcels
-  // or parcel data. Returns the previous value of the relevant bit, which may
-  // be the same as the old value.
-  bool SetSideIsMonitoringPeer(LinkSide side, bool is_monitoring);
+  AtomicQueueState& GetQueueState(LinkSide side);
 };
 
 // The size of this structure is fixed at 64 bytes to ensure that it fits the
diff --git a/third_party/ipcz/src/ipcz/sequenced_queue.h b/third_party/ipcz/src/ipcz/sequenced_queue.h
index c2de7f7..b1d3189 100644
--- a/third_party/ipcz/src/ipcz/sequenced_queue.h
+++ b/third_party/ipcz/src/ipcz/sequenced_queue.h
@@ -6,11 +6,13 @@
 #define IPCZ_SRC_IPCZ_SEQUENCED_QUEUE_H_
 
 #include <cstddef>
+#include <cstdint>
 #include <vector>
 
 #include "ipcz/sequence_number.h"
 #include "third_party/abseil-cpp/absl/container/inlined_vector.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
+#include "util/safe_math.h"
 
 namespace ipcz {
 
@@ -90,6 +92,11 @@
     return base_sequence_number_;
   }
 
+  // The total size of all element from this queue so far.
+  uint64_t total_consumed_element_size() const {
+    return total_consumed_element_size_;
+  }
+
   // The final length of the sequence that can be popped from this queue. Null
   // if a final length has not yet been set. If the final length is N, then the
   // last ordered element that can be pushed to or popped from the queue has a
@@ -124,6 +131,13 @@
     return entries_[0]->total_span_size;
   }
 
+  // Returns the total size of all elements previously popped from this queue,
+  // plus the total size of all elemenets currently ready for popping.
+  uint64_t GetTotalElementSizeQueuedSoFar() const {
+    return CheckAdd(total_consumed_element_size_,
+                    static_cast<uint64_t>(GetTotalAvailableElementSize()));
+  }
+
   // Returns the total length of the contiguous sequence already pushed and/or
   // popped from this queue so far. This is essentially
   // `current_sequence_number()` plus `GetNumAvailableElements()`. If
@@ -213,24 +227,29 @@
     return !HasNextElement() && !ExpectsMoreElements();
   }
 
-  // Resets this queue to start at the initial SequenceNumber `n`. Must be
-  // called only on an empty queue and only when the caller can be sure they
-  // won't want to push any elements with a SequenceNumber below `n`.
-  void ResetInitialSequenceNumber(SequenceNumber n) {
+  // Resets this queue to a state which behaves as if a sequence of parcels of
+  // length `n` has already been pushed and popped from the queue, with a total
+  // cumulative element size of `total_consumed_element_size`. Must be called
+  // only on an empty queue and only when the caller can be sure they won't want
+  // to push any elements with a SequenceNumber below `n`.
+  void ResetSequence(SequenceNumber n, uint64_t total_consumed_element_size) {
     ABSL_ASSERT(num_entries_ == 0);
     base_sequence_number_ = n;
+    total_consumed_element_size_ = total_consumed_element_size;
   }
 
   // Attempts to skip SequenceNumber `n` in the sequence by advancing the
   // current SequenceNumber by one. Returns true on success and false on
-  // failure.
+  // failure. `element_size` is the size of the skipped element as it would have
+  // been reported by ElementTraits::GetElementSize() if the element in question
+  // were actually pushed into the queue.
   //
   // This can only succeed when `current_sequence_number()` is equal to `n`, no
-  // entry for SequenceNumber `n` is already in the queue, and the `n` is less
+  // entry for SequenceNumber `n` is already in the queue, and n` is less than
   // the final sequence length if applicable. Success is equivalent to pushing
   // and immediately popping element `n` except that it does not grow, shrink,
   // or otherwise modify the queue's underlying storage.
-  bool MaybeSkipSequenceNumber(SequenceNumber n) {
+  bool SkipElement(SequenceNumber n, size_t element_size) {
     if (base_sequence_number_ != n || HasNextElement() ||
         (final_sequence_length_ && *final_sequence_length_ <= n)) {
       return false;
@@ -240,6 +259,8 @@
     if (num_entries_ != 0) {
       entries_.remove_prefix(1);
     }
+    total_consumed_element_size_ = CheckAdd(
+        total_consumed_element_size_, static_cast<uint64_t>(element_size));
     return true;
   }
 
@@ -307,13 +328,13 @@
     base_sequence_number_ = SequenceNumber{base_sequence_number_.value() + 1};
 
     // Make sure the next queued entry has up-to-date accounting, if present.
+    const size_t element_size = ElementTraits::GetElementSize(element);
     if (entries_.size() > 1 && entries_[1]) {
       Entry& next = *entries_[1];
       next.span_start = head.span_start;
       next.span_end = head.span_end;
       next.num_entries_in_span = head.num_entries_in_span - 1;
-      next.total_span_size =
-          head.total_span_size - ElementTraits::GetElementSize(element);
+      next.total_span_size = head.total_span_size - element_size;
 
       size_t tail_index = next.span_end.value() - sequence_number.value();
       if (tail_index > 1) {
@@ -333,6 +354,8 @@
       entries_ = EntryView(storage_.data(), entries_.size());
     }
 
+    total_consumed_element_size_ = CheckAdd(
+        total_consumed_element_size_, static_cast<uint64_t>(element_size));
     return true;
   }
 
@@ -344,10 +367,16 @@
   }
 
  protected:
-  void ReduceNextElementSize(size_t amount) {
+  // Adjusts the recorded size of the element at the head of this queue, as if
+  // the element were partially consumed. After this call, the value returned by
+  // GetTotalAvailableElementSize() will be decreased by `amount`, and the value
+  // returned by total_consumed_element_size() will increase by the same.
+  void PartiallyConsumeNextElement(size_t amount) {
     ABSL_ASSERT(HasNextElement());
     ABSL_ASSERT(entries_[0]->total_span_size >= amount);
     entries_[0]->total_span_size -= amount;
+    total_consumed_element_size_ =
+        CheckAdd(total_consumed_element_size_, static_cast<uint64_t>(amount));
   }
 
  private:
@@ -556,6 +585,10 @@
   // The number of slots in `entries_` which are actually occupied.
   size_t num_entries_ = 0;
 
+  // Tracks the sum of the element sizes of every element fully or partially
+  // consumed from the queue so far.
+  uint64_t total_consumed_element_size_ = 0;
+
   // The final length of the sequence to be enqueued, if known.
   absl::optional<SequenceNumber> final_sequence_length_;
 };
diff --git a/third_party/ipcz/src/ipcz/sequenced_queue_test.cc b/third_party/ipcz/src/ipcz/sequenced_queue_test.cc
index 54ed16f9..8c966ea 100644
--- a/third_party/ipcz/src/ipcz/sequenced_queue_test.cc
+++ b/third_party/ipcz/src/ipcz/sequenced_queue_test.cc
@@ -181,35 +181,66 @@
   EXPECT_TRUE(q.IsSequenceFullyConsumed());
 }
 
-TEST(SequencedQueueTest, MaybeSkipSequenceNumber) {
-  TestQueue q;
+TEST(SequencedQueueTest, SkipElement) {
+  TestQueueWithSize q;
   const std::string kEntry = "woot";
-  EXPECT_TRUE(q.MaybeSkipSequenceNumber(SequenceNumber(0)));
-  EXPECT_FALSE(q.MaybeSkipSequenceNumber(SequenceNumber(0)));
+  constexpr size_t kTestElementSize = 42;
+
+  // Skipping an element should update accounting appropriately.
+  EXPECT_TRUE(q.SkipElement(SequenceNumber(0), kTestElementSize));
+  EXPECT_EQ(0u, q.GetTotalAvailableElementSize());
+  EXPECT_EQ(kTestElementSize, q.GetTotalElementSizeQueuedSoFar());
+
+  // We can't skip or push an element that's already been skipped.
+  EXPECT_FALSE(q.SkipElement(SequenceNumber(0), kTestElementSize));
   EXPECT_FALSE(q.Push(SequenceNumber(0), kEntry));
+
+  // And we can't skip an element that's already been pushed.
   EXPECT_TRUE(q.Push(SequenceNumber(1), kEntry));
-  EXPECT_FALSE(q.MaybeSkipSequenceNumber(SequenceNumber(1)));
+  EXPECT_FALSE(q.SkipElement(SequenceNumber(1), 7));
+  EXPECT_EQ(kEntry.size(), q.GetTotalAvailableElementSize());
+  EXPECT_EQ(kEntry.size() + kTestElementSize,
+            q.GetTotalElementSizeQueuedSoFar());
 
   std::string s;
   EXPECT_TRUE(q.Pop(s));
+  EXPECT_EQ(0u, q.GetTotalAvailableElementSize());
+  EXPECT_EQ(kEntry.size() + kTestElementSize,
+            q.GetTotalElementSizeQueuedSoFar());
 
-  // Skip ahead to SequenceNumber 4.
-  EXPECT_TRUE(q.MaybeSkipSequenceNumber(SequenceNumber(2)));
-  EXPECT_TRUE(q.MaybeSkipSequenceNumber(SequenceNumber(3)));
+  // Skip ahead past SequenceNumber 2 and 3.
+  EXPECT_TRUE(q.SkipElement(SequenceNumber(2), kTestElementSize));
+  EXPECT_EQ(0u, q.GetTotalAvailableElementSize());
+  EXPECT_EQ(kEntry.size() + kTestElementSize * 2,
+            q.GetTotalElementSizeQueuedSoFar());
+  EXPECT_TRUE(q.SkipElement(SequenceNumber(3), kTestElementSize));
+  EXPECT_EQ(0u, q.GetTotalAvailableElementSize());
+  EXPECT_EQ(kEntry.size() + kTestElementSize * 3,
+            q.GetTotalElementSizeQueuedSoFar());
+
+  // SequenceNumber 4 can now be pushed while 2 and 3 cannot.
   EXPECT_FALSE(q.Push(SequenceNumber(2), kEntry));
   EXPECT_FALSE(q.Push(SequenceNumber(3), kEntry));
   EXPECT_TRUE(q.Push(SequenceNumber(4), kEntry));
-  EXPECT_FALSE(q.MaybeSkipSequenceNumber(SequenceNumber(4)));
+  EXPECT_FALSE(q.SkipElement(SequenceNumber(4), kTestElementSize));
+  EXPECT_EQ(kEntry.size(), q.GetTotalAvailableElementSize());
+  EXPECT_EQ(kEntry.size() * 2 + kTestElementSize * 3,
+            q.GetTotalElementSizeQueuedSoFar());
 
+  // Cap the sequence at 6 elements and verify that accounting remains intact
+  // when we skip the last element.
   EXPECT_TRUE(q.SetFinalSequenceLength(SequenceNumber(6)));
   EXPECT_FALSE(q.IsSequenceFullyConsumed());
   EXPECT_TRUE(q.Pop(s));
   EXPECT_FALSE(q.IsSequenceFullyConsumed());
-  EXPECT_TRUE(q.MaybeSkipSequenceNumber(SequenceNumber(5)));
+  EXPECT_TRUE(q.SkipElement(SequenceNumber(5), kTestElementSize));
+  EXPECT_EQ(0u, q.GetTotalAvailableElementSize());
+  EXPECT_EQ(kEntry.size() * 2 + kTestElementSize * 4,
+            q.GetTotalElementSizeQueuedSoFar());
   EXPECT_TRUE(q.IsSequenceFullyConsumed());
 
   // Fully consumed queue: skipping must fail.
-  EXPECT_FALSE(q.MaybeSkipSequenceNumber(SequenceNumber(6)));
+  EXPECT_FALSE(q.SkipElement(SequenceNumber(6), kTestElementSize));
 }
 
 TEST(SequencedQueueTest, Accounting) {
diff --git a/third_party/ipcz/src/ipcz/trap_set.cc b/third_party/ipcz/src/ipcz/trap_set.cc
index 2aacb02..3a8d0b2 100644
--- a/third_party/ipcz/src/ipcz/trap_set.cc
+++ b/third_party/ipcz/src/ipcz/trap_set.cc
@@ -16,7 +16,7 @@
 
 namespace {
 
-IpczTrapConditionFlags GetSatisfiedConditions(
+IpczTrapConditionFlags GetSatisfiedConditionsForUpdate(
     const IpczTrapConditions& conditions,
     TrapSet::UpdateReason reason,
     const IpczPortalStatus& status) {
@@ -52,9 +52,12 @@
   return event_flags;
 }
 
-bool NeedRemoteState(IpczTrapConditionFlags flags) {
-  return (flags & (IPCZ_TRAP_BELOW_MAX_REMOTE_PARCELS |
-                   IPCZ_TRAP_BELOW_MAX_REMOTE_BYTES)) != 0;
+bool NeedRemoteParcels(IpczTrapConditionFlags flags) {
+  return (flags & IPCZ_TRAP_BELOW_MAX_REMOTE_PARCELS) != 0;
+}
+
+bool NeedRemoteBytes(IpczTrapConditionFlags flags) {
+  return (flags & IPCZ_TRAP_BELOW_MAX_REMOTE_BYTES) != 0;
 }
 
 }  // namespace
@@ -65,6 +68,14 @@
   ABSL_ASSERT(empty());
 }
 
+// static
+IpczTrapConditionFlags TrapSet::GetSatisfiedConditions(
+    const IpczTrapConditions& conditions,
+    const IpczPortalStatus& current_status) {
+  return GetSatisfiedConditionsForUpdate(conditions, UpdateReason::kInstallTrap,
+                                         current_status);
+}
+
 IpczResult TrapSet::Add(const IpczTrapConditions& conditions,
                         IpczTrapEventHandler handler,
                         uintptr_t context,
@@ -72,8 +83,8 @@
                         IpczTrapConditionFlags* satisfied_condition_flags,
                         IpczPortalStatus* status) {
   last_known_status_ = current_status;
-  IpczTrapConditionFlags flags = GetSatisfiedConditions(
-      conditions, UpdateReason::kInstallTrap, current_status);
+  IpczTrapConditionFlags flags =
+      GetSatisfiedConditions(conditions, current_status);
   if (flags != 0) {
     if (satisfied_condition_flags) {
       *satisfied_condition_flags = flags;
@@ -91,8 +102,11 @@
   }
 
   traps_.emplace_back(conditions, handler, context);
-  if (NeedRemoteState(conditions.flags)) {
-    ++num_traps_monitoring_remote_state_;
+  if (NeedRemoteParcels(conditions.flags)) {
+    ++num_traps_monitoring_remote_parcels_;
+  }
+  if (NeedRemoteBytes(conditions.flags)) {
+    ++num_traps_monitoring_remote_bytes_;
   }
   return IPCZ_RESULT_OK;
 }
@@ -104,7 +118,7 @@
   for (auto* it = traps_.begin(); it != traps_.end();) {
     const Trap& trap = *it;
     const IpczTrapConditionFlags flags =
-        GetSatisfiedConditions(trap.conditions, reason, status);
+        GetSatisfiedConditionsForUpdate(trap.conditions, reason, status);
     if (!flags) {
       ++it;
       continue;
@@ -112,8 +126,11 @@
 
     dispatcher.DeferEvent(trap.handler, trap.context, flags, status);
     it = traps_.erase(it);
-    if (NeedRemoteState(flags)) {
-      --num_traps_monitoring_remote_state_;
+    if (NeedRemoteParcels(flags)) {
+      --num_traps_monitoring_remote_parcels_;
+    }
+    if (NeedRemoteBytes(flags)) {
+      --num_traps_monitoring_remote_bytes_;
     }
   }
 }
@@ -124,7 +141,8 @@
                           last_known_status_);
   }
   traps_.clear();
-  num_traps_monitoring_remote_state_ = 0;
+  num_traps_monitoring_remote_parcels_ = 0;
+  num_traps_monitoring_remote_bytes_ = 0;
 }
 
 TrapSet::Trap::Trap(IpczTrapConditions conditions,
diff --git a/third_party/ipcz/src/ipcz/trap_set.h b/third_party/ipcz/src/ipcz/trap_set.h
index 671f0cd..604eae2 100644
--- a/third_party/ipcz/src/ipcz/trap_set.h
+++ b/third_party/ipcz/src/ipcz/trap_set.h
@@ -51,9 +51,24 @@
 
   // Indicates whether any installed traps in this set require monitoring of
   // remote queue state.
-  bool need_remote_state() const {
-    return num_traps_monitoring_remote_state_ > 0;
+  bool need_remote_parcels() const {
+    return num_traps_monitoring_remote_parcels_ > 0;
   }
+  bool need_remote_bytes() const {
+    return num_traps_monitoring_remote_bytes_ > 0;
+  }
+  bool need_remote_state() const {
+    return need_remote_parcels() || need_remote_bytes();
+  }
+
+  // Returns the set of trap condition flags within `conditions` that would be
+  // raised right now if a trap were installed to watch for them, given
+  // `current_status` as the status of the portal being watched. If this returns
+  // zero (IPCZ_NO_FLAGS), then no watched conditions are satisfied and a
+  // corresponding call to Add() would succeed.
+  static IpczTrapConditionFlags GetSatisfiedConditions(
+      const IpczTrapConditions& conditions,
+      const IpczPortalStatus& current_status);
 
   // Attempts to install a new trap in the set. This effectively implements
   // the ipcz Trap() API. If `conditions` are already met, returns
@@ -92,7 +107,8 @@
 
   using TrapList = absl::InlinedVector<Trap, 4>;
   TrapList traps_;
-  size_t num_traps_monitoring_remote_state_ = 0;
+  size_t num_traps_monitoring_remote_parcels_ = 0;
+  size_t num_traps_monitoring_remote_bytes_ = 0;
   IpczPortalStatus last_known_status_ = {.size = sizeof(last_known_status_)};
 };
 
diff --git a/third_party/ipcz/src/queueing_test.cc b/third_party/ipcz/src/queueing_test.cc
index d560dc5..7fdfea1 100644
--- a/third_party/ipcz/src/queueing_test.cc
+++ b/third_party/ipcz/src/queueing_test.cc
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <limits>
+#include <string>
+
 #include "ipcz/ipcz.h"
 #include "test/multinode_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -186,5 +189,80 @@
   Close(c);
 }
 
+constexpr size_t kStressTestPortalCapacity = 256;
+constexpr size_t kStressTestPayloadSize = 4 * 1024 * 1024;
+
+MULTINODE_TEST_NODE(QueueingTestNode, RemoteQueueFeedbackStressTestClient) {
+  IpczHandle b = ConnectToBroker();
+
+  size_t bytes_received = 0;
+  while (bytes_received < kStressTestPayloadSize) {
+    // Consistency check: ensure that the portal never has more than
+    // kStressTestPortalCapacity bytes available to retrieve. Otherwise limits
+    // were not properly enforced by the sender.
+    IpczPortalStatus status = {.size = sizeof(status)};
+    EXPECT_EQ(IPCZ_RESULT_OK,
+              ipcz().QueryPortalStatus(b, IPCZ_NO_FLAGS, nullptr, &status));
+    EXPECT_LE(status.num_local_bytes, kStressTestPortalCapacity);
+
+    const void* data;
+    size_t num_bytes;
+    const IpczResult begin_result =
+        ipcz().BeginGet(b, IPCZ_NO_FLAGS, nullptr, &data, &num_bytes, nullptr);
+    if (begin_result == IPCZ_RESULT_OK) {
+      bytes_received += num_bytes;
+      EXPECT_EQ(std::string_view(static_cast<const char*>(data), num_bytes),
+                std::string(num_bytes, '!'));
+      EXPECT_EQ(IPCZ_RESULT_OK, ipcz().EndGet(b, num_bytes, 0, IPCZ_NO_FLAGS,
+                                              nullptr, nullptr));
+      continue;
+    }
+
+    ASSERT_EQ(IPCZ_RESULT_UNAVAILABLE, begin_result);
+    WaitForConditions(
+        b, {.flags = IPCZ_TRAP_ABOVE_MIN_LOCAL_BYTES, .min_local_bytes = 0});
+  }
+
+  Close(b);
+}
+
+MULTINODE_TEST(QueueingTest, RemoteQueueFeedbackStressTest) {
+  IpczHandle c = SpawnTestNode<RemoteQueueFeedbackStressTestClient>();
+
+  size_t bytes_remaining = kStressTestPayloadSize;
+  while (bytes_remaining) {
+    void* data;
+    size_t capacity = bytes_remaining;
+    const IpczPutLimits limits = {
+        .size = sizeof(limits),
+        .max_queued_parcels = std::numeric_limits<size_t>::max(),
+        .max_queued_bytes = kStressTestPortalCapacity,
+    };
+    const IpczBeginPutOptions options = {
+        .size = sizeof(options),
+        .limits = &limits,
+    };
+    const IpczResult begin_result = ipcz().BeginPut(
+        c, IPCZ_BEGIN_PUT_ALLOW_PARTIAL, &options, &capacity, &data);
+    if (begin_result == IPCZ_RESULT_OK) {
+      size_t num_bytes = std::min(bytes_remaining, capacity);
+      bytes_remaining -= num_bytes;
+      memset(data, '!', num_bytes);
+      EXPECT_EQ(IPCZ_RESULT_OK, ipcz().EndPut(c, num_bytes, nullptr, 0,
+                                              IPCZ_NO_FLAGS, nullptr));
+      continue;
+    }
+    ASSERT_EQ(IPCZ_RESULT_RESOURCE_EXHAUSTED, begin_result);
+
+    EXPECT_EQ(
+        IPCZ_RESULT_OK,
+        WaitForConditions(c, {.flags = IPCZ_TRAP_BELOW_MAX_REMOTE_BYTES,
+                              .max_remote_bytes = kStressTestPortalCapacity}));
+  }
+
+  WaitForConditionFlags(c, IPCZ_TRAP_PEER_CLOSED);
+  Close(c);
+}
+
 }  // namespace
 }  // namespace ipcz
diff --git a/third_party/ipcz/src/util/safe_math.h b/third_party/ipcz/src/util/safe_math.h
index 5affb98..e4dfa90f 100644
--- a/third_party/ipcz/src/util/safe_math.h
+++ b/third_party/ipcz/src/util/safe_math.h
@@ -6,6 +6,7 @@
 #define IPCZ_SRC_UTIL_SAFE_MATH_
 
 #include <limits>
+#include <type_traits>
 
 #include "third_party/abseil-cpp/absl/base/macros.h"
 #include "third_party/abseil-cpp/absl/base/optimization.h"
@@ -22,6 +23,18 @@
   return static_cast<Dst>(value);
 }
 
+template <typename Dst, typename Src>
+constexpr Dst saturated_cast(Src value) {
+  static_assert(std::is_unsigned_v<Src> && std::is_unsigned_v<Dst>,
+                "saturated_cast only supports unsigned types");
+  constexpr Dst kMaxDst = std::numeric_limits<Dst>::max();
+  constexpr Src kMaxSrc = std::numeric_limits<Src>::max();
+  if (ABSL_PREDICT_TRUE(kMaxDst >= kMaxSrc || value <= kMaxDst)) {
+    return static_cast<Dst>(value);
+  }
+  return kMaxDst;
+}
+
 template <typename T>
 constexpr T CheckAdd(T a, T b) {
   T result;
diff --git a/third_party/ipcz/src/util/safe_math_test.cc b/third_party/ipcz/src/util/safe_math_test.cc
new file mode 100644
index 0000000..7288211
--- /dev/null
+++ b/third_party/ipcz/src/util/safe_math_test.cc
@@ -0,0 +1,34 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "util/safe_math.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ipcz {
+namespace {
+
+template <typename T>
+uint64_t AsUint64(T value) {
+  return static_cast<uint64_t>(value);
+}
+
+TEST(SafeMathTest, SaturatedCast) {
+  const uint32_t kMaxUint32 = 0xffffffff;
+  const uint64_t kSmallUint64 = 0x12345678;
+  const uint64_t kLargeUint64 = 0x123456789abcull;
+
+  // Casting to a smaller type within its range yields the same value.
+  EXPECT_EQ(kSmallUint64, AsUint64(saturated_cast<uint32_t>(kSmallUint64)));
+
+  // Casting to a smaller type outside of its range yields the max value for
+  // the destination type.
+  EXPECT_EQ(kMaxUint32, saturated_cast<uint32_t>(kLargeUint64));
+
+  // Casting to a larger type always yields the same value.
+  EXPECT_EQ(AsUint64(kMaxUint32), saturated_cast<uint64_t>(kMaxUint32));
+}
+
+}  // namespace
+}  // namespace ipcz
diff --git a/third_party/tflite/README.chromium b/third_party/tflite/README.chromium
index 27c9aa1..91c2aa7 100644
--- a/third_party/tflite/README.chromium
+++ b/third_party/tflite/README.chromium
@@ -1,8 +1,8 @@
 Name: TensorFlow Lite
 Short Name: tflite
 URL: https://github.com/tensorflow/tensorflow
-Version: b6b10f9f529189ab903782ca308f44a35d3d427d
-Date: 2022/08/23
+Version: 58711f1fe3010139f47bcf76105654ff99251793
+Date: 2022/08/31
 License: Apache 2.0
 License File: LICENSE
 Security Critical: Yes
@@ -12,3 +12,8 @@
 TFLite is a part of the open-source machine-learning library TensorFlow that
 provides a stable ML framework optimized for binary size and execution on
 mobile devices with limited computation and memory resources.
+
+Update Process/Notes:
+The owners ensure that TFLite and its dependencies are rolled once per week. If
+you need to roll this library sooner, please reach out to one of the owners so
+all the dependencies and necessary validation tests can be run.
diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.h b/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.h
index 0ac89e1..1db04894 100644
--- a/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.h
+++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.h
@@ -726,6 +726,9 @@
         virtual HRESULT STDMETHODCALLTYPE GetVersion( 

             /* [retval][out] */ BSTR *version) = 0;

         

+        virtual HRESULT STDMETHODCALLTYPE FetchPolicies( 

+            /* [in] */ IUpdaterCallback *callback) = 0;

+        

         virtual HRESULT STDMETHODCALLTYPE CheckForUpdate( 

             /* [string][in] */ const WCHAR *app_id) = 0;

         

@@ -802,6 +805,11 @@
             IUpdater * This,

             /* [retval][out] */ BSTR *version);

         

+        DECLSPEC_XFGVIRT(IUpdater, FetchPolicies)

+        HRESULT ( STDMETHODCALLTYPE *FetchPolicies )( 

+            IUpdater * This,

+            /* [in] */ IUpdaterCallback *callback);

+        

         DECLSPEC_XFGVIRT(IUpdater, CheckForUpdate)

         HRESULT ( STDMETHODCALLTYPE *CheckForUpdate )( 

             IUpdater * This,

@@ -891,6 +899,9 @@
 #define IUpdater_GetVersion(This,version)	\

     ( (This)->lpVtbl -> GetVersion(This,version) ) 

 

+#define IUpdater_FetchPolicies(This,callback)	\

+    ( (This)->lpVtbl -> FetchPolicies(This,callback) ) 

+

 #define IUpdater_CheckForUpdate(This,app_id)	\

     ( (This)->lpVtbl -> CheckForUpdate(This,app_id) ) 

 

diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.tlb b/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.tlb
index feff6f8..859cf9c2 100644
--- a/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.tlb
+++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl.tlb
Binary files differ
diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl_p.c b/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl_p.c
index 8315fcf1..55e7cbcc 100644
--- a/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl_p.c
+++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/arm64/updater_idl_p.c
@@ -47,7 +47,7 @@
 #include "updater_idl.h"

 

 #define TYPE_FORMAT_STRING_SIZE   145                               

-#define PROC_FORMAT_STRING_SIZE   1127                              

+#define PROC_FORMAT_STRING_SIZE   1169                              

 #define EXPR_FORMAT_STRING_SIZE   1                                 

 #define TRANSMIT_AS_TABLE_SIZE    0            

 #define WIRE_MARSHAL_TABLE_SIZE   1            

@@ -745,7 +745,7 @@
 /* 628 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure CheckForUpdate */

+	/* Procedure FetchPolicies */

 

 /* 630 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

@@ -767,11 +767,11 @@
 /* 658 */	0x81,		/* 129 */

 			0x0,		/* 0 */

 

-	/* Parameter app_id */

+	/* Parameter callback */

 

-/* 660 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 660 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

 /* 662 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

-/* 664 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 664 */	NdrFcShort( 0x56 ),	/* Type Offset=86 */

 

 	/* Return value */

 

@@ -780,412 +780,447 @@
 /* 670 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure RegisterApp */

+	/* Procedure CheckForUpdate */

 

 /* 672 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

 /* 674 */	NdrFcLong( 0x0 ),	/* 0 */

 /* 678 */	NdrFcShort( 0x5 ),	/* 5 */

-/* 680 */	NdrFcShort( 0x48 ),	/* ARM64 Stack size/offset = 72 */

+/* 680 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

 /* 682 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 684 */	NdrFcShort( 0x8 ),	/* 8 */

 /* 686 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x8,		/* 8 */

-/* 688 */	0x14,		/* 20 */

+			0x2,		/* 2 */

+/* 688 */	0xe,		/* 14 */

 			0x1,		/* Ext Flags:  new corr desc, */

 /* 690 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 692 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 694 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 696 */	NdrFcShort( 0x8 ),	/* 8 */

-/* 698 */	0x8,		/* 8 */

+/* 696 */	NdrFcShort( 0x2 ),	/* 2 */

+/* 698 */	0x2,		/* 2 */

 			0x80,		/* 128 */

 /* 700 */	0x81,		/* 129 */

-			0x82,		/* 130 */

-/* 702 */	0x83,		/* 131 */

-			0x84,		/* 132 */

-/* 704 */	0x85,		/* 133 */

-			0x86,		/* 134 */

-/* 706 */	0x87,		/* 135 */

 			0x0,		/* 0 */

 

 	/* Parameter app_id */

 

-/* 708 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 710 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

-/* 712 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter brand_code */

-

-/* 714 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 716 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

-/* 718 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter brand_path */

-

-/* 720 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 722 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

-/* 724 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter tag */

-

-/* 726 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 728 */	NdrFcShort( 0x20 ),	/* ARM64 Stack size/offset = 32 */

-/* 730 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter version */

-

-/* 732 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 734 */	NdrFcShort( 0x28 ),	/* ARM64 Stack size/offset = 40 */

-/* 736 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter existence_checker_path */

-

-/* 738 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 740 */	NdrFcShort( 0x30 ),	/* ARM64 Stack size/offset = 48 */

-/* 742 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter callback */

-

-/* 744 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 746 */	NdrFcShort( 0x38 ),	/* ARM64 Stack size/offset = 56 */

-/* 748 */	NdrFcShort( 0x5a ),	/* Type Offset=90 */

+/* 702 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 704 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

+/* 706 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Return value */

 

-/* 750 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 752 */	NdrFcShort( 0x40 ),	/* ARM64 Stack size/offset = 64 */

-/* 754 */	0x8,		/* FC_LONG */

+/* 708 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 710 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

+/* 712 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure RunPeriodicTasks */

+	/* Procedure RegisterApp */

 

-/* 756 */	0x33,		/* FC_AUTO_HANDLE */

+/* 714 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

-/* 758 */	NdrFcLong( 0x0 ),	/* 0 */

-/* 762 */	NdrFcShort( 0x6 ),	/* 6 */

-/* 764 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

-/* 766 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 768 */	NdrFcShort( 0x8 ),	/* 8 */

-/* 770 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x2,		/* 2 */

-/* 772 */	0xe,		/* 14 */

+/* 716 */	NdrFcLong( 0x0 ),	/* 0 */

+/* 720 */	NdrFcShort( 0x6 ),	/* 6 */

+/* 722 */	NdrFcShort( 0x48 ),	/* ARM64 Stack size/offset = 72 */

+/* 724 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 726 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 728 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

+			0x8,		/* 8 */

+/* 730 */	0x14,		/* 20 */

 			0x1,		/* Ext Flags:  new corr desc, */

-/* 774 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 776 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 778 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 780 */	NdrFcShort( 0x2 ),	/* 2 */

-/* 782 */	0x2,		/* 2 */

+/* 732 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 734 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 736 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 738 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 740 */	0x8,		/* 8 */

 			0x80,		/* 128 */

-/* 784 */	0x81,		/* 129 */

+/* 742 */	0x81,		/* 129 */

+			0x82,		/* 130 */

+/* 744 */	0x83,		/* 131 */

+			0x84,		/* 132 */

+/* 746 */	0x85,		/* 133 */

+			0x86,		/* 134 */

+/* 748 */	0x87,		/* 135 */

 			0x0,		/* 0 */

 

+	/* Parameter app_id */

+

+/* 750 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 752 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

+/* 754 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter brand_code */

+

+/* 756 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 758 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

+/* 760 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter brand_path */

+

+/* 762 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 764 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

+/* 766 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter tag */

+

+/* 768 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 770 */	NdrFcShort( 0x20 ),	/* ARM64 Stack size/offset = 32 */

+/* 772 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter version */

+

+/* 774 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 776 */	NdrFcShort( 0x28 ),	/* ARM64 Stack size/offset = 40 */

+/* 778 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter existence_checker_path */

+

+/* 780 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 782 */	NdrFcShort( 0x30 ),	/* ARM64 Stack size/offset = 48 */

+/* 784 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

 	/* Parameter callback */

 

 /* 786 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 788 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

+/* 788 */	NdrFcShort( 0x38 ),	/* ARM64 Stack size/offset = 56 */

 /* 790 */	NdrFcShort( 0x6c ),	/* Type Offset=108 */

 

 	/* Return value */

 

 /* 792 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 794 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

+/* 794 */	NdrFcShort( 0x40 ),	/* ARM64 Stack size/offset = 64 */

 /* 796 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure Update */

+	/* Procedure RunPeriodicTasks */

 

 /* 798 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

 /* 800 */	NdrFcLong( 0x0 ),	/* 0 */

 /* 804 */	NdrFcShort( 0x7 ),	/* 7 */

-/* 806 */	NdrFcShort( 0x38 ),	/* ARM64 Stack size/offset = 56 */

-/* 808 */	NdrFcShort( 0x10 ),	/* 16 */

+/* 806 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

+/* 808 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 810 */	NdrFcShort( 0x8 ),	/* 8 */

 /* 812 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x6,		/* 6 */

-/* 814 */	0x12,		/* 18 */

+			0x2,		/* 2 */

+/* 814 */	0xe,		/* 14 */

 			0x1,		/* Ext Flags:  new corr desc, */

 /* 816 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 818 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 820 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 822 */	NdrFcShort( 0x6 ),	/* 6 */

-/* 824 */	0x6,		/* 6 */

+/* 822 */	NdrFcShort( 0x2 ),	/* 2 */

+/* 824 */	0x2,		/* 2 */

 			0x80,		/* 128 */

 /* 826 */	0x81,		/* 129 */

+			0x0,		/* 0 */

+

+	/* Parameter callback */

+

+/* 828 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

+/* 830 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

+/* 832 */	NdrFcShort( 0x56 ),	/* Type Offset=86 */

+

+	/* Return value */

+

+/* 834 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 836 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

+/* 838 */	0x8,		/* FC_LONG */

+			0x0,		/* 0 */

+

+	/* Procedure Update */

+

+/* 840 */	0x33,		/* FC_AUTO_HANDLE */

+			0x6c,		/* Old Flags:  object, Oi2 */

+/* 842 */	NdrFcLong( 0x0 ),	/* 0 */

+/* 846 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 848 */	NdrFcShort( 0x38 ),	/* ARM64 Stack size/offset = 56 */

+/* 850 */	NdrFcShort( 0x10 ),	/* 16 */

+/* 852 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 854 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

+			0x6,		/* 6 */

+/* 856 */	0x12,		/* 18 */

+			0x1,		/* Ext Flags:  new corr desc, */

+/* 858 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 860 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 862 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 864 */	NdrFcShort( 0x6 ),	/* 6 */

+/* 866 */	0x6,		/* 6 */

+			0x80,		/* 128 */

+/* 868 */	0x81,		/* 129 */

 			0x82,		/* 130 */

-/* 828 */	0x83,		/* 131 */

+/* 870 */	0x83,		/* 131 */

 			0x84,		/* 132 */

-/* 830 */	0x85,		/* 133 */

+/* 872 */	0x85,		/* 133 */

 			0x0,		/* 0 */

 

 	/* Parameter app_id */

 

-/* 832 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 834 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

-/* 836 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 874 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 876 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

+/* 878 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter install_data_index */

 

-/* 838 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 840 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

-/* 842 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 880 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 882 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

+/* 884 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter priority */

 

-/* 844 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

-/* 846 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

-/* 848 */	0x8,		/* FC_LONG */

+/* 886 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

+/* 888 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

+/* 890 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

 	/* Parameter same_version_update_allowed */

 

-/* 850 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

-/* 852 */	NdrFcShort( 0x20 ),	/* ARM64 Stack size/offset = 32 */

-/* 854 */	0x8,		/* FC_LONG */

-			0x0,		/* 0 */

-

-	/* Parameter observer */

-

-/* 856 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 858 */	NdrFcShort( 0x28 ),	/* ARM64 Stack size/offset = 40 */

-/* 860 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

-

-	/* Return value */

-

-/* 862 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 864 */	NdrFcShort( 0x30 ),	/* ARM64 Stack size/offset = 48 */

-/* 866 */	0x8,		/* FC_LONG */

-			0x0,		/* 0 */

-

-	/* Procedure UpdateAll */

-

-/* 868 */	0x33,		/* FC_AUTO_HANDLE */

-			0x6c,		/* Old Flags:  object, Oi2 */

-/* 870 */	NdrFcLong( 0x0 ),	/* 0 */

-/* 874 */	NdrFcShort( 0x8 ),	/* 8 */

-/* 876 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

-/* 878 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 880 */	NdrFcShort( 0x8 ),	/* 8 */

-/* 882 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x2,		/* 2 */

-/* 884 */	0xe,		/* 14 */

-			0x1,		/* Ext Flags:  new corr desc, */

-/* 886 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 888 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 890 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 892 */	NdrFcShort( 0x2 ),	/* 2 */

-/* 894 */	0x2,		/* 2 */

-			0x80,		/* 128 */

-/* 896 */	0x81,		/* 129 */

+/* 892 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

+/* 894 */	NdrFcShort( 0x20 ),	/* ARM64 Stack size/offset = 32 */

+/* 896 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

 	/* Parameter observer */

 

 /* 898 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 900 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

+/* 900 */	NdrFcShort( 0x28 ),	/* ARM64 Stack size/offset = 40 */

 /* 902 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

 

 	/* Return value */

 

 /* 904 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 906 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

+/* 906 */	NdrFcShort( 0x30 ),	/* ARM64 Stack size/offset = 48 */

 /* 908 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure Install */

+	/* Procedure UpdateAll */

 

 /* 910 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

 /* 912 */	NdrFcLong( 0x0 ),	/* 0 */

 /* 916 */	NdrFcShort( 0x9 ),	/* 9 */

-/* 918 */	NdrFcShort( 0x58 ),	/* ARM64 Stack size/offset = 88 */

-/* 920 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 918 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

+/* 920 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 922 */	NdrFcShort( 0x8 ),	/* 8 */

 /* 924 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0xa,		/* 10 */

-/* 926 */	0x16,		/* 22 */

+			0x2,		/* 2 */

+/* 926 */	0xe,		/* 14 */

 			0x1,		/* Ext Flags:  new corr desc, */

 /* 928 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 930 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 932 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 934 */	NdrFcShort( 0xa ),	/* 10 */

-/* 936 */	0xa,		/* 10 */

+/* 934 */	NdrFcShort( 0x2 ),	/* 2 */

+/* 936 */	0x2,		/* 2 */

 			0x80,		/* 128 */

 /* 938 */	0x81,		/* 129 */

-			0x82,		/* 130 */

-/* 940 */	0x83,		/* 131 */

-			0x84,		/* 132 */

-/* 942 */	0x85,		/* 133 */

-			0x86,		/* 134 */

-/* 944 */	0x87,		/* 135 */

-			0xf8,		/* 248 */

-/* 946 */	0xf8,		/* 248 */

-			0x0,		/* 0 */

-

-	/* Parameter app_id */

-

-/* 948 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 950 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

-/* 952 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter brand_code */

-

-/* 954 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 956 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

-/* 958 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter brand_path */

-

-/* 960 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 962 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

-/* 964 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter tag */

-

-/* 966 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 968 */	NdrFcShort( 0x20 ),	/* ARM64 Stack size/offset = 32 */

-/* 970 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter version */

-

-/* 972 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 974 */	NdrFcShort( 0x28 ),	/* ARM64 Stack size/offset = 40 */

-/* 976 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter existence_checker_path */

-

-/* 978 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 980 */	NdrFcShort( 0x30 ),	/* ARM64 Stack size/offset = 48 */

-/* 982 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter install_data_index */

-

-/* 984 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 986 */	NdrFcShort( 0x38 ),	/* ARM64 Stack size/offset = 56 */

-/* 988 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter priority */

-

-/* 990 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

-/* 992 */	NdrFcShort( 0x40 ),	/* ARM64 Stack size/offset = 64 */

-/* 994 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

 	/* Parameter observer */

 

-/* 996 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 998 */	NdrFcShort( 0x48 ),	/* ARM64 Stack size/offset = 72 */

-/* 1000 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

+/* 940 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

+/* 942 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

+/* 944 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

 

 	/* Return value */

 

-/* 1002 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 1004 */	NdrFcShort( 0x50 ),	/* ARM64 Stack size/offset = 80 */

-/* 1006 */	0x8,		/* FC_LONG */

+/* 946 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 948 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

+/* 950 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure CancelInstalls */

+	/* Procedure Install */

 

-/* 1008 */	0x33,		/* FC_AUTO_HANDLE */

+/* 952 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

-/* 1010 */	NdrFcLong( 0x0 ),	/* 0 */

-/* 1014 */	NdrFcShort( 0xa ),	/* 10 */

-/* 1016 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

-/* 1018 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 1020 */	NdrFcShort( 0x8 ),	/* 8 */

-/* 1022 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x2,		/* 2 */

-/* 1024 */	0xe,		/* 14 */

+/* 954 */	NdrFcLong( 0x0 ),	/* 0 */

+/* 958 */	NdrFcShort( 0xa ),	/* 10 */

+/* 960 */	NdrFcShort( 0x58 ),	/* ARM64 Stack size/offset = 88 */

+/* 962 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 964 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 966 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

+			0xa,		/* 10 */

+/* 968 */	0x16,		/* 22 */

 			0x1,		/* Ext Flags:  new corr desc, */

-/* 1026 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 1028 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 1030 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 1032 */	NdrFcShort( 0x2 ),	/* 2 */

-/* 1034 */	0x2,		/* 2 */

+/* 970 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 972 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 974 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 976 */	NdrFcShort( 0xa ),	/* 10 */

+/* 978 */	0xa,		/* 10 */

 			0x80,		/* 128 */

-/* 1036 */	0x81,		/* 129 */

+/* 980 */	0x81,		/* 129 */

+			0x82,		/* 130 */

+/* 982 */	0x83,		/* 131 */

+			0x84,		/* 132 */

+/* 984 */	0x85,		/* 133 */

+			0x86,		/* 134 */

+/* 986 */	0x87,		/* 135 */

+			0xf8,		/* 248 */

+/* 988 */	0xf8,		/* 248 */

 			0x0,		/* 0 */

 

 	/* Parameter app_id */

 

-/* 1038 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 1040 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

-/* 1042 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 990 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 992 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

+/* 994 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter brand_code */

+

+/* 996 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 998 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

+/* 1000 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter brand_path */

+

+/* 1002 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1004 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

+/* 1006 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter tag */

+

+/* 1008 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1010 */	NdrFcShort( 0x20 ),	/* ARM64 Stack size/offset = 32 */

+/* 1012 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter version */

+

+/* 1014 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1016 */	NdrFcShort( 0x28 ),	/* ARM64 Stack size/offset = 40 */

+/* 1018 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter existence_checker_path */

+

+/* 1020 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1022 */	NdrFcShort( 0x30 ),	/* ARM64 Stack size/offset = 48 */

+/* 1024 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter install_data_index */

+

+/* 1026 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1028 */	NdrFcShort( 0x38 ),	/* ARM64 Stack size/offset = 56 */

+/* 1030 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter priority */

+

+/* 1032 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

+/* 1034 */	NdrFcShort( 0x40 ),	/* ARM64 Stack size/offset = 64 */

+/* 1036 */	0x8,		/* FC_LONG */

+			0x0,		/* 0 */

+

+	/* Parameter observer */

+

+/* 1038 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

+/* 1040 */	NdrFcShort( 0x48 ),	/* ARM64 Stack size/offset = 72 */

+/* 1042 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

 

 	/* Return value */

 

 /* 1044 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 1046 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

+/* 1046 */	NdrFcShort( 0x50 ),	/* ARM64 Stack size/offset = 80 */

 /* 1048 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure RunInstaller */

+	/* Procedure CancelInstalls */

 

 /* 1050 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

 /* 1052 */	NdrFcLong( 0x0 ),	/* 0 */

 /* 1056 */	NdrFcShort( 0xb ),	/* 11 */

-/* 1058 */	NdrFcShort( 0x40 ),	/* ARM64 Stack size/offset = 64 */

+/* 1058 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

 /* 1060 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 1062 */	NdrFcShort( 0x8 ),	/* 8 */

 /* 1064 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x7,		/* 7 */

-/* 1066 */	0x12,		/* 18 */

+			0x2,		/* 2 */

+/* 1066 */	0xe,		/* 14 */

 			0x1,		/* Ext Flags:  new corr desc, */

 /* 1068 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 1070 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 1072 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 1074 */	NdrFcShort( 0x7 ),	/* 7 */

-/* 1076 */	0x7,		/* 7 */

+/* 1074 */	NdrFcShort( 0x2 ),	/* 2 */

+/* 1076 */	0x2,		/* 2 */

 			0x80,		/* 128 */

 /* 1078 */	0x81,		/* 129 */

+			0x0,		/* 0 */

+

+	/* Parameter app_id */

+

+/* 1080 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1082 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

+/* 1084 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Return value */

+

+/* 1086 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 1088 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

+/* 1090 */	0x8,		/* FC_LONG */

+			0x0,		/* 0 */

+

+	/* Procedure RunInstaller */

+

+/* 1092 */	0x33,		/* FC_AUTO_HANDLE */

+			0x6c,		/* Old Flags:  object, Oi2 */

+/* 1094 */	NdrFcLong( 0x0 ),	/* 0 */

+/* 1098 */	NdrFcShort( 0xc ),	/* 12 */

+/* 1100 */	NdrFcShort( 0x40 ),	/* ARM64 Stack size/offset = 64 */

+/* 1102 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 1104 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 1106 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

+			0x7,		/* 7 */

+/* 1108 */	0x12,		/* 18 */

+			0x1,		/* Ext Flags:  new corr desc, */

+/* 1110 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 1112 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 1114 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 1116 */	NdrFcShort( 0x7 ),	/* 7 */

+/* 1118 */	0x7,		/* 7 */

+			0x80,		/* 128 */

+/* 1120 */	0x81,		/* 129 */

 			0x82,		/* 130 */

-/* 1080 */	0x83,		/* 131 */

+/* 1122 */	0x83,		/* 131 */

 			0x84,		/* 132 */

-/* 1082 */	0x85,		/* 133 */

+/* 1124 */	0x85,		/* 133 */

 			0x86,		/* 134 */

 

 	/* Parameter app_id */

 

-/* 1084 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 1086 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

-/* 1088 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 1126 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1128 */	NdrFcShort( 0x8 ),	/* ARM64 Stack size/offset = 8 */

+/* 1130 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter installer_path */

 

-/* 1090 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 1092 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

-/* 1094 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 1132 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1134 */	NdrFcShort( 0x10 ),	/* ARM64 Stack size/offset = 16 */

+/* 1136 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter install_args */

 

-/* 1096 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 1098 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

-/* 1100 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 1138 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1140 */	NdrFcShort( 0x18 ),	/* ARM64 Stack size/offset = 24 */

+/* 1142 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter install_data */

 

-/* 1102 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 1104 */	NdrFcShort( 0x20 ),	/* ARM64 Stack size/offset = 32 */

-/* 1106 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 1144 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1146 */	NdrFcShort( 0x20 ),	/* ARM64 Stack size/offset = 32 */

+/* 1148 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter install_settings */

 

-/* 1108 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 1110 */	NdrFcShort( 0x28 ),	/* ARM64 Stack size/offset = 40 */

-/* 1112 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 1150 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1152 */	NdrFcShort( 0x28 ),	/* ARM64 Stack size/offset = 40 */

+/* 1154 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter observer */

 

-/* 1114 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 1116 */	NdrFcShort( 0x30 ),	/* ARM64 Stack size/offset = 48 */

-/* 1118 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

+/* 1156 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

+/* 1158 */	NdrFcShort( 0x30 ),	/* ARM64 Stack size/offset = 48 */

+/* 1160 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

 

 	/* Return value */

 

-/* 1120 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 1122 */	NdrFcShort( 0x38 ),	/* ARM64 Stack size/offset = 56 */

-/* 1124 */	0x8,		/* FC_LONG */

+/* 1162 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 1164 */	NdrFcShort( 0x38 ),	/* ARM64 Stack size/offset = 56 */

+/* 1166 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

 			0x0

@@ -1265,38 +1300,38 @@
 /* 84 */	0x2a,		/* 42 */

 			0xb,		/* 11 */

 /* 86 */	

-			0x11, 0x8,	/* FC_RP [simple_pointer] */

-/* 88 */	

-			0x25,		/* FC_C_WSTRING */

-			0x5c,		/* FC_PAD */

-/* 90 */	

 			0x2f,		/* FC_IP */

 			0x5a,		/* FC_CONSTANT_IID */

-/* 92 */	NdrFcLong( 0x3fdec4cb ),	/* 1071563979 */

-/* 96 */	NdrFcShort( 0x8501 ),	/* -31487 */

-/* 98 */	NdrFcShort( 0x4ecd ),	/* 20173 */

-/* 100 */	0xa4,		/* 164 */

-			0xcf,		/* 207 */

-/* 102 */	0xbf,		/* 191 */

-			0x70,		/* 112 */

-/* 104 */	0x32,		/* 50 */

-			0x62,		/* 98 */

-/* 106 */	0x18,		/* 24 */

-			0xd0,		/* 208 */

+/* 88 */	NdrFcLong( 0x8bab6f84 ),	/* -1951699068 */

+/* 92 */	NdrFcShort( 0xad67 ),	/* -21145 */

+/* 94 */	NdrFcShort( 0x4819 ),	/* 18457 */

+/* 96 */	0xb8,		/* 184 */

+			0x46,		/* 70 */

+/* 98 */	0xcc,		/* 204 */

+			0x89,		/* 137 */

+/* 100 */	0x8,		/* 8 */

+			0x80,		/* 128 */

+/* 102 */	0xfd,		/* 253 */

+			0x3b,		/* 59 */

+/* 104 */	

+			0x11, 0x8,	/* FC_RP [simple_pointer] */

+/* 106 */	

+			0x25,		/* FC_C_WSTRING */

+			0x5c,		/* FC_PAD */

 /* 108 */	

 			0x2f,		/* FC_IP */

 			0x5a,		/* FC_CONSTANT_IID */

-/* 110 */	NdrFcLong( 0x8bab6f84 ),	/* -1951699068 */

-/* 114 */	NdrFcShort( 0xad67 ),	/* -21145 */

-/* 116 */	NdrFcShort( 0x4819 ),	/* 18457 */

-/* 118 */	0xb8,		/* 184 */

-			0x46,		/* 70 */

-/* 120 */	0xcc,		/* 204 */

-			0x89,		/* 137 */

-/* 122 */	0x8,		/* 8 */

-			0x80,		/* 128 */

-/* 124 */	0xfd,		/* 253 */

-			0x3b,		/* 59 */

+/* 110 */	NdrFcLong( 0x3fdec4cb ),	/* 1071563979 */

+/* 114 */	NdrFcShort( 0x8501 ),	/* -31487 */

+/* 116 */	NdrFcShort( 0x4ecd ),	/* 20173 */

+/* 118 */	0xa4,		/* 164 */

+			0xcf,		/* 207 */

+/* 120 */	0xbf,		/* 191 */

+			0x70,		/* 112 */

+/* 122 */	0x32,		/* 50 */

+			0x62,		/* 98 */

+/* 124 */	0x18,		/* 24 */

+			0xd0,		/* 208 */

 /* 126 */	

 			0x2f,		/* FC_IP */

 			0x5a,		/* FC_CONSTANT_IID */

@@ -1621,12 +1656,13 @@
     588,

     630,

     672,

-    756,

+    714,

     798,

-    868,

+    840,

     910,

-    1008,

-    1050

+    952,

+    1050,

+    1092

     };

 

 static const MIDL_STUBLESS_PROXY_INFO IUpdater_ProxyInfo =

@@ -1650,7 +1686,7 @@
     0,

     0,

     0};

-CINTERFACE_PROXY_VTABLE(12) _IUpdaterProxyVtbl = 

+CINTERFACE_PROXY_VTABLE(13) _IUpdaterProxyVtbl = 

 {

     &IUpdater_ProxyInfo,

     &IID_IUpdater,

@@ -1658,6 +1694,7 @@
     IUnknown_AddRef_Proxy,

     IUnknown_Release_Proxy ,

     (void *) (INT_PTR) -1 /* IUpdater::GetVersion */ ,

+    (void *) (INT_PTR) -1 /* IUpdater::FetchPolicies */ ,

     (void *) (INT_PTR) -1 /* IUpdater::CheckForUpdate */ ,

     (void *) (INT_PTR) -1 /* IUpdater::RegisterApp */ ,

     (void *) (INT_PTR) -1 /* IUpdater::RunPeriodicTasks */ ,

@@ -1672,7 +1709,7 @@
 {

     &IID_IUpdater,

     &IUpdater_ServerInfo,

-    12,

+    13,

     0, /* pure interpreted */

     CStdStubBuffer_METHODS

 };

diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.h b/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.h
index 72f2a7c..810871d7 100644
--- a/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.h
+++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.h
@@ -726,6 +726,9 @@
         virtual HRESULT STDMETHODCALLTYPE GetVersion( 

             /* [retval][out] */ BSTR *version) = 0;

         

+        virtual HRESULT STDMETHODCALLTYPE FetchPolicies( 

+            /* [in] */ IUpdaterCallback *callback) = 0;

+        

         virtual HRESULT STDMETHODCALLTYPE CheckForUpdate( 

             /* [string][in] */ const WCHAR *app_id) = 0;

         

@@ -802,6 +805,11 @@
             IUpdater * This,

             /* [retval][out] */ BSTR *version);

         

+        DECLSPEC_XFGVIRT(IUpdater, FetchPolicies)

+        HRESULT ( STDMETHODCALLTYPE *FetchPolicies )( 

+            IUpdater * This,

+            /* [in] */ IUpdaterCallback *callback);

+        

         DECLSPEC_XFGVIRT(IUpdater, CheckForUpdate)

         HRESULT ( STDMETHODCALLTYPE *CheckForUpdate )( 

             IUpdater * This,

@@ -891,6 +899,9 @@
 #define IUpdater_GetVersion(This,version)	\

     ( (This)->lpVtbl -> GetVersion(This,version) ) 

 

+#define IUpdater_FetchPolicies(This,callback)	\

+    ( (This)->lpVtbl -> FetchPolicies(This,callback) ) 

+

 #define IUpdater_CheckForUpdate(This,app_id)	\

     ( (This)->lpVtbl -> CheckForUpdate(This,app_id) ) 

 

diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.tlb b/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.tlb
index feff6f8..859cf9c2 100644
--- a/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.tlb
+++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl.tlb
Binary files differ
diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl_p.c b/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl_p.c
index 03f2a3cb..73f173f2 100644
--- a/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl_p.c
+++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/x64/updater_idl_p.c
@@ -47,7 +47,7 @@
 #include "updater_idl.h"

 

 #define TYPE_FORMAT_STRING_SIZE   145                               

-#define PROC_FORMAT_STRING_SIZE   1013                              

+#define PROC_FORMAT_STRING_SIZE   1051                              

 #define EXPR_FORMAT_STRING_SIZE   1                                 

 #define TRANSMIT_AS_TABLE_SIZE    0            

 #define WIRE_MARSHAL_TABLE_SIZE   1            

@@ -685,7 +685,7 @@
 /* 568 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure CheckForUpdate */

+	/* Procedure FetchPolicies */

 

 /* 570 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

@@ -703,11 +703,11 @@
 /* 592 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 594 */	NdrFcShort( 0x0 ),	/* 0 */

 

-	/* Parameter app_id */

+	/* Parameter callback */

 

-/* 596 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 596 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

 /* 598 */	NdrFcShort( 0x8 ),	/* X64 Stack size/offset = 8 */

-/* 600 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 600 */	NdrFcShort( 0x56 ),	/* Type Offset=86 */

 

 	/* Return value */

 

@@ -716,17 +716,17 @@
 /* 606 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure RegisterApp */

+	/* Procedure CheckForUpdate */

 

 /* 608 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

 /* 610 */	NdrFcLong( 0x0 ),	/* 0 */

 /* 614 */	NdrFcShort( 0x5 ),	/* 5 */

-/* 616 */	NdrFcShort( 0x48 ),	/* X64 Stack size/offset = 72 */

+/* 616 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

 /* 618 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 620 */	NdrFcShort( 0x8 ),	/* 8 */

 /* 622 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x8,		/* 8 */

+			0x2,		/* 2 */

 /* 624 */	0xa,		/* 10 */

 			0x1,		/* Ext Flags:  new corr desc, */

 /* 626 */	NdrFcShort( 0x0 ),	/* 0 */

@@ -738,93 +738,93 @@
 

 /* 634 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

 /* 636 */	NdrFcShort( 0x8 ),	/* X64 Stack size/offset = 8 */

-/* 638 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter brand_code */

-

-/* 640 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 642 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

-/* 644 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter brand_path */

-

-/* 646 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 648 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

-/* 650 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter tag */

-

-/* 652 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 654 */	NdrFcShort( 0x20 ),	/* X64 Stack size/offset = 32 */

-/* 656 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter version */

-

-/* 658 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 660 */	NdrFcShort( 0x28 ),	/* X64 Stack size/offset = 40 */

-/* 662 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter existence_checker_path */

-

-/* 664 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 666 */	NdrFcShort( 0x30 ),	/* X64 Stack size/offset = 48 */

-/* 668 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter callback */

-

-/* 670 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 672 */	NdrFcShort( 0x38 ),	/* X64 Stack size/offset = 56 */

-/* 674 */	NdrFcShort( 0x5a ),	/* Type Offset=90 */

+/* 638 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Return value */

 

-/* 676 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 678 */	NdrFcShort( 0x40 ),	/* X64 Stack size/offset = 64 */

-/* 680 */	0x8,		/* FC_LONG */

+/* 640 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 642 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

+/* 644 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure RunPeriodicTasks */

+	/* Procedure RegisterApp */

 

-/* 682 */	0x33,		/* FC_AUTO_HANDLE */

+/* 646 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

-/* 684 */	NdrFcLong( 0x0 ),	/* 0 */

-/* 688 */	NdrFcShort( 0x6 ),	/* 6 */

-/* 690 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

-/* 692 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 694 */	NdrFcShort( 0x8 ),	/* 8 */

-/* 696 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x2,		/* 2 */

-/* 698 */	0xa,		/* 10 */

+/* 648 */	NdrFcLong( 0x0 ),	/* 0 */

+/* 652 */	NdrFcShort( 0x6 ),	/* 6 */

+/* 654 */	NdrFcShort( 0x48 ),	/* X64 Stack size/offset = 72 */

+/* 656 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 658 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 660 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

+			0x8,		/* 8 */

+/* 662 */	0xa,		/* 10 */

 			0x1,		/* Ext Flags:  new corr desc, */

-/* 700 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 702 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 704 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 706 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 664 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 666 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 668 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 670 */	NdrFcShort( 0x0 ),	/* 0 */

+

+	/* Parameter app_id */

+

+/* 672 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 674 */	NdrFcShort( 0x8 ),	/* X64 Stack size/offset = 8 */

+/* 676 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter brand_code */

+

+/* 678 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 680 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

+/* 682 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter brand_path */

+

+/* 684 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 686 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

+/* 688 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter tag */

+

+/* 690 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 692 */	NdrFcShort( 0x20 ),	/* X64 Stack size/offset = 32 */

+/* 694 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter version */

+

+/* 696 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 698 */	NdrFcShort( 0x28 ),	/* X64 Stack size/offset = 40 */

+/* 700 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter existence_checker_path */

+

+/* 702 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 704 */	NdrFcShort( 0x30 ),	/* X64 Stack size/offset = 48 */

+/* 706 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter callback */

 

 /* 708 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 710 */	NdrFcShort( 0x8 ),	/* X64 Stack size/offset = 8 */

+/* 710 */	NdrFcShort( 0x38 ),	/* X64 Stack size/offset = 56 */

 /* 712 */	NdrFcShort( 0x6c ),	/* Type Offset=108 */

 

 	/* Return value */

 

 /* 714 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 716 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

+/* 716 */	NdrFcShort( 0x40 ),	/* X64 Stack size/offset = 64 */

 /* 718 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure Update */

+	/* Procedure RunPeriodicTasks */

 

 /* 720 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

 /* 722 */	NdrFcLong( 0x0 ),	/* 0 */

 /* 726 */	NdrFcShort( 0x7 ),	/* 7 */

-/* 728 */	NdrFcShort( 0x38 ),	/* X64 Stack size/offset = 56 */

-/* 730 */	NdrFcShort( 0x10 ),	/* 16 */

+/* 728 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

+/* 730 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 732 */	NdrFcShort( 0x8 ),	/* 8 */

 /* 734 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x6,		/* 6 */

+			0x2,		/* 2 */

 /* 736 */	0xa,		/* 10 */

 			0x1,		/* Ext Flags:  new corr desc, */

 /* 738 */	NdrFcShort( 0x0 ),	/* 0 */

@@ -832,87 +832,87 @@
 /* 742 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 744 */	NdrFcShort( 0x0 ),	/* 0 */

 

+	/* Parameter callback */

+

+/* 746 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

+/* 748 */	NdrFcShort( 0x8 ),	/* X64 Stack size/offset = 8 */

+/* 750 */	NdrFcShort( 0x56 ),	/* Type Offset=86 */

+

+	/* Return value */

+

+/* 752 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 754 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

+/* 756 */	0x8,		/* FC_LONG */

+			0x0,		/* 0 */

+

+	/* Procedure Update */

+

+/* 758 */	0x33,		/* FC_AUTO_HANDLE */

+			0x6c,		/* Old Flags:  object, Oi2 */

+/* 760 */	NdrFcLong( 0x0 ),	/* 0 */

+/* 764 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 766 */	NdrFcShort( 0x38 ),	/* X64 Stack size/offset = 56 */

+/* 768 */	NdrFcShort( 0x10 ),	/* 16 */

+/* 770 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 772 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

+			0x6,		/* 6 */

+/* 774 */	0xa,		/* 10 */

+			0x1,		/* Ext Flags:  new corr desc, */

+/* 776 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 778 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 780 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 782 */	NdrFcShort( 0x0 ),	/* 0 */

+

 	/* Parameter app_id */

 

-/* 746 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 748 */	NdrFcShort( 0x8 ),	/* X64 Stack size/offset = 8 */

-/* 750 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 784 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 786 */	NdrFcShort( 0x8 ),	/* X64 Stack size/offset = 8 */

+/* 788 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter install_data_index */

 

-/* 752 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 754 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

-/* 756 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 790 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 792 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

+/* 794 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter priority */

 

-/* 758 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

-/* 760 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

-/* 762 */	0x8,		/* FC_LONG */

+/* 796 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

+/* 798 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

+/* 800 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

 	/* Parameter same_version_update_allowed */

 

-/* 764 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

-/* 766 */	NdrFcShort( 0x20 ),	/* X64 Stack size/offset = 32 */

-/* 768 */	0x8,		/* FC_LONG */

+/* 802 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

+/* 804 */	NdrFcShort( 0x20 ),	/* X64 Stack size/offset = 32 */

+/* 806 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

 	/* Parameter observer */

 

-/* 770 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 772 */	NdrFcShort( 0x28 ),	/* X64 Stack size/offset = 40 */

-/* 774 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

-

-	/* Return value */

-

-/* 776 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 778 */	NdrFcShort( 0x30 ),	/* X64 Stack size/offset = 48 */

-/* 780 */	0x8,		/* FC_LONG */

-			0x0,		/* 0 */

-

-	/* Procedure UpdateAll */

-

-/* 782 */	0x33,		/* FC_AUTO_HANDLE */

-			0x6c,		/* Old Flags:  object, Oi2 */

-/* 784 */	NdrFcLong( 0x0 ),	/* 0 */

-/* 788 */	NdrFcShort( 0x8 ),	/* 8 */

-/* 790 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

-/* 792 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 794 */	NdrFcShort( 0x8 ),	/* 8 */

-/* 796 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x2,		/* 2 */

-/* 798 */	0xa,		/* 10 */

-			0x1,		/* Ext Flags:  new corr desc, */

-/* 800 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 802 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 804 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 806 */	NdrFcShort( 0x0 ),	/* 0 */

-

-	/* Parameter observer */

-

 /* 808 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 810 */	NdrFcShort( 0x8 ),	/* X64 Stack size/offset = 8 */

+/* 810 */	NdrFcShort( 0x28 ),	/* X64 Stack size/offset = 40 */

 /* 812 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

 

 	/* Return value */

 

 /* 814 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 816 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

+/* 816 */	NdrFcShort( 0x30 ),	/* X64 Stack size/offset = 48 */

 /* 818 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure Install */

+	/* Procedure UpdateAll */

 

 /* 820 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

 /* 822 */	NdrFcLong( 0x0 ),	/* 0 */

 /* 826 */	NdrFcShort( 0x9 ),	/* 9 */

-/* 828 */	NdrFcShort( 0x58 ),	/* X64 Stack size/offset = 88 */

-/* 830 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 828 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

+/* 830 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 832 */	NdrFcShort( 0x8 ),	/* 8 */

 /* 834 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0xa,		/* 10 */

+			0x2,		/* 2 */

 /* 836 */	0xa,		/* 10 */

 			0x1,		/* Ext Flags:  new corr desc, */

 /* 838 */	NdrFcShort( 0x0 ),	/* 0 */

@@ -920,110 +920,110 @@
 /* 842 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 844 */	NdrFcShort( 0x0 ),	/* 0 */

 

+	/* Parameter observer */

+

+/* 846 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

+/* 848 */	NdrFcShort( 0x8 ),	/* X64 Stack size/offset = 8 */

+/* 850 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

+

+	/* Return value */

+

+/* 852 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 854 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

+/* 856 */	0x8,		/* FC_LONG */

+			0x0,		/* 0 */

+

+	/* Procedure Install */

+

+/* 858 */	0x33,		/* FC_AUTO_HANDLE */

+			0x6c,		/* Old Flags:  object, Oi2 */

+/* 860 */	NdrFcLong( 0x0 ),	/* 0 */

+/* 864 */	NdrFcShort( 0xa ),	/* 10 */

+/* 866 */	NdrFcShort( 0x58 ),	/* X64 Stack size/offset = 88 */

+/* 868 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 870 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 872 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

+			0xa,		/* 10 */

+/* 874 */	0xa,		/* 10 */

+			0x1,		/* Ext Flags:  new corr desc, */

+/* 876 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 878 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 880 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 882 */	NdrFcShort( 0x0 ),	/* 0 */

+

 	/* Parameter app_id */

 

-/* 846 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 848 */	NdrFcShort( 0x8 ),	/* X64 Stack size/offset = 8 */

-/* 850 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 884 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 886 */	NdrFcShort( 0x8 ),	/* X64 Stack size/offset = 8 */

+/* 888 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter brand_code */

 

-/* 852 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 854 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

-/* 856 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 890 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 892 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

+/* 894 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter brand_path */

 

-/* 858 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 860 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

-/* 862 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 896 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 898 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

+/* 900 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter tag */

 

-/* 864 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 866 */	NdrFcShort( 0x20 ),	/* X64 Stack size/offset = 32 */

-/* 868 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 902 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 904 */	NdrFcShort( 0x20 ),	/* X64 Stack size/offset = 32 */

+/* 906 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter version */

 

-/* 870 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 872 */	NdrFcShort( 0x28 ),	/* X64 Stack size/offset = 40 */

-/* 874 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 908 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 910 */	NdrFcShort( 0x28 ),	/* X64 Stack size/offset = 40 */

+/* 912 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter existence_checker_path */

 

-/* 876 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 878 */	NdrFcShort( 0x30 ),	/* X64 Stack size/offset = 48 */

-/* 880 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 914 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 916 */	NdrFcShort( 0x30 ),	/* X64 Stack size/offset = 48 */

+/* 918 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter install_data_index */

 

-/* 882 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 884 */	NdrFcShort( 0x38 ),	/* X64 Stack size/offset = 56 */

-/* 886 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 920 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 922 */	NdrFcShort( 0x38 ),	/* X64 Stack size/offset = 56 */

+/* 924 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter priority */

 

-/* 888 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

-/* 890 */	NdrFcShort( 0x40 ),	/* X64 Stack size/offset = 64 */

-/* 892 */	0x8,		/* FC_LONG */

+/* 926 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

+/* 928 */	NdrFcShort( 0x40 ),	/* X64 Stack size/offset = 64 */

+/* 930 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

 	/* Parameter observer */

 

-/* 894 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 896 */	NdrFcShort( 0x48 ),	/* X64 Stack size/offset = 72 */

-/* 898 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

-

-	/* Return value */

-

-/* 900 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 902 */	NdrFcShort( 0x50 ),	/* X64 Stack size/offset = 80 */

-/* 904 */	0x8,		/* FC_LONG */

-			0x0,		/* 0 */

-

-	/* Procedure CancelInstalls */

-

-/* 906 */	0x33,		/* FC_AUTO_HANDLE */

-			0x6c,		/* Old Flags:  object, Oi2 */

-/* 908 */	NdrFcLong( 0x0 ),	/* 0 */

-/* 912 */	NdrFcShort( 0xa ),	/* 10 */

-/* 914 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

-/* 916 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 918 */	NdrFcShort( 0x8 ),	/* 8 */

-/* 920 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x2,		/* 2 */

-/* 922 */	0xa,		/* 10 */

-			0x1,		/* Ext Flags:  new corr desc, */

-/* 924 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 926 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 928 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 930 */	NdrFcShort( 0x0 ),	/* 0 */

-

-	/* Parameter app_id */

-

-/* 932 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 934 */	NdrFcShort( 0x8 ),	/* X64 Stack size/offset = 8 */

-/* 936 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 932 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

+/* 934 */	NdrFcShort( 0x48 ),	/* X64 Stack size/offset = 72 */

+/* 936 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

 

 	/* Return value */

 

 /* 938 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 940 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

+/* 940 */	NdrFcShort( 0x50 ),	/* X64 Stack size/offset = 80 */

 /* 942 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure RunInstaller */

+	/* Procedure CancelInstalls */

 

 /* 944 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

 /* 946 */	NdrFcLong( 0x0 ),	/* 0 */

 /* 950 */	NdrFcShort( 0xb ),	/* 11 */

-/* 952 */	NdrFcShort( 0x40 ),	/* X64 Stack size/offset = 64 */

+/* 952 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

 /* 954 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 956 */	NdrFcShort( 0x8 ),	/* 8 */

 /* 958 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x7,		/* 7 */

+			0x2,		/* 2 */

 /* 960 */	0xa,		/* 10 */

 			0x1,		/* Ext Flags:  new corr desc, */

 /* 962 */	NdrFcShort( 0x0 ),	/* 0 */

@@ -1035,43 +1035,74 @@
 

 /* 970 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

 /* 972 */	NdrFcShort( 0x8 ),	/* X64 Stack size/offset = 8 */

-/* 974 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter installer_path */

-

-/* 976 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 978 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

-/* 980 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter install_args */

-

-/* 982 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 984 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

-/* 986 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter install_data */

-

-/* 988 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 990 */	NdrFcShort( 0x20 ),	/* X64 Stack size/offset = 32 */

-/* 992 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter install_settings */

-

-/* 994 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 996 */	NdrFcShort( 0x28 ),	/* X64 Stack size/offset = 40 */

-/* 998 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter observer */

-

-/* 1000 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 1002 */	NdrFcShort( 0x30 ),	/* X64 Stack size/offset = 48 */

-/* 1004 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

+/* 974 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Return value */

 

-/* 1006 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 1008 */	NdrFcShort( 0x38 ),	/* X64 Stack size/offset = 56 */

-/* 1010 */	0x8,		/* FC_LONG */

+/* 976 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 978 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

+/* 980 */	0x8,		/* FC_LONG */

+			0x0,		/* 0 */

+

+	/* Procedure RunInstaller */

+

+/* 982 */	0x33,		/* FC_AUTO_HANDLE */

+			0x6c,		/* Old Flags:  object, Oi2 */

+/* 984 */	NdrFcLong( 0x0 ),	/* 0 */

+/* 988 */	NdrFcShort( 0xc ),	/* 12 */

+/* 990 */	NdrFcShort( 0x40 ),	/* X64 Stack size/offset = 64 */

+/* 992 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 994 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 996 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

+			0x7,		/* 7 */

+/* 998 */	0xa,		/* 10 */

+			0x1,		/* Ext Flags:  new corr desc, */

+/* 1000 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 1002 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 1004 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 1006 */	NdrFcShort( 0x0 ),	/* 0 */

+

+	/* Parameter app_id */

+

+/* 1008 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1010 */	NdrFcShort( 0x8 ),	/* X64 Stack size/offset = 8 */

+/* 1012 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter installer_path */

+

+/* 1014 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1016 */	NdrFcShort( 0x10 ),	/* X64 Stack size/offset = 16 */

+/* 1018 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter install_args */

+

+/* 1020 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1022 */	NdrFcShort( 0x18 ),	/* X64 Stack size/offset = 24 */

+/* 1024 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter install_data */

+

+/* 1026 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1028 */	NdrFcShort( 0x20 ),	/* X64 Stack size/offset = 32 */

+/* 1030 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter install_settings */

+

+/* 1032 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 1034 */	NdrFcShort( 0x28 ),	/* X64 Stack size/offset = 40 */

+/* 1036 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter observer */

+

+/* 1038 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

+/* 1040 */	NdrFcShort( 0x30 ),	/* X64 Stack size/offset = 48 */

+/* 1042 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

+

+	/* Return value */

+

+/* 1044 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 1046 */	NdrFcShort( 0x38 ),	/* X64 Stack size/offset = 56 */

+/* 1048 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

 			0x0

@@ -1151,38 +1182,38 @@
 /* 84 */	0x2a,		/* 42 */

 			0xb,		/* 11 */

 /* 86 */	

-			0x11, 0x8,	/* FC_RP [simple_pointer] */

-/* 88 */	

-			0x25,		/* FC_C_WSTRING */

-			0x5c,		/* FC_PAD */

-/* 90 */	

 			0x2f,		/* FC_IP */

 			0x5a,		/* FC_CONSTANT_IID */

-/* 92 */	NdrFcLong( 0x3fdec4cb ),	/* 1071563979 */

-/* 96 */	NdrFcShort( 0x8501 ),	/* -31487 */

-/* 98 */	NdrFcShort( 0x4ecd ),	/* 20173 */

-/* 100 */	0xa4,		/* 164 */

-			0xcf,		/* 207 */

-/* 102 */	0xbf,		/* 191 */

-			0x70,		/* 112 */

-/* 104 */	0x32,		/* 50 */

-			0x62,		/* 98 */

-/* 106 */	0x18,		/* 24 */

-			0xd0,		/* 208 */

+/* 88 */	NdrFcLong( 0x8bab6f84 ),	/* -1951699068 */

+/* 92 */	NdrFcShort( 0xad67 ),	/* -21145 */

+/* 94 */	NdrFcShort( 0x4819 ),	/* 18457 */

+/* 96 */	0xb8,		/* 184 */

+			0x46,		/* 70 */

+/* 98 */	0xcc,		/* 204 */

+			0x89,		/* 137 */

+/* 100 */	0x8,		/* 8 */

+			0x80,		/* 128 */

+/* 102 */	0xfd,		/* 253 */

+			0x3b,		/* 59 */

+/* 104 */	

+			0x11, 0x8,	/* FC_RP [simple_pointer] */

+/* 106 */	

+			0x25,		/* FC_C_WSTRING */

+			0x5c,		/* FC_PAD */

 /* 108 */	

 			0x2f,		/* FC_IP */

 			0x5a,		/* FC_CONSTANT_IID */

-/* 110 */	NdrFcLong( 0x8bab6f84 ),	/* -1951699068 */

-/* 114 */	NdrFcShort( 0xad67 ),	/* -21145 */

-/* 116 */	NdrFcShort( 0x4819 ),	/* 18457 */

-/* 118 */	0xb8,		/* 184 */

-			0x46,		/* 70 */

-/* 120 */	0xcc,		/* 204 */

-			0x89,		/* 137 */

-/* 122 */	0x8,		/* 8 */

-			0x80,		/* 128 */

-/* 124 */	0xfd,		/* 253 */

-			0x3b,		/* 59 */

+/* 110 */	NdrFcLong( 0x3fdec4cb ),	/* 1071563979 */

+/* 114 */	NdrFcShort( 0x8501 ),	/* -31487 */

+/* 116 */	NdrFcShort( 0x4ecd ),	/* 20173 */

+/* 118 */	0xa4,		/* 164 */

+			0xcf,		/* 207 */

+/* 120 */	0xbf,		/* 191 */

+			0x70,		/* 112 */

+/* 122 */	0x32,		/* 50 */

+			0x62,		/* 98 */

+/* 124 */	0x18,		/* 24 */

+			0xd0,		/* 208 */

 /* 126 */	

 			0x2f,		/* FC_IP */

 			0x5a,		/* FC_CONSTANT_IID */

@@ -1507,12 +1538,13 @@
     532,

     570,

     608,

-    682,

+    646,

     720,

-    782,

+    758,

     820,

-    906,

-    944

+    858,

+    944,

+    982

     };

 

 static const MIDL_STUBLESS_PROXY_INFO IUpdater_ProxyInfo =

@@ -1536,7 +1568,7 @@
     0,

     0,

     0};

-CINTERFACE_PROXY_VTABLE(12) _IUpdaterProxyVtbl = 

+CINTERFACE_PROXY_VTABLE(13) _IUpdaterProxyVtbl = 

 {

     &IUpdater_ProxyInfo,

     &IID_IUpdater,

@@ -1544,6 +1576,7 @@
     IUnknown_AddRef_Proxy,

     IUnknown_Release_Proxy ,

     (void *) (INT_PTR) -1 /* IUpdater::GetVersion */ ,

+    (void *) (INT_PTR) -1 /* IUpdater::FetchPolicies */ ,

     (void *) (INT_PTR) -1 /* IUpdater::CheckForUpdate */ ,

     (void *) (INT_PTR) -1 /* IUpdater::RegisterApp */ ,

     (void *) (INT_PTR) -1 /* IUpdater::RunPeriodicTasks */ ,

@@ -1558,7 +1591,7 @@
 {

     &IID_IUpdater,

     &IUpdater_ServerInfo,

-    12,

+    13,

     0, /* pure interpreted */

     CStdStubBuffer_METHODS

 };

diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.h b/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.h
index 86ae07a..2e9a1df 100644
--- a/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.h
+++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.h
@@ -726,6 +726,9 @@
         virtual HRESULT STDMETHODCALLTYPE GetVersion( 

             /* [retval][out] */ BSTR *version) = 0;

         

+        virtual HRESULT STDMETHODCALLTYPE FetchPolicies( 

+            /* [in] */ IUpdaterCallback *callback) = 0;

+        

         virtual HRESULT STDMETHODCALLTYPE CheckForUpdate( 

             /* [string][in] */ const WCHAR *app_id) = 0;

         

@@ -802,6 +805,11 @@
             IUpdater * This,

             /* [retval][out] */ BSTR *version);

         

+        DECLSPEC_XFGVIRT(IUpdater, FetchPolicies)

+        HRESULT ( STDMETHODCALLTYPE *FetchPolicies )( 

+            IUpdater * This,

+            /* [in] */ IUpdaterCallback *callback);

+        

         DECLSPEC_XFGVIRT(IUpdater, CheckForUpdate)

         HRESULT ( STDMETHODCALLTYPE *CheckForUpdate )( 

             IUpdater * This,

@@ -891,6 +899,9 @@
 #define IUpdater_GetVersion(This,version)	\

     ( (This)->lpVtbl -> GetVersion(This,version) ) 

 

+#define IUpdater_FetchPolicies(This,callback)	\

+    ( (This)->lpVtbl -> FetchPolicies(This,callback) ) 

+

 #define IUpdater_CheckForUpdate(This,app_id)	\

     ( (This)->lpVtbl -> CheckForUpdate(This,app_id) ) 

 

diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.tlb b/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.tlb
index d6d2cfb..3e86b19d 100644
--- a/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.tlb
+++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl.tlb
Binary files differ
diff --git a/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl_p.c b/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl_p.c
index 0c16fe0..3c7c70d 100644
--- a/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl_p.c
+++ b/third_party/win_build_output/midl/chrome/updater/app/server/win/x86/updater_idl_p.c
@@ -50,7 +50,7 @@
 #include "updater_idl.h"

 

 #define TYPE_FORMAT_STRING_SIZE   145                               

-#define PROC_FORMAT_STRING_SIZE   967                               

+#define PROC_FORMAT_STRING_SIZE   1003                              

 #define EXPR_FORMAT_STRING_SIZE   1                                 

 #define TRANSMIT_AS_TABLE_SIZE    0            

 #define WIRE_MARSHAL_TABLE_SIZE   1            

@@ -681,7 +681,7 @@
 /* 538 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure CheckForUpdate */

+	/* Procedure FetchPolicies */

 

 /* 540 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

@@ -698,11 +698,11 @@
 /* 560 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 562 */	NdrFcShort( 0x0 ),	/* 0 */

 

-	/* Parameter app_id */

+	/* Parameter callback */

 

-/* 564 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 564 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

 /* 566 */	NdrFcShort( 0x4 ),	/* x86 Stack size/offset = 4 */

-/* 568 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 568 */	NdrFcShort( 0x56 ),	/* Type Offset=86 */

 

 	/* Return value */

 

@@ -711,17 +711,17 @@
 /* 574 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure RegisterApp */

+	/* Procedure CheckForUpdate */

 

 /* 576 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

 /* 578 */	NdrFcLong( 0x0 ),	/* 0 */

 /* 582 */	NdrFcShort( 0x5 ),	/* 5 */

-/* 584 */	NdrFcShort( 0x24 ),	/* x86 Stack size/offset = 36 */

+/* 584 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

 /* 586 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 588 */	NdrFcShort( 0x8 ),	/* 8 */

 /* 590 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x8,		/* 8 */

+			0x2,		/* 2 */

 /* 592 */	0x8,		/* 8 */

 			0x1,		/* Ext Flags:  new corr desc, */

 /* 594 */	NdrFcShort( 0x0 ),	/* 0 */

@@ -732,287 +732,287 @@
 

 /* 600 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

 /* 602 */	NdrFcShort( 0x4 ),	/* x86 Stack size/offset = 4 */

-/* 604 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter brand_code */

-

-/* 606 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 608 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

-/* 610 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter brand_path */

-

-/* 612 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 614 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

-/* 616 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter tag */

-

-/* 618 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 620 */	NdrFcShort( 0x10 ),	/* x86 Stack size/offset = 16 */

-/* 622 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter version */

-

-/* 624 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 626 */	NdrFcShort( 0x14 ),	/* x86 Stack size/offset = 20 */

-/* 628 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter existence_checker_path */

-

-/* 630 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 632 */	NdrFcShort( 0x18 ),	/* x86 Stack size/offset = 24 */

-/* 634 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter callback */

-

-/* 636 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 638 */	NdrFcShort( 0x1c ),	/* x86 Stack size/offset = 28 */

-/* 640 */	NdrFcShort( 0x5a ),	/* Type Offset=90 */

+/* 604 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Return value */

 

-/* 642 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 644 */	NdrFcShort( 0x20 ),	/* x86 Stack size/offset = 32 */

-/* 646 */	0x8,		/* FC_LONG */

+/* 606 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 608 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

+/* 610 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure RunPeriodicTasks */

+	/* Procedure RegisterApp */

 

-/* 648 */	0x33,		/* FC_AUTO_HANDLE */

+/* 612 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

-/* 650 */	NdrFcLong( 0x0 ),	/* 0 */

-/* 654 */	NdrFcShort( 0x6 ),	/* 6 */

-/* 656 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

-/* 658 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 660 */	NdrFcShort( 0x8 ),	/* 8 */

-/* 662 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x2,		/* 2 */

-/* 664 */	0x8,		/* 8 */

+/* 614 */	NdrFcLong( 0x0 ),	/* 0 */

+/* 618 */	NdrFcShort( 0x6 ),	/* 6 */

+/* 620 */	NdrFcShort( 0x24 ),	/* x86 Stack size/offset = 36 */

+/* 622 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 624 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 626 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

+			0x8,		/* 8 */

+/* 628 */	0x8,		/* 8 */

 			0x1,		/* Ext Flags:  new corr desc, */

-/* 666 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 668 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 670 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 630 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 632 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 634 */	NdrFcShort( 0x0 ),	/* 0 */

+

+	/* Parameter app_id */

+

+/* 636 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 638 */	NdrFcShort( 0x4 ),	/* x86 Stack size/offset = 4 */

+/* 640 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter brand_code */

+

+/* 642 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 644 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

+/* 646 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter brand_path */

+

+/* 648 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 650 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

+/* 652 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter tag */

+

+/* 654 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 656 */	NdrFcShort( 0x10 ),	/* x86 Stack size/offset = 16 */

+/* 658 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter version */

+

+/* 660 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 662 */	NdrFcShort( 0x14 ),	/* x86 Stack size/offset = 20 */

+/* 664 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter existence_checker_path */

+

+/* 666 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 668 */	NdrFcShort( 0x18 ),	/* x86 Stack size/offset = 24 */

+/* 670 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter callback */

 

 /* 672 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 674 */	NdrFcShort( 0x4 ),	/* x86 Stack size/offset = 4 */

+/* 674 */	NdrFcShort( 0x1c ),	/* x86 Stack size/offset = 28 */

 /* 676 */	NdrFcShort( 0x6c ),	/* Type Offset=108 */

 

 	/* Return value */

 

 /* 678 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 680 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

+/* 680 */	NdrFcShort( 0x20 ),	/* x86 Stack size/offset = 32 */

 /* 682 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure Update */

+	/* Procedure RunPeriodicTasks */

 

 /* 684 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

 /* 686 */	NdrFcLong( 0x0 ),	/* 0 */

 /* 690 */	NdrFcShort( 0x7 ),	/* 7 */

-/* 692 */	NdrFcShort( 0x1c ),	/* x86 Stack size/offset = 28 */

-/* 694 */	NdrFcShort( 0x10 ),	/* 16 */

+/* 692 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

+/* 694 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 696 */	NdrFcShort( 0x8 ),	/* 8 */

 /* 698 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x6,		/* 6 */

+			0x2,		/* 2 */

 /* 700 */	0x8,		/* 8 */

 			0x1,		/* Ext Flags:  new corr desc, */

 /* 702 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 704 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 706 */	NdrFcShort( 0x0 ),	/* 0 */

 

+	/* Parameter callback */

+

+/* 708 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

+/* 710 */	NdrFcShort( 0x4 ),	/* x86 Stack size/offset = 4 */

+/* 712 */	NdrFcShort( 0x56 ),	/* Type Offset=86 */

+

+	/* Return value */

+

+/* 714 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 716 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

+/* 718 */	0x8,		/* FC_LONG */

+			0x0,		/* 0 */

+

+	/* Procedure Update */

+

+/* 720 */	0x33,		/* FC_AUTO_HANDLE */

+			0x6c,		/* Old Flags:  object, Oi2 */

+/* 722 */	NdrFcLong( 0x0 ),	/* 0 */

+/* 726 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 728 */	NdrFcShort( 0x1c ),	/* x86 Stack size/offset = 28 */

+/* 730 */	NdrFcShort( 0x10 ),	/* 16 */

+/* 732 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 734 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

+			0x6,		/* 6 */

+/* 736 */	0x8,		/* 8 */

+			0x1,		/* Ext Flags:  new corr desc, */

+/* 738 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 740 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 742 */	NdrFcShort( 0x0 ),	/* 0 */

+

 	/* Parameter app_id */

 

-/* 708 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 710 */	NdrFcShort( 0x4 ),	/* x86 Stack size/offset = 4 */

-/* 712 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 744 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 746 */	NdrFcShort( 0x4 ),	/* x86 Stack size/offset = 4 */

+/* 748 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter install_data_index */

 

-/* 714 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 716 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

-/* 718 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 750 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 752 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

+/* 754 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter priority */

 

-/* 720 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

-/* 722 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

-/* 724 */	0x8,		/* FC_LONG */

+/* 756 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

+/* 758 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

+/* 760 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

 	/* Parameter same_version_update_allowed */

 

-/* 726 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

-/* 728 */	NdrFcShort( 0x10 ),	/* x86 Stack size/offset = 16 */

-/* 730 */	0x8,		/* FC_LONG */

+/* 762 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

+/* 764 */	NdrFcShort( 0x10 ),	/* x86 Stack size/offset = 16 */

+/* 766 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

 	/* Parameter observer */

 

-/* 732 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 734 */	NdrFcShort( 0x14 ),	/* x86 Stack size/offset = 20 */

-/* 736 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

-

-	/* Return value */

-

-/* 738 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 740 */	NdrFcShort( 0x18 ),	/* x86 Stack size/offset = 24 */

-/* 742 */	0x8,		/* FC_LONG */

-			0x0,		/* 0 */

-

-	/* Procedure UpdateAll */

-

-/* 744 */	0x33,		/* FC_AUTO_HANDLE */

-			0x6c,		/* Old Flags:  object, Oi2 */

-/* 746 */	NdrFcLong( 0x0 ),	/* 0 */

-/* 750 */	NdrFcShort( 0x8 ),	/* 8 */

-/* 752 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

-/* 754 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 756 */	NdrFcShort( 0x8 ),	/* 8 */

-/* 758 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x2,		/* 2 */

-/* 760 */	0x8,		/* 8 */

-			0x1,		/* Ext Flags:  new corr desc, */

-/* 762 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 764 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 766 */	NdrFcShort( 0x0 ),	/* 0 */

-

-	/* Parameter observer */

-

 /* 768 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 770 */	NdrFcShort( 0x4 ),	/* x86 Stack size/offset = 4 */

+/* 770 */	NdrFcShort( 0x14 ),	/* x86 Stack size/offset = 20 */

 /* 772 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

 

 	/* Return value */

 

 /* 774 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 776 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

+/* 776 */	NdrFcShort( 0x18 ),	/* x86 Stack size/offset = 24 */

 /* 778 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure Install */

+	/* Procedure UpdateAll */

 

 /* 780 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

 /* 782 */	NdrFcLong( 0x0 ),	/* 0 */

 /* 786 */	NdrFcShort( 0x9 ),	/* 9 */

-/* 788 */	NdrFcShort( 0x2c ),	/* x86 Stack size/offset = 44 */

-/* 790 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 788 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

+/* 790 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 792 */	NdrFcShort( 0x8 ),	/* 8 */

 /* 794 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0xa,		/* 10 */

+			0x2,		/* 2 */

 /* 796 */	0x8,		/* 8 */

 			0x1,		/* Ext Flags:  new corr desc, */

 /* 798 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 800 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 802 */	NdrFcShort( 0x0 ),	/* 0 */

 

+	/* Parameter observer */

+

+/* 804 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

+/* 806 */	NdrFcShort( 0x4 ),	/* x86 Stack size/offset = 4 */

+/* 808 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

+

+	/* Return value */

+

+/* 810 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 812 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

+/* 814 */	0x8,		/* FC_LONG */

+			0x0,		/* 0 */

+

+	/* Procedure Install */

+

+/* 816 */	0x33,		/* FC_AUTO_HANDLE */

+			0x6c,		/* Old Flags:  object, Oi2 */

+/* 818 */	NdrFcLong( 0x0 ),	/* 0 */

+/* 822 */	NdrFcShort( 0xa ),	/* 10 */

+/* 824 */	NdrFcShort( 0x2c ),	/* x86 Stack size/offset = 44 */

+/* 826 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 828 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 830 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

+			0xa,		/* 10 */

+/* 832 */	0x8,		/* 8 */

+			0x1,		/* Ext Flags:  new corr desc, */

+/* 834 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 836 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 838 */	NdrFcShort( 0x0 ),	/* 0 */

+

 	/* Parameter app_id */

 

-/* 804 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 806 */	NdrFcShort( 0x4 ),	/* x86 Stack size/offset = 4 */

-/* 808 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 840 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 842 */	NdrFcShort( 0x4 ),	/* x86 Stack size/offset = 4 */

+/* 844 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter brand_code */

 

-/* 810 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 812 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

-/* 814 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 846 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 848 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

+/* 850 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter brand_path */

 

-/* 816 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 818 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

-/* 820 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 852 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 854 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

+/* 856 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter tag */

 

-/* 822 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 824 */	NdrFcShort( 0x10 ),	/* x86 Stack size/offset = 16 */

-/* 826 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 858 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 860 */	NdrFcShort( 0x10 ),	/* x86 Stack size/offset = 16 */

+/* 862 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter version */

 

-/* 828 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 830 */	NdrFcShort( 0x14 ),	/* x86 Stack size/offset = 20 */

-/* 832 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 864 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 866 */	NdrFcShort( 0x14 ),	/* x86 Stack size/offset = 20 */

+/* 868 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter existence_checker_path */

 

-/* 834 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 836 */	NdrFcShort( 0x18 ),	/* x86 Stack size/offset = 24 */

-/* 838 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 870 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 872 */	NdrFcShort( 0x18 ),	/* x86 Stack size/offset = 24 */

+/* 874 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter install_data_index */

 

-/* 840 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 842 */	NdrFcShort( 0x1c ),	/* x86 Stack size/offset = 28 */

-/* 844 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 876 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 878 */	NdrFcShort( 0x1c ),	/* x86 Stack size/offset = 28 */

+/* 880 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Parameter priority */

 

-/* 846 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

-/* 848 */	NdrFcShort( 0x20 ),	/* x86 Stack size/offset = 32 */

-/* 850 */	0x8,		/* FC_LONG */

+/* 882 */	NdrFcShort( 0x48 ),	/* Flags:  in, base type, */

+/* 884 */	NdrFcShort( 0x20 ),	/* x86 Stack size/offset = 32 */

+/* 886 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

 	/* Parameter observer */

 

-/* 852 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 854 */	NdrFcShort( 0x24 ),	/* x86 Stack size/offset = 36 */

-/* 856 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

-

-	/* Return value */

-

-/* 858 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 860 */	NdrFcShort( 0x28 ),	/* x86 Stack size/offset = 40 */

-/* 862 */	0x8,		/* FC_LONG */

-			0x0,		/* 0 */

-

-	/* Procedure CancelInstalls */

-

-/* 864 */	0x33,		/* FC_AUTO_HANDLE */

-			0x6c,		/* Old Flags:  object, Oi2 */

-/* 866 */	NdrFcLong( 0x0 ),	/* 0 */

-/* 870 */	NdrFcShort( 0xa ),	/* 10 */

-/* 872 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

-/* 874 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 876 */	NdrFcShort( 0x8 ),	/* 8 */

-/* 878 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x2,		/* 2 */

-/* 880 */	0x8,		/* 8 */

-			0x1,		/* Ext Flags:  new corr desc, */

-/* 882 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 884 */	NdrFcShort( 0x0 ),	/* 0 */

-/* 886 */	NdrFcShort( 0x0 ),	/* 0 */

-

-	/* Parameter app_id */

-

-/* 888 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 890 */	NdrFcShort( 0x4 ),	/* x86 Stack size/offset = 4 */

-/* 892 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

+/* 888 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

+/* 890 */	NdrFcShort( 0x24 ),	/* x86 Stack size/offset = 36 */

+/* 892 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

 

 	/* Return value */

 

 /* 894 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 896 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

+/* 896 */	NdrFcShort( 0x28 ),	/* x86 Stack size/offset = 40 */

 /* 898 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

-	/* Procedure RunInstaller */

+	/* Procedure CancelInstalls */

 

 /* 900 */	0x33,		/* FC_AUTO_HANDLE */

 			0x6c,		/* Old Flags:  object, Oi2 */

 /* 902 */	NdrFcLong( 0x0 ),	/* 0 */

 /* 906 */	NdrFcShort( 0xb ),	/* 11 */

-/* 908 */	NdrFcShort( 0x20 ),	/* x86 Stack size/offset = 32 */

+/* 908 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

 /* 910 */	NdrFcShort( 0x0 ),	/* 0 */

 /* 912 */	NdrFcShort( 0x8 ),	/* 8 */

 /* 914 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

-			0x7,		/* 7 */

+			0x2,		/* 2 */

 /* 916 */	0x8,		/* 8 */

 			0x1,		/* Ext Flags:  new corr desc, */

 /* 918 */	NdrFcShort( 0x0 ),	/* 0 */

@@ -1023,43 +1023,73 @@
 

 /* 924 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

 /* 926 */	NdrFcShort( 0x4 ),	/* x86 Stack size/offset = 4 */

-/* 928 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter installer_path */

-

-/* 930 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 932 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

-/* 934 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter install_args */

-

-/* 936 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 938 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

-/* 940 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter install_data */

-

-/* 942 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 944 */	NdrFcShort( 0x10 ),	/* x86 Stack size/offset = 16 */

-/* 946 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter install_settings */

-

-/* 948 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

-/* 950 */	NdrFcShort( 0x14 ),	/* x86 Stack size/offset = 20 */

-/* 952 */	NdrFcShort( 0x58 ),	/* Type Offset=88 */

-

-	/* Parameter observer */

-

-/* 954 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

-/* 956 */	NdrFcShort( 0x18 ),	/* x86 Stack size/offset = 24 */

-/* 958 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

+/* 928 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

 

 	/* Return value */

 

-/* 960 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

-/* 962 */	NdrFcShort( 0x1c ),	/* x86 Stack size/offset = 28 */

-/* 964 */	0x8,		/* FC_LONG */

+/* 930 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 932 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

+/* 934 */	0x8,		/* FC_LONG */

+			0x0,		/* 0 */

+

+	/* Procedure RunInstaller */

+

+/* 936 */	0x33,		/* FC_AUTO_HANDLE */

+			0x6c,		/* Old Flags:  object, Oi2 */

+/* 938 */	NdrFcLong( 0x0 ),	/* 0 */

+/* 942 */	NdrFcShort( 0xc ),	/* 12 */

+/* 944 */	NdrFcShort( 0x20 ),	/* x86 Stack size/offset = 32 */

+/* 946 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 948 */	NdrFcShort( 0x8 ),	/* 8 */

+/* 950 */	0x46,		/* Oi2 Flags:  clt must size, has return, has ext, */

+			0x7,		/* 7 */

+/* 952 */	0x8,		/* 8 */

+			0x1,		/* Ext Flags:  new corr desc, */

+/* 954 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 956 */	NdrFcShort( 0x0 ),	/* 0 */

+/* 958 */	NdrFcShort( 0x0 ),	/* 0 */

+

+	/* Parameter app_id */

+

+/* 960 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 962 */	NdrFcShort( 0x4 ),	/* x86 Stack size/offset = 4 */

+/* 964 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter installer_path */

+

+/* 966 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 968 */	NdrFcShort( 0x8 ),	/* x86 Stack size/offset = 8 */

+/* 970 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter install_args */

+

+/* 972 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 974 */	NdrFcShort( 0xc ),	/* x86 Stack size/offset = 12 */

+/* 976 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter install_data */

+

+/* 978 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 980 */	NdrFcShort( 0x10 ),	/* x86 Stack size/offset = 16 */

+/* 982 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter install_settings */

+

+/* 984 */	NdrFcShort( 0x10b ),	/* Flags:  must size, must free, in, simple ref, */

+/* 986 */	NdrFcShort( 0x14 ),	/* x86 Stack size/offset = 20 */

+/* 988 */	NdrFcShort( 0x6a ),	/* Type Offset=106 */

+

+	/* Parameter observer */

+

+/* 990 */	NdrFcShort( 0xb ),	/* Flags:  must size, must free, in, */

+/* 992 */	NdrFcShort( 0x18 ),	/* x86 Stack size/offset = 24 */

+/* 994 */	NdrFcShort( 0x7e ),	/* Type Offset=126 */

+

+	/* Return value */

+

+/* 996 */	NdrFcShort( 0x70 ),	/* Flags:  out, return, base type, */

+/* 998 */	NdrFcShort( 0x1c ),	/* x86 Stack size/offset = 28 */

+/* 1000 */	0x8,		/* FC_LONG */

 			0x0,		/* 0 */

 

 			0x0

@@ -1139,38 +1169,38 @@
 /* 84 */	0x2a,		/* 42 */

 			0xb,		/* 11 */

 /* 86 */	

-			0x11, 0x8,	/* FC_RP [simple_pointer] */

-/* 88 */	

-			0x25,		/* FC_C_WSTRING */

-			0x5c,		/* FC_PAD */

-/* 90 */	

 			0x2f,		/* FC_IP */

 			0x5a,		/* FC_CONSTANT_IID */

-/* 92 */	NdrFcLong( 0x3fdec4cb ),	/* 1071563979 */

-/* 96 */	NdrFcShort( 0x8501 ),	/* -31487 */

-/* 98 */	NdrFcShort( 0x4ecd ),	/* 20173 */

-/* 100 */	0xa4,		/* 164 */

-			0xcf,		/* 207 */

-/* 102 */	0xbf,		/* 191 */

-			0x70,		/* 112 */

-/* 104 */	0x32,		/* 50 */

-			0x62,		/* 98 */

-/* 106 */	0x18,		/* 24 */

-			0xd0,		/* 208 */

+/* 88 */	NdrFcLong( 0x8bab6f84 ),	/* -1951699068 */

+/* 92 */	NdrFcShort( 0xad67 ),	/* -21145 */

+/* 94 */	NdrFcShort( 0x4819 ),	/* 18457 */

+/* 96 */	0xb8,		/* 184 */

+			0x46,		/* 70 */

+/* 98 */	0xcc,		/* 204 */

+			0x89,		/* 137 */

+/* 100 */	0x8,		/* 8 */

+			0x80,		/* 128 */

+/* 102 */	0xfd,		/* 253 */

+			0x3b,		/* 59 */

+/* 104 */	

+			0x11, 0x8,	/* FC_RP [simple_pointer] */

+/* 106 */	

+			0x25,		/* FC_C_WSTRING */

+			0x5c,		/* FC_PAD */

 /* 108 */	

 			0x2f,		/* FC_IP */

 			0x5a,		/* FC_CONSTANT_IID */

-/* 110 */	NdrFcLong( 0x8bab6f84 ),	/* -1951699068 */

-/* 114 */	NdrFcShort( 0xad67 ),	/* -21145 */

-/* 116 */	NdrFcShort( 0x4819 ),	/* 18457 */

-/* 118 */	0xb8,		/* 184 */

-			0x46,		/* 70 */

-/* 120 */	0xcc,		/* 204 */

-			0x89,		/* 137 */

-/* 122 */	0x8,		/* 8 */

-			0x80,		/* 128 */

-/* 124 */	0xfd,		/* 253 */

-			0x3b,		/* 59 */

+/* 110 */	NdrFcLong( 0x3fdec4cb ),	/* 1071563979 */

+/* 114 */	NdrFcShort( 0x8501 ),	/* -31487 */

+/* 116 */	NdrFcShort( 0x4ecd ),	/* 20173 */

+/* 118 */	0xa4,		/* 164 */

+			0xcf,		/* 207 */

+/* 120 */	0xbf,		/* 191 */

+			0x70,		/* 112 */

+/* 122 */	0x32,		/* 50 */

+			0x62,		/* 98 */

+/* 124 */	0x18,		/* 24 */

+			0xd0,		/* 208 */

 /* 126 */	

 			0x2f,		/* FC_IP */

 			0x5a,		/* FC_CONSTANT_IID */

@@ -1495,12 +1525,13 @@
     504,

     540,

     576,

-    648,

+    612,

     684,

-    744,

+    720,

     780,

-    864,

-    900

+    816,

+    900,

+    936

     };

 

 static const MIDL_STUBLESS_PROXY_INFO IUpdater_ProxyInfo =

@@ -1524,7 +1555,7 @@
     0,

     0,

     0};

-CINTERFACE_PROXY_VTABLE(12) _IUpdaterProxyVtbl = 

+CINTERFACE_PROXY_VTABLE(13) _IUpdaterProxyVtbl = 

 {

     &IUpdater_ProxyInfo,

     &IID_IUpdater,

@@ -1532,6 +1563,7 @@
     IUnknown_AddRef_Proxy,

     IUnknown_Release_Proxy ,

     (void *) (INT_PTR) -1 /* IUpdater::GetVersion */ ,

+    (void *) (INT_PTR) -1 /* IUpdater::FetchPolicies */ ,

     (void *) (INT_PTR) -1 /* IUpdater::CheckForUpdate */ ,

     (void *) (INT_PTR) -1 /* IUpdater::RegisterApp */ ,

     (void *) (INT_PTR) -1 /* IUpdater::RunPeriodicTasks */ ,

@@ -1546,7 +1578,7 @@
 {

     &IID_IUpdater,

     &IUpdater_ServerInfo,

-    12,

+    13,

     0, /* pure interpreted */

     CStdStubBuffer_METHODS

 };

diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 65389aa..5ef67c4 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -567,7 +567,7 @@
       'GPU FYI Mac Builder': 'gpu_fyi_tests_release_trybot',
       'GPU FYI Mac Builder (asan)': 'gpu_fyi_tests_release_trybot_asan',
       'GPU FYI Mac Builder (dbg)': 'gpu_fyi_tests_debug_trybot',
-      'GPU FYI Mac arm64 Builder': 'gpu_fyi_tests_release_trybot_arm64',
+      'GPU FYI Mac arm64 Builder': 'gpu_fyi_tests_release_trybot_arm64_reclient',
       'GPU FYI Win Builder': 'gpu_fyi_tests_release_trybot_x86_reclient',
       'GPU FYI Win x64 Builder': 'gpu_fyi_tests_release_trybot_reclient',
       'GPU FYI Win x64 Builder (dbg)': 'gpu_fyi_tests_debug_trybot_reclient',
@@ -1394,11 +1394,11 @@
     ],
 
     'android_cast_debug_static_bot_compile_only': [
-      'android', 'cast', 'clang', 'debug_static_bot', 'compile_only',
+      'android', 'cast_android', 'cast_receiver', 'clang', 'debug_static_bot', 'compile_only',
     ],
 
     'android_cast_debug_static_bot_reclient': [
-      'android', 'cast', 'clang', 'debug_static_bot_reclient',
+      'android', 'cast_android', 'cast_receiver', 'clang', 'debug_static_bot_reclient',
     ],
 
     'android_clang_asan_debug_bot_reclient': [
@@ -2572,6 +2572,10 @@
       'gpu_fyi_tests', 'release_trybot_minimal_symbols', 'arm64', 'disable_nacl',
     ],
 
+    'gpu_fyi_tests_release_trybot_arm64_reclient': [
+      'gpu_fyi_tests', 'release_trybot_minimal_symbols_reclient', 'arm64', 'disable_nacl',
+    ],
+
     'gpu_fyi_tests_release_trybot_asan': [
       'gpu_fyi_tests', 'release_trybot_minimal_symbols', 'asan', 'disable_nacl',
     ],
@@ -3804,6 +3808,10 @@
       'gn_args': 'is_chromecast=true'
     },
 
+    'cast_android': {
+      'gn_args': 'is_cast_android=true'
+    },
+
     'cast_audio': {
       'gn_args': 'is_cast_audio_only=true'
     },
diff --git a/tools/mb/mb_config_expectations/chromium.android.json b/tools/mb/mb_config_expectations/chromium.android.json
index 296e7eaf..9c6b80a 100644
--- a/tools/mb/mb_config_expectations/chromium.android.json
+++ b/tools/mb/mb_config_expectations/chromium.android.json
@@ -79,8 +79,9 @@
   },
   "Cast Android (dbg)": {
     "gn_args": {
+      "enable_cast_receiver": true,
       "ffmpeg_branding": "Chrome",
-      "is_chromecast": true,
+      "is_cast_android": true,
       "is_clang": true,
       "is_component_build": false,
       "is_debug": true,
diff --git a/tools/mb/mb_config_expectations/chromium.gpu.fyi.json b/tools/mb/mb_config_expectations/chromium.gpu.fyi.json
index 9f54e1b..9ff37015 100644
--- a/tools/mb/mb_config_expectations/chromium.gpu.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.gpu.fyi.json
@@ -138,7 +138,7 @@
       "proprietary_codecs": true,
       "symbol_level": 1,
       "target_cpu": "arm64",
-      "use_goma": true
+      "use_remoteexec": true
     }
   },
   "GPU FYI Win Builder": {
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.android.json b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
index 62042ff6..8468d25 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.android.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.android.json
@@ -1188,8 +1188,9 @@
   },
   "cast_shell_android": {
     "gn_args": {
+      "enable_cast_receiver": true,
       "ffmpeg_branding": "Chrome",
-      "is_chromecast": true,
+      "is_cast_android": true,
       "is_clang": true,
       "is_component_build": false,
       "is_debug": true,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 9987a32..b9b85b2 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -10776,6 +10776,7 @@
   <int value="18" label="EMF_INVALID_PORT_CONTEXT"/>
   <int value="19" label="AWCI_INVALID_CALL_FROM_NOT_PRIMARY_MAIN_FRAME"/>
   <int value="20" label="EFD_INVALID_EXTENSION_ID_FOR_PROCESS"/>
+  <int value="21" label="EMF_INVALID_EXTENSION_ID_FOR_TAB_MSG"/>
 </enum>
 
 <enum name="BadMessageReasonGuestView">
@@ -58073,6 +58074,7 @@
   <int value="-907481658" label="ArcMouseWheelSmoothScroll:enabled"/>
   <int value="-907234795" label="NewAudioRenderingMixingStrategy:disabled"/>
   <int value="-905538983" label="SimplifyHttpsIndicator:disabled"/>
+  <int value="-903524547" label="DiscoFeedEndpoint:disabled"/>
   <int value="-903359589" label="CrOSEnforceSystemAec:enabled"/>
   <int value="-902125579" label="ImmersiveUiMode:disabled"/>
   <int value="-900871741" label="DesktopPWAsNotificationIconAndTitle:disabled"/>
@@ -61420,6 +61422,7 @@
   <int value="1181056275" label="enable-cloud-backup"/>
   <int value="1181825084" label="NewDragSpecInLauncher:enabled"/>
   <int value="1182356056" label="MacV2GPUSandbox:enabled"/>
+  <int value="1183125644" label="DiscoFeedEndpoint:enabled"/>
   <int value="1183260592" label="WebAssemblyBaseline:enabled"/>
   <int value="1183431946" label="v8-cache-options"/>
   <int value="1184093076" label="WebRtcUseMinMaxVEADimensions:enabled"/>
@@ -69858,6 +69861,48 @@
       label="c942262c0c7c0a95bb152b71c42556ddbe9a04fa8378373550d2b7ce27d952a3"/>
   <int value="521"
       label="42431627ea76cc78697f915e3455b1b2ec82ff2f6380ee6423ef3c0840b7e631"/>
+  <int value="522"
+      label="693c9aa6b245b3b0261637750863eadb6c248a16e52d6f4bc90c86bbf32d7042"/>
+  <int value="523"
+      label="a02fafa192c8cb81cb1341554f9c05b71cca2a890b0d1298d683647c961efbdf"/>
+  <int value="524"
+      label="e04a022ce32f4ccf2c7f6046287b828a32a909f5e751447f83fd2c71f6fd8173"/>
+  <int value="525"
+      label="ae7f962cb9e6a7dbf7b833fb18fa9b71a89175df949c232b6a9ef7cb3df2bbfc"/>
+  <int value="526"
+      label="96352d0ad875c027db82d599baa8d42e5c472649981eceed3bfc65f4c81fd5c1"/>
+  <int value="527"
+      label="e14e51891f3492243eea613bc2c814d47224b224c57d38169e958e30b3dedee4"/>
+  <int value="528"
+      label="b15ac9561204756124b9c4d3fe406d93833ff66652f67fbf139f5bbf030a0e64"/>
+  <int value="529"
+      label="a495c8d110e8b9e200f370aeda3ff92ee43f8e3d4ec0db1c0dc58bd762880ba5"/>
+  <int value="530"
+      label="d6ec6348a7c4d42ac48d9c43145a8cd71971362363267c6673a77b8a8573a66b"/>
+  <int value="531"
+      label="6a97b51c8219e93e5dec64bad5806cdeb0f8355be47e757010b702456e01aafd"/>
+  <int value="532"
+      label="48a8a7ecd03a83b26aec7574d09d6453e95f90360634ce204bcbd473997d4c05"/>
+  <int value="533"
+      label="c2b3c31a4a29850aa8f3cf472a1169ff71b416579f6a4482ec7744b83df988ac"/>
+  <int value="534"
+      label="fc784300ec8df4d3d1bad763835182918d52a9ff0238bdf695a1cd9bdb98321c"/>
+  <int value="535"
+      label="762195c225586ee6c0237456e2107dc54f1efc21f61a792ebd515913cce68332"/>
+  <int value="536"
+      label="681dc482c296c8402c6ebb20e68309a3bc846523ae34b984a84ee697a3312db7"/>
+  <int value="537"
+      label="f0011f92fcf9be36c7a5b36e7bc862ab20e94ef36fea8a561db0a8d7750c1f51"/>
+  <int value="538"
+      label="fee8af929175687f4638a3fc983db8ecd0e5e2a83e737f3fb77b4c22fcbac0a6"/>
+  <int value="539"
+      label="bdaccbf2e8b27c0c02a689ee866c9b86ec04442afcdddd5d4ec36def21e761dd"/>
+  <int value="540"
+      label="581cc15821169694c39c2991b53e93ab945a42b076661774c2ecf38a3323acea"/>
+  <int value="541"
+      label="bb0ce7040314a143dcd10e65ccaeef7010e1b784d15d195d77b5601956bf9e3f"/>
+  <int value="542"
+      label="de7b6932e9c44582ce0de07abdab7eea90c75d6d2a07331df57bd5cb88553d13"/>
 </enum>
 
 <enum name="Network3GGobiError">
@@ -81061,6 +81106,7 @@
   <int value="25" label="kProfilePickerView"/>
   <int value="26" label="kCommanderFrontend"/>
   <int value="27" label="kDiceWebSigninInterceptionBubble"/>
+  <int value="28" label="kHistoryMenuBridge"/>
 </enum>
 
 <enum name="ProfileMenuActionableItem">
diff --git a/tools/metrics/histograms/metadata/apps/histograms.xml b/tools/metrics/histograms/metadata/apps/histograms.xml
index ed1026f..ddf0974 100644
--- a/tools/metrics/histograms/metadata/apps/histograms.xml
+++ b/tools/metrics/histograms/metadata/apps/histograms.xml
@@ -2131,10 +2131,6 @@
   </summary>
   <token key="AppListTabletModeTransition">
     <variant name=""/>
-    <variant name=".DragReleaseHide"
-        summary="Release drag to hide the app list"/>
-    <variant name=".DragReleaseShow"
-        summary="Release drag to show the app list"/>
     <variant name=".EnterFullscreenAllApps"
         summary="Enter kFullScreenAllApps state in tablet"/>
     <variant name=".EnterFullscreenSearch"
diff --git a/tools/metrics/histograms/metadata/bookmarks/histograms.xml b/tools/metrics/histograms/metadata/bookmarks/histograms.xml
index b0a237e..5a2efd85 100644
--- a/tools/metrics/histograms/metadata/bookmarks/histograms.xml
+++ b/tools/metrics/histograms/metadata/bookmarks/histograms.xml
@@ -153,6 +153,13 @@
 
 <histogram name="Bookmarks.Count.OnProfileLoad" units="bookmarks"
     expires_after="2023-02-26">
+  <obsolete>
+    Logged on profile open, including for profiles that do not support
+    bookmarks. (We did not investigate thoroughly; we don't know what value
+    typically was logged. Presumably 0.) Replaced in M-107 with the histogram
+    Bookmarks.Count.OnProfileLoad3, which is similar but only emitted on
+    profiles that support bookmarks.
+  </obsolete>
   <owner>supertri@chromium.org</owner>
   <owner>isherman@chromium.org</owner>
   <owner>aidanday@google.com</owner>
@@ -180,9 +187,36 @@
     there is at least one duplicate.
   </summary>
   <token key="UniquenessCriterion">
-    <variant name="Url2" summary="URL"/>
-    <variant name="UrlAndTitle" summary="URL-title pair"/>
-    <variant name="UrlAndTitleAndParent" summary="URL-title-parent triple"/>
+    <variant name="Url2" summary="URL">
+      <obsolete>
+        This histogram was fine. It is being replaced with a version
+        &quot;3&quot; for a simple reason. Some other
+        Bookmarks.Count.OnProfileLoad* histograms needed to switch to a version
+        3. This one is making the switch so all these histograms have the same
+        suffix.
+      </obsolete>
+    </variant>
+    <variant name="Url3" summary="URL"/>
+    <variant name="UrlAndTitle" summary="URL-title pair">
+      <obsolete>
+        This histogram was fine. It is being replaced with a version
+        &quot;3&quot; for a simple reason. Some other
+        Bookmarks.Count.OnProfileLoad* histograms needed to switch to a version
+        3. This one is making the switch so all these histograms have the same
+        suffix.
+      </obsolete>
+    </variant>
+    <variant name="UrlAndTitle3" summary="URL-title pair"/>
+    <variant name="UrlAndTitleAndParent" summary="URL-title-parent triple">
+      <obsolete>
+        This histogram was fine. It is being replaced with a version
+        &quot;3&quot; for a simple reason. Some other
+        Bookmarks.Count.OnProfileLoad* histograms needed to switch to a version
+        3. This one is making the switch so all these histograms have the same
+        suffix.
+      </obsolete>
+    </variant>
+    <variant name="UrlAndTitleAndParent3" summary="URL-title-parent triple"/>
   </token>
 </histogram>
 
@@ -196,12 +230,54 @@
     user. Recorded when bookmarks are loaded into storage from disk.
   </summary>
   <token key="UniquenessCriterion">
-    <variant name="Url" summary="URL"/>
-    <variant name="UrlAndTitle" summary="URL-title pair"/>
-    <variant name="UrlAndTitleAndParent" summary="URL-title-parent triple"/>
+    <variant name="Url" summary="URL">
+      <obsolete>
+        Logged on profile open, including for profiles that do not support
+        bookmarks. (We did not investigate thoroughly; we don't know what value
+        typically was logged. Presumably 0.) Replaced in M-107 with the
+        histogram name with a &quot;3&quot; at the end, which is similar but
+        only emitted on profiles that support bookmarks.
+      </obsolete>
+    </variant>
+    <variant name="Url3" summary="URL"/>
+    <variant name="UrlAndTitle" summary="URL-title pair">
+      <obsolete>
+        Logged on profile open, including for profiles that do not support
+        bookmarks. (We did not investigate thoroughly; we don't know what value
+        typically was logged. Presumably 0.) Replaced in M-107 with the
+        histogram name with a &quot;3&quot; at the end, which is similar but
+        only emitted on profiles that support bookmarks.
+      </obsolete>
+    </variant>
+    <variant name="UrlAndTitle3" summary="URL-title pair"/>
+    <variant name="UrlAndTitleAndParent" summary="URL-title-parent triple">
+      <obsolete>
+        Logged on profile open, including for profiles that do not support
+        bookmarks. (We did not investigate thoroughly; we don't know what value
+        typically was logged. Presumably 0.) Replaced in M-107 with the
+        histogram name with a &quot;3&quot; at the end, which is similar but
+        only emitted on profiles that support bookmarks.
+      </obsolete>
+    </variant>
+    <variant name="UrlAndTitleAndParent3" summary="URL-title-parent triple"/>
   </token>
 </histogram>
 
+<histogram name="Bookmarks.Count.OnProfileLoad3" units="bookmarks"
+    expires_after="2023-02-19">
+  <owner>supertri@chromium.org</owner>
+  <owner>isherman@chromium.org</owner>
+  <owner>aidanday@google.com</owner>
+  <owner>mamir@chromium.org</owner>
+  <component>UI&gt;Browser&gt;Bookmarks</component>
+  <summary>
+    The total number of bookmarks a user has saved, excluding folders. Recorded
+    when a profile is opened - precisely, when bookmarks are loaded into storage
+    from disk. The count includes all bookmarks both in the &quot;Bookmarks
+    Bar&quot; and also under &quot;Other Bookmarks&quot;.
+  </summary>
+</histogram>
+
 <histogram name="Bookmarks.Count.OpenInIncognito" units="bookmarks"
     expires_after="M82">
   <owner>twellington@google.com</owner>
@@ -739,10 +815,29 @@
 
 <histogram name="Bookmarks.Storage.FileSizeAtStartup" units="KB"
     expires_after="2023-04-21">
+  <obsolete>
+    Logged on profile open, including for profiles that do not support
+    bookmarks. (We did not investigate thoroughly; we don't know what value
+    typically was logged. Presumably 0.) Replaced in M-107 with
+    Bookmarks.Storage.FileSizeAtStartup2, which is similar but only emitted on
+    profiles that support bookmarks.
+  </obsolete>
   <owner>wylieb@chromium.org</owner>
   <owner>chrome-collections@google.com</owner>
   <component>UI&gt;Browser&gt;Bookmarks</component>
-  <summary>Size of the bookmarks file, recorded at startup.</summary>
+  <summary>
+    Size of the bookmarks file, recorded when the bookmarks model is loaded.
+  </summary>
+</histogram>
+
+<histogram name="Bookmarks.Storage.FileSizeAtStartup2" units="KB"
+    expires_after="2023-04-21">
+  <owner>wylieb@chromium.org</owner>
+  <owner>chrome-collections@google.com</owner>
+  <component>UI&gt;Browser&gt;Bookmarks</component>
+  <summary>
+    Size of the bookmarks file, recorded when the bookmarks model is loaded.
+  </summary>
 </histogram>
 
 <histogram name="Bookmarks.Storage.TimeSinceLastScheduledSave" units="ms"
@@ -758,6 +853,24 @@
 
 <histogram name="Bookmarks.Storage.TimeToLoadAtStartup" units="ms"
     expires_after="2023-04-21">
+  <obsolete>
+    Logged on profile open, including for profiles that do not support
+    bookmarks. (We did not investigate thoroughly; we don't know what value
+    typically was logged. Presumably something small.) Replaced in M-107 with
+    Bookmarks.Storage.TimeToLoadAtStartup2, which is similar but only emitted on
+    profiles that support bookmarks.
+  </obsolete>
+  <owner>wylieb@chromium.org</owner>
+  <owner>chrome-collections@google.com</owner>
+  <component>UI&gt;Browser&gt;Bookmarks</component>
+  <summary>
+    Duration of loading the bookmarks file, recorded when the bookmark model is
+    loaded.
+  </summary>
+</histogram>
+
+<histogram name="Bookmarks.Storage.TimeToLoadAtStartup2" units="ms"
+    expires_after="2023-04-21">
   <owner>wylieb@chromium.org</owner>
   <owner>chrome-collections@google.com</owner>
   <component>UI&gt;Browser&gt;Bookmarks</component>
@@ -769,6 +882,24 @@
 
 <histogram name="Bookmarks.Times.OnProfileLoad.TimeSinceAdded" units="days"
     expires_after="2023-06-08">
+  <obsolete>
+    Logged on profile open, including for profiles that do not support
+    bookmarks. (We did not investigate thoroughly; we don't know what value
+    typically was logged. Presumably 0.) Replaced in M-107 with
+    Bookmarks.Times.OnProfileLoad.TimeSinceAdded3, which is similar but only
+    emitted on profiles that support bookmarks.
+  </obsolete>
+  <owner>wylieb@chromium.org</owner>
+  <owner>chrome-collections@google.com</owner>
+  <component>UI&gt;Browser&gt;Bookmarks</component>
+  <summary>
+    Records the average number of days since each bookmark was added. Recorded
+    on profile load.
+  </summary>
+</histogram>
+
+<histogram name="Bookmarks.Times.OnProfileLoad.TimeSinceAdded3" units="days"
+    expires_after="2023-06-08">
   <owner>wylieb@chromium.org</owner>
   <owner>chrome-collections@google.com</owner>
   <component>UI&gt;Browser&gt;Bookmarks</component>
diff --git a/tools/metrics/histograms/metadata/storage/histograms.xml b/tools/metrics/histograms/metadata/storage/histograms.xml
index 9c3c55e..257a8db 100644
--- a/tools/metrics/histograms/metadata/storage/histograms.xml
+++ b/tools/metrics/histograms/metadata/storage/histograms.xml
@@ -761,6 +761,19 @@
   </summary>
 </histogram>
 
+<histogram name="Storage.SharedStorage.Document.Timing.Run.ExecutedInWorklet"
+    units="ms" expires_after="2023-07-31">
+  <owner>cammie@chromium.org</owner>
+  <owner>yaoxia@chromium.org</owner>
+  <owner>chrome-ads-histograms@google.com</owner>
+  <summary>
+    Measures the time from when the end of the call to
+    `SharedStorageWorkletHost::RunOperationOnWorklet()` to the end of
+    `SharedStorageWorkletHost::OnRunOperationOnWorkletFinished()`. Recorded in
+    `SharedStorageWorkletHost::OnRunOperationOnWorkletFinished()`.
+  </summary>
+</histogram>
+
 <histogram name="Storage.SharedStorage.Document.Timing.SelectURL" units="ms"
     expires_after="2023-07-31">
   <owner>cammie@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/web_rtc/histograms.xml b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
index 9a271574..ae00997f 100644
--- a/tools/metrics/histograms/metadata/web_rtc/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
@@ -1222,8 +1222,8 @@
 </histogram>
 
 <histogram name="WebRTC.DesktopCapture.Win.DesktopCapturerImpl"
-    enum="WebRtcDesktopCapturerImpl" expires_after="2023-01-22">
-  <owner>jamiewalch@chromium.org</owner>
+    enum="WebRtcDesktopCapturerImpl" expires_after="2023-02-12">
+  <owner>alcooper@chromium.org</owner>
   <owner>auorion@microsoft.com</owner>
   <owner>edgecapabilitiesdev@microsoft.com</owner>
   <summary>
@@ -1234,7 +1234,7 @@
 
 <histogram name="WebRTC.DesktopCapture.Win.WgcCapturerResult"
     enum="WebRtcWgcCapturerResult" expires_after="2023-02-12">
-  <owner>jamiewalch@chromium.org</owner>
+  <owner>alcooper@chromium.org</owner>
   <owner>auorion@microsoft.com</owner>
   <owner>edgecapabilitiesdev@microsoft.com</owner>
   <summary>
@@ -1245,7 +1245,7 @@
 
 <histogram name="WebRTC.DesktopCapture.Win.WgcCaptureSessionGetFrameResult"
     enum="WebRtcWgcCaptureSessionGetFrameResult" expires_after="2023-02-12">
-  <owner>jamiewalch@chromium.org</owner>
+  <owner>alcooper@chromium.org</owner>
   <owner>auorion@microsoft.com</owner>
   <owner>edgecapabilitiesdev@microsoft.com</owner>
   <summary>
@@ -1255,7 +1255,7 @@
 
 <histogram name="WebRTC.DesktopCapture.Win.WgcCaptureSessionStartResult"
     enum="WebRtcWgcCaptureSessionStartResult" expires_after="2023-02-12">
-  <owner>jamiewalch@chromium.org</owner>
+  <owner>alcooper@chromium.org</owner>
   <owner>auorion@microsoft.com</owner>
   <owner>edgecapabilitiesdev@microsoft.com</owner>
   <summary>
@@ -1264,8 +1264,8 @@
 </histogram>
 
 <histogram name="WebRTC.DesktopCapture.Win.{Capturer}CapturerFrameTime"
-    units="ms" expires_after="2022-10-09">
-  <owner>jamiewalch@chromium.org</owner>
+    units="ms" expires_after="2023-02-12">
+  <owner>alcooper@chromium.org</owner>
   <owner>auorion@microsoft.com</owner>
   <owner>edgecapabilitiesdev@microsoft.com</owner>
   <summary>This measures the performance of the {Capturer} capturer.</summary>
diff --git a/tools/perf/core/perf_dashboard_machine_group_mapping.json b/tools/perf/core/perf_dashboard_machine_group_mapping.json
index cd94667a..0b9ae6a 100644
--- a/tools/perf/core/perf_dashboard_machine_group_mapping.json
+++ b/tools/perf/core/perf_dashboard_machine_group_mapping.json
@@ -6,6 +6,7 @@
   "chromium.chromedriver": "ChromiumChromeDriver",
   "chromium.chromiumos": "ChromiumChromiumos",
   "chromium.clang": "ChromiumClang",
+  "chromium.fuchsia": "ChromiumFuchsia",
   "chromium.fyi": "ChromiumFYI",
   "chromium.gatekeeper": "Gatekeeper",
   "chromium.goma": "ChromiumGoma",
@@ -62,6 +63,7 @@
   "tryserver.chromium.android": "TryserverChromiumAndroid",
   "tryserver.chromium.angle": "TryServerANGLE",
   "tryserver.chromium.chromiumos": "TryserverChromiumChromiumOS",
+  "tryserver.chromium.fuchsia": "TryServerChromiumFuchsia",
   "tryserver.chromium.linux": "TryServerChromiumLinux",
   "tryserver.chromium.mac": "TryServerChromiumMac",
   "tryserver.chromium.perf": "ChromiumPerfTryServer",
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 141bdbe..77e4306 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,16 +5,16 @@
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "win": {
-            "hash": "a43e51118290b3a20ff7fb85da03d19b339bdd20",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/55013a0f8dd066206aa43497599033cfdf5bb362/trace_processor_shell.exe"
+            "hash": "558209a5f281ce750fbd7dbd1ec77a2e89a87171",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/cfc11efaad09f07f28857a9fea242db5891a8c63/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "58893933be305d3bfe0a72ebebcacde2ac3ca893",
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "mac": {
-            "hash": "446dfdfe1c7dfb504d2aeaad155da7b59cddefdc",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/55013a0f8dd066206aa43497599033cfdf5bb362/trace_processor_shell"
+            "hash": "a8799c1d5dfcbb98688649856f527dc412f45364",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/e1a17e56441b2c341762f451eb0ce897f93f16d0/trace_processor_shell"
         },
         "mac_arm64": {
             "hash": "e1ad4861384b06d911a65f035317914b8cc975c6",
@@ -22,7 +22,7 @@
         },
         "linux": {
             "hash": "14da0c92972850febdbc2e7c611ce51ddbf657c4",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/e1a17e56441b2c341762f451eb0ce897f93f16d0/trace_processor_shell"
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/69fad4021735eb642e032ba68f483660495ff015/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/visual_debugger/app.html b/tools/visual_debugger/app.html
index 807edc8..f46284e 100644
--- a/tools/visual_debugger/app.html
+++ b/tools/visual_debugger/app.html
@@ -250,7 +250,7 @@
       <option>100%</option>
       <option>50%</option>
       <option>200%</option>
-      <option>Free Camera</option>
+      <option disabled>Free Camera</option>
     </select>
   </div>
 
@@ -267,7 +267,11 @@
   </div>
 
   <div class='section'>
-    <canvas id='canvas'></canvas>
+    <!--We need to fix viewer size to avoid scroll position change when 
+      multiple displays are present. crbug.com/1358526-->
+    <div style="height:4000px;  border: 1px dotted gray;">
+        <canvas id='canvas' style="top :0px"></canvas>
+    </div>
   </div>
 
   <div class='modalContainer'></div>
diff --git a/tools/visual_debugger/server.py b/tools/visual_debugger/server.py
index f0985940..839f17783 100755
--- a/tools/visual_debugger/server.py
+++ b/tools/visual_debugger/server.py
@@ -3,6 +3,12 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import sys
+
+if (sys.version_info < (3, )):
+  print("FAILURE. Python 3 or greater required. Please run with \"python3\".")
+  sys.exit(7)
+
 from http.server import HTTPServer, SimpleHTTPRequestHandler, test
 from functools import partial
 import sys
diff --git a/ui/accessibility/ax_event_generator.cc b/ui/accessibility/ax_event_generator.cc
index 4c7fbdb..406cf5a 100644
--- a/ui/accessibility/ax_event_generator.cc
+++ b/ui/accessibility/ax_event_generator.cc
@@ -202,10 +202,8 @@
 AXEventGenerator::AXEventGenerator() = default;
 
 AXEventGenerator::AXEventGenerator(AXTree* tree) : tree_(tree) {
-  if (tree_) {
+  if (tree)  // Can be null in unit tests.
     tree_event_observation_.Observe(tree_.get());
-    live_region_tracker_ = std::make_unique<AXLiveRegionTracker>(*tree_);
-  }
 }
 
 AXEventGenerator::~AXEventGenerator() = default;
@@ -217,10 +215,8 @@
     live_region_tracker_.reset();
   }
   tree_ = new_tree;
-  if (tree_) {
+  if (tree_)
     tree_event_observation_.Observe(tree_.get());
-    live_region_tracker_ = std::make_unique<AXLiveRegionTracker>(*tree_);
-  }
 }
 
 void AXEventGenerator::ReleaseTree() {
@@ -228,6 +224,13 @@
   tree_ = nullptr;
 }
 
+AXLiveRegionTracker* AXEventGenerator::GetOrCreateLiveRegionTracker() {
+  DCHECK(tree_->root());
+  if (!live_region_tracker_)
+    live_region_tracker_ = std::make_unique<AXLiveRegionTracker>(*tree_);
+  return live_region_tracker_.get();
+}
+
 bool AXEventGenerator::empty() const {
   return tree_events_.empty();
 }
@@ -777,7 +780,7 @@
 
 void AXEventGenerator::OnNodeWillBeDeleted(AXTree* tree, AXNode* node) {
   DCHECK_EQ(tree_, tree);
-  live_region_tracker_->OnNodeWillBeDeleted(*node);
+  GetOrCreateLiveRegionTracker()->OnNodeWillBeDeleted(*node);
   FireValueInTextFieldChangedEventIfNecessary(tree, node);
 }
 
@@ -805,6 +808,15 @@
 
 void AXEventGenerator::OnNodeCreated(AXTree* tree, AXNode* node) {
   DCHECK_EQ(tree_, tree);
+  // Note: now that AXEventGenerator is part of AXTreeManager, this is being
+  // called before BrowserAccessibilityManager::OnNodeCreated() is called,
+  // where things used to be the other way around. That means that the new
+  // node is in the tree's map, but not BAM's map yet, which means certain
+  // calls, such as IsLeaf() may trigger a DCHECK because they call GetFromID(),
+  // which checks to make sure that the id maps are in sync.
+  // TODO(accesibility) Use a single id map so that issues like this go away.
+  // Or for now, just have this call BAM::OnNodeCreated() directly to enforce
+  // the order.
   FireValueInTextFieldChangedEventIfNecessary(tree, node);
 }
 
@@ -822,7 +834,8 @@
          change.type == NODE_REPARENTED || change.type == SUBTREE_REPARENTED)) {
       if (change.node->HasStringAttribute(
               ax::mojom::StringAttribute::kContainerLiveStatus)) {
-        live_region_tracker_->UpdateCachedLiveRootForNode(*change.node);
+        GetOrCreateLiveRegionTracker()->UpdateCachedLiveRootForNode(
+            *change.node);
       }
     }
 
@@ -850,7 +863,8 @@
   // TODO(mrobinson): Consider designing AXEventGenerator to have a more
   // resilient way to queue up events for nodes that might be destroyed and
   // recreated in a single update.
-  for (auto& id : live_region_tracker_->live_region_roots_with_changes()) {
+  for (auto& id :
+       GetOrCreateLiveRegionTracker()->live_region_roots_with_changes()) {
     // If node is null, the live region root with a change was deleted during
     // the course of this update and we should not trigger an event.
     if (AXNode* node = tree_->GetFromId(id)) {
@@ -858,7 +872,7 @@
     }
   }
 
-  live_region_tracker_->OnAtomicUpdateFinished();
+  GetOrCreateLiveRegionTracker()->OnAtomicUpdateFinished();
 
   PostprocessEvents();
 }
@@ -870,7 +884,8 @@
 }
 
 void AXEventGenerator::FireLiveRegionEvents(AXNode* node) {
-  AXNode* live_root = live_region_tracker_->GetLiveRootIfNotBusy(*node);
+  AXNode* live_root =
+      GetOrCreateLiveRegionTracker()->GetLiveRootIfNotBusy(*node);
 
   // Note that |live_root| might be nullptr if a live region was just added,
   // or if it has aria-busy="true".
@@ -911,7 +926,7 @@
     AXNode* target_node) {
   // Text is only found on leaf nodes, so the text in a text field would change
   // if any of the leaf nodes in it have changed their names.
-  if (!target_node->IsLeaf())
+  if (target_node->GetChildCount())
     return;
 
   AXNode* text_field_ancestor = target_node->GetTextFieldAncestor();
diff --git a/ui/accessibility/ax_event_generator.h b/ui/accessibility/ax_event_generator.h
index a7ec36b..377622b 100644
--- a/ui/accessibility/ax_event_generator.h
+++ b/ui/accessibility/ax_event_generator.h
@@ -344,6 +344,8 @@
           ancestor_ignored_changed_map);
   void PostprocessEvents();
 
+  AXLiveRegionTracker* GetOrCreateLiveRegionTracker();
+
   raw_ptr<AXTree> tree_ = nullptr;  // Not owned.
   std::map<AXNodeID, std::set<EventParams>> tree_events_;
 
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc
index 1bebc3e1..5df39dd 100644
--- a/ui/accessibility/ax_node.cc
+++ b/ui/accessibility/ax_node.cc
@@ -1376,6 +1376,20 @@
   return &table_info->extra_mac_nodes;
 }
 
+bool AXNode::IsGenerated() const {
+  bool is_generated_node = id() < 0;
+#if DCHECK_IS_ON()
+  // Currently, the only generated nodes are columns and table header
+  // containers, and when those roles occur, they are always extra mac nodes.
+  // This could change in the future.
+  bool is_extra_mac_node_role =
+      GetRole() == ax::mojom::Role::kColumn ||
+      GetRole() == ax::mojom::Role::kTableHeaderContainer;
+  DCHECK_EQ(is_generated_node, is_extra_mac_node_role);
+#endif
+  return is_generated_node;
+}
+
 //
 // Table row-like nodes.
 //
diff --git a/ui/accessibility/ax_node.h b/ui/accessibility/ax_node.h
index b17d839..0ab5264 100644
--- a/ui/accessibility/ax_node.h
+++ b/ui/accessibility/ax_node.h
@@ -603,6 +603,9 @@
   // table header container node, or nullptr if not applicable.
   const std::vector<AXNode*>* GetExtraMacNodes() const;
 
+  // Return true for mock nodes added to the map, such as extra mac nodes.
+  bool IsGenerated() const;
+
   // Table row-like nodes.
   bool IsTableRow() const;
   absl::optional<int> GetTableRowRowIndex() const;
diff --git a/ui/accessibility/ax_node_unittest.cc b/ui/accessibility/ax_node_unittest.cc
index 9dd6024..ef59955f 100644
--- a/ui/accessibility/ax_node_unittest.cc
+++ b/ui/accessibility/ax_node_unittest.cc
@@ -757,7 +757,7 @@
   row.id = 3;
   gridcell_1.id = 4;
   gridcell_2.id = 5;
-  gridcell_2.id = 6;
+  gridcell_3.id = 6;
 
   root.role = ax::mojom::Role::kRootWebArea;
   root.child_ids = {grid.id};
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc
index 88703db..465886db 100644
--- a/ui/accessibility/ax_tree.cc
+++ b/ui/accessibility/ax_tree.cc
@@ -737,13 +737,6 @@
 }
 
 AXTree::AXTree() {
-  AXNodeData root;
-  root.id = kInvalidAXNodeID;
-
-  AXTreeUpdate initial_state;
-  initial_state.root_id = kInvalidAXNodeID;
-  initial_state.nodes.push_back(root);
-  CHECK(Unserialize(initial_state)) << error();
   // TODO(chrishall): should language_detection_manager be a member or pointer?
   // TODO(chrishall): do we want to initialize all the time, on demand, or only
   //                  when feature flag is set?
@@ -790,6 +783,8 @@
 }
 
 AXNode* AXTree::GetFromId(AXNodeID id) const {
+  if (id == ui::kInvalidAXNodeID)
+    return nullptr;
   auto iter = id_map_.find(id);
   return iter != id_map_.end() ? iter->second.get() : nullptr;
 }
@@ -1036,6 +1031,12 @@
 }
 
 bool AXTree::Unserialize(const AXTreeUpdate& update) {
+#if DCHECK_IS_ON()
+  for (const auto& new_data : update.nodes)
+    DCHECK(new_data.id != kInvalidAXNodeID)
+        << "AXTreeUpdate contains invalid node: " << update.ToString();
+#endif
+
   event_data_ = std::make_unique<AXEvent>();
   event_data_->event_from = update.event_from;
   event_data_->event_from_action = update.event_from_action;
@@ -1159,7 +1160,8 @@
       }
     }
 
-    DCHECK_EQ(!GetFromId(update.root_id), update_state.root_will_be_created);
+    DCHECK_EQ(update.root_id != kInvalidAXNodeID && !GetFromId(update.root_id),
+              update_state.root_will_be_created);
 
     // Update all of the nodes in the update.
     for (const AXNodeData& updated_node_data : update_state.updated_nodes) {
@@ -1290,14 +1292,10 @@
   }
 
   // Now that the unignored cached values are up to date, notify observers of
-  // the nodes that were deleted from the tree but not reparented.
-  for (AXNodeID node_id : update_state.removed_node_ids) {
-    if (!update_state.IsCreatedNode(node_id))
-      NotifyNodeHasBeenDeleted(node_id);
-  }
-
-  // Now that the unignored cached values are up to date, notify observers of
-  // new nodes in the tree.
+  // new nodes in the tree. This is done before notifications of deleted nodes,
+  // because deleting nodes can cause events to be fired, which will need to
+  // access the root, and therefore the BrowserAccessibilityManager needs to be
+  // aware of any newly created root as soon as possible.
   for (AXNodeID node_id : update_state.new_node_ids) {
     AXNode* node = GetFromId(node_id);
     if (node)
@@ -1305,6 +1303,13 @@
   }
 
   // Now that the unignored cached values are up to date, notify observers of
+  // the nodes that were deleted from the tree but not reparented.
+  for (AXNodeID node_id : update_state.removed_node_ids) {
+    if (!update_state.IsCreatedNode(node_id))
+      NotifyNodeHasBeenDeleted(node_id);
+  }
+
+  // Now that the unignored cached values are up to date, notify observers of
   // node changes.
   for (AXNodeID changed_id : update_state.node_data_changed_ids) {
     AXNode* node = GetFromId(changed_id);
@@ -1385,6 +1390,7 @@
   // |update_state| must already contain information about all of the expected
   // changes and invalidations to apply. If any of these are missing, observers
   // may not be notified of changes.
+  SANITIZER_CHECK(id != kInvalidAXNodeID);
   DCHECK(!GetFromId(id));
   DCHECK_GT(update_state->GetPendingCreateNodeCount(id), 0);
   DCHECK(update_state->InvalidatesUnignoredCachedValues(id));
@@ -1493,13 +1499,17 @@
     }
   }
 
-  update_state->root_will_be_created =
-      !GetFromId(update.root_id) ||
-      !update_state->ShouldPendingNodeExistInTree(update.root_id);
+  if (update.root_id != kInvalidAXNodeID) {
+    update_state->root_will_be_created =
+        !GetFromId(update.root_id) ||
+        !update_state->ShouldPendingNodeExistInTree(update.root_id);
+  }
 
   // Populate |update_state| with all of the changes that will be performed
   // on the tree during the update.
   for (const AXNodeData& new_data : update_state->updated_nodes) {
+    if (new_data.id == kInvalidAXNodeID)
+      continue;
     bool is_new_root =
         update_state->root_will_be_created && new_data.id == update.root_id;
     if (!ComputePendingChangesToNode(new_data, is_new_root, update_state)) {
@@ -1835,8 +1845,18 @@
     const AXTreeData* optional_new_tree_data,
     const AXNodeData& new_data) {
   DCHECK(!GetTreeUpdateInProgressState());
-  if (node->id() == kInvalidAXNodeID)
+  DCHECK(node);
+  DCHECK(node->id() != kInvalidAXNodeID);
+
+  // Do not fire generated events for initial empty document:
+  // The initial empty document and changes to it are uninteresting. It is a
+  // bit of a hack that may not need to exist in the future
+  // TODO(accessibility) Find a way to remove the initial empty document and the
+  // need for this special case.
+  if (node->GetRole() == ax::mojom::Role::kRootWebArea &&
+      old_data.child_ids.empty() && !node->GetParentCrossingTreeBoundary()) {
     return;
+  }
 
   for (AXTreeObserver& observer : observers_)
     observer.OnNodeDataChanged(this, old_data, new_data);
@@ -2095,17 +2115,18 @@
 
 void AXTree::DestroyNodeAndSubtree(AXNode* node,
                                    AXTreeUpdateState* update_state) {
+  AXNodeID id = node->id();
+
   DCHECK(GetTreeUpdateInProgressState());
-  DCHECK(!update_state ||
-         update_state->GetPendingDestroyNodeCount(node->id()) > 0);
+  DCHECK(!update_state || update_state->GetPendingDestroyNodeCount(id) > 0);
 
   // Clear out any reverse relations.
   AXNodeData empty_data;
-  empty_data.id = node->id();
+  empty_data.id = id;
   UpdateReverseRelations(node, empty_data);
 
-  AXNodeID id = node->id();
   auto iter = id_map_.find(id);
+  DCHECK(iter != id_map_.end());
   std::unique_ptr<AXNode> node_to_delete = std::move(iter->second);
   id_map_.erase(iter);
   node = nullptr;
@@ -2625,7 +2646,9 @@
     AXNodeID& node_id,
     int32_t& offset,
     ax::mojom::TextAffinity& affinity) {
-  AXNode* node = tree.GetFromId(node_id);
+  AXNode* node = nullptr;
+  if (node_id != kInvalidAXNodeID)
+    node = tree.GetFromId(node_id);
   if (!node) {
     node_id = kInvalidAXNodeID;
     offset = -1;
diff --git a/ui/accessibility/ax_tree_unittest.cc b/ui/accessibility/ax_tree_unittest.cc
index bb75f11a..1756572 100644
--- a/ui/accessibility/ax_tree_unittest.cc
+++ b/ui/accessibility/ax_tree_unittest.cc
@@ -1213,44 +1213,26 @@
   initial_state.nodes.push_back(node);
   initial_state.nodes.push_back(node);
   ui::AXTree tree;
+#if DCHECK_IS_ON()
+  EXPECT_DEATH_IF_SUPPORTED(tree.Unserialize(initial_state),
+                            "AXTreeUpdate contains invalid node");
+#else
   tree.Unserialize(initial_state);
+#endif
 }
 
 // UAF caught by ax_tree_fuzzer
 TEST(AXTreeTest, BogusAXTree2) {
   AXTreeUpdate initial_state;
+  initial_state.root_id = 1;
   AXNodeData node;
-  node.id = 0;
+  node.id = 1;
   initial_state.nodes.push_back(node);
   AXNodeData node2;
-  node2.id = 0;
-  node2.child_ids.push_back(0);
-  node2.child_ids.push_back(0);
-  initial_state.nodes.push_back(node2);
-  ui::AXTree tree;
-#if defined(AX_FAIL_FAST_BUILD)
-  EXPECT_DEATH_IF_SUPPORTED(tree.Unserialize(initial_state),
-                            "Node 0 has duplicate child id 0");
-#else
-  EXPECT_FALSE(tree.Unserialize(initial_state));
-  EXPECT_EQ("Node 0 has duplicate child id 0", tree.error());
-#endif
-}
-
-// UAF caught by ax_tree_fuzzer
-TEST(AXTreeTest, BogusAXTree3) {
-  AXTreeUpdate initial_state;
-  AXNodeData node;
-  node.id = 0;
-  node.child_ids.push_back(1);
-  initial_state.nodes.push_back(node);
-
-  AXNodeData node2;
   node2.id = 1;
   node2.child_ids.push_back(1);
   node2.child_ids.push_back(1);
   initial_state.nodes.push_back(node2);
-
   ui::AXTree tree;
 #if defined(AX_FAIL_FAST_BUILD)
   EXPECT_DEATH_IF_SUPPORTED(tree.Unserialize(initial_state),
@@ -1261,6 +1243,30 @@
 #endif
 }
 
+// UAF caught by ax_tree_fuzzer
+TEST(AXTreeTest, BogusAXTree3) {
+  AXTreeUpdate initial_state;
+  initial_state.root_id = 1;
+  AXNodeData node;
+  node.id = 1;
+  node.child_ids.push_back(2);
+  node.child_ids.push_back(2);
+  initial_state.nodes.push_back(node);
+
+  AXNodeData node2;
+  node2.id = 2;
+  initial_state.nodes.push_back(node2);
+
+  ui::AXTree tree;
+#if defined(AX_FAIL_FAST_BUILD)
+  EXPECT_DEATH_IF_SUPPORTED(tree.Unserialize(initial_state),
+                            "Node 1 has duplicate child id 2");
+#else
+  EXPECT_FALSE(tree.Unserialize(initial_state));
+  EXPECT_EQ("Node 2 has duplicate child id 1", tree.error());
+#endif
+}
+
 TEST(AXTreeTest, RoleAndStateChangeCallbacks) {
   AXTreeUpdate initial_state;
   initial_state.root_id = 1;
diff --git a/ui/accessibility/platform/ax_platform_node_delegate.cc b/ui/accessibility/platform/ax_platform_node_delegate.cc
index 3548a24..0f8da985 100644
--- a/ui/accessibility/platform/ax_platform_node_delegate.cc
+++ b/ui/accessibility/platform/ax_platform_node_delegate.cc
@@ -12,9 +12,11 @@
 
 AXPlatformNodeDelegate::AXPlatformNodeDelegate(ui::AXNode* node) : node_(node) {
   DCHECK(node);
+  DCHECK(node->IsDataValid());
 }
 
 void AXPlatformNodeDelegate::SetNode(AXNode& node) {
+  DCHECK(node.IsDataValid());
   node_ = &node;
 }
 
diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h
index 03472ecaf..24c2ce7 100644
--- a/ui/aura/window_tree_host.h
+++ b/ui/aura/window_tree_host.h
@@ -407,7 +407,6 @@
   void MaybeUpdateComposibleVisibilityForVideoLockCountChange();
   bool CalculateCompositorVisibilityFromOcclusionState() const;
 
-  // See `kApplyNativeOcclusionToCompositorTypeRelease` for details.
   // TODO(https://crbug.com/1248235): remove this.
   bool ShouldReleaseResourcesWhenHidden() const;
 
diff --git a/ui/base/ui_base_features.cc b/ui/base/ui_base_features.cc
index 90cff76..27c412a 100644
--- a/ui/base/ui_base_features.cc
+++ b/ui/base/ui_base_features.cc
@@ -29,7 +29,7 @@
 // If enabled, the occluded region of the HWND is supplied to WindowTracker.
 const base::Feature kApplyNativeOccludedRegionToWindowTracker{
     "ApplyNativeOccludedRegionToWindowTracker",
-    base::FEATURE_DISABLED_BY_DEFAULT};
+    base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Once enabled, the exact behavior is dictated by the field trial param
 // name `kApplyNativeOcclusionToCompositorType`.
diff --git a/ui/chromeos/styles/cros_colors.json5 b/ui/chromeos/styles/cros_colors.json5
index 671e984..d954f71 100644
--- a/ui/chromeos/styles/cros_colors.json5
+++ b/ui/chromeos/styles/cros_colors.json5
@@ -67,6 +67,7 @@
       light: "$google_blue_700",
       dark: "$google_blue_200",
       debug: "$google_red_700",
+      generate_per_mode: true,
     },
 
     /*
diff --git a/ui/ozone/platform/wayland/common/wayland_util.h b/ui/ozone/platform/wayland/common/wayland_util.h
index 836258d..aec43ee 100644
--- a/ui/ozone/platform/wayland/common/wayland_util.h
+++ b/ui/ozone/platform/wayland/common/wayland_util.h
@@ -41,6 +41,13 @@
 using BufferFormatsWithModifiersMap =
     base::flat_map<gfx::BufferFormat, std::vector<uint64_t>>;
 
+// Constants used to determine how pointer/touch events are processed and
+// dispatched.
+enum class EventDispatchPolicy {
+  kImmediate,
+  kOnFrame,
+};
+
 // Identifies the direction of the "hittest" for Wayland. |connection|
 // is used to identify whether values from shell v5 or v6 must be used.
 uint32_t IdentifyDirection(const ui::WaylandConnection& connection,
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.h b/ui/ozone/platform/wayland/host/wayland_event_source.h
index 26f9f88..b6f75d4 100644
--- a/ui/ozone/platform/wayland/host/wayland_event_source.h
+++ b/ui/ozone/platform/wayland/host/wayland_event_source.h
@@ -19,6 +19,7 @@
 #include "ui/events/pointer_details.h"
 #include "ui/events/types/event_type.h"
 #include "ui/gfx/geometry/point_f.h"
+#include "ui/ozone/platform/wayland/common/wayland_util.h"
 #include "ui/ozone/platform/wayland/host/wayland_input_method_context.h"
 #include "ui/ozone/platform/wayland/host/wayland_keyboard.h"
 #include "ui/ozone/platform/wayland/host/wayland_pointer.h"
@@ -33,15 +34,6 @@
 class Vector2dF;
 }
 
-namespace wl {
-
-enum class EventDispatchPolicy {
-  kImmediate,
-  kOnFrame,
-};
-
-}  // namespace wl
-
 namespace ui {
 
 class WaylandConnection;
diff --git a/ui/ozone/platform/wayland/host/wayland_pointer.cc b/ui/ozone/platform/wayland/host/wayland_pointer.cc
index 1435713..feabbc7 100644
--- a/ui/ozone/platform/wayland/host/wayland_pointer.cc
+++ b/ui/ozone/platform/wayland/host/wayland_pointer.cc
@@ -11,12 +11,9 @@
 #include "ui/events/types/event_type.h"
 #include "ui/ozone/platform/wayland/common/wayland_util.h"
 #include "ui/ozone/platform/wayland/host/wayland_connection.h"
-#include "ui/ozone/platform/wayland/host/wayland_event_source.h"
 #include "ui/ozone/platform/wayland/host/wayland_serial_tracker.h"
 #include "ui/ozone/platform/wayland/host/wayland_window.h"
 
-// TODO(forney): Handle version 5 of wl_pointer.
-
 namespace ui {
 
 namespace {
diff --git a/ui/ozone/platform/wayland/host/wayland_touch.cc b/ui/ozone/platform/wayland/host/wayland_touch.cc
index 3992670..afacef7 100644
--- a/ui/ozone/platform/wayland/host/wayland_touch.cc
+++ b/ui/ozone/platform/wayland/host/wayland_touch.cc
@@ -12,7 +12,6 @@
 #include "ui/gfx/geometry/point_f.h"
 #include "ui/ozone/platform/wayland/common/wayland_util.h"
 #include "ui/ozone/platform/wayland/host/wayland_connection.h"
-#include "ui/ozone/platform/wayland/host/wayland_event_source.h"
 #include "ui/ozone/platform/wayland/host/wayland_serial_tracker.h"
 #include "ui/ozone/platform/wayland/host/wayland_window.h"
 
diff --git a/ui/views/OWNERS b/ui/views/OWNERS
index bbe15824..32e5ffae 100644
--- a/ui/views/OWNERS
+++ b/ui/views/OWNERS
@@ -25,5 +25,7 @@
 per-file *_cocoa.*=lgrey@chromium.org
 per-file *.mm=lgrey@chromium.org
 
+per-file *_win.*=davidbienvenu@chromium.org
+
 # If you're doing structural changes get a review from one of the OWNERS.
 per-file BUILD.gn=*
diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc
index dacb2199..ea3e9e6 100644
--- a/ui/views/controls/label.cc
+++ b/ui/views/controls/label.cc
@@ -205,8 +205,24 @@
 void Label::SetEnabledColor(SkColor color) {
   if (enabled_color_set_ && requested_enabled_color_ == color)
     return;
-  requested_enabled_color_ = color;
+
   enabled_color_set_ = true;
+  UpdateEnabledColor(color);
+}
+
+void Label::SetEnabledColorId(absl::optional<ui::ColorId> enabled_color_id) {
+  if (enabled_color_id_ == enabled_color_id)
+    return;
+
+  enabled_color_id_ = enabled_color_id;
+  OnPropertyChanged(&enabled_color_id_, kPropertyEffectsPaint);
+}
+
+void Label::UpdateEnabledColor(SkColor color) {
+  if (requested_enabled_color_ == color)
+    return;
+
+  requested_enabled_color_ = color;
   RecalculateColors();
   OnPropertyChanged(&requested_enabled_color_, kPropertyEffectsPaint);
 }
@@ -805,6 +821,8 @@
 void Label::OnThemeChanged() {
   View::OnThemeChanged();
   UpdateColorsFromTheme();
+  if (enabled_color_id_)
+    UpdateEnabledColor(GetColorProvider()->GetColor(*enabled_color_id_));
 }
 
 ui::Cursor Label::GetCursor(const ui::MouseEvent& event) {
@@ -1210,7 +1228,7 @@
 
 void Label::UpdateColorsFromTheme() {
   ui::ColorProvider* color_provider = GetColorProvider();
-  if (!enabled_color_set_) {
+  if (!enabled_color_set_ && !enabled_color_id_.has_value()) {
     const absl::optional<SkColor> cascading_color =
         GetCascadingProperty(this, kCascadingLabelEnabledColor);
     requested_enabled_color_ = cascading_color.value_or(
diff --git a/ui/views/controls/label.h b/ui/views/controls/label.h
index 28c9b4fc..70650af4 100644
--- a/ui/views/controls/label.h
+++ b/ui/views/controls/label.h
@@ -132,6 +132,8 @@
   // enabled.
   SkColor GetEnabledColor() const;
   virtual void SetEnabledColor(SkColor color);
+  void SetEnabledColorId(absl::optional<ui::ColorId> enabled_color_id);
+  void UpdateEnabledColor(SkColor color);
 
   // Gets/Sets the background color. This won't be explicitly drawn, but the
   // label will force the text color to be readable over it.
@@ -468,6 +470,8 @@
   SkColor actual_selection_text_color_ = gfx::kPlaceholderColor;
   SkColor selection_background_color_ = gfx::kPlaceholderColor;
 
+  absl::optional<ui::ColorId> enabled_color_id_;
+
   // Set to true once the corresponding setter is invoked.
   bool enabled_color_set_ = false;
   bool background_color_set_ = false;
@@ -512,6 +516,7 @@
 VIEW_BUILDER_PROPERTY(SkColor, BackgroundColor)
 VIEW_BUILDER_PROPERTY(SkColor, SelectionTextColor)
 VIEW_BUILDER_PROPERTY(SkColor, SelectionBackgroundColor)
+VIEW_BUILDER_PROPERTY(ui::ColorId, EnabledColorId)
 VIEW_BUILDER_PROPERTY(const gfx::ShadowValues&, Shadows)
 VIEW_BUILDER_PROPERTY(bool, SubpixelRenderingEnabled)
 VIEW_BUILDER_PROPERTY(bool, SkipSubpixelRenderingOpacityCheck)
diff --git a/ui/views/controls/label_unittest.cc b/ui/views/controls/label_unittest.cc
index b8f0524..0aca0c7d 100644
--- a/ui/views/controls/label_unittest.cc
+++ b/ui/views/controls/label_unittest.cc
@@ -23,6 +23,7 @@
 #include "ui/base/clipboard/clipboard.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/ui_base_switches.h"
+#include "ui/color/color_provider.h"
 #include "ui/compositor/canvas_painter.h"
 #include "ui/compositor/layer.h"
 #include "ui/events/base_event_utils.h"
@@ -290,6 +291,14 @@
   EXPECT_EQ(color, label()->GetEnabledColor());
 }
 
+TEST_F(LabelTest, ColorPropertyOnEnabledColorIdChange) {
+  const auto color = label()->GetWidget()->GetColorProvider()->GetColor(
+      ui::kColorPrimaryForeground);
+  label()->SetAutoColorReadabilityEnabled(false);
+  label()->SetEnabledColorId(ui::kColorPrimaryForeground);
+  EXPECT_EQ(color, label()->GetEnabledColor());
+}
+
 TEST_F(LabelTest, AlignmentProperty) {
   const bool was_rtl = base::i18n::IsRTL();
 
diff --git a/ui/webui/resources/cr_elements/cr_scrollable_behavior.js b/ui/webui/resources/cr_elements/cr_scrollable_behavior.js
index 64eb8902..ea723d3 100644
--- a/ui/webui/resources/cr_elements/cr_scrollable_behavior.js
+++ b/ui/webui/resources/cr_elements/cr_scrollable_behavior.js
@@ -47,24 +47,17 @@
   intervalId_: null,
 
   ready() {
-    const readyAsync = () => {
+    beforeNextRender(this, () => {
       this.requestUpdateScroll();
 
       // Listen to the 'scroll' event for each scrollable container.
-      const scrollableElements = this.root.querySelectorAll('[scrollable]');
+      const scrollableElements =
+          this.shadowRoot.querySelectorAll('[scrollable]');
       for (let i = 0; i < scrollableElements.length; i++) {
         scrollableElements[i].addEventListener(
             'scroll', this.updateScrollEvent_.bind(this));
       }
-    };
-
-    // TODO(dpapad): Remove Polymer 1 codepath when Polymer 2 migration has
-    // completed.
-    if (Polymer.DomIf) {
-      beforeNextRender(this, readyAsync);
-      return;
-    }
-    readyAsync();
+    });
   },
 
   detached() {
@@ -85,7 +78,7 @@
 
     this.requestUpdateScroll();
 
-    const nodeList = this.root.querySelectorAll('[scrollable] iron-list');
+    const nodeList = this.shadowRoot.querySelectorAll('[scrollable] iron-list');
     if (!nodeList.length) {
       return;
     }
@@ -137,7 +130,8 @@
    */
   requestUpdateScroll() {
     requestAnimationFrame(function() {
-      const scrollableElements = this.root.querySelectorAll('[scrollable]');
+      const scrollableElements =
+          this.shadowRoot.querySelectorAll('[scrollable]');
       for (let i = 0; i < scrollableElements.length; i++) {
         this.updateScroll_(/** @type {!HTMLElement} */ (scrollableElements[i]));
       }