diff --git a/AUTHORS b/AUTHORS
index 68f3377..8cf38d1e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -449,7 +449,6 @@
 Girish Kumar M <mck.giri@samsung.com>
 Gitanshu Mehndiratta <g.mehndiratt@samsung.com>
 Giuseppe Iuculano <giuseppe@iuculano.it>
-Gloam <gaoqingguang@kuaishou.com>
 Gnanasekar Somanathan <gnanasekar.s@samsung.com>
 Gordana Cmiljanovic <gordana.cmiljanovic@imgtec.com>
 Goutham Jagannatha <wrm364@motorola.com>
diff --git a/DEPS b/DEPS
index 7a0330a..167fef6 100644
--- a/DEPS
+++ b/DEPS
@@ -313,19 +313,19 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'src_internal_revision': 'd2f1105690202f0c66a12b243f4a7772300fa0e0',
+  'src_internal_revision': '6b110587054eb66ac230575205a3a948d3d14303',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '8132e3356d63b576df1471f1e10d7ea2da4cd1bd',
+  'skia_revision': '85971b25cf4b94a4843f6a4e9faa6412b3d56d92',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'bf7fbd2548b2e6dd2d9ca12ede93e52d28e7baab',
+  'v8_revision': 'bc56dafb2ce1ddfbca6861bb92038b40da83db54',
   # 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': 'f56f97009543b0a93aca86fd425400e649aaf51d',
+  'angle_revision': '889b01efcbf6e993d29f937515ca7e9d5e73b990',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -333,7 +333,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': 'f51bfc7f6b03b942534d9cab8fe4cb7c3b75420d',
+  'pdfium_revision': '0bb4790a4455400532900b350d967260fa1ea552',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -368,7 +368,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
-  'freetype_revision': '3fa5c84565f2431a13247f055623508137dc5739',
+  'freetype_revision': 'a35da2c09312e222e5728e849988f1acf998df9a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -388,11 +388,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'b9ebaddcd0d4298e8e65641a5f454f7603e90b40',
+  'catapult_revision': 'f496845cb9f8db416fc711747fe8594364109465',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling chromium_variations
   # and whatever else without interference from each other.
-  'chromium_variations_revision': 'ccdc1ba5ff762128cd9add94b211d53261227297',
+  'chromium_variations_revision': '6d4720af28ceb0c0ff855c0e7223e1d8f532c19e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling CrossBench
   # and whatever else without interference from each other.
@@ -408,7 +408,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '31efe53d04bae3442cb0bf323586848a6893a490',
+  'devtools_frontend_revision': '44e8b4234dadbbf5d67d4b82cf8e26e3ce525395',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -448,7 +448,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': 'c3245174b4f2bf8d8bb5d74a343397d568e5ca9a',
+  'dawn_revision': '3d86265f5114096248c400539e3bc4da9d4bc834',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -500,7 +500,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.
-  'libcxxabi_revision':    'db9800c042df3ee2691031a58b5e37e89a7356a3',
+  'libcxxabi_revision':    'cbc5f2b0cdd7de12e105368fe4d5bb4109278998',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -524,7 +524,7 @@
 
   # If you change this, also update the libc++ revision in
   # //buildtools/deps_revisions.gni.
-  'libcxx_revision':       '2f6750b44bbad5726de61f2b4e2021fedba63666',
+  'libcxx_revision':       '8d4b8a60c23515932186285479fe1e9c073cc513',
 
   # GN CIPD package version.
   'gn_version': 'git_revision:182a6eb05d15cc76d2302f7928fdb4f645d52c53',
@@ -848,12 +848,12 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    '3550ec36b687fc1d983b858dadd2016af443b8de',
+    '6df998f988f76d25861fc7aeea8fa55bcc6c98b8',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
   'src/docs/website': {
-    'url': Var('chromium_git') + '/website.git' + '@' + '6ca9b5dcd42207c82e48d0d921742abe1a778815',
+    'url': Var('chromium_git') + '/website.git' + '@' + 'df59ae11bb4ef8c7ab3803d84cc7808c2b294030',
   },
 
   'src/ios/third_party/earl_grey2/src': {
@@ -1054,7 +1054,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': '_i7u9FvhJhwRUkGaNmG9XnlMwHxAidtYKEGeD_Q8rJoC',
+          'version': 'mKlggNDsEv0JjWpi3rudjBg2bHFe469T00mjfL10gX0C',
       },
     ],
     'condition': 'checkout_android',
@@ -1298,13 +1298,13 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '406be8281e32743a86df7c855ba608739e812dea',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '8f761f57958a1affcc2752f48ba5e5edf8dc1042',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '4cbcaa06310577799ba02946d89a4f8b4218a0b9',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'afa14b392c2fddb74fbf11018f8dad67d5c42f95',
     'condition': 'checkout_src_internal',
   },
 
@@ -1769,7 +1769,7 @@
     Var('pdfium_git') + '/pdfium.git' + '@' +  Var('pdfium_revision'),
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '43f878eaee4f5cd96b7404f6830af679a283ebce',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '34f1b98dca5071866b2f0778605dcea0a3d1fbef',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1803,7 +1803,7 @@
   },
 
   'src/third_party/re2/src':
-    Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + 'ece4cecab5c8445d93abd98d88c899f370b4ea4a',
+    Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + '928a015e6ecc02519abb5d4a8732099545c48346',
 
   'src/third_party/r8': {
       'packages': [
@@ -1839,7 +1839,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/robolectric',
-              'version': 'hzetqh1qFI32FOgQroZvGcGdomrgVBJ6WKRnl1KFw6EC',
+              'version': 'UmWqaevXYVw3D8VySDJcqj3aU9zMDFwt1RySUuU0vI8C',
           },
       ],
       'condition': 'checkout_android',
@@ -1914,7 +1914,7 @@
       'dep_type': 'cipd',
   },
 
-  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@178effa90318284c25994f6cf9216bc6346883f7',
+  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@07facff77053becb70a23e07b60200ec6ddc8f36',
 
   'src/third_party/vulkan_memory_allocator':
     Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + '56300b29fbfcc693ee6609ddad3fdd5b7a449a21',
@@ -1951,10 +1951,10 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'f4bf599a8b575df685c31d9c4729a70a04e377ed',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '6696b0e2df59ae2bb5a29a7b1dbb50e4109b6b55',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'c78f0a43e79c2b0fa86dbd7775dfaed04d79b9f1',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '1a22983098e6ed36489bc762c945f55abfb9514e',
+    Var('webrtc_git') + '/src.git' + '@' + '2bf3620e13769857cdf6b28a17abe47918ccf2bd',
 
   # Wuffs' canonical repository is at github.com/google/wuffs, but we use
   # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file.
@@ -2088,7 +2088,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'YAK_rAOjiQsVCWX5Mp4CAn9LPkPf1OFulLlKKlC2AV4C',
+        'version': 'W0LwaJyPIgJNS9Xheugak4MNmHre6lqvpwmb4YR7mu0C',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4122,7 +4122,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        'b78bef8066637f477844e27db169a452d4934d5f',
+        'd40d38dc60efd0a1af6d8ed0f6076a44cabe7d95',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
index 0797858..385b9521 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -147,8 +147,6 @@
                 BlinkFeatures.USER_AGENT_CLIENT_HINT,
                 "Enables user-agent client hints in WebView."),
         Flag.baseFeature(
-                BlinkFeatures.PERMISSIONS_POLICY_UNLOAD, "Enables unload as a Permissions-Policy."),
-        Flag.baseFeature(
                 "DefaultPassthroughCommandDecoder", "Use the passthrough GLES2 command decoder."),
         Flag.baseFeature(
                 GpuFeatures.WEBVIEW_VULKAN,
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 9f5e45e..dfd7103 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -3257,6 +3257,7 @@
     "frame/default_frame_header_unittest.cc",
     "frame/non_client_frame_view_ash_unittest.cc",
     "frame_sink/frame_sink_holder_unittest.cc",
+    "frame_sink/frame_sink_host_unittest.cc",
     "frame_sink/ui_resource_manager_unittest.cc",
     "frame_throttler/frame_throttling_controller_unittest.cc",
     "game_dashboard/game_dashboard_context_unittest.cc",
diff --git a/ash/accelerators/ash_accelerator_configuration.cc b/ash/accelerators/ash_accelerator_configuration.cc
index 5439cbc..17c9f08 100644
--- a/ash/accelerators/ash_accelerator_configuration.cc
+++ b/ash/accelerators/ash_accelerator_configuration.cc
@@ -22,6 +22,7 @@
 #include "base/containers/cxx20_erase.h"
 #include "base/containers/span.h"
 #include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -207,6 +208,15 @@
   // Store a copy of the pref overrides.
   accelerator_overrides_ =
       pref_service->GetDict(prefs::kShortcutCustomizationOverrides).Clone();
+
+  // Count the total number of modifications and store the histogram.
+  int num_entries = 0;
+  for (const auto entry : accelerator_overrides_) {
+    num_entries += entry.second.GetList().size();
+  }
+  base::UmaHistogramCounts1000(
+      "Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", num_entries);
+
   // Reset to default first.
   ResetAllAccelerators();
   ApplyPrefOverrides();
diff --git a/ash/accelerators/ash_accelerator_configuration_unittest.cc b/ash/accelerators/ash_accelerator_configuration_unittest.cc
index 566f4a5..bb85d45 100644
--- a/ash/accelerators/ash_accelerator_configuration_unittest.cc
+++ b/ash/accelerators/ash_accelerator_configuration_unittest.cc
@@ -18,6 +18,7 @@
 #include "ash/test/ash_test_base.h"
 #include "base/containers/contains.h"
 #include "base/ranges/algorithm.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "ui/base/accelerators/accelerator.h"
 #include "ui/base/ui_base_features.h"
@@ -162,17 +163,20 @@
     AshTestBase::SetUp();
     config_ = std::make_unique<AshAcceleratorConfiguration>();
     config_->AddObserver(&observer_);
+    histogram_tester_ = std::make_unique<base::HistogramTester>();
   }
 
   void TearDown() override {
     config_->RemoveObserver(&observer_);
     AshTestBase::TearDown();
+    histogram_tester_.reset();
   }
 
  protected:
   base::test::ScopedFeatureList scoped_feature_list_;
   UpdatedAcceleratorsObserver observer_;
   std::unique_ptr<AshAcceleratorConfiguration> config_;
+  std::unique_ptr<base::HistogramTester> histogram_tester_;
 };
 
 TEST_F(AshAcceleratorConfigurationTest, VerifyAcceleratorMappingPopulated) {
@@ -1524,6 +1528,12 @@
 
 TEST_F(AshAcceleratorConfigurationTest, RemoveAcceleratorThenResetAllPref) {
   SimulateNewUserFirstLogin(kFakeUserEmail);
+
+  // Check histogram. There are two counts initially since there has been
+  // two separate logins in this test.
+  histogram_tester_->ExpectBucketCount(
+      "Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 0, 2);
+
   const AcceleratorData test_data[] = {
       {/*trigger_on_press=*/true, ui::VKEY_SPACE, ui::EF_CONTROL_DOWN,
        AcceleratorAction::kSwitchToLastUsedIme},
@@ -1586,6 +1596,9 @@
        AcceleratorAction::kCycleBackwardMru},
   };
   ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
+  // `SimuateUserLogin` triggers the metric twice in tests.
+  histogram_tester_->ExpectBucketCount(
+      "Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 1, 2);
 
   // Now reset all to default.
   result = config_->RestoreAllDefaults();
@@ -1600,6 +1613,10 @@
   EXPECT_TRUE(reset_pref_overrides.empty());
   // `test_data` is the default state of accelerators.
   ExpectAllAcceleratorsEqual(test_data, config_->GetAllAccelerators());
+  // Expect increases in the `0` bucket, it gets incremented by 2 due to
+  // `SimulateUserLogin`.
+  histogram_tester_->ExpectBucketCount(
+      "Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 0, 4);
 }
 
 TEST_F(AshAcceleratorConfigurationTest, RemoveAcceleratorThenResetPref) {
@@ -1692,6 +1709,8 @@
   };
 
   config_->Initialize(test_data);
+  histogram_tester_->ExpectBucketCount(
+      "Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 0, 2);
 
   // Expect that there are no entries stored in the override pref.
   const base::Value::Dict& pref_overrides = GetOverridePref();
@@ -1751,6 +1770,8 @@
   EXPECT_EQ(1u, relogin_overrides.size());
   // Verify pref overrides were loaded correctly.
   ExpectAllAcceleratorsEqual(updated_test_data, config_->GetAllAccelerators());
+  histogram_tester_->ExpectBucketCount(
+      "Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 1, 2);
 }
 
 TEST_F(AshAcceleratorConfigurationTest, AddAcceleratorWithConflictWithPrefs) {
@@ -1846,6 +1867,8 @@
   };
 
   config_->Initialize(test_data);
+  histogram_tester_->ExpectBucketCount(
+      "Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 0, 2);
 
   // Expect that there are no entries stored in the override pref.
   const base::Value::Dict& pref_overrides = GetOverridePref();
@@ -1933,6 +1956,8 @@
   SimulateNewUserFirstLogin(kFakeUserEmail2);
   const base::Value::Dict& other_user_pref_overrides = GetOverridePref();
   EXPECT_TRUE(other_user_pref_overrides.empty());
+  histogram_tester_->ExpectBucketCount(
+      "Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 0, 4);
 
   // Now re-login to the original profile.
   GetSessionControllerClient()->LockScreen();
@@ -1952,6 +1977,8 @@
   // accelerators.
   ExpectAllAcceleratorsEqual(expected_test_data_2,
                              config_->GetAllAccelerators());
+  histogram_tester_->ExpectBucketCount(
+      "Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 1, 2);
 }
 
 TEST_F(AshAcceleratorConfigurationTest,
@@ -1967,6 +1994,8 @@
   };
 
   config_->Initialize(test_data);
+  histogram_tester_->ExpectBucketCount(
+      "Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 0, 2);
 
   // Expect that there are no entries stored in the override pref.
   const base::Value::Dict& pref_overrides = GetOverridePref();
@@ -2115,6 +2144,8 @@
   // accelerators.
   ExpectAllAcceleratorsEqual(expected_test_data_3,
                              config_->GetAllAccelerators());
+  histogram_tester_->ExpectBucketCount(
+      "Ash.ShortcutCustomization.CustomizationsLoadedOnStartup", 1, 2);
 }
 
 TEST_F(AshAcceleratorConfigurationTest, RemoveThenAddAcceleratorWithPrefs) {
diff --git a/ash/accessibility/autoclick/autoclick_controller.cc b/ash/accessibility/autoclick/autoclick_controller.cc
index 35789b73..20fedb6 100644
--- a/ash/accessibility/autoclick/autoclick_controller.cc
+++ b/ash/accessibility/autoclick/autoclick_controller.cc
@@ -304,6 +304,9 @@
     return;
   menu_bubble_controller_->SetScrollPosition(bounds_in_screen,
                                              scroll_location_);
+  if (scrollable_bounds_callback_for_testing_) {
+    scrollable_bounds_callback_for_testing_.Run(bounds_in_screen);
+  }
 }
 
 void AutoclickController::UpdateAutoclickMenuBoundsIfNeeded() {
diff --git a/ash/accessibility/autoclick/autoclick_controller.h b/ash/accessibility/autoclick/autoclick_controller.h
index ae2c124c..9a24a54d 100644
--- a/ash/accessibility/autoclick/autoclick_controller.h
+++ b/ash/accessibility/autoclick/autoclick_controller.h
@@ -8,6 +8,7 @@
 #include "ash/ash_export.h"
 #include "ash/constants/ash_constants.h"
 #include "ash/public/cpp/ash_constants.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/time/time.h"
 #include "ui/aura/client/cursor_client_observer.h"
@@ -123,6 +124,10 @@
   AccessibilityFeatureDisableDialog* GetDisableDialogForTesting() {
     return disable_dialog_.get();
   }
+  void SetScrollableBoundsCallbackForTesting(
+      base::RepeatingCallback<void(const gfx::Rect&)> callback) {
+    scrollable_bounds_callback_for_testing_ = callback;
+  }
 
  private:
   void SetTapDownTarget(aura::Window* target);
@@ -202,6 +207,8 @@
   // will not be started. This ensures the autoclick ring is not drawn over
   // the scroll position buttons, and extra clicks will not be generated there.
   bool over_scroll_button_ = false;
+  base::RepeatingCallback<void(const gfx::Rect&)>
+      scrollable_bounds_callback_for_testing_;
 
   // The widget containing the autoclick ring.
   std::unique_ptr<views::Widget> ring_widget_;
diff --git a/ash/app_list/app_list_presenter_unittest.cc b/ash/app_list/app_list_presenter_unittest.cc
index 0b64d15..0559f4a 100644
--- a/ash/app_list/app_list_presenter_unittest.cc
+++ b/ash/app_list/app_list_presenter_unittest.cc
@@ -1680,7 +1680,8 @@
 
   SearchBoxView* search_box_view = GetSearchBoxView();
   search_box_view->GetWidget()->LayoutRootViewIfNecessary();
-  EXPECT_TRUE(search_box_view->close_button()->GetVisible());
+  EXPECT_TRUE(
+      search_box_view->filter_and_close_button_container()->GetVisible());
   LeftClickOn(search_box_view->close_button());
 
   EXPECT_EQ(std::vector<std::u16string>({u""}),
diff --git a/ash/app_list/views/app_list_bubble_view_unittest.cc b/ash/app_list/views/app_list_bubble_view_unittest.cc
index 1bf1761..736b8f0 100644
--- a/ash/app_list/views/app_list_bubble_view_unittest.cc
+++ b/ash/app_list/views/app_list_bubble_view_unittest.cc
@@ -543,13 +543,15 @@
   PressAndReleaseKey(ui::VKEY_A);
 
   EXPECT_TRUE(GetSearchPage()->GetVisible());
-  EXPECT_TRUE(search_box_view->close_button()->GetVisible());
+  EXPECT_TRUE(
+      search_box_view->filter_and_close_button_container()->GetVisible());
   for (int i = 0; i < 100; ++i) {
     PressAndReleaseKey(ui::VKEY_A);
   }
   // Close button should be visible for long queries and within search box
   // view bounds.
-  EXPECT_TRUE(search_box_view->close_button()->GetVisible());
+  EXPECT_TRUE(
+      search_box_view->filter_and_close_button_container()->GetVisible());
   EXPECT_TRUE(search_box_view->GetBoundsInScreen().Contains(
       search_box_view->close_button()->GetBoundsInScreen()));
 }
@@ -623,13 +625,13 @@
 
   // By default the assistant button is visible.
   SearchBoxView* view = GetSearchBoxView();
-  EXPECT_TRUE(view->assistant_button()->GetVisible());
-  EXPECT_FALSE(view->close_button()->GetVisible());
+  EXPECT_TRUE(view->assistant_button_container()->GetVisible());
+  EXPECT_FALSE(view->filter_and_close_button_container()->GetVisible());
 
   // Typing text shows the close button instead.
   PressAndReleaseKey(ui::VKEY_A);
-  EXPECT_FALSE(view->assistant_button()->GetVisible());
-  EXPECT_TRUE(view->close_button()->GetVisible());
+  EXPECT_FALSE(view->assistant_button_container()->GetVisible());
+  EXPECT_TRUE(view->filter_and_close_button_container()->GetVisible());
 }
 
 TEST_F(AppListBubbleViewTest, ClickingAssistantButtonShowsAssistantPage) {
@@ -678,7 +680,8 @@
   // Close button is visible after typing text.
   SearchBoxView* search_box_view = GetSearchBoxView();
   search_box_view->GetWidget()->LayoutRootViewIfNecessary();
-  EXPECT_TRUE(search_box_view->close_button()->GetVisible());
+  EXPECT_TRUE(
+      search_box_view->filter_and_close_button_container()->GetVisible());
   EXPECT_FALSE(search_box_view->search_box()->GetText().empty());
 
   // Clicking the close button clears the search, but the search box is still
@@ -686,7 +689,8 @@
   LeftClickOn(search_box_view->close_button());
   EXPECT_EQ(std::vector<std::u16string>({u""}),
             app_list_client->GetAndResetPastSearchQueries());
-  EXPECT_FALSE(search_box_view->close_button()->GetVisible());
+  EXPECT_FALSE(
+      search_box_view->filter_and_close_button_container()->GetVisible());
   EXPECT_TRUE(search_box_view->search_box()->GetText().empty());
   EXPECT_TRUE(search_box_view->search_box()->HasFocus());
   EXPECT_TRUE(search_box_view->is_search_box_active());
diff --git a/ash/app_list/views/app_list_item_view.cc b/ash/app_list/views/app_list_item_view.cc
index 222bcda..b5be9434 100644
--- a/ash/app_list/views/app_list_item_view.cc
+++ b/ash/app_list/views/app_list_item_view.cc
@@ -1865,13 +1865,24 @@
             },
             base::Unretained(this)));
     progress_indicator_->SetInnerIconVisible(false);
+    progress_indicator_->SetInnerRingVisible(false);
+    progress_indicator_->SetOuterRingStrokeWidth(2.0);
     EnsureLayer();
     layer()->Add(progress_indicator_->CreateLayer(base::BindRepeating(
         [](AppListItemView* view, ui::ColorId color_id) {
           return view->GetColorProvider()->GetColor(color_id);
         },
         base::Unretained(this))));
-    progress_indicator_->SetColorId(cros_tokens::kCrosRefPrimary70);
+  }
+
+  EnsureLayer();
+
+  if (item()->app_status() == AppStatus::kPending) {
+    progress_indicator_->SetColorId(cros_tokens::kCrosSysHighlightShape);
+    progress_indicator_->SetOuterRingTrackVisible(true);
+  } else {
+    progress_indicator_->SetColorId(cros_tokens::kCrosSysPrimary);
+    progress_indicator_->SetOuterRingTrackVisible(false);
   }
 
   UpdateProgressRingBounds();
@@ -1886,7 +1897,6 @@
   CHECK(!is_folder_);
 
   gfx::Size progress_indicator_size = app_list_config_->grid_icon_size();
-  EnsureLayer();
 
   const gfx::Rect progress_bounds = GetIconBoundsForTargetViewBounds(
       app_list_config_, rect,
diff --git a/ash/app_list/views/app_list_main_view_unittest.cc b/ash/app_list/views/app_list_main_view_unittest.cc
index f15fd9c..bd55fb9d 100644
--- a/ash/app_list/views/app_list_main_view_unittest.cc
+++ b/ash/app_list/views/app_list_main_view_unittest.cc
@@ -221,7 +221,8 @@
 TEST_P(AppListMainViewTest, CloseButtonInvisibleAfterCloseButtonClicked) {
   PressAndReleaseKey(ui::VKEY_A);
   ClickButton(search_box_view()->close_button());
-  EXPECT_FALSE(search_box_view()->close_button()->GetVisible());
+  EXPECT_FALSE(
+      search_box_view()->filter_and_close_button_container()->GetVisible());
 }
 
 // Tests that the search box becomes empty after close button is clicked.
diff --git a/ash/app_list/views/app_list_view_pixeltest.cc b/ash/app_list/views/app_list_view_pixeltest.cc
index e1011e9..e47a9a7 100644
--- a/ash/app_list/views/app_list_view_pixeltest.cc
+++ b/ash/app_list/views/app_list_view_pixeltest.cc
@@ -426,8 +426,7 @@
 // Verifies the default layout for tablet mode launcher.
 TEST_P(AppListViewTabletPixelTest, Basic) {
   EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
-      "tablet_launcher_basics",
-      /*revision_number=*/IsJellyEnabled() ? 7 : 6,
+      "tablet_launcher_basics", 9,
       GetAppListTestHelper()->GetAppsContainerView()));
 }
 
@@ -448,8 +447,7 @@
   generator->MoveTouchBy(0, -40);
 
   EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
-      "tablet_launcher_top_gradient_zone",
-      /*revision_number=*/IsJellyEnabled() ? 6 : 5,
+      "tablet_launcher_top_gradient_zone", 7,
       GetAppListTestHelper()->GetAppsContainerView()));
 }
 
@@ -470,8 +468,7 @@
   generator->MoveTouchBy(0, -90);
 
   EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
-      "tablet_launcher_bottom_gradient_zone",
-      /*revision_number=*/IsJellyEnabled() ? 7 : 6,
+      "tablet_launcher_bottom_gradient_zone", 9,
       GetAppListTestHelper()->GetAppsContainerView()));
 }
 
diff --git a/ash/app_list/views/search_box_view_unittest.cc b/ash/app_list/views/search_box_view_unittest.cc
index 248c4e0..081abd8 100644
--- a/ash/app_list/views/search_box_view_unittest.cc
+++ b/ash/app_list/views/search_box_view_unittest.cc
@@ -159,8 +159,9 @@
 
   void TearDown() override {
     ui::ColorProviderManager::ResetForTesting();
-    if (app_list_view_)
+    if (app_list_view_) {
       app_list_view_->GetWidget()->Close();
+    }
     widget_->CloseNow();
     views::test::WidgetTest::TearDown();
   }
@@ -279,13 +280,13 @@
 
 // Tests that the close button is invisible by default.
 TEST_F(SearchBoxViewTest, CloseButtonInvisibleByDefault) {
-  EXPECT_FALSE(view()->close_button()->GetVisible());
+  EXPECT_FALSE(view()->filter_and_close_button_container()->GetVisible());
 }
 
 // Tests that the close button becomes visible after typing in the search box.
 TEST_F(SearchBoxViewTest, CloseButtonVisibleAfterTyping) {
   KeyPress(ui::VKEY_A);
-  EXPECT_TRUE(view()->close_button()->GetVisible());
+  EXPECT_TRUE(view()->filter_and_close_button_container()->GetVisible());
 }
 
 // Tests that the filter button is not created if the image search feature is
@@ -303,7 +304,7 @@
 // activated (in zero state).
 TEST_F(SearchBoxViewTest, CloseButtonVisibleInZeroStateSearchBox) {
   SetSearchBoxActive(true, ui::ET_MOUSE_PRESSED);
-  EXPECT_FALSE(view()->close_button()->GetVisible());
+  EXPECT_FALSE(view()->filter_and_close_button_container()->GetVisible());
 }
 
 // TODO(crbug.com/1446550): Re-enable this test
@@ -579,16 +580,16 @@
   // Tile results are not created when testing productivity launcher.
   selection = GetResultSelectionController()->selected_result();
 
-    EXPECT_EQ(u"testing almost", selection->result()->title());
+  EXPECT_EQ(u"testing almost", selection->result()->title());
 
-    // New result can override the default selection.
-    CreateSearchResultAt(0, ash::SearchResultDisplayType::kList, 1.0, u"test",
-                         std::u16string(),
-                         ash::AppListSearchResultCategory::kWeb);
-    base::RunLoop().RunUntilIdle();
+  // New result can override the default selection.
+  CreateSearchResultAt(0, ash::SearchResultDisplayType::kList, 1.0, u"test",
+                       std::u16string(),
+                       ash::AppListSearchResultCategory::kWeb);
+  base::RunLoop().RunUntilIdle();
 
-    selection = GetResultSelectionController()->selected_result();
-    EXPECT_EQ(u"test", selection->result()->title());
+  selection = GetResultSelectionController()->selected_result();
+  EXPECT_EQ(u"test", selection->result()->title());
 }
 
 // Tests that the default selection is reset after resetting and reactivating
@@ -668,7 +669,7 @@
 
 // Tests that the assistant button is visible by default.
 TEST_F(SearchBoxViewAssistantButtonTest, AssistantButtonVisibleByDefault) {
-  EXPECT_TRUE(view()->assistant_button()->GetVisible());
+  EXPECT_TRUE(view()->assistant_button_container()->GetVisible());
 }
 
 // Tests that the assistant button is invisible after typing in the search box,
@@ -676,10 +677,10 @@
 TEST_F(SearchBoxViewAssistantButtonTest,
        AssistantButtonChangeVisibilityWithTyping) {
   KeyPress(ui::VKEY_A);
-  EXPECT_FALSE(view()->assistant_button()->GetVisible());
+  EXPECT_FALSE(view()->assistant_button_container()->GetVisible());
 
   KeyPress(ui::VKEY_BACK);
-  EXPECT_TRUE(view()->assistant_button()->GetVisible());
+  EXPECT_TRUE(view()->assistant_button_container()->GetVisible());
 }
 
 class SearchBoxViewFilterButtonTest : public SearchBoxViewTest {
@@ -697,13 +698,13 @@
 
 // Tests that the filter button is invisible by default.
 TEST_F(SearchBoxViewFilterButtonTest, FilterButtonInvisibleByDefault) {
-  EXPECT_FALSE(view()->filter_button()->GetVisible());
+  EXPECT_FALSE(view()->filter_button()->parent()->GetVisible());
 }
 
 // Tests that the filter button becomes visible after typing in the search box.
 TEST_F(SearchBoxViewFilterButtonTest, FilterButtonVisibleAfterTyping) {
   KeyPress(ui::VKEY_A);
-  EXPECT_TRUE(view()->filter_button()->GetVisible());
+  EXPECT_TRUE(view()->filter_button()->parent()->GetVisible());
 }
 
 class SearchBoxViewAutocompleteTest : public SearchBoxViewTest {
@@ -1097,24 +1098,25 @@
 
   // Initially the assistant button should be shown, and the close button
   // hidden.
-  EXPECT_FALSE(search_box->close_button()->GetVisible());
-  EXPECT_TRUE(search_box->assistant_button()->GetVisible());
+  EXPECT_FALSE(search_box->filter_and_close_button_container()->GetVisible());
+  EXPECT_TRUE(search_box->assistant_button_container()->GetVisible());
 
   // Set search box to active state.
   search_box->SetSearchBoxActive(true, ui::ET_MOUSE_PRESSED);
 
   // Close button should be fading in.
-  EXPECT_TRUE(search_box->close_button()->GetVisible());
-  auto* close_animator = search_box->close_button()->layer()->GetAnimator();
+  EXPECT_TRUE(search_box->filter_and_close_button_container()->GetVisible());
+  auto* close_animator =
+      search_box->filter_and_close_button_container()->layer()->GetAnimator();
   ASSERT_TRUE(close_animator);
   EXPECT_TRUE(close_animator->IsAnimatingProperty(
       ui::LayerAnimationElement::AnimatableProperty::OPACITY));
   EXPECT_EQ(close_animator->GetTargetOpacity(), 1.0f);
 
   // Assistant button should be fading out.
-  EXPECT_TRUE(search_box->assistant_button()->GetVisible());
+  EXPECT_TRUE(search_box->assistant_button_container()->GetVisible());
   auto* assistant_animator =
-      search_box->assistant_button()->layer()->GetAnimator();
+      search_box->assistant_button_container()->layer()->GetAnimator();
   EXPECT_TRUE(assistant_animator->IsAnimatingProperty(
       ui::LayerAnimationElement::AnimatableProperty::OPACITY));
   EXPECT_EQ(assistant_animator->GetTargetOpacity(), 0.0f);
@@ -1123,13 +1125,13 @@
   search_box->SetSearchBoxActive(false, ui::ET_MOUSE_PRESSED);
 
   // Close button should be fading out.
-  EXPECT_TRUE(search_box->close_button()->GetVisible());
+  EXPECT_TRUE(search_box->filter_and_close_button_container()->GetVisible());
   EXPECT_TRUE(close_animator->IsAnimatingProperty(
       ui::LayerAnimationElement::AnimatableProperty::OPACITY));
   EXPECT_EQ(close_animator->GetTargetOpacity(), 0.0f);
 
   // Assistant button should be fading in.
-  EXPECT_TRUE(search_box->assistant_button()->GetVisible());
+  EXPECT_TRUE(search_box->assistant_button_container()->GetVisible());
   ASSERT_TRUE(assistant_animator);
   EXPECT_TRUE(assistant_animator->IsAnimatingProperty(
       ui::LayerAnimationElement::AnimatableProperty::OPACITY));
diff --git a/ash/capture_mode/camera_video_frame_renderer.cc b/ash/capture_mode/camera_video_frame_renderer.cc
index 683cc1e..318ce50 100644
--- a/ash/capture_mode/camera_video_frame_renderer.cc
+++ b/ash/capture_mode/camera_video_frame_renderer.cc
@@ -70,10 +70,8 @@
       context_provider_->ContextCapabilities().max_texture_size;
   video_resource_updater_ = std::make_unique<media::VideoResourceUpdater>(
       context_provider_.get(), layer_tree_frame_sink_.get(),
-      &client_resource_provider_,
-      /*use_stream_video_draw_quad=*/false,
-      /*use_gpu_memory_buffer_resources=*/false,
-      /*use_r16_texture=*/false, max_texture_size);
+      &client_resource_provider_, /*use_stream_video_draw_quad=*/false,
+      /*use_gpu_memory_buffer_resources=*/false, max_texture_size);
 
   video_frame_handler_.StartHandlingFrames(/*delegate=*/this);
 }
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index fb76571b..75d42f20 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -108,7 +108,7 @@
 
 BASE_FEATURE(kAltClickAndSixPackCustomization,
              "AltClickAndSixPackCustomization",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Controls whether to enable AutoEnrollment for Kiosk in OOBE
 BASE_FEATURE(kAutoEnrollmentKioskInOobe,
@@ -1827,9 +1827,7 @@
              base::FEATURE_DISABLED_BY_DEFAULT);
 
 // Enables the use of the new System Nudges. (go/cros-educationalnudge-spec)
-BASE_FEATURE(kSystemNudgeV2,
-             "SystemNudgeV2",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+BASE_FEATURE(kSystemNudgeV2, "SystemNudgeV2", base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Enables the Night Light feature.
 BASE_FEATURE(kNightLight, "NightLight", base::FEATURE_ENABLED_BY_DEFAULT);
@@ -2917,6 +2915,12 @@
              "PeripheralCustomization",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+// Enable peripheral notification to notify users when a input device is
+// connected to the user's chromebook for the first time.
+BASE_FEATURE(kPeripheralNotification,
+             "PeripheralNotification",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 // Enables or disables whether to store UMA logs per-user and whether metrics
 // consent is per-user.
 BASE_FEATURE(kPerUserMetrics,
@@ -3871,6 +3875,11 @@
   return base::FeatureList::IsEnabled(kPerDeskShelf);
 }
 
+bool IsPeripheralNotificationEnabled() {
+  return base::FeatureList::IsEnabled(kPeripheralNotification) &&
+         IsPeripheralCustomizationEnabled();
+}
+
 bool IsPersonalizationJellyEnabled() {
   return chromeos::features::IsJellyEnabled();
 }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index 88b83df1..0446637 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -602,6 +602,7 @@
 BASE_DECLARE_FEATURE(kPcieBillboardNotification);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPerDeskShelf);
 COMPONENT_EXPORT(ASH_CONSTANTS)
+COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPeripheralNotification);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPerUserMetrics);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPhoneHub);
 COMPONENT_EXPORT(ASH_CONSTANTS)
@@ -1094,6 +1095,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPcieBillboardNotificationEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPciguardUiEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPerDeskShelfEnabled();
+COMPONENT_EXPORT(ASH_CONSTANTS) bool isPeripheralNotificationEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPhoneHubCameraRollEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS)
 bool IsPhoneHubFeatureSetupErrorHandlingEnabled();
@@ -1111,6 +1113,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPipDoubleTapToResizeEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPipPinchToResizeEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPipTiltEnabled();
+COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPipTuckEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool ArePostLoginGlanceablesEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPrivacyIndicatorsEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsLocalPrinterObservingEnabled();
diff --git a/ash/display/cursor_window_controller.cc b/ash/display/cursor_window_controller.cc
index 8b6adc0..fd39a66 100644
--- a/ash/display/cursor_window_controller.cc
+++ b/ash/display/cursor_window_controller.cc
@@ -250,10 +250,7 @@
     : delegate_(new CursorWindowDelegate()),
       is_cursor_motion_blur_enabled_(
           base::CommandLine::ForCurrentProcess()->HasSwitch(
-              switches::kAshEnableCursorMotionBlur)),
-      // TODO(b/296641218): Find another way to make sure gpu process is fully
-      // initialized first before updating cursor view.
-      start_time_(base::TimeTicks::Now()) {}
+              switches::kAshEnableCursorMotionBlur)) {}
 
 CursorWindowController::~CursorWindowController() {
   SetContainer(NULL);
@@ -292,7 +289,7 @@
 }
 
 bool CursorWindowController::ShouldEnableCursorCompositing() {
-  if (CanEnableMotionBlur()) {
+  if (is_cursor_motion_blur_enabled_) {
     return true;
   }
 
@@ -518,7 +515,7 @@
   bounds_in_screen_ = display_.bounds();
   rotation_ = display_.rotation();
 
-  if (CanEnableMotionBlur()) {
+  if (is_cursor_motion_blur_enabled_) {
     UpdateCursorView();
   } else {
     delegate_->SetCursorWindow(nullptr);
@@ -659,9 +656,4 @@
   return delegate_->cursor_images()[0];
 }
 
-bool CursorWindowController::CanEnableMotionBlur() const {
-  return is_cursor_motion_blur_enabled_ &&
-         base::TimeTicks::Now() - start_time_ > base::Seconds(5);
-}
-
 }  // namespace ash
diff --git a/ash/display/cursor_window_controller.h b/ash/display/cursor_window_controller.h
index 56493f3..4fb3737 100644
--- a/ash/display/cursor_window_controller.h
+++ b/ash/display/cursor_window_controller.h
@@ -159,7 +159,6 @@
   views::UniqueWidgetPtr cursor_view_widget_;
 
   const bool is_cursor_motion_blur_enabled_;
-  base::TimeTicks start_time_;
   base::ScopedObservation<aura::Window, aura::WindowObserver>
       scoped_container_observer_{this};
 };
diff --git a/ash/events/peripheral_customization_event_rewriter.cc b/ash/events/peripheral_customization_event_rewriter.cc
index afb353b..83ed64af 100644
--- a/ash/events/peripheral_customization_event_rewriter.cc
+++ b/ash/events/peripheral_customization_event_rewriter.cc
@@ -53,6 +53,41 @@
           static_cast<int>(ui::DomKey::Constant<'v'>::Character),
           ui::EF_CONTROL_DOWN);
       break;
+    case mojom::StaticShortcutAction::kUndo:
+      key_event = mojom::KeyEvent(
+          ui::VKEY_Z, static_cast<int>(ui::DomCode::US_Z),
+          static_cast<int>(ui::DomKey::Constant<'z'>::Character),
+          ui::EF_CONTROL_DOWN);
+      break;
+    case mojom::StaticShortcutAction::kRedo:
+      key_event = mojom::KeyEvent(
+          ui::VKEY_Z, static_cast<int>(ui::DomCode::US_Z),
+          static_cast<int>(ui::DomKey::Constant<'z'>::Character),
+          ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);
+      break;
+    case mojom::StaticShortcutAction::kZoomIn:
+      key_event = mojom::KeyEvent(
+          ui::VKEY_OEM_PLUS, static_cast<int>(ui::DomCode::EQUAL),
+          static_cast<int>(ui::DomKey::Constant<'='>::Character),
+          ui::EF_CONTROL_DOWN);
+      break;
+    case mojom::StaticShortcutAction::kZoomOut:
+      key_event = mojom::KeyEvent(
+          ui::VKEY_OEM_MINUS, static_cast<int>(ui::DomCode::MINUS),
+          static_cast<int>(ui::DomKey::Constant<'-'>::Character),
+          ui::EF_CONTROL_DOWN);
+      break;
+    case mojom::StaticShortcutAction::kPreviousPage:
+      key_event = mojom::KeyEvent(
+          ui::VKEY_BROWSER_BACK, static_cast<int>(ui::DomCode::BROWSER_BACK),
+          static_cast<int>(ui::DomKey::BROWSER_BACK), ui::EF_NONE);
+      break;
+    case mojom::StaticShortcutAction::kNextPage:
+      key_event = mojom::KeyEvent(
+          ui::VKEY_BROWSER_FORWARD,
+          static_cast<int>(ui::DomCode::BROWSER_FORWARD),
+          static_cast<int>(ui::DomKey::BROWSER_FORWARD), ui::EF_NONE);
+      break;
   }
   return key_event;
 }
diff --git a/ash/events/peripheral_customization_event_rewriter_unittest.cc b/ash/events/peripheral_customization_event_rewriter_unittest.cc
index 38d1e1d0..0dd3103 100644
--- a/ash/events/peripheral_customization_event_rewriter_unittest.cc
+++ b/ash/events/peripheral_customization_event_rewriter_unittest.cc
@@ -1137,6 +1137,42 @@
                                   ui::EF_CONTROL_DOWN,
                                   ui::DomCode::US_V,
                                   ui::DomKey::Constant<'v'>::Character)},
+            {mojom::StaticShortcutAction::kUndo,
+             CreateKeyButtonEvent(ui::ET_KEY_PRESSED,
+                                  ui::VKEY_Z,
+                                  ui::EF_CONTROL_DOWN,
+                                  ui::DomCode::US_Z,
+                                  ui::DomKey::Constant<'z'>::Character)},
+            {mojom::StaticShortcutAction::kRedo,
+             CreateKeyButtonEvent(ui::ET_KEY_PRESSED,
+                                  ui::VKEY_Z,
+                                  ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN,
+                                  ui::DomCode::US_Z,
+                                  ui::DomKey::Constant<'z'>::Character)},
+            {mojom::StaticShortcutAction::kZoomIn,
+             CreateKeyButtonEvent(ui::ET_KEY_PRESSED,
+                                  ui::VKEY_OEM_PLUS,
+                                  ui::EF_CONTROL_DOWN,
+                                  ui::DomCode::EQUAL,
+                                  ui::DomKey::Constant<'='>::Character)},
+            {mojom::StaticShortcutAction::kZoomOut,
+             CreateKeyButtonEvent(ui::ET_KEY_PRESSED,
+                                  ui::VKEY_OEM_MINUS,
+                                  ui::EF_CONTROL_DOWN,
+                                  ui::DomCode::MINUS,
+                                  ui::DomKey::Constant<'-'>::Character)},
+            {mojom::StaticShortcutAction::kPreviousPage,
+             CreateKeyButtonEvent(ui::ET_KEY_PRESSED,
+                                  ui::VKEY_BROWSER_BACK,
+                                  ui::EF_NONE,
+                                  ui::DomCode::BROWSER_BACK,
+                                  ui::DomKey::BROWSER_BACK)},
+            {mojom::StaticShortcutAction::kNextPage,
+             CreateKeyButtonEvent(ui::ET_KEY_PRESSED,
+                                  ui::VKEY_BROWSER_FORWARD,
+                                  ui::EF_NONE,
+                                  ui::DomCode::BROWSER_FORWARD,
+                                  ui::DomKey::BROWSER_FORWARD)},
         })));
 
 TEST_F(StaticShortcutActionRewritingTest, StaticShortcutDisableMouseRewriting) {
diff --git a/ash/fast_ink/fast_ink_host.cc b/ash/fast_ink/fast_ink_host.cc
index 74c985b..6644b57 100644
--- a/ash/fast_ink/fast_ink_host.cc
+++ b/ash/fast_ink/fast_ink_host.cc
@@ -34,12 +34,9 @@
 
 FastInkHost::ScopedPaint::ScopedPaint(const FastInkHost* host,
                                       const gfx::Rect& damage_rect_in_window)
-    : gpu_memory_buffer_(host->gpu_memory_buffer_.get()),
-      damage_rect_(fast_ink_internal::BufferRectFromWindowRect(
-          host->window_to_buffer_transform_,
-          gpu_memory_buffer_->GetSize(),
-          damage_rect_in_window)),
-      canvas_(damage_rect_.size(), 1.0f, false) {
+    : host_(const_cast<FastInkHost*>(host)),
+      damage_rect_(host->BufferRectFromWindowRect(damage_rect_in_window)),
+      canvas_(damage_rect_.size(), /*image_scale*/ 1.0f, /*is_opaque*/ false) {
   canvas_.Translate(-damage_rect_.OffsetFromOrigin());
   canvas_.Transform(host->window_to_buffer_transform_);
 }
@@ -48,38 +45,7 @@
   if (damage_rect_.IsEmpty()) {
     return;
   }
-
-  {
-    // TODO(zoraiznaeem): Investigate the precision as we will get non trivial
-    // additional time of printing the error log.
-    TRACE_EVENT0("ui", "FastInkHost::ScopedPaint::Map");
-
-    if (!gpu_memory_buffer_->Map()) {
-      LOG(ERROR) << "Failed to map GPU memory buffer";
-      return;
-    }
-  }
-
-  // Copy result to GPU memory buffer. This is effectively a memcpy and unlike
-  // drawing to the buffer directly this ensures that the buffer is never in a
-  // state that would result in flicker.
-  {
-    TRACE_EVENT1("ui", "FastInkHost::ScopedPaint::Copy", "damage_rect",
-                 damage_rect_.ToString());
-
-    uint8_t* data = static_cast<uint8_t*>(gpu_memory_buffer_->memory(0));
-    int stride = gpu_memory_buffer_->stride(0);
-    canvas_.GetBitmap().readPixels(
-        SkImageInfo::MakeN32Premul(damage_rect_.width(), damage_rect_.height()),
-        data + damage_rect_.y() * stride + damage_rect_.x() * 4, stride, 0, 0);
-  }
-
-  {
-    TRACE_EVENT0("ui", "FastInkHost::UpdateBuffer::Unmap");
-
-    // Unmap to flush writes to buffer.
-    gpu_memory_buffer_->Unmap();
-  }
+  host_->Draw(canvas_.GetBitmap(), damage_rect_);
 }
 
 // -----------------------------------------------------------------------------
@@ -89,60 +55,17 @@
 FastInkHost::~FastInkHost() = default;
 
 void FastInkHost::Init(aura::Window* host_window) {
-  InitializeFastInkBuffer(host_window);
+  InitBufferMetadata(host_window);
   FrameSinkHost::Init(host_window);
 }
 
 void FastInkHost::InitForTesting(
     aura::Window* host_window,
     std::unique_ptr<cc::LayerTreeFrameSink> layer_tree_frame_sink) {
-  InitializeFastInkBuffer(host_window);
+  InitBufferMetadata(host_window);
   FrameSinkHost::InitForTesting(host_window, std::move(layer_tree_frame_sink));
 }
 
-void FastInkHost::InitializeFastInkBuffer(aura::Window* host_window) {
-  // Take the root transform and apply this during buffer update instead of
-  // leaving this up to the compositor. The benefit is that HW requirements
-  // for being able to take advantage of overlays and direct scanout are
-  // reduced significantly. Frames are submitted to the compositor with the
-  // inverse transform to cancel out the transformation that would otherwise
-  // be done by the compositor.
-  window_to_buffer_transform_ = host_window->GetHost()->GetRootTransform();
-  gfx::Rect bounds(host_window->GetBoundsInScreen().size());
-
-  const gfx::Size buffer_size =
-      cc::MathUtil::MapEnclosingClippedRect(window_to_buffer_transform_, bounds)
-          .size();
-
-  // Create a single GPU memory buffer. Content will be written into this
-  // buffer without any buffering. The result is that we might be modifying
-  // the buffer while it's being displayed. This provides minimal latency
-  // but with potential tearing. Note that we have to draw into a temporary
-  // surface and copy it into GPU memory buffer to avoid flicker.
-  gpu_memory_buffer_ = fast_ink_internal::CreateGpuBuffer(
-      buffer_size,
-      gfx::BufferUsageAndFormat(gfx::BufferUsage::SCANOUT_CPU_READ_WRITE,
-                                SK_B32_SHIFT ? gfx::BufferFormat::RGBA_8888
-                                             : gfx::BufferFormat::BGRA_8888));
-  LOG_IF(ERROR, !gpu_memory_buffer_) << "Failed to create GPU memory buffer";
-
-  if (switches::ShouldClearFastInkBuffer()) {
-    bool map_result = gpu_memory_buffer_->Map();
-    LOG_IF(ERROR, !map_result) << "Failed to map gpu buffer";
-    uint8_t* memory = static_cast<uint8_t*>(gpu_memory_buffer_->memory(0));
-    if (memory != nullptr) {
-      gfx::Size size = gpu_memory_buffer_->GetSize();
-      int stride = gpu_memory_buffer_->stride(0);
-      // Clear the buffer before usage, since it may be uninitialized.
-      // (http://b/168735625)
-      for (int i = 0; i < size.height(); ++i) {
-        memset(memory + i * stride, 0, size.width() * 4);
-      }
-    }
-    gpu_memory_buffer_->Unmap();
-  }
-}
-
 std::unique_ptr<FastInkHost::ScopedPaint> FastInkHost::CreateScopedPaint(
     const gfx::Rect& damage_rect_in_window) const {
   return std::make_unique<ScopedPaint>(this, damage_rect_in_window);
@@ -166,4 +89,112 @@
   return frame;
 }
 
+void FastInkHost::OnFirstFrameRequested() {
+  InitializeFastInkBuffer(host_window());
+}
+
+void FastInkHost::InitBufferMetadata(aura::Window* host_window) {
+  // Take the root transform and apply this during buffer update instead of
+  // leaving this up to the compositor. The benefit is that HW requirements
+  // for being able to take advantage of overlays and direct scanout are
+  // reduced significantly. Frames are submitted to the compositor with the
+  // inverse transform to cancel out the transformation that would otherwise
+  // be done by the compositor.
+  window_to_buffer_transform_ = host_window->GetHost()->GetRootTransform();
+  gfx::Rect bounds(host_window->GetBoundsInScreen().size());
+  buffer_size_ =
+      cc::MathUtil::MapEnclosingClippedRect(window_to_buffer_transform_, bounds)
+          .size();
+}
+
+void FastInkHost::InitializeFastInkBuffer(aura::Window* host_window) {
+  // `gpu_memory_buffer_` should only be initialized once.
+  DCHECK(!gpu_memory_buffer_);
+
+  // Create a single GPU memory buffer. Content will be written into this
+  // buffer without any buffering. The result is that we might be modifying
+  // the buffer while it's being displayed. This provides minimal latency
+  // but with potential tearing. Note that we have to draw into a temporary
+  // surface and copy it into GPU memory buffer to avoid flicker.
+  gpu_memory_buffer_ = fast_ink_internal::CreateGpuBuffer(
+      buffer_size_,
+      gfx::BufferUsageAndFormat(gfx::BufferUsage::SCANOUT_CPU_READ_WRITE,
+                                SK_B32_SHIFT ? gfx::BufferFormat::RGBA_8888
+                                             : gfx::BufferFormat::BGRA_8888));
+  LOG_IF(ERROR, !gpu_memory_buffer_) << "Failed to create GPU memory buffer";
+
+  if (switches::ShouldClearFastInkBuffer()) {
+    bool map_result = gpu_memory_buffer_->Map();
+    LOG_IF(ERROR, !map_result) << "Failed to map gpu buffer";
+    uint8_t* memory = static_cast<uint8_t*>(gpu_memory_buffer_->memory(0));
+    if (memory != nullptr) {
+      gfx::Size size = gpu_memory_buffer_->GetSize();
+      int stride = gpu_memory_buffer_->stride(0);
+      // Clear the buffer before usage, since it may be uninitialized.
+      // (http://b/168735625)
+      for (int i = 0; i < size.height(); ++i) {
+        memset(memory + i * stride, 0, size.width() * 4);
+      }
+    }
+    gpu_memory_buffer_->Unmap();
+  }
+
+  // Draw pending bitmaps to the buffer.
+  for (auto pending_bitmap : pending_bitmaps_) {
+    DrawBitmap(pending_bitmap.bitmap, pending_bitmap.damage_rect);
+  }
+  pending_bitmaps_.clear();
+}
+
+gfx::Rect FastInkHost::BufferRectFromWindowRect(
+    const gfx::Rect& rect_in_window) const {
+  return fast_ink_internal::BufferRectFromWindowRect(
+      window_to_buffer_transform_, buffer_size_, rect_in_window);
+}
+
+void FastInkHost::Draw(SkBitmap bitmap, const gfx::Rect& damage_rect) {
+  if (!gpu_memory_buffer_) {
+    // GPU process should be ready soon after start and `pending_bitmaps_`
+    // should be drawn promptly. 60 is an arbitrary cap that should never
+    // hit.
+    DCHECK_LT(pending_bitmaps_.size(), 60u);
+    pending_bitmaps_.push_back(PendingBitmap(bitmap, damage_rect));
+    return;
+  }
+  DrawBitmap(bitmap, damage_rect);
+}
+
+void FastInkHost::DrawBitmap(SkBitmap bitmap, const gfx::Rect& damage_rect) {
+  {
+    // TODO(zoraiznaeem): Investigate the precision as we will get non trivial
+    // additional time of printing the error log.
+    TRACE_EVENT0("ui", "FastInkHost::ScopedPaint::Map");
+
+    if (!gpu_memory_buffer_->Map()) {
+      LOG(ERROR) << "Failed to map GPU memory buffer";
+      return;
+    }
+  }
+  // Copy result to GPU memory buffer. This is effectively a memcpy and unlike
+  // drawing to the buffer directly this ensures that the buffer is never in a
+  // state that would result in flicker.
+  {
+    TRACE_EVENT1("ui", "FastInkHost::ScopedPaint::Copy", "damage_rect",
+                 damage_rect.ToString());
+
+    uint8_t* data = static_cast<uint8_t*>(gpu_memory_buffer_->memory(0));
+    const int stride = gpu_memory_buffer_->stride(0);
+    bitmap.readPixels(
+        SkImageInfo::MakeN32Premul(damage_rect.width(), damage_rect.height()),
+        data + damage_rect.y() * stride + damage_rect.x() * 4, stride, 0, 0);
+  }
+
+  {
+    TRACE_EVENT0("ui", "FastInkHost::UpdateBuffer::Unmap");
+
+    // Unmap to flush writes to buffer.
+    gpu_memory_buffer_->Unmap();
+  }
+}
+
 }  // namespace ash
diff --git a/ash/fast_ink/fast_ink_host.h b/ash/fast_ink/fast_ink_host.h
index 0be86af..9c4adb9 100644
--- a/ash/fast_ink/fast_ink_host.h
+++ b/ash/fast_ink/fast_ink_host.h
@@ -44,10 +44,10 @@
     gfx::Canvas& canvas() { return canvas_; }
 
    private:
-    raw_ptr<gfx::GpuMemoryBuffer, ExperimentalAsh> gpu_memory_buffer_;
+    const raw_ptr<FastInkHost> host_;
 
     // Damage rect in the buffer coordinates.
-    const gfx::Rect damage_rect_;
+    gfx::Rect damage_rect_;
     gfx::Canvas canvas_;
   };
 
@@ -65,6 +65,14 @@
     return window_to_buffer_transform_;
   }
 
+  gfx::GpuMemoryBuffer* gpu_memory_buffer_for_test() {
+    return gpu_memory_buffer_.get();
+  }
+
+  int get_pending_bitmaps_size_for_test() const {
+    return pending_bitmaps_.size();
+  }
+
   // FrameSinkHost:
   void Init(aura::Window* host_window) override;
   void InitForTesting(
@@ -79,13 +87,27 @@
       bool auto_update,
       const gfx::Size& last_submitted_frame_size,
       float last_submitted_frame_dsf) override;
+  void OnFirstFrameRequested() override;
 
  private:
+  void InitBufferMetadata(aura::Window* host_window);
   void InitializeFastInkBuffer(aura::Window* host_window);
+  gfx::Rect BufferRectFromWindowRect(const gfx::Rect& rect_in_window) const;
+  void Draw(SkBitmap bitmap, const gfx::Rect& damage_rect);
+  void DrawBitmap(SkBitmap bitmap, const gfx::Rect& damage_rect);
 
   std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
 
   gfx::Transform window_to_buffer_transform_;
+
+  gfx::Size buffer_size_;
+
+  struct PendingBitmap {
+    SkBitmap bitmap;
+    gfx::Rect damage_rect;
+  };
+
+  std::vector<PendingBitmap> pending_bitmaps_;
 };
 
 }  // namespace ash
diff --git a/ash/fast_ink/fast_ink_host_unittest.cc b/ash/fast_ink/fast_ink_host_unittest.cc
index 242763de..2c0e5dd 100644
--- a/ash/fast_ink/fast_ink_host_unittest.cc
+++ b/ash/fast_ink/fast_ink_host_unittest.cc
@@ -32,6 +32,7 @@
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/geometry/transform.h"
 #include "ui/gfx/gpu_memory_buffer.h"
+#include "ui/views/widget/widget.h"
 
 namespace ash {
 namespace {
@@ -61,13 +62,9 @@
     auto* root_window = ash_test_helper()->GetHost()->window();
     gfx::Rect screen_bounds = root_window->GetBoundsInScreen();
 
-    auto host_window =
-        CreateTestWindow(screen_bounds, aura::client::WINDOW_TYPE_NORMAL,
-                         kShellWindowId_OverlayContainer);
-
-    // `host_window` is owned by the root_window and it will be deleted as
-    // window hierarchy is deleted during Shell deletion.
-    host_window_ = host_window.release();
+    widget_ = CreateTestWidget(nullptr, kShellWindowId_OverlayContainer);
+    widget_->SetBounds(screen_bounds);
+    host_window_ = widget_->GetNativeWindow();
 
     auto layer_tree_frame_sink = std::make_unique<TestLayerTreeFrameSink>();
     layer_tree_frame_sink_ = layer_tree_frame_sink.get();
@@ -79,14 +76,19 @@
     begin_frame_source_ = std::make_unique<TestBeginFrameSource>();
     layer_tree_frame_sink_->client()->SetBeginFrameSource(
         begin_frame_source_.get());
-
-    // Request the first frame from FrameSinkHost.
-    begin_frame_source_->GetBeginFrameObserver()->OnBeginFrame(
-        CreateValidBeginFrameArgsForTesting());
   }
 
   // AshTestBase:
-  void TearDown() override { AshTestBase::TearDown(); }
+  void TearDown() override {
+    widget_.reset();
+    AshTestBase::TearDown();
+  }
+
+  void OnBeginFrame() {
+    // Request a frame from FrameSinkHost.
+    begin_frame_source_->GetBeginFrameObserver()->OnBeginFrame(
+        CreateValidBeginFrameArgsForTesting());
+  }
 
  protected:
   std::string first_display_specs_;
@@ -95,6 +97,7 @@
   gfx::Rect expected_quad_rect_;
   gfx::Rect expected_quad_layer_rect_;
 
+  std::unique_ptr<views::Widget> widget_;
   raw_ptr<aura::Window, DanglingUntriaged> host_window_;
   std::unique_ptr<FastInkHost> fast_ink_host_;
   raw_ptr<TestLayerTreeFrameSink, DanglingUntriaged> layer_tree_frame_sink_;
@@ -102,6 +105,9 @@
 };
 
 TEST_P(FastInkHostTest, CorrectFrameSubmittedToLayerTreeFrameSink) {
+  // Request the first frame.
+  OnBeginFrame();
+
   SCOPED_TRACE(base::StringPrintf(
       "Test params: first_display_specs=%s | auto_update=%s | content_rect=%s "
       "| expected_quad_rect=%s | expected_quad_layer_rect=%s",
@@ -151,30 +157,67 @@
   EXPECT_EQ(frame.resource_list.back().is_overlay_candidate, auto_update_);
 }
 
+TEST_P(FastInkHostTest, DelayPaintingUntilReceivingFirstBeginFrame) {
+  // Buffer is not initialized when there is no begin frame received.
+  ASSERT_FALSE(fast_ink_host_->gpu_memory_buffer_for_test());
+  EXPECT_EQ(fast_ink_host_->get_pending_bitmaps_size_for_test(), 0);
+
+  int pending_bitmaps_size = 0;
+  for (SkColor color : {SK_ColorRED, SK_ColorYELLOW, SK_ColorGREEN}) {
+    {
+      const gfx::Rect damage_rect_in_window =
+          gfx::Rect(host_window_->bounds().size());
+      auto paint = fast_ink_host_->CreateScopedPaint(damage_rect_in_window);
+      paint->canvas().DrawRect(gfx::RectF(damage_rect_in_window), color);
+    }
+    // The bitmap is waiting to be drawn because no gpu memory buffer is
+    // initialized.
+    ++pending_bitmaps_size;
+    EXPECT_EQ(fast_ink_host_->get_pending_bitmaps_size_for_test(),
+              pending_bitmaps_size);
+  }
+
+  // Request the first frame.
+  OnBeginFrame();
+
+  // Buffer should be initialized after receiving the first begin frame.
+  gfx::GpuMemoryBuffer* gpu_memory_buffer =
+      fast_ink_host_->gpu_memory_buffer_for_test();
+  ASSERT_TRUE(gpu_memory_buffer);
+  // Pending bitmaps should be drawn and cleared.
+  EXPECT_EQ(fast_ink_host_->get_pending_bitmaps_size_for_test(), 0);
+
+  ASSERT_TRUE(gpu_memory_buffer->Map());
+  // Pending bitmaps should be correctly copied to the gpu memory buffer.
+  EXPECT_EQ(*static_cast<SkColor*>(gpu_memory_buffer->memory(0)),
+            SK_ColorGREEN);
+  gpu_memory_buffer->Unmap();
+}
+
 INSTANTIATE_TEST_SUITE_P(
     /* no prefix */,
     FastInkHostTest,
     testing::Values(
-        // When auto updating surface, we update the full surface
-        // (equaling display work area in pixels), ignoring the content_rect.
+        // When auto updating surface, we update the full surface, ignoring the
+        // content_rect.
         std::make_tuple(
             /*first_display_specs=*/"1000x500",
             /*auto_update=*/true,
             /*content_rect=*/gfx::Rect(10, 10),
-            /*expected_quad_rect=*/gfx::Rect(0, 0, 1000, 452),
-            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 452)),
+            /*expected_quad_rect=*/gfx::Rect(0, 0, 1000, 500),
+            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 500)),
         std::make_tuple(
             /*first_display_specs=*/"1000x500*2",
             /*auto_update=*/true,
             /*content_rect=*/gfx::Rect(10, 10),
-            /*expected_quad_rect=*/gfx::Rect(0, 0, 1000, 404),
-            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 404)),
+            /*expected_quad_rect=*/gfx::Rect(0, 0, 1000, 500),
+            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 500)),
         std::make_tuple(
             /*first_display_specs=*/"1000x500*2/r",
             /*auto_update=*/true,
             /*content_rect=*/gfx::Rect(10, 10),
-            /*expected_quad_rect=*/gfx::Rect(0, 0, 904, 500),
-            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 500, 904)),
+            /*expected_quad_rect=*/gfx::Rect(0, 0, 1000, 500),
+            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 500, 1000)),
         // When auto updating is off, we update the surface enclosed by
         // content_rect.
         std::make_tuple(
@@ -182,19 +225,19 @@
             /*auto_update=*/false,
             /*content_rect=*/gfx::Rect(10, 10),
             /*expected_quad_rect=*/gfx::Rect(0, 0, 10, 10),
-            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 452)),
+            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 500)),
         std::make_tuple(
             /*first_display_specs=*/"1000x500*2",
             /*auto_update=*/false,
             /*content_rect=*/gfx::Rect(10, 10),
             /*expected_quad_rect=*/gfx::Rect(0, 0, 20, 20),
-            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 404)),
+            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 500)),
         std::make_tuple(
             /*first_display_specs=*/"1000x500*2/l",
             /*auto_update=*/false,
             /*content_rect=*/gfx::Rect(10, 15),
             /*expected_quad_rect=*/gfx::Rect(0, 480, 30, 20),
-            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 500, 904)),
+            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 500, 1000)),
         // If content rect is partially outside of the buffer, quad rect is
         // clipped by buffer size.
         std::make_tuple(
@@ -202,7 +245,7 @@
             /*auto_update=*/false,
             /*content_rect=*/gfx::Rect(995, 0, 10, 10),
             /*expected_quad_rect=*/gfx::Rect(995, 0, 5, 10),
-            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 452))));
+            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 500))));
 
 }  // namespace
 }  // namespace ash
diff --git a/ash/frame_sink/frame_sink_holder.cc b/ash/frame_sink/frame_sink_holder.cc
index 985e9c3..a8db34e 100644
--- a/ash/frame_sink/frame_sink_holder.cc
+++ b/ash/frame_sink/frame_sink_holder.cc
@@ -22,9 +22,12 @@
 
 FrameSinkHolder::FrameSinkHolder(
     std::unique_ptr<cc::LayerTreeFrameSink> frame_sink,
-    const GetCompositorFrameCallback callback)
+    const GetCompositorFrameCallback get_compositor_frame_callback,
+    const OnFirstFrameRequestedCallback on_first_frame_requested_callback)
     : frame_sink_(std::move(frame_sink)),
-      get_compositor_frame_callback_(std::move(callback)) {
+      get_compositor_frame_callback_(std::move(get_compositor_frame_callback)),
+      on_first_frame_requested_callback_(
+          std::move(on_first_frame_requested_callback)) {
   frame_sink_->BindToClient(this);
 }
 
@@ -161,9 +164,12 @@
     return false;
   }
 
-  viz::BeginFrameAck current_begin_frame_ack(args, false);
+  if (!first_frame_requested_) {
+    first_frame_requested_ = true;
+    on_first_frame_requested_callback_.Run();
+  }
 
-  first_frame_requested_ = true;
+  viz::BeginFrameAck current_begin_frame_ack(args, false);
 
   if (pending_compositor_frame_ack_ ||
       !(pending_compositor_frame_ || auto_update_)) {
diff --git a/ash/frame_sink/frame_sink_holder.h b/ash/frame_sink/frame_sink_holder.h
index ef04a84..331331440 100644
--- a/ash/frame_sink/frame_sink_holder.h
+++ b/ash/frame_sink/frame_sink_holder.h
@@ -50,10 +50,14 @@
           bool auto_update,
           const gfx::Size& last_submitted_frame_size,
           float last_submitted_frame_dsf)>;
+  // Refer to declaration of `FrameSinkHost::OnFirstFrameRequested` for a
+  // detailed comment.
+  using OnFirstFrameRequestedCallback = base::RepeatingCallback<void()>;
 
-  // The callback is the source of frames for the holder.
-  FrameSinkHolder(std::unique_ptr<cc::LayerTreeFrameSink> frame_sink,
-                  GetCompositorFrameCallback callback);
+  FrameSinkHolder(
+      std::unique_ptr<cc::LayerTreeFrameSink> frame_sink,
+      GetCompositorFrameCallback get_compositor_frame_callback,
+      OnFirstFrameRequestedCallback on_first_frame_requested_callback);
 
   FrameSinkHolder(const FrameSinkHolder&) = delete;
   FrameSinkHolder& operator=(const FrameSinkHolder&) = delete;
@@ -135,7 +139,7 @@
   // Extend the lifetime of `this` by adding it as a observer to `root_window`.
   void SetRootWindowForDeletion(aura::Window* root_window);
 
-  // True when the display compositor has already asked for the a compositor
+  // True when the display compositor has already asked for a compositor
   // frame. This signifies that the gpu process has been fully initialized.
   bool first_frame_requested_ = false;
 
@@ -181,6 +185,10 @@
   // The callback to generate the next compositor frame.
   GetCompositorFrameCallback get_compositor_frame_callback_;
 
+  // The callback invoked when the display compositor asks for a compositor
+  // frame for the first time.
+  OnFirstFrameRequestedCallback on_first_frame_requested_callback_;
+
   // Observation of the root window to which this holder becomes an observer to
   // extend its lifespan till all the in-flight resource to display compositor
   // are reclaimed.
diff --git a/ash/frame_sink/frame_sink_holder_unittest.cc b/ash/frame_sink/frame_sink_holder_unittest.cc
index 0b3861d..5233a86 100644
--- a/ash/frame_sink/frame_sink_holder_unittest.cc
+++ b/ash/frame_sink/frame_sink_holder_unittest.cc
@@ -68,6 +68,8 @@
     return frame;
   }
 
+  void OnFirstFrameRequested() {}
+
   void SetFrameResources(std::vector<viz::ResourceId> frame_resource) {
     latest_frame_resources_ = std::move(frame_resource);
   }
@@ -112,6 +114,8 @@
     frame_sink_holder_ = std::make_unique<FrameSinkHolder>(
         std::move(layer_tree_frame_sink),
         base::BindRepeating(&TestFrameFactory::CreateCompositorFrame,
+                            base::Unretained(frame_factory_.get())),
+        base::BindRepeating(&TestFrameFactory::OnFirstFrameRequested,
                             base::Unretained(frame_factory_.get())));
 
     holder_weak_ptr_ = frame_sink_holder_->GetWeakPtr();
diff --git a/ash/frame_sink/frame_sink_host.cc b/ash/frame_sink/frame_sink_host.cc
index 22bf536..9d88eb7 100644
--- a/ash/frame_sink/frame_sink_host.cc
+++ b/ash/frame_sink/frame_sink_host.cc
@@ -56,6 +56,8 @@
   frame_sink_holder_ = std::make_unique<FrameSinkHolder>(
       std::move(layer_tree_frame_sink),
       base::BindRepeating(&FrameSinkHost::CreateCompositorFrame,
+                          base::Unretained(this)),
+      base::BindRepeating(&FrameSinkHost::OnFirstFrameRequested,
                           base::Unretained(this)));
 }
 
@@ -119,4 +121,6 @@
   host_window_ = nullptr;
 }
 
+void FrameSinkHost::OnFirstFrameRequested() {}
+
 }  // namespace ash
diff --git a/ash/frame_sink/frame_sink_host.h b/ash/frame_sink/frame_sink_host.h
index a01b3c7..d48406e 100644
--- a/ash/frame_sink/frame_sink_host.h
+++ b/ash/frame_sink/frame_sink_host.h
@@ -46,6 +46,7 @@
   ~FrameSinkHost() override;
 
   aura::Window* host_window() { return host_window_; }
+  const aura::Window* host_window() const { return host_window_; }
 
   void SetPresentationCallback(PresentationCallback callback);
 
@@ -95,6 +96,11 @@
       const gfx::Size& last_submitted_frame_size,
       float last_submitted_frame_dsf) = 0;
 
+  // Callback invoked when underlying frame sink holder gets the first begin
+  // frame from viz. This signifies that the gpu process has been fully
+  // initialized.
+  virtual void OnFirstFrameRequested();
+
   const gfx::Rect& GetTotalDamage() const { return total_damage_rect_; }
 
   void UnionDamage(const gfx::Rect& rect) { total_damage_rect_.Union(rect); }
diff --git a/ash/frame_sink/frame_sink_host_unittest.cc b/ash/frame_sink/frame_sink_host_unittest.cc
new file mode 100644
index 0000000..9cd6f49
--- /dev/null
+++ b/ash/frame_sink/frame_sink_host_unittest.cc
@@ -0,0 +1,110 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/frame_sink/frame_sink_host.h"
+
+#include <memory>
+
+#include "ash/frame_sink/test/test_begin_frame_source.h"
+#include "ash/frame_sink/test/test_layer_tree_frame_sink.h"
+#include "ash/test/ash_test_base.h"
+#include "ash/test/ash_test_helper.h"
+#include "components/viz/common/frame_sinks/begin_frame_args.h"
+#include "components/viz/common/quads/compositor_frame.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/views/widget/widget.h"
+
+namespace ash {
+namespace {
+
+class TestFrameSinkHost : public FrameSinkHost {
+ public:
+  TestFrameSinkHost() = default;
+
+  TestFrameSinkHost(const TestFrameSinkHost&) = delete;
+  TestFrameSinkHost& operator=(const TestFrameSinkHost&) = delete;
+
+  std::unique_ptr<viz::CompositorFrame> CreateCompositorFrame(
+      const viz::BeginFrameAck& begin_frame_ack,
+      UiResourceManager& resource_manager,
+      bool auto_refresh,
+      const gfx::Size& last_submitted_frame_size,
+      float last_submitted_frame_dsf) override {
+    return std::make_unique<viz::CompositorFrame>();
+  }
+
+  void OnFirstFrameRequested() override { ++on_first_frame_requested_counter_; }
+
+  int on_first_frame_requested_counter() const {
+    return on_first_frame_requested_counter_;
+  }
+
+ private:
+  int on_first_frame_requested_counter_ = 0;
+};
+
+class FrameSinkHostTest : public AshTestBase {
+ public:
+  FrameSinkHostTest() = default;
+  FrameSinkHostTest(const FrameSinkHostTest&) = delete;
+  FrameSinkHostTest& operator=(const FrameSinkHostTest&) = delete;
+
+  // AshTestBase:
+  void SetUp() override {
+    AshTestBase::SetUp();
+
+    auto* root_window = ash_test_helper()->GetHost()->window();
+    gfx::Rect screen_bounds = root_window->GetBoundsInScreen();
+
+    widget_ = CreateTestWidget(nullptr, kShellWindowId_OverlayContainer);
+    widget_->SetBounds(screen_bounds);
+    host_window_ = widget_->GetNativeWindow();
+
+    auto layer_tree_frame_sink = std::make_unique<TestLayerTreeFrameSink>();
+    layer_tree_frame_sink_ = layer_tree_frame_sink.get();
+
+    frame_sink_host_ = std::make_unique<TestFrameSinkHost>();
+    frame_sink_host_->InitForTesting(host_window_,
+                                     std::move(layer_tree_frame_sink));
+
+    begin_frame_source_ = std::make_unique<TestBeginFrameSource>();
+    layer_tree_frame_sink_->client()->SetBeginFrameSource(
+        begin_frame_source_.get());
+  }
+
+  void TearDown() override {
+    widget_.reset();
+    AshTestBase::TearDown();
+  }
+
+  void OnBeginFrame() {
+    // Request a frame from FrameSinkHost.
+    begin_frame_source_->GetBeginFrameObserver()->OnBeginFrame(
+        CreateValidBeginFrameArgsForTesting());
+  }
+
+ protected:
+  std::unique_ptr<views::Widget> widget_;
+  raw_ptr<aura::Window, DanglingUntriaged> host_window_;
+  std::unique_ptr<TestFrameSinkHost> frame_sink_host_;
+  raw_ptr<TestLayerTreeFrameSink, DanglingUntriaged> layer_tree_frame_sink_;
+  std::unique_ptr<TestBeginFrameSource> begin_frame_source_;
+};
+
+TEST_F(FrameSinkHostTest, OnFirstFrameRequestedShouldOnlyBeCalledOnce) {
+  EXPECT_EQ(frame_sink_host_->on_first_frame_requested_counter(), 0);
+
+  // Request the first frame.
+  OnBeginFrame();
+  // `FrameSinkHost::OnFirstFrameRequested` should be called.
+  EXPECT_EQ(frame_sink_host_->on_first_frame_requested_counter(), 1);
+
+  // Request the second frame.
+  OnBeginFrame();
+  // `FrameSinkHost::OnFirstFrameRequested` should not be called again.
+  EXPECT_EQ(frame_sink_host_->on_first_frame_requested_counter(), 1);
+}
+
+}  // namespace
+}  // namespace ash
diff --git a/ash/game_dashboard/game_dashboard_main_menu_view.cc b/ash/game_dashboard/game_dashboard_main_menu_view.cc
index 0b3bc24c..92822767 100644
--- a/ash/game_dashboard/game_dashboard_main_menu_view.cc
+++ b/ash/game_dashboard/game_dashboard_main_menu_view.cc
@@ -59,7 +59,7 @@
 constexpr float kBackgroundRadius = 12;
 
 // Creates an individual Game Dashboard Tile.
-std::unique_ptr<FeatureTile> CreateTile(
+std::unique_ptr<FeatureTile> CreateFeatureTile(
     base::RepeatingClosure callback,
     bool is_togglable,
     FeatureTile::TileType type,
@@ -413,7 +413,7 @@
   container->SetBetweenChildSpacing(kCenterPadding);
 
   const bool toolbar_visible = context_->IsToolbarVisible();
-  toolbar_tile_ = container->AddChildView(CreateTile(
+  toolbar_tile_ = container->AddChildView(CreateFeatureTile(
       base::BindRepeating(&GameDashboardMainMenuView::OnToolbarTilePressed,
                           base::Unretained(this)),
       /*is_togglable=*/true, FeatureTile::TileType::kCompact,
@@ -429,7 +429,7 @@
 
   if (base::FeatureList::IsEnabled(
           features::kFeatureManagementGameDashboardRecordGame)) {
-    record_game_tile_ = container->AddChildView(CreateTile(
+    record_game_tile_ = container->AddChildView(CreateFeatureTile(
         base::BindRepeating(&GameDashboardMainMenuView::OnRecordGameTilePressed,
                             base::Unretained(this)),
         /*is_togglable=*/true, FeatureTile::TileType::kCompact,
@@ -448,7 +448,7 @@
         GameDashboardController::Get()->active_recording_context() == context_);
   }
 
-  container->AddChildView(CreateTile(
+  container->AddChildView(CreateFeatureTile(
       base::BindRepeating(&GameDashboardMainMenuView::OnScreenshotTilePressed,
                           base::Unretained(this)),
       /*is_togglable=*/true, FeatureTile::TileType::kCompact,
@@ -480,7 +480,7 @@
 
   // Add the game controls tile which shows and hides the game controls mapping
   // hint.
-  game_controls_tile_ = container->AddChildView(CreateTile(
+  game_controls_tile_ = container->AddChildView(CreateFeatureTile(
       base::BindRepeating(&GameDashboardMainMenuView::OnGameControlsTilePressed,
                           base::Unretained(this)),
       /*is_togglable=*/true, FeatureTile::TileType::kCompact,
diff --git a/ash/projector/projector_metadata_controller.cc b/ash/projector/projector_metadata_controller.cc
index 79b632b..17b1c58 100644
--- a/ash/projector/projector_metadata_controller.cc
+++ b/ash/projector/projector_metadata_controller.cc
@@ -4,6 +4,8 @@
 
 #include "ash/projector/projector_metadata_controller.h"
 
+#include "ash/constants/ash_features.h"
+#include "ash/projector/projector_metadata_model.h"
 #include "ash/projector/projector_metrics.h"
 #include "ash/projector/projector_ui_controller.h"
 #include "ash/public/cpp/projector/projector_controller.h"
@@ -55,6 +57,9 @@
   metadata_ = std::make_unique<ProjectorMetadata>();
   metadata_->SetCaptionLanguage(
       GetFormattedLangauge(icu::Locale::getDefault()));
+  if (ash::features::IsProjectorV2Enabled()) {
+    metadata_->SetMetadataVersionNumber(MetadataVersionNumber::kV2);
+  }
 }
 
 void ProjectorMetadataController::RecordTranscription(
diff --git a/ash/projector/projector_metadata_model.cc b/ash/projector/projector_metadata_model.cc
index 315d8ed..1be1c1b 100644
--- a/ash/projector/projector_metadata_model.cc
+++ b/ash/projector/projector_metadata_model.cc
@@ -4,6 +4,7 @@
 
 #include "ash/projector/projector_metadata_model.h"
 
+#include "ash/constants/ash_features.h"
 #include "base/json/json_writer.h"
 
 namespace ash {
@@ -18,6 +19,7 @@
 constexpr base::StringPiece kKeyIdeasKey = "tableOfContent";
 constexpr base::StringPiece kOffset = "offset";
 constexpr base::StringPiece kRecognitionStatus = "recognitionStatus";
+constexpr base::StringPiece kMetadataVersionNumber = "version";
 
 base::Value::Dict HypothesisPartsToDict(
     const media::HypothesisParts& hypothesis_parts) {
@@ -141,6 +143,11 @@
   speech_recognition_status_ = status;
 }
 
+void ProjectorMetadata::SetMetadataVersionNumber(
+    MetadataVersionNumber version) {
+  metadata_version_number_ = version;
+}
+
 void ProjectorMetadata::MarkKeyIdea() {
   should_mark_key_idea_ = true;
 }
@@ -179,6 +186,7 @@
 //      },
 //    ],
 //    "recognitionStatus": 0,
+//    "version": 2,
 //  }
 //
 // Which is:
@@ -204,6 +212,10 @@
   metadata.Set(kKeyIdeasKey, std::move(key_ideas_list));
   metadata.Set(kRecognitionStatus,
                static_cast<int>(speech_recognition_status_));
+  if (ash::features::IsProjectorV2Enabled()) {
+    metadata.Set(kMetadataVersionNumber,
+                 static_cast<int>(metadata_version_number_));
+  }
   return metadata;
 }
 
diff --git a/ash/projector/projector_metadata_model.h b/ash/projector/projector_metadata_model.h
index ff4712c..adce3e3d 100644
--- a/ash/projector/projector_metadata_model.h
+++ b/ash/projector/projector_metadata_model.h
@@ -28,6 +28,12 @@
   kError = 2
 };
 
+enum class ASH_EXPORT MetadataVersionNumber : int {
+  kUnknown = 0,
+  kV1 = 1,
+  kV2 = 2
+};
+
 // Base class to describe a metadata item.
 class MetadataItem {
  public:
@@ -104,6 +110,7 @@
   void SetSpeechRecognitionStatus(RecognitionStatus status);
   // Marks a beginning of a key idea. The timing info of the next transcript
   // will be used as the timing of the key idea.
+  void SetMetadataVersionNumber(MetadataVersionNumber version);
   void MarkKeyIdea();
   // Serializes the metadata for storage.
   std::string Serialize();
@@ -123,6 +130,7 @@
 
   // The speech recognition status.
   RecognitionStatus speech_recognition_status_ = RecognitionStatus::kIncomplete;
+  MetadataVersionNumber metadata_version_number_;
 };
 
 }  // namespace ash
diff --git a/ash/projector/projector_metadata_model_unittest.cc b/ash/projector/projector_metadata_model_unittest.cc
index 7c4f991..943cdfc1 100644
--- a/ash/projector/projector_metadata_model_unittest.cc
+++ b/ash/projector/projector_metadata_model_unittest.cc
@@ -9,12 +9,12 @@
 #include <string>
 #include <vector>
 
+#include "ash/constants/ash_features.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
-#include "base/logging.h"
 #include "base/strings/stringprintf.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/values.h"
-#include "media/mojo/mojom/speech_recognition_service.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace ash {
@@ -96,6 +96,65 @@
     ]
   })";
 
+constexpr char kCompleteMetadataV2Template[] = R"({
+    "captions": [
+      {
+        "endOffset": 3000,
+        "hypothesisParts": [
+          {
+            "offset": 1000,
+            "text": [
+              "transcript"
+            ]
+          },
+          {
+            "offset": 2000,
+            "text": [
+              "text"
+            ]
+          }
+        ],
+        "startOffset": 1000,
+        "text": "transcript text"
+      },
+      {
+        "endOffset": 5000,
+        "hypothesisParts": [
+          {
+            "offset": 3200,
+            "text": [
+              "transcript"
+            ]
+          },
+          {
+            "offset": 4200,
+            "text": [
+              "text"
+            ]
+          },
+          {
+            "offset": 4500,
+            "text": [
+              "2"
+            ]
+          }
+        ],
+        "startOffset": 3000,
+        "text": "transcript text 2"
+      }
+    ],
+    "captionLanguage": "en",
+    "recognitionStatus": %i,
+    "version": 2,
+    "tableOfContent": [
+      {
+        "endOffset": 5000,
+        "startOffset": 3000,
+        "text": ""
+      }
+    ]
+  })";
+
 void AssertSerializedString(const std::string& expected,
                             const std::string& actual) {
   absl::optional<base::Value> expected_value = base::JSONReader::Read(expected);
@@ -151,6 +210,37 @@
                             BuildHypothesisPartsList(hypothesis_part).c_str());
 }
 
+void populateMetadata(ProjectorMetadata& metadata) {
+  metadata.SetCaptionLanguage("en");
+  metadata.SetMetadataVersionNumber(MetadataVersionNumber::kV2);
+
+  std::vector<media::HypothesisParts> first_transcript;
+  first_transcript.emplace_back(std::vector<std::string>({"transcript"}),
+                                base::Milliseconds(1000));
+  first_transcript.emplace_back(std::vector<std::string>({"text"}),
+                                base::Milliseconds(2000));
+
+  metadata.AddTranscript(std::make_unique<ProjectorTranscript>(
+      /*start_time=*/base::Milliseconds(1000),
+      /*end_time=*/base::Milliseconds(3000), "transcript text",
+      std::move(first_transcript)));
+
+  metadata.MarkKeyIdea();
+
+  std::vector<media::HypothesisParts> second_transcript;
+  second_transcript.emplace_back(std::vector<std::string>({"transcript"}),
+                                 base::Milliseconds(3200));
+  second_transcript.emplace_back(std::vector<std::string>({"text"}),
+                                 base::Milliseconds(4200));
+  second_transcript.emplace_back(std::vector<std::string>({"2"}),
+                                 base::Milliseconds(4500));
+
+  metadata.AddTranscript(std::make_unique<ProjectorTranscript>(
+      /*start_time=*/base::Milliseconds(3000),
+      /*end_time=*/base::Milliseconds(5000), "transcript text 2",
+      std::move(second_transcript)));
+}
+
 }  // namespace
 
 class ProjectorKeyIdeaTest : public testing::Test {
@@ -220,37 +310,17 @@
 
   ProjectorMetadataTest(const ProjectorMetadataTest&) = delete;
   ProjectorMetadataTest& operator=(const ProjectorMetadataTest&) = delete;
+
+ protected:
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 TEST_F(ProjectorMetadataTest, Serialize) {
+  scoped_feature_list_.InitWithFeatures(
+      /*enabled_features=*/{},
+      /*disabled_features=*/{ash::features::kProjectorV2});
   ProjectorMetadata metadata;
-  metadata.SetCaptionLanguage("en");
-
-  std::vector<media::HypothesisParts> first_transcript;
-  first_transcript.emplace_back(std::vector<std::string>({"transcript"}),
-                                base::Milliseconds(1000));
-  first_transcript.emplace_back(std::vector<std::string>({"text"}),
-                                base::Milliseconds(2000));
-
-  metadata.AddTranscript(std::make_unique<ProjectorTranscript>(
-      /*start_time=*/base::Milliseconds(1000),
-      /*end_time=*/base::Milliseconds(3000), "transcript text",
-      std::move(first_transcript)));
-
-  metadata.MarkKeyIdea();
-
-  std::vector<media::HypothesisParts> second_transcript;
-  second_transcript.emplace_back(std::vector<std::string>({"transcript"}),
-                                 base::Milliseconds(3200));
-  second_transcript.emplace_back(std::vector<std::string>({"text"}),
-                                 base::Milliseconds(4200));
-  second_transcript.emplace_back(std::vector<std::string>({"2"}),
-                                 base::Milliseconds(4500));
-
-  metadata.AddTranscript(std::make_unique<ProjectorTranscript>(
-      /*start_time=*/base::Milliseconds(3000),
-      /*end_time=*/base::Milliseconds(5000), "transcript text 2",
-      std::move(second_transcript)));
+  populateMetadata(metadata);
 
   metadata.SetSpeechRecognitionStatus(RecognitionStatus::kIncomplete);
   AssertSerializedString(
@@ -269,6 +339,28 @@
       base::StringPrintf(kCompleteMetadataTemplate,
                          static_cast<int>(RecognitionStatus::kError)),
       metadata.Serialize());
+
+  metadata.SetMetadataVersionNumber(MetadataVersionNumber::kV2);
+  // V2 feature flag not enabled, setting version number has no effort.
+  AssertSerializedString(
+      base::StringPrintf(kCompleteMetadataTemplate,
+                         static_cast<int>(RecognitionStatus::kError)),
+      metadata.Serialize());
+}
+
+TEST_F(ProjectorMetadataTest, SerializeV2) {
+  scoped_feature_list_.InitWithFeatures(
+      /*enabled_features=*/{ash::features::kProjectorV2},
+      /*disabled_features=*/{});
+  ProjectorMetadata metadata;
+  populateMetadata(metadata);
+  metadata.SetMetadataVersionNumber(MetadataVersionNumber::kV2);
+
+  metadata.SetSpeechRecognitionStatus(RecognitionStatus::kComplete);
+  AssertSerializedString(
+      base::StringPrintf(kCompleteMetadataV2Template,
+                         static_cast<int>(RecognitionStatus::kComplete)),
+      metadata.Serialize());
 }
 
 }  // namespace ash
diff --git a/ash/public/cpp/external_arc/message_center/arc_notification_item_impl.cc b/ash/public/cpp/external_arc/message_center/arc_notification_item_impl.cc
index 0ce18fc..81801a0 100644
--- a/ash/public/cpp/external_arc/message_center/arc_notification_item_impl.cc
+++ b/ash/public/cpp/external_arc/message_center/arc_notification_item_impl.cc
@@ -105,7 +105,14 @@
         base::UTF8ToUTF16(data->accessible_name.value());
   }
 
-  if (manager_->IsOpeningSettingsSupported() && !is_setting_shown) {
+  const bool render_on_chrome =
+      features::IsRenderArcNotificationsByChromeEnabled() &&
+      data->render_on_chrome;
+
+  if (render_on_chrome) {
+    rich_data.settings_button_handler =
+        message_center::SettingsButtonHandler::INLINE;
+  } else if (manager_->IsOpeningSettingsSupported() && !is_setting_shown) {
     rich_data.settings_button_handler =
         message_center::SettingsButtonHandler::DELEGATE;
   } else {
@@ -128,10 +135,6 @@
     notifier_id.group_key = data->group_key;
   }
 
-  const bool render_on_chrome =
-      features::IsRenderArcNotificationsByChromeEnabled() &&
-      data->render_on_chrome;
-
   const auto notification_type =
       render_on_chrome
           ? ((data->indeterminate_progress || data->progress_max != -1)
diff --git a/ash/public/cpp/night_light_controller.h b/ash/public/cpp/night_light_controller.h
index 12a30be..94b970d2 100644
--- a/ash/public/cpp/night_light_controller.h
+++ b/ash/public/cpp/night_light_controller.h
@@ -38,7 +38,7 @@
   virtual void SetCurrentGeoposition(const SimpleGeoposition& position) = 0;
 
   // Whether Night Light is enabled.
-  virtual bool GetEnabled() const = 0;
+  virtual bool IsNightLightEnabled() const = 0;
 
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
diff --git a/ash/public/mojom/input_device_settings.mojom b/ash/public/mojom/input_device_settings.mojom
index 89c8955..ef4b2b4 100644
--- a/ash/public/mojom/input_device_settings.mojom
+++ b/ash/public/mojom/input_device_settings.mojom
@@ -339,6 +339,12 @@
   kDisable = 0,
   kCopy = 1,
   kPaste = 2,
+  kUndo = 3,
+  kRedo = 4,
+  kZoomIn = 5,
+  kZoomOut = 6,
+  kPreviousPage = 7,
+  kNextPage = 8,
 };
 
 // Contains the customization restrictions of the devices.
diff --git a/ash/search_box/search_box_view_base.cc b/ash/search_box/search_box_view_base.cc
index 1405fb3..fedcc07f 100644
--- a/ash/search_box/search_box_view_base.cc
+++ b/ash/search_box/search_box_view_base.cc
@@ -139,8 +139,6 @@
     SetHasInkDropActionOnClick(true);
     views::InkDrop::UseInkDropForFloodFillRipple(views::InkDrop::Get(this),
                                                  /*highlight_on_hover=*/true);
-    SetPaintToLayer();
-    layer()->SetFillsBoundsOpaquely(false);
 
     SetPreferredSize(gfx::Size(kBubbleLauncherSearchBoxButtonSizeDip,
                                kBubbleLauncherSearchBoxButtonSizeDip));
@@ -177,9 +175,6 @@
     SchedulePaint();
   }
 
-  void set_is_showing(bool is_showing) { is_showing_ = is_showing; }
-  bool is_showing() { return is_showing_; }
-
   void UpdateInkDropColorAndOpacity(SkColor background_color) {
     const std::pair<SkColor, float> base_color_and_opacity =
         ash::ColorProvider::Get()->GetInkDropBaseColorAndOpacity(
@@ -192,9 +187,6 @@
  private:
   int GetButtonRadius() const { return width() / 2; }
 
-  // Whether the button is showing/shown or hiding/hidden.
-  bool is_showing_ = false;
-
   const char* GetClassName() const override { return "SearchBoxImageButton"; }
 };
 
@@ -437,7 +429,7 @@
   search_box_button_container_ =
       content_container_->AddChildView(std::make_unique<views::View>());
   search_box_button_container_->SetLayoutManager(
-      std::make_unique<views::BoxLayout>());
+      std::make_unique<views::FillLayout>());
   content_container_->SetFlexForView(search_box_button_container_, 0,
                                      /*use_min_size=*/true);
 }
@@ -468,28 +460,39 @@
 
 views::ImageButton* SearchBoxViewBase::CreateCloseButton(
     const base::RepeatingClosure& button_callback) {
+  MaybeCreateFilterAndCloseButtonContainer();
+
   DCHECK(!close_button_);
-  close_button_ = search_box_button_container_->AddChildView(
+  close_button_ = filter_and_close_button_container_->AddChildView(
       std::make_unique<SearchBoxImageButton>(button_callback));
-  close_button_->SetVisible(false);
   return close_button_;
 }
 
 views::ImageButton* SearchBoxViewBase::CreateAssistantButton(
     const base::RepeatingClosure& button_callback) {
+  // `assistant_button_container_` is used to align the assistant button to the
+  // end of the `search_box_button_container_`.
+  assistant_button_container_ = search_box_button_container_->AddChildView(
+      std::make_unique<views::BoxLayoutView>());
+  assistant_button_container_->SetMainAxisAlignment(
+      views::BoxLayout::MainAxisAlignment::kEnd);
+  assistant_button_container_->SetPaintToLayer();
+  assistant_button_container_->layer()->SetFillsBoundsOpaquely(false);
+  assistant_button_container_->SetVisible(false);
+
   DCHECK(!assistant_button_);
-  assistant_button_ = search_box_button_container_->AddChildView(
+  assistant_button_ = assistant_button_container_->AddChildView(
       std::make_unique<SearchBoxImageButton>(button_callback));
-  assistant_button_->SetVisible(false);
   return assistant_button_;
 }
 
 views::ImageButton* SearchBoxViewBase::CreateFilterButton(
     const base::RepeatingClosure& button_callback) {
+  MaybeCreateFilterAndCloseButtonContainer();
+
   DCHECK(!filter_button_);
-  filter_button_ = search_box_button_container_->AddChildView(
+  filter_button_ = filter_and_close_button_container_->AddChildView(
       std::make_unique<SearchBoxImageButton>(button_callback));
-  filter_button_->SetVisible(false);
   return filter_button_;
 }
 
@@ -508,6 +511,10 @@
   return views::AsViewClass<views::ImageButton>(assistant_button_);
 }
 
+views::View* SearchBoxViewBase::assistant_button_container() {
+  return views::AsViewClass<views::View>(assistant_button_container_);
+}
+
 views::ImageButton* SearchBoxViewBase::close_button() {
   return views::AsViewClass<views::ImageButton>(close_button_);
 }
@@ -516,6 +523,10 @@
   return views::AsViewClass<views::ImageButton>(filter_button_);
 }
 
+views::View* SearchBoxViewBase::filter_and_close_button_container() {
+  return views::AsViewClass<views::View>(filter_and_close_button_container_);
+}
+
 views::ImageView* SearchBoxViewBase::search_icon() {
   return search_icon_;
 }
@@ -698,24 +709,18 @@
       (show_close_button_when_active_ && is_search_box_active_);
 
   if (should_show_close_button) {
-    MaybeFadeButtonIn(close_button_);
-    if (filter_button_) {
-      MaybeFadeButtonIn(filter_button_);
-    }
+    MaybeFadeContainerIn(filter_and_close_button_container_);
   } else {
-    MaybeFadeButtonOut(close_button_);
-    if (filter_button_) {
-      MaybeFadeButtonOut(filter_button_);
-    }
+    MaybeFadeContainerOut(filter_and_close_button_container_);
   }
 
   if (assistant_button_) {
     const bool should_show_assistant_button =
         show_assistant_button_ && !should_show_close_button;
     if (should_show_assistant_button) {
-      MaybeFadeButtonIn(assistant_button_);
+      MaybeFadeContainerIn(assistant_button_container_);
     } else {
-      MaybeFadeButtonOut(assistant_button_);
+      MaybeFadeContainerOut(assistant_button_container_);
     }
   }
 
@@ -723,13 +728,12 @@
   InvalidateLayout();
 }
 
-void SearchBoxViewBase::MaybeFadeButtonIn(SearchBoxImageButton* button) {
-  CHECK(button);
-  if (button->GetVisible() && button->is_showing())
+void SearchBoxViewBase::MaybeFadeContainerIn(views::View* container) {
+  CHECK(container);
+  if (container->GetVisible() &&
+      container->layer()->GetTargetOpacity() == 1.0f) {
     return;
-
-  if (!button->layer()->GetAnimator()->is_animating())
-    button->layer()->SetOpacity(0.0f);
+  }
 
   views::AnimationBuilder()
       .SetPreemptionStrategy(
@@ -737,35 +741,34 @@
       .Once()
       .At(kButtonFadeInDelay)
       .SetDuration(kButtonFadeInDuration)
-      .SetOpacity(button->layer(), 1.0f, gfx::Tween::LINEAR);
+      .SetOpacity(container->layer(), 1.0f, gfx::Tween::LINEAR);
 
-  // Set the button visible after scheduling the animation because scheduling
-  // the animation might abort a fade-out, which sets the button invisible.
-  button->SetVisible(true);
-  button->set_is_showing(true);
+  // Set the container visible after scheduling the animation because scheduling
+  // the animation might abort a fade-out, which sets the container invisible.
+  container->SetVisible(true);
 }
 
-void SearchBoxViewBase::MaybeFadeButtonOut(SearchBoxImageButton* button) {
-  CHECK(button);
-  if (!button->GetVisible() || !button->is_showing())
+void SearchBoxViewBase::MaybeFadeContainerOut(views::View* container) {
+  CHECK(container);
+  if (!container->GetVisible() || container->layer()->GetTargetOpacity() == 0) {
     return;
+  }
 
   views::AnimationBuilder()
       .SetPreemptionStrategy(
           ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET)
-      .OnEnded(base::BindOnce(&SearchBoxViewBase::SetVisibilityHidden,
-                              weak_factory_.GetWeakPtr(), button))
-      .OnAborted(base::BindOnce(&SearchBoxViewBase::SetVisibilityHidden,
-                                weak_factory_.GetWeakPtr(), button))
+      .OnEnded(base::BindOnce(&SearchBoxViewBase::SetContainerVisibilityHidden,
+                              weak_factory_.GetWeakPtr(), container))
+      .OnAborted(
+          base::BindOnce(&SearchBoxViewBase::SetContainerVisibilityHidden,
+                         weak_factory_.GetWeakPtr(), container))
       .Once()
       .SetDuration(kButtonFadeOutDuration)
-      .SetOpacity(button->layer(), 0.0f, gfx::Tween::LINEAR);
-
-  button->set_is_showing(false);
+      .SetOpacity(container->layer(), 0.0f, gfx::Tween::LINEAR);
 }
 
-void SearchBoxViewBase::SetVisibilityHidden(SearchBoxImageButton* button) {
-  button->SetVisible(false);
+void SearchBoxViewBase::SetContainerVisibilityHidden(views::View* container) {
+  container->SetVisible(false);
 }
 
 void SearchBoxViewBase::ContentsChanged(views::Textfield* sender,
@@ -840,4 +843,15 @@
   }
 }
 
+void SearchBoxViewBase::MaybeCreateFilterAndCloseButtonContainer() {
+  if (!filter_and_close_button_container_) {
+    filter_and_close_button_container_ =
+        search_box_button_container_->AddChildView(
+            std::make_unique<views::BoxLayoutView>());
+    filter_and_close_button_container_->SetPaintToLayer();
+    filter_and_close_button_container_->layer()->SetFillsBoundsOpaquely(false);
+    filter_and_close_button_container_->SetVisible(false);
+  }
+}
+
 }  // namespace ash
diff --git a/ash/search_box/search_box_view_base.h b/ash/search_box/search_box_view_base.h
index ffa8d21..81d37f3 100644
--- a/ash/search_box/search_box_view_base.h
+++ b/ash/search_box/search_box_view_base.h
@@ -83,8 +83,10 @@
       const gfx::Rect& rect) const;
 
   views::ImageButton* assistant_button();
+  views::View* assistant_button_container();
   views::ImageButton* close_button();
   views::ImageButton* filter_button();
+  views::View* filter_and_close_button_container();
   views::ImageView* search_icon();
   views::Textfield* search_box() { return search_box_; }
 
@@ -180,14 +182,14 @@
   // Updates the visibility of the close and assistant buttons.
   void UpdateButtonsVisibility();
 
-  // When necessary, starts the fade in animation for the button.
-  void MaybeFadeButtonIn(SearchBoxImageButton* button);
+  // When necessary, starts the fade in animation for the button container.
+  void MaybeFadeContainerIn(views::View* container);
 
-  // When necessary, starts the fade out animation for the button.
-  void MaybeFadeButtonOut(SearchBoxImageButton* button);
+  // When necessary, starts the fade out animation for the button container.
+  void MaybeFadeContainerOut(views::View* container);
 
-  // Used as a callback to set the button's visibility to false.
-  void SetVisibilityHidden(SearchBoxImageButton* button);
+  // Used as a callback to set the button container's visibility to false.
+  void SetContainerVisibilityHidden(views::View* container);
 
   // Overridden from views::TextfieldController:
   void ContentsChanged(views::Textfield* sender,
@@ -227,6 +229,10 @@
   void SetPreferredStyleForSearchboxText(const gfx::FontList& font_list,
                                          ui::ColorId text_color_id);
 
+  // Initializes `filter_and_close_button_container_` if it has not already been
+  // done.
+  void MaybeCreateFilterAndCloseButtonContainer();
+
  private:
   void OnEnabledChanged();
 
@@ -237,6 +243,10 @@
   raw_ptr<SearchBoxImageButton, ExperimentalAsh> assistant_button_ = nullptr;
   raw_ptr<SearchBoxImageButton, ExperimentalAsh> close_button_ = nullptr;
   raw_ptr<SearchBoxImageButton, ExperimentalAsh> filter_button_ = nullptr;
+  raw_ptr<views::BoxLayoutView, ExperimentalAsh> assistant_button_container_ =
+      nullptr;
+  raw_ptr<views::BoxLayoutView, ExperimentalAsh>
+      filter_and_close_button_container_ = nullptr;
   raw_ptr<views::BoxLayoutView, ExperimentalAsh> text_container_ = nullptr;
 
   raw_ptr<views::Textfield, ExperimentalAsh> search_box_;
diff --git a/ash/system/brightness/unified_brightness_view.cc b/ash/system/brightness/unified_brightness_view.cc
index 8184c7a6..e740dc93 100644
--- a/ash/system/brightness/unified_brightness_view.cc
+++ b/ash/system/brightness/unified_brightness_view.cc
@@ -48,7 +48,7 @@
       return;
     }
 
-    const bool toggled = night_light_controller_->GetEnabled();
+    const bool toggled = night_light_controller_->IsNightLightEnabled();
     night_light_button_ = AddChildView(std::make_unique<IconButton>(
         base::BindRepeating(&UnifiedBrightnessView::OnNightLightButtonPressed,
                             base::Unretained(this)),
@@ -141,7 +141,7 @@
 void UnifiedBrightnessView::UpdateNightLightButton() {
   night_light_button_->SetEnabled(
       TrayPopupUtils::CanShowNightLightFeatureTile());
-  const bool toggled = night_light_controller_->GetEnabled();
+  const bool toggled = night_light_controller_->IsNightLightEnabled();
 
   // Sets `night_light_button_` toggle state to update its icon, icon color,
   // and background color.
diff --git a/ash/system/hotspot/hotspot_feature_pod_controller.cc b/ash/system/hotspot/hotspot_feature_pod_controller.cc
index ef54342..736a7dc 100644
--- a/ash/system/hotspot/hotspot_feature_pod_controller.cc
+++ b/ash/system/hotspot/hotspot_feature_pod_controller.cc
@@ -89,7 +89,8 @@
     return;
   }
 
-  EnableHotspotIfAllowedAndDiveIn();
+  TrackDiveInUMA();
+  tray_controller_->ShowHotspotDetailedView();
 }
 
 void HotspotFeaturePodController::OnHotspotInfoChanged() {
diff --git a/ash/system/hotspot/hotspot_feature_pod_controller_unittest.cc b/ash/system/hotspot/hotspot_feature_pod_controller_unittest.cc
index 4f30ba6..e8abc33 100644
--- a/ash/system/hotspot/hotspot_feature_pod_controller_unittest.cc
+++ b/ash/system/hotspot/hotspot_feature_pod_controller_unittest.cc
@@ -282,11 +282,11 @@
             hotspot_feature_tile_->GetTooltipText());
   EXPECT_STREQ(kHotspotOffIcon.name, GetVectorIconName());
 
-  // Press on the drive in label should toggle hotspot and navigate to the
-  // detailed page.
+  // Press on the drive in label should navigate to the detailed page without
+  // toggling hotspot.
   UpdateHotspotInfo(HotspotState::kDisabled, HotspotAllowStatus::kAllowed);
   PressLabel();
-  EXPECT_TRUE(hotspot_feature_tile_->IsToggled());
+  EXPECT_FALSE(hotspot_feature_tile_->IsToggled());
   EXPECT_TRUE(hotspot_feature_tile_->GetVisible());
   EXPECT_TRUE(hotspot_feature_tile_->GetEnabled());
   ExpectHotspotDetailedViewShown();
@@ -409,13 +409,13 @@
   histogram_tester->ExpectTotalCount(kDiveInHistogram,
                                      /*expected_count=*/0);
 
-  // Toggle hotspot and show hotspot detailed view when pressing on the label.
+  // Press on the label to show detailed page.
   PressLabel();
   histogram_tester->ExpectTotalCount(kToggledOnHistogram,
-                                     /*expected_count=*/1);
+                                     /*expected_count=*/0);
   histogram_tester->ExpectBucketCount(kToggledOnHistogram,
                                       QsFeatureCatalogName::kHotspot,
-                                      /*expected_count=*/1);
+                                      /*expected_count=*/0);
   histogram_tester->ExpectTotalCount(kToggledOffHistogram,
                                      /*expected_count=*/0);
   histogram_tester->ExpectTotalCount(kDiveInHistogram,
@@ -423,6 +423,8 @@
   histogram_tester->ExpectBucketCount(kDiveInHistogram,
                                       QsFeatureCatalogName::kHotspot,
                                       /*expected_count=*/1);
+
+  // Press on the icon to toggle hotspot and show detailed page.
   PressIcon();
   histogram_tester->ExpectTotalCount(kToggledOnHistogram,
                                      /*expected_count=*/1);
@@ -430,15 +432,15 @@
                                       QsFeatureCatalogName::kHotspot,
                                       /*expected_count=*/1);
   histogram_tester->ExpectTotalCount(kToggledOffHistogram,
-                                     /*expected_count=*/1);
+                                     /*expected_count=*/0);
   histogram_tester->ExpectBucketCount(kToggledOffHistogram,
                                       QsFeatureCatalogName::kHotspot,
-                                      /*expected_count=*/1);
+                                      /*expected_count=*/0);
   histogram_tester->ExpectTotalCount(kDiveInHistogram,
-                                     /*expected_count=*/1);
+                                     /*expected_count=*/2);
   histogram_tester->ExpectBucketCount(kDiveInHistogram,
                                       QsFeatureCatalogName::kHotspot,
-                                      /*expected_count=*/1);
+                                      /*expected_count=*/2);
 }
 
 }  // namespace ash
diff --git a/ash/system/locale/locale_detailed_view.cc b/ash/system/locale/locale_detailed_view.cc
index 5718056f..83489df 100644
--- a/ash/system/locale/locale_detailed_view.cc
+++ b/ash/system/locale/locale_detailed_view.cc
@@ -4,7 +4,6 @@
 
 #include "ash/system/locale/locale_detailed_view.h"
 
-#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/system_tray_client.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/shell.h"
@@ -20,7 +19,6 @@
 #include "base/i18n/case_conversion.h"
 #include "base/memory/raw_ptr.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chromeos/constants/chromeos_features.h"
 #include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -61,12 +59,9 @@
     AddChildView(tri_view);
     SetLayoutManager(std::make_unique<views::FillLayout>());
 
-    const bool is_jelly_enabled = chromeos::features::IsJellyEnabled();
     views::Label* iso_code_label = TrayPopupUtils::CreateDefaultLabel();
     iso_code_label->SetEnabledColorId(
-        is_jelly_enabled
-            ? static_cast<ui::ColorId>(cros_tokens::kCrosSysOnSurface)
-            : kColorAshTextColorPrimary);
+        static_cast<ui::ColorId>(cros_tokens::kCrosSysOnSurface));
     iso_code_label->SetAutoColorReadabilityEnabled(false);
     iso_code_label->SetText(base::i18n::ToUpper(
         base::UTF8ToUTF16(l10n_util::GetLanguage(iso_code))));
@@ -78,15 +73,9 @@
 
     auto* display_name_view = TrayPopupUtils::CreateDefaultLabel();
     display_name_view->SetText(display_name);
-    if (is_jelly_enabled) {
-      display_name_view->SetEnabledColorId(cros_tokens::kCrosSysOnSurface);
-      TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosButton2,
-                                            *display_name_view);
-    } else {
-      display_name_view->SetEnabledColorId(kColorAshTextColorPrimary);
-      TrayPopupUtils::SetLabelFontList(
-          display_name_view, TrayPopupUtils::FontStyle::kDetailedViewLabel);
-    }
+    display_name_view->SetEnabledColorId(cros_tokens::kCrosSysOnSurface);
+    TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosButton2,
+                                          *display_name_view);
     display_name_view->SetHorizontalAlignment(gfx::ALIGN_LEFT);
     tri_view->AddView(TriView::Container::CENTER, display_name_view);
 
@@ -95,9 +84,7 @@
           /*use_wide_layout=*/false);
       checked_image->SetImage(ui::ImageModel::FromVectorIcon(
           kCheckCircleIcon,
-          is_jelly_enabled
-              ? static_cast<ui::ColorId>(cros_tokens::kCrosSysPrimary)
-              : kColorAshIconColorProminent,
+          static_cast<ui::ColorId>(cros_tokens::kCrosSysPrimary),
           kMenuIconSize));
       tri_view->AddView(TriView::Container::END, checked_image);
     }
@@ -147,9 +134,7 @@
 
   // Setup the container for the locale list views.
   views::View* container =
-      features::IsQsRevampEnabled()
-          ? scroll_content()->AddChildView(std::make_unique<RoundedContainer>())
-          : scroll_content();
+      scroll_content()->AddChildView(std::make_unique<RoundedContainer>());
 
   const std::vector<LocaleInfo>& locales =
       Shell::Get()->system_tray_model()->locale()->locale_list();
diff --git a/ash/system/locale/locale_detailed_view_pixeltest.cc b/ash/system/locale/locale_detailed_view_pixeltest.cc
index 6028ebd..10cfe63 100644
--- a/ash/system/locale/locale_detailed_view_pixeltest.cc
+++ b/ash/system/locale/locale_detailed_view_pixeltest.cc
@@ -5,7 +5,6 @@
 #include <utility>
 #include <vector>
 
-#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/locale_update_controller.h"
 #include "ash/shell.h"
 #include "ash/system/model/system_tray_model.h"
@@ -16,26 +15,19 @@
 #include "ash/test/ash_test_base.h"
 #include "ash/test/pixel/ash_pixel_differ.h"
 #include "ash/test/pixel/ash_pixel_test_init_params.h"
-#include "base/test/scoped_feature_list.h"
-#include "chromeos/constants/chromeos_features.h"
 
 namespace ash {
 namespace {
 
 class LocaleDetailedViewPixelTest : public AshTestBase {
  public:
-  LocaleDetailedViewPixelTest() {
-    feature_list_.InitWithFeatures(
-        {features::kQsRevamp, chromeos::features::kJelly}, {});
-  }
+  LocaleDetailedViewPixelTest() = default;
 
   // AshTestBase:
   absl::optional<pixel_test::InitParams> CreatePixelTestInitParams()
       const override {
     return pixel_test::InitParams();
   }
-
-  base::test::ScopedFeatureList feature_list_;
 };
 
 TEST_F(LocaleDetailedViewPixelTest, Basics) {
diff --git a/ash/system/locale/locale_detailed_view_unittest.cc b/ash/system/locale/locale_detailed_view_unittest.cc
index 425dbd4..56bd79f2 100644
--- a/ash/system/locale/locale_detailed_view_unittest.cc
+++ b/ash/system/locale/locale_detailed_view_unittest.cc
@@ -7,7 +7,6 @@
 #include <memory>
 #include <vector>
 
-#include "ash/constants/ash_features.h"
 #include "ash/public/cpp/locale_update_controller.h"
 #include "ash/shell.h"
 #include "ash/style/rounded_container.h"
@@ -16,7 +15,6 @@
 #include "ash/system/tray/fake_detailed_view_delegate.h"
 #include "ash/test/ash_test_base.h"
 #include "base/memory/raw_ptr.h"
-#include "base/test/scoped_feature_list.h"
 #include "ui/views/view_utils.h"
 #include "ui/views/widget/widget.h"
 
@@ -25,9 +23,7 @@
 
 class LocaleDetailedViewTest : public AshTestBase {
  public:
-  LocaleDetailedViewTest() {
-    feature_list_.InitAndEnableFeature(features::kQsRevamp);
-  }
+  LocaleDetailedViewTest() = default;
 
   void CreateDetailedView() {
     widget_ = CreateFramelessTestWidget();
@@ -43,7 +39,6 @@
     delegate_.reset();
   }
 
-  base::test::ScopedFeatureList feature_list_;
   std::unique_ptr<views::Widget> widget_;
   std::unique_ptr<DetailedViewDelegate> delegate_;
   raw_ptr<LocaleDetailedView, DanglingUntriaged | ExperimentalAsh>
diff --git a/ash/system/media/media_tray.cc b/ash/system/media/media_tray.cc
index c7f6ea9f..b0eab9fb 100644
--- a/ash/system/media/media_tray.cc
+++ b/ash/system/media/media_tray.cc
@@ -27,8 +27,6 @@
 #include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/metrics/histogram_functions.h"
-#include "base/strings/string_util.h"
-#include "chromeos/constants/chromeos_features.h"
 #include "components/media_message_center/notification_theme.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_registry_simple.h"
@@ -46,7 +44,6 @@
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/box_layout.h"
-#include "ui/views/layout/fill_layout.h"
 
 namespace ash {
 
@@ -66,8 +63,9 @@
 // kMinimumScreenSizeDiagonal.
 bool GetIsPinnedToShelfByDefault() {
   // Happens in test.
-  if (!Shell::HasInstance())
+  if (!Shell::HasInstance()) {
     return false;
+  }
 
   display::ManagedDisplayInfo info =
       Shell::Get()->display_manager()->GetDisplayInfo(
@@ -105,13 +103,9 @@
     if (base::FeatureList::IsEnabled(
             media::kGlobalMediaControlsCrOSUpdatedUI)) {
       title_label_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
-      if (chromeos::features::IsJellyEnabled()) {
-        TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosTitle1,
-                                              *title_label_);
-      } else {
-        TrayPopupUtils::SetLabelFontList(title_label_,
-                                         TrayPopupUtils::FontStyle::kTitle);
-      }
+      TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosTitle1,
+                                            *title_label_);
+
     } else {
       title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
       title_label_->SetFontList(views::Label::GetDefaultFontList().Derive(
@@ -199,13 +193,8 @@
           /*has_border=*/false) {
   SetIconSize(kTrayTopShortcutButtonIconSize);
   SetToggledVectorIcon(kPinnedIcon);
-  if (chromeos::features::IsJellyEnabled()) {
-    SetIconColorId(cros_tokens::kCrosSysOnSurface);
-    SetBackgroundToggledColorId(cros_tokens::kCrosSysSystemPrimaryContainer);
-  } else {
-    SetIconColor(AshColorProvider::Get()->GetContentLayerColor(
-        AshColorProvider::ContentLayerType::kIconColorPrimary));
-  }
+  SetIconColorId(cros_tokens::kCrosSysOnSurface);
+  SetBackgroundToggledColorId(cros_tokens::kCrosSysSystemPrimaryContainer);
   SetToggled(MediaTray::IsPinnedToShelf());
 }
 
@@ -236,20 +225,17 @@
   icon->SetTooltipText(l10n_util::GetStringUTF16(
       IDS_ASH_GLOBAL_MEDIA_CONTROLS_BUTTON_TOOLTIP_TEXT));
   icon_ = tray_container()->AddChildView(std::move(icon));
-  if (chromeos::features::IsJellyEnabled()) {
-    UpdateTrayItemColor(is_active());
-  } else {
-    icon_->SetImage(ui::ImageModel::FromVectorIcon(kGlobalMediaControlsIcon,
-                                                   kColorAshIconColorPrimary));
-  }
+  UpdateTrayItemColor(is_active());
 }
 
 MediaTray::~MediaTray() {
-  if (bubble_)
+  if (bubble_) {
     bubble_->GetBubbleView()->ResetDelegate();
+  }
 
-  if (MediaNotificationProvider::Get())
+  if (MediaNotificationProvider::Get()) {
     MediaNotificationProvider::Get()->RemoveObserver(this);
+  }
 
   Shell::Get()->session_controller()->RemoveObserver(this);
 }
@@ -259,8 +245,9 @@
 }
 
 void MediaTray::OnNotificationListViewSizeChanged() {
-  if (!bubble_)
+  if (!bubble_) {
     return;
+  }
 
   bubble_->GetBubbleView()->UpdateBubble();
 }
@@ -297,8 +284,9 @@
 }
 
 void MediaTray::CloseBubble() {
-  if (MediaNotificationProvider::Get())
+  if (MediaNotificationProvider::Get()) {
     MediaNotificationProvider::Get()->OnBubbleClosing();
+  }
   SetIsActive(false);
   empty_state_view_ = nullptr;
   bubble_.reset();
@@ -306,8 +294,9 @@
 }
 
 void MediaTray::HideBubbleWithView(const TrayBubbleView* bubble_view) {
-  if (bubble_ && bubble_->bubble_view() == bubble_view)
+  if (bubble_ && bubble_->bubble_view() == bubble_view) {
     CloseBubble();
+  }
 }
 
 void MediaTray::ClickedOutsideBubble() {
@@ -315,7 +304,6 @@
 }
 
 void MediaTray::UpdateTrayItemColor(bool is_active) {
-  DCHECK(chromeos::features::IsJellyEnabled());
   icon_->SetImage(ui::ImageModel::FromVectorIcon(
       kGlobalMediaControlsIcon,
       is_active ? cros_tokens::kCrosSysSystemOnPrimaryContainer
@@ -346,21 +334,25 @@
 }
 
 void MediaTray::UpdateDisplayState() {
-  if (!MediaNotificationProvider::Get())
+  if (!MediaNotificationProvider::Get()) {
     return;
+  }
 
-  if (bubble_ && Shell::Get()->session_controller()->IsScreenLocked())
+  if (bubble_ && Shell::Get()->session_controller()->IsScreenLocked()) {
     CloseBubble();
+  }
 
   bool has_session =
       MediaNotificationProvider::Get()->HasActiveNotifications() ||
       MediaNotificationProvider::Get()->HasFrozenNotifications();
 
-  if (bubble_ && !has_session)
+  if (bubble_ && !has_session) {
     ShowEmptyState();
+  }
 
-  if (bubble_ && has_session && empty_state_view_)
+  if (bubble_ && has_session && empty_state_view_) {
     empty_state_view_->SetVisible(false);
+  }
 
   bool should_show = has_session &&
                      !Shell::Get()->session_controller()->IsScreenLocked() &&
@@ -404,8 +396,9 @@
 }
 
 void MediaTray::SetNotificationColorTheme() {
-  if (!MediaNotificationProvider::Get())
+  if (!MediaNotificationProvider::Get()) {
     return;
+  }
 
   media_message_center::NotificationTheme theme;
   theme.primary_text_color = AshColorProvider::Get()->GetContentLayerColor(
@@ -462,8 +455,9 @@
 }
 
 void MediaTray::AnchorUpdated() {
-  if (!bubble_)
+  if (!bubble_) {
     return;
+  }
 
   bubble_->GetBubbleView()->SetAnchorRect(
       shelf()->GetStatusAreaWidget()->GetMediaTrayAnchorRect());
diff --git a/ash/system/media/quick_settings_media_view_container_unittest.cc b/ash/system/media/quick_settings_media_view_container_unittest.cc
index e2539ec..78b9ef8 100644
--- a/ash/system/media/quick_settings_media_view_container_unittest.cc
+++ b/ash/system/media/quick_settings_media_view_container_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "ash/system/media/quick_settings_media_view_container.h"
 
-#include "ash/constants/ash_features.h"
 #include "ash/system/media/media_tray.h"
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/system/unified/unified_system_tray_bubble.h"
@@ -24,8 +23,8 @@
   ~QuickSettingsMediaViewContainerTest() override = default;
 
   void SetUp() override {
-    feature_list_.InitWithFeatures(
-        {features::kQsRevamp, media::kGlobalMediaControlsCrOSUpdatedUI}, {});
+    feature_list_.InitWithFeatures({media::kGlobalMediaControlsCrOSUpdatedUI},
+                                   {});
     NoSessionAshTestBase::SetUp();
 
     MediaTray::SetPinnedToShelf(false);
diff --git a/ash/system/media/quick_settings_media_view_controller_unittest.cc b/ash/system/media/quick_settings_media_view_controller_unittest.cc
index 267ac69..73e4dd0 100644
--- a/ash/system/media/quick_settings_media_view_controller_unittest.cc
+++ b/ash/system/media/quick_settings_media_view_controller_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "ash/system/media/quick_settings_media_view_controller.h"
 
-#include "ash/constants/ash_features.h"
 #include "ash/system/media/media_tray.h"
 #include "ash/system/media/mock_media_notification_provider.h"
 #include "ash/system/media/quick_settings_media_view.h"
@@ -27,8 +26,8 @@
   ~QuickSettingsMediaViewControllerTest() override = default;
 
   void SetUp() override {
-    feature_list_.InitWithFeatures(
-        {features::kQsRevamp, media::kGlobalMediaControlsCrOSUpdatedUI}, {});
+    feature_list_.InitWithFeatures({media::kGlobalMediaControlsCrOSUpdatedUI},
+                                   {});
     AshTestBase::SetUp();
     provider_ = std::make_unique<MockMediaNotificationProvider>();
 
diff --git a/ash/system/media/quick_settings_media_view_unittest.cc b/ash/system/media/quick_settings_media_view_unittest.cc
index 72ece94..bd8fa82 100644
--- a/ash/system/media/quick_settings_media_view_unittest.cc
+++ b/ash/system/media/quick_settings_media_view_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "ash/system/media/quick_settings_media_view.h"
 
-#include "ash/constants/ash_features.h"
 #include "ash/system/media/media_tray.h"
 #include "ash/system/media/quick_settings_media_view_controller.h"
 #include "ash/system/unified/unified_system_tray.h"
@@ -15,7 +14,6 @@
 #include "base/time/time.h"
 #include "components/global_media_controls/public/views/media_item_ui_view.h"
 #include "components/media_message_center/mock_media_notification_item.h"
-#include "media/base/media_switches.h"
 #include "ui/events/types/event_type.h"
 
 namespace ash {
@@ -29,8 +27,8 @@
   ~QuickSettingsMediaViewTest() override = default;
 
   void SetUp() override {
-    feature_list_.InitWithFeatures(
-        {features::kQsRevamp, media::kGlobalMediaControlsCrOSUpdatedUI}, {});
+    feature_list_.InitWithFeatures({media::kGlobalMediaControlsCrOSUpdatedUI},
+                                   {});
     NoSessionAshTestBase::SetUp();
 
     MediaTray::SetPinnedToShelf(false);
diff --git a/ash/system/media/unified_media_controls_container_unittest.cc b/ash/system/media/unified_media_controls_container_unittest.cc
index 8030984..dc71a9a 100644
--- a/ash/system/media/unified_media_controls_container_unittest.cc
+++ b/ash/system/media/unified_media_controls_container_unittest.cc
@@ -6,29 +6,21 @@
 
 #include <memory>
 
-#include "ash/constants/ash_features.h"
 #include "ash/system/media/media_tray.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/status_area_widget_test_helper.h"
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/system/unified/unified_system_tray_bubble.h"
-#include "ash/system/unified/unified_system_tray_view.h"
 #include "ash/test/ash_test_base.h"
-#include "base/test/scoped_feature_list.h"
 
 namespace ash {
 
-class UnifiedMediaControlsContainerTest
-    : public AshTestBase,
-      public testing::WithParamInterface<bool> {
+class UnifiedMediaControlsContainerTest : public AshTestBase {
  public:
   UnifiedMediaControlsContainerTest() = default;
   ~UnifiedMediaControlsContainerTest() override = default;
 
   void SetUp() override {
-    scoped_feature_list_.InitWithFeatureState(features::kQsRevamp,
-                                              IsQsRevampEnabled());
-
     AshTestBase::SetUp();
 
     // Ensure media tray is not pinned to shelf so that media controls
@@ -40,13 +32,6 @@
         ->ShowBubble();
   }
 
-  UnifiedSystemTrayView* system_tray_view() {
-    return StatusAreaWidgetTestHelper::GetStatusAreaWidget()
-        ->unified_system_tray()
-        ->bubble()
-        ->unified_view();
-  }
-
   QuickSettingsView* quick_settings_view() {
     return StatusAreaWidgetTestHelper::GetStatusAreaWidget()
         ->unified_system_tray()
@@ -55,39 +40,20 @@
   }
 
   UnifiedMediaControlsContainer* media_controls_container() {
-    return features::IsQsRevampEnabled()
-               ? quick_settings_view()->media_controls_container_for_testing()
-               : system_tray_view()->media_controls_container_for_testing();
+    return quick_settings_view()->media_controls_container_for_testing();
   }
 
-  bool IsQsRevampEnabled() { return GetParam(); }
-
-  void ShowMediaControls() {
-    features::IsQsRevampEnabled() ? quick_settings_view()->ShowMediaControls()
-                                  : system_tray_view()->ShowMediaControls();
-  }
+  void ShowMediaControls() { quick_settings_view()->ShowMediaControls(); }
 
   void ShowDetailedView() {
     auto view = std::make_unique<views::View>();
-    features::IsQsRevampEnabled()
-        ? quick_settings_view()->SetDetailedView(std::move(view))
-        : system_tray_view()->SetDetailedView(std::move(view));
+    quick_settings_view()->SetDetailedView(std::move(view));
   }
 
-  void ResetDetailedView() {
-    features::IsQsRevampEnabled() ? quick_settings_view()->ResetDetailedView()
-                                  : system_tray_view()->ResetDetailedView();
-  }
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
+  void ResetDetailedView() { quick_settings_view()->ResetDetailedView(); }
 };
 
-INSTANTIATE_TEST_SUITE_P(All,
-                         UnifiedMediaControlsContainerTest,
-                         testing::Bool());
-
-TEST_P(UnifiedMediaControlsContainerTest, DoNotShowControlsWhenInDetailedView) {
+TEST_F(UnifiedMediaControlsContainerTest, DoNotShowControlsWhenInDetailedView) {
   // Navigate to a dummy detailed view.
   ShowDetailedView();
 
@@ -100,25 +66,7 @@
   EXPECT_TRUE(media_controls_container()->GetVisible());
 }
 
-TEST_P(UnifiedMediaControlsContainerTest, HideControlsWhenSystemMenuCollapse) {
-  // Quick settings is not collapsable.
-  if (features::IsQsRevampEnabled()) {
-    return;
-  }
-
-  EXPECT_FALSE(media_controls_container()->GetVisible());
-  system_tray_view()->SetExpandedAmount(0.0f);
-
-  // Simulate media playing, container should be hidden since menu is collapsed.
-  system_tray_view()->ShowMediaControls();
-  EXPECT_FALSE(media_controls_container()->GetVisible());
-
-  // Controls should be shown as the menu is expanding back to normal state.
-  system_tray_view()->SetExpandedAmount(0.1f);
-  EXPECT_TRUE(media_controls_container()->GetVisible());
-}
-
-TEST_P(UnifiedMediaControlsContainerTest, ShowMediaControls) {
+TEST_F(UnifiedMediaControlsContainerTest, ShowMediaControls) {
   // Simulate media playing and media controls should show.
   ShowMediaControls();
   EXPECT_TRUE(media_controls_container()->GetVisible());
diff --git a/ash/system/message_center/ash_message_popup_collection.cc b/ash/system/message_center/ash_message_popup_collection.cc
index 6b4c6cc..4bcdd6d8d 100644
--- a/ash/system/message_center/ash_message_popup_collection.cc
+++ b/ash/system/message_center/ash_message_popup_collection.cc
@@ -30,6 +30,7 @@
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "ash/wm/window_properties.h"
 #include "ash/wm/work_area_insets.h"
+#include "base/auto_reset.h"
 #include "base/check.h"
 #include "base/i18n/rtl.h"
 #include "base/metrics/histogram_functions.h"
@@ -85,6 +86,13 @@
     return;
   }
 
+  // Ignore changes happen to the popup collection height when bubble changes is
+  // being handled. This is to avoid crashes (b/305781721) when we handle both
+  // the bubble and the collection height changes at the same time.
+  if (is_handling_bubble_change_) {
+    return;
+  }
+
   // Do nothing if there's no open corner anchored shelf pod bubble.
   auto* status_area =
       StatusAreaWidget::ForWindow(popup_collection_->shelf_->GetWindow());
@@ -169,6 +177,10 @@
     return;
   }
 
+  // This is to make sure that we don't close the bubble through
+  // `OnPopupCollectionHeightChanged()` to avoid crashes (b/305781721).
+  base::AutoReset<bool> reset(&is_handling_bubble_change_, true);
+
   int previous_baseline_offset = baseline_offset_;
 
   // If the popup collection does not fit in the available space when opening a
diff --git a/ash/system/message_center/ash_message_popup_collection.h b/ash/system/message_center/ash_message_popup_collection.h
index f68167a8..dfcee2e3 100644
--- a/ash/system/message_center/ash_message_popup_collection.h
+++ b/ash/system/message_center/ash_message_popup_collection.h
@@ -182,6 +182,10 @@
     int baseline_offset_ = 0;
     NotifierCollisionSurfaceType surface_type_ =
         NotifierCollisionSurfaceType::kNone;
+
+    // True if bubble changes are being handled in
+    // `HandleBubbleVisibilityOrBoundsChanged()`.
+    bool is_handling_bubble_change_ = false;
   };
 
   // message_center::MessageView::Observer:
diff --git a/ash/system/message_center/ash_notification_view.cc b/ash/system/message_center/ash_notification_view.cc
index a2891c0..71f0590 100644
--- a/ash/system/message_center/ash_notification_view.cc
+++ b/ash/system/message_center/ash_notification_view.cc
@@ -43,6 +43,7 @@
 #include "base/strings/strcat.h"
 #include "base/time/time.h"
 #include "chromeos/constants/chromeos_features.h"
+#include "components/vector_icons/vector_icons.h"
 #include "ui/base/dragdrop/os_exchange_data.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
@@ -171,6 +172,9 @@
 // than this value, we draw a background around the image.
 constexpr int kSmallImageBackgroundThreshold = 6;
 
+// The horizontal spacing between control button icons.
+constexpr int kControlButtonsHorizontalSpacing = 6;
+
 // Helpers ---------------------------------------------------------------------
 
 // Configure the style for labels in notification view. `is_color_primary`
@@ -542,6 +546,7 @@
                   .AddChild(
                       views::Builder<views::FlexLayoutView>()
                           .SetOrientation(views::LayoutOrientation::kVertical)
+                          .SetCrossAxisAlignment(views::LayoutAlignment::kEnd)
                           .AddChild(
                               views::Builder<views::BoxLayoutView>()
                                   .SetMainAxisAlignment(MainAxisAlignment::kEnd)
@@ -550,9 +555,14 @@
                                   .AddChild(
                                       CreateControlButtonsBuilder()
                                           .CopyAddressTo(&control_buttons_view_)
-                                          .SetProperty(
-                                              views::kCrossAxisAlignmentKey,
-                                              views::LayoutAlignment::kEnd)
+                                          .SetBetweenButtonSpacing(
+                                              kControlButtonsHorizontalSpacing)
+                                          .SetCloseButtonIcon(
+                                              vector_icons::
+                                                  kCloseChromeRefreshIcon)
+                                          .SetSettingsButtonIcon(
+                                              vector_icons::
+                                                  kSettingsOutlineIcon)
                                           .SetButtonIconColors(
                                               AshColorProvider::Get()
                                                   ->GetContentLayerColor(
@@ -567,9 +577,7 @@
                                   .CopyAddressTo(&expand_button_)
                                   .SetCallback(base::BindRepeating(
                                       &AshNotificationView::ToggleExpand,
-                                      base::Unretained(this)))
-                                  .SetProperty(views::kCrossAxisAlignmentKey,
-                                               views::LayoutAlignment::kEnd))));
+                                      base::Unretained(this))))));
 
   // Main right view contains all the views besides control buttons, app icon,
   // grouped container and action buttons.
@@ -1023,12 +1031,12 @@
 
   for (auto* notification : notifications) {
     auto notification_view =
-            MessageViewFactory::Create(*notification, /*shown_in_popup=*/false);
+        MessageViewFactory::Create(*notification, /*shown_in_popup=*/false);
     // The child can either be an AshNotificationView or a custom notification
     // view.
     if (notification->type() != message_center::NOTIFICATION_TYPE_CUSTOM) {
       auto* ash_notification_view =
-              static_cast<AshNotificationView*>(notification_view.get());
+          static_cast<AshNotificationView*>(notification_view.get());
       ash_notification_view->SetGroupedChildExpanded(IsExpanded());
     }
 
diff --git a/ash/system/message_center/ash_notification_view_pixeltest.cc b/ash/system/message_center/ash_notification_view_pixeltest.cc
index 9d64f0b..4cce46d1 100644
--- a/ash/system/message_center/ash_notification_view_pixeltest.cc
+++ b/ash/system/message_center/ash_notification_view_pixeltest.cc
@@ -150,7 +150,7 @@
   EXPECT_TRUE(close_button->HasFocus());
   EXPECT_EQ(control_buttons_layer->opacity(), 1);
   EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
-      "close_button_focused", /*revision_number=*/1, notification_view));
+      "close_button_focused", /*revision_number=*/2, notification_view));
 }
 
 // Regression test for http://b/267195370. Tests that a notification with no
@@ -197,6 +197,51 @@
       "progress_collapsed", /*revision_number=*/0, notification_view));
 }
 
+// Tests the control buttons UI for the case of a notification with just the
+// close button.
+TEST_P(AshNotificationViewPixelTest, CloseControlButton) {
+  // Generate a notification that should show just the close control button.
+  // Also toggle the notification bubble so that the notification doesn't
+  // disappear during the test.
+  const std::string id = test_api()->AddNotification();
+  test_api()->ToggleBubble();
+
+  // Hover the mouse over the notification so that the close control button is
+  // visible when taking a screenshot.
+  auto* notification_view = static_cast<AshNotificationView*>(
+      test_api()->GetNotificationViewForId(id));
+  GetEventGenerator()->MoveMouseTo(
+      notification_view->GetBoundsInScreen().CenterPoint(), /*count=*/10);
+
+  // Verify with a pixel test that the close control button is visible and has
+  // the proper placement.
+  EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
+      "close_control_button", /*revision_number=*/0, notification_view));
+}
+
+// Tests the control buttons UI for the case of a notification with both the
+// settings and close buttons.
+TEST_P(AshNotificationViewPixelTest, SettingsAndCloseControlButtons) {
+  // Generate a notification that should show both the settings and close
+  // control buttons. Also toggle the notification bubble so that the
+  // notification doesn't disappear during the test.
+  const std::string id = test_api()->AddNotificationWithSettingsButton();
+  test_api()->ToggleBubble();
+
+  // Hover the mouse over the notification so that the control buttons are
+  // visible when taking a screenshot.
+  auto* notification_view = static_cast<AshNotificationView*>(
+      test_api()->GetNotificationViewForId(id));
+  GetEventGenerator()->MoveMouseTo(
+      notification_view->GetBoundsInScreen().CenterPoint(), /*count=*/10);
+
+  // Verify with a pixel test that the control buttons are visible and have
+  // proper spacing between them.
+  EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
+      "settings_and_close_control_buttons", /*revision_number=*/0,
+      notification_view));
+}
+
 class AshNotificationViewTitlePixelTest
     : public AshNotificationViewPixelTestBase,
       public testing::WithParamInterface<
diff --git a/ash/system/night_light/night_light_controller_impl.cc b/ash/system/night_light/night_light_controller_impl.cc
index ece5fd4..80571a7 100644
--- a/ash/system/night_light/night_light_controller_impl.cc
+++ b/ash/system/night_light/night_light_controller_impl.cc
@@ -631,7 +631,7 @@
 }
 
 void NightLightControllerImpl::Toggle() {
-  SetEnabled(!GetEnabled(), AnimationDuration::kShort);
+  SetEnabled(!IsNightLightEnabled(), AnimationDuration::kShort);
 }
 
 void NightLightControllerImpl::OnDisplayConfigurationChanged() {
@@ -642,7 +642,8 @@
   // This newly initialized |host| could be of a newly added display, or of a
   // newly created mirroring display (either for mirroring or unified). we need
   // to apply the current temperature immediately without animation.
-  ApplyTemperatureToHost(host, GetEnabled() ? GetColorTemperature() : 0.0f);
+  ApplyTemperatureToHost(host,
+                         IsNightLightEnabled() ? GetColorTemperature() : 0.0f);
 }
 
 void NightLightControllerImpl::OnActiveUserPrefServiceChanged(
@@ -705,7 +706,7 @@
   Refresh(/*did_schedule_change=*/true, keep_manual_toggles_during_schedules);
 }
 
-bool NightLightControllerImpl::GetEnabled() const {
+bool NightLightControllerImpl::IsNightLightEnabled() const {
   return active_user_pref_service_ &&
          active_user_pref_service_->GetBoolean(prefs::kNightLightEnabled);
 }
@@ -799,7 +800,7 @@
     return false;
 
   VLOG(1) << "Restoring a previous schedule.";
-  DCHECK_NE(GetEnabled(), target_state.target_status);
+  DCHECK_NE(IsNightLightEnabled(), target_state.target_status);
   ScheduleNextToggle(target_state.target_time - delegate_->GetNow());
   return true;
 }
@@ -818,7 +819,7 @@
 
 void NightLightControllerImpl::ShowAutoNightLightNotification() {
   DCHECK(features::IsAutoNightLightEnabled());
-  DCHECK(GetEnabled());
+  DCHECK(IsNightLightEnabled());
   DCHECK(!UserHasEverDismissedAutoNightLightNotification());
   DCHECK_EQ(ScheduleType::kSunsetToSunrise, GetScheduleType());
 
@@ -900,7 +901,8 @@
 
 void NightLightControllerImpl::RefreshDisplaysTemperature(
     float color_temperature) {
-  const float new_temperature = GetEnabled() ? color_temperature : 0.0f;
+  const float new_temperature =
+      IsNightLightEnabled() ? color_temperature : 0.0f;
   temperature_animation_->AnimateToNewValue(
       new_temperature, animation_duration_ == AnimationDuration::kShort
                            ? kManualAnimationDuration
@@ -915,7 +917,8 @@
 
 void NightLightControllerImpl::ReapplyColorTemperatures() {
   DCHECK(temperature_animation_);
-  const float target_temperature = GetEnabled() ? GetColorTemperature() : 0.0f;
+  const float target_temperature =
+      IsNightLightEnabled() ? GetColorTemperature() : 0.0f;
   if (temperature_animation_->is_animating()) {
     // Do not interrupt an on-going animation towards the same target value.
     if (temperature_animation_->target_temperature() == target_temperature)
@@ -981,7 +984,7 @@
 
 void NightLightControllerImpl::NotifyStatusChanged() {
   for (auto& observer : observers_)
-    observer.OnNightLightEnabledChanged(GetEnabled());
+    observer.OnNightLightEnabledChanged(IsNightLightEnabled());
 }
 
 void NightLightControllerImpl::NotifyClientWithScheduleChange() {
@@ -990,7 +993,7 @@
 }
 
 void NightLightControllerImpl::OnEnabledPrefChanged() {
-  const bool enabled = GetEnabled();
+  const bool enabled = IsNightLightEnabled();
   VLOG(1) << "Enable state changed. New state: " << enabled << ".";
   DCHECK(active_user_pref_service_);
 
@@ -1178,7 +1181,7 @@
   DCHECK_GE(start_time, now);
   DCHECK_GE(end_time, now);
 
-  if (did_schedule_change && enable_now != GetEnabled()) {
+  if (did_schedule_change && enable_now != IsNightLightEnabled()) {
     // If the change in the schedule introduces a change in the status, then
     // calling SetEnabled() is all we need, since it will trigger a change in
     // the user prefs to which we will respond by calling Refresh(). This will
@@ -1196,14 +1199,14 @@
   // wish and maintain the current status that they desire, but we schedule the
   // status to be toggled according to the time that corresponds with the
   // opposite status of the current one.
-  ScheduleNextToggle(GetEnabled() ? end_time - now : start_time - now);
+  ScheduleNextToggle(IsNightLightEnabled() ? end_time - now : start_time - now);
   RefreshDisplaysTemperature(GetColorTemperature());
 }
 
 void NightLightControllerImpl::ScheduleNextToggle(base::TimeDelta delay) {
   DCHECK(active_user_pref_service_);
 
-  const bool new_status = !GetEnabled();
+  const bool new_status = !IsNightLightEnabled();
   const base::Time target_time = delegate_->GetNow() + delay;
 
   per_user_schedule_target_state_[active_user_pref_service_] =
diff --git a/ash/system/night_light/night_light_controller_impl.h b/ash/system/night_light/night_light_controller_impl.h
index 33b9bff3d..b5dde7b0 100644
--- a/ash/system/night_light/night_light_controller_impl.h
+++ b/ash/system/night_light/night_light_controller_impl.h
@@ -181,7 +181,7 @@
 
   // ash::NightLightController:
   void SetCurrentGeoposition(const SimpleGeoposition& position) override;
-  bool GetEnabled() const override;
+  bool IsNightLightEnabled() const override;
 
   // chromeos::PowerManagerClient::Observer:
   void SuspendDone(base::TimeDelta sleep_duration) override;
diff --git a/ash/system/night_light/night_light_controller_unittest.cc b/ash/system/night_light/night_light_controller_unittest.cc
index b7798bf..265a52e0 100644
--- a/ash/system/night_light/night_light_controller_unittest.cc
+++ b/ash/system/night_light/night_light_controller_unittest.cc
@@ -277,14 +277,14 @@
   TestObserver observer;
   NightLightControllerImpl* controller = GetController();
   SetNightLightEnabled(false);
-  ASSERT_FALSE(controller->GetEnabled());
+  ASSERT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
   controller->Toggle();
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   EXPECT_TRUE(observer.status());
   TestCompositorsTemperature(GetController()->GetColorTemperature());
   controller->Toggle();
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   EXPECT_FALSE(observer.status());
   TestCompositorsTemperature(0.0f);
 }
@@ -296,7 +296,7 @@
   TestObserver observer;
   NightLightControllerImpl* controller = GetController();
   SetNightLightEnabled(false);
-  ASSERT_FALSE(controller->GetEnabled());
+  ASSERT_FALSE(controller->IsNightLightEnabled());
 
   // Setting the temperature while NightLight is disabled only changes the
   // color temperature field, but root layers temperatures are not affected, nor
@@ -309,7 +309,7 @@
   // When NightLight is enabled, temperature changes actually affect the root
   // layers temperatures.
   SetNightLightEnabled(true);
-  ASSERT_TRUE(controller->GetEnabled());
+  ASSERT_TRUE(controller->IsNightLightEnabled());
   const float temperature2 = 0.7f;
   controller->SetColorTemperature(temperature2);
   EXPECT_EQ(temperature2, controller->GetColorTemperature());
@@ -320,7 +320,7 @@
   // 0.0f. Observers only receive an enabled status change notification; no
   // temperature change notification.
   SetNightLightEnabled(false);
-  ASSERT_FALSE(controller->GetEnabled());
+  ASSERT_FALSE(controller->IsNightLightEnabled());
   EXPECT_FALSE(observer.status());
   EXPECT_EQ(temperature2, controller->GetColorTemperature());
   TestCompositorsTemperature(0.0f);
@@ -328,7 +328,7 @@
   // When re-enabled, the stored temperature is re-applied.
   SetNightLightEnabled(true);
   EXPECT_TRUE(observer.status());
-  ASSERT_TRUE(controller->GetEnabled());
+  ASSERT_TRUE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(temperature2);
 }
 
@@ -336,7 +336,7 @@
   // Start with one display and enable NightLight.
   NightLightControllerImpl* controller = GetController();
   SetNightLightEnabled(true);
-  ASSERT_TRUE(controller->GetEnabled());
+  ASSERT_TRUE(controller->IsNightLightEnabled());
   const float temperature = 0.2f;
   controller->SetColorTemperature(temperature);
   EXPECT_EQ(temperature, controller->GetColorTemperature());
@@ -389,7 +389,7 @@
   // Test start with user1 logged in.
   NightLightControllerImpl* controller = GetController();
   SetNightLightEnabled(true);
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   const float user1_temperature = 0.8f;
   controller->SetColorTemperature(user1_temperature);
   EXPECT_EQ(user1_temperature, controller->GetColorTemperature());
@@ -397,7 +397,7 @@
 
   // Switch to user 2, and expect NightLight to be disabled.
   SwitchActiveUser(kUser2Email);
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   // Changing user_2's color temperature shouldn't affect user_1's settings.
   const float user2_temperature = 0.2f;
   user2_pref_service()->SetDouble(prefs::kNightLightTemperature,
@@ -410,7 +410,7 @@
   // Switch back to user 1, to find NightLight is still enabled, and the same
   // user's color temperature are re-applied.
   SwitchActiveUser(kUser1Email);
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   EXPECT_EQ(user1_temperature, controller->GetColorTemperature());
   TestCompositorsTemperature(user1_temperature);
 }
@@ -421,7 +421,7 @@
   // Test start with user1 logged in.
   NightLightControllerImpl* controller = GetController();
   user1_pref_service()->SetBoolean(prefs::kNightLightEnabled, true);
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   const float temperature1 = 0.65f;
   user1_pref_service()->SetDouble(prefs::kNightLightTemperature, temperature1);
   EXPECT_EQ(temperature1, controller->GetColorTemperature());
@@ -431,7 +431,7 @@
   EXPECT_EQ(temperature2, controller->GetColorTemperature());
   TestCompositorsTemperature(temperature2);
   user1_pref_service()->SetBoolean(prefs::kNightLightEnabled, false);
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
 }
 
 // Tests transitioning from kNone to kCustom and back to kNone schedule types.
@@ -452,14 +452,14 @@
   //
   // Even though "Now" is inside the NightLight interval, nothing should change,
   // since the schedule type is "none".
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
 
   // Now change the schedule type to custom, NightLight should turn on
   // immediately with a short animation duration, and the timer should be
   // running with a delay of exactly 2 hours scheduling the end.
   controller->SetScheduleType(ScheduleType::kCustom);
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(controller->GetColorTemperature());
   EXPECT_EQ(NightLightControllerImpl::AnimationDuration::kShort,
             controller->last_animation_duration());
@@ -469,7 +469,7 @@
   // If the user changes the schedule type to "none", the NightLight status
   // should not change, but the timer should not be running.
   controller->SetScheduleType(ScheduleType::kNone);
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(controller->GetColorTemperature());
   EXPECT_FALSE(controller->timer()->IsRunning());
 }
@@ -482,7 +482,7 @@
   controller->SetCustomStartTime(TimeOfDay(15 * 60));
   controller->SetCustomEndTime(TimeOfDay(20 * 60));
   controller->SetScheduleType(ScheduleType::kCustom);
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(controller->GetColorTemperature());
 
   // Simulate reaching the end time by triggering the timer's user task. Make
@@ -496,7 +496,7 @@
   // Now is 8:00 PM.
   delegate()->SetFakeNow(TimeOfDay(20 * 60));
   controller->timer()->FireNow();
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
   EXPECT_EQ(NightLightControllerImpl::AnimationDuration::kLong,
             controller->last_animation_duration());
@@ -521,7 +521,7 @@
   controller->SetCustomStartTime(TimeOfDay(15 * 60));
   controller->SetCustomEndTime(TimeOfDay(20 * 60));
   controller->SetScheduleType(ScheduleType::kCustom);
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
 
   // What happens if the user manually turns NightLight on while the schedule
@@ -530,7 +530,7 @@
   // button must override any automatic schedule, and should be performed with
   // the short animation duration.
   controller->Toggle();
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(controller->GetColorTemperature());
   EXPECT_EQ(NightLightControllerImpl::AnimationDuration::kShort,
             controller->last_animation_duration());
@@ -542,7 +542,7 @@
   // Manually turning it back off should also be respected, and this time the
   // start is scheduled at 3:00 PM tomorrow after 19 hours from "now" (8:00 PM).
   controller->Toggle();
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
   EXPECT_EQ(NightLightControllerImpl::AnimationDuration::kShort,
             controller->last_animation_duration());
@@ -570,7 +570,7 @@
   // to kCustom, shouldn't affect the status. Validate the timer is running with
   // a 2-hour delay.
   controller->SetScheduleType(ScheduleType::kCustom);
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
   EXPECT_TRUE(controller->timer()->IsRunning());
   EXPECT_EQ(base::Hours(2), controller->timer()->GetCurrentDelay());
@@ -578,7 +578,7 @@
   // Change the start time in such a way that doesn't change the status, but
   // despite that, confirm that schedule has been updated.
   controller->SetCustomStartTime(TimeOfDay(19 * 60));  // 7:00 PM.
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
   EXPECT_TRUE(controller->timer()->IsRunning());
   EXPECT_EQ(base::Hours(3), controller->timer()->GetCurrentDelay());
@@ -586,7 +586,7 @@
   // Changing the end time in a similar fashion to the above and expect no
   // change.
   controller->SetCustomEndTime(TimeOfDay(23 * 60));  // 11:00 PM.
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
   EXPECT_TRUE(controller->timer()->IsRunning());
   EXPECT_EQ(base::Hours(3), controller->timer()->GetCurrentDelay());
@@ -611,7 +611,7 @@
   // Custom times should have no effect when the schedule type is sunset to
   // sunrise.
   controller->SetScheduleType(ScheduleType::kSunsetToSunrise);
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
   EXPECT_TRUE(controller->timer()->IsRunning());
   EXPECT_EQ(base::Hours(4), controller->timer()->GetCurrentDelay());
@@ -619,7 +619,7 @@
   // Simulate reaching sunset.
   delegate()->SetFakeNow(TimeOfDay(20 * 60));  // Now is 8:00 PM.
   controller->timer()->FireNow();
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(controller->GetColorTemperature());
   EXPECT_EQ(NightLightControllerImpl::AnimationDuration::kLong,
             controller->last_animation_duration());
@@ -630,7 +630,7 @@
   // Simulate reaching sunrise.
   delegate()->SetFakeNow(TimeOfDay(5 * 60));  // Now is 5:00 AM.
   controller->timer()->FireNow();
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
   EXPECT_EQ(NightLightControllerImpl::AnimationDuration::kLong,
             controller->last_animation_duration());
@@ -656,7 +656,7 @@
 
   // Expect that timer is running and the start is scheduled after 4 hours.
   controller->SetScheduleType(ScheduleType::kSunsetToSunrise);
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
   EXPECT_TRUE(controller->timer()->IsRunning());
   EXPECT_EQ(base::Hours(4), controller->timer()->GetCurrentDelay());
@@ -664,7 +664,7 @@
   // Simulate reaching sunset.
   delegate()->SetFakeNow(TimeOfDay(20 * 60));  // Now is 8:00 PM.
   controller->timer()->FireNow();
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(controller->GetColorTemperature());
   EXPECT_EQ(NightLightControllerImpl::AnimationDuration::kLong,
             controller->last_animation_duration());
@@ -685,7 +685,7 @@
 
   // Expect that the scheduled end delay has been updated, and the status hasn't
   // changed.
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(controller->GetColorTemperature());
   EXPECT_TRUE(controller->timer()->IsRunning());
   EXPECT_EQ(base::Hours(7), controller->timer()->GetCurrentDelay());
@@ -693,7 +693,7 @@
   // Simulate reaching sunrise.
   delegate()->SetFakeNow(TimeOfDay(3 * 60));  // Now is 5:00 AM.
   controller->timer()->FireNow();
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
   EXPECT_EQ(NightLightControllerImpl::AnimationDuration::kLong,
             controller->last_animation_duration());
@@ -737,7 +737,7 @@
 
   // Expect that timer is running and is scheduled at next custom start time.
   controller->SetScheduleType(ScheduleType::kCustom);
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
   EXPECT_TRUE(controller->timer()->IsRunning());
   EXPECT_EQ(base::Minutes(time_diff(fake_now, kCustom_Start)),
@@ -758,7 +758,7 @@
 
   // Expect the controller to enter night light mode and  the scheduled end
   // delay has been updated.
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(controller->GetColorTemperature());
   EXPECT_EQ(NightLightControllerImpl::AnimationDuration::kShort,
             controller->last_animation_duration());
@@ -774,7 +774,7 @@
 
   controller->SetCurrentGeoposition(
       SimpleGeoposition{kFakePosition1_Latitude, kFakePosition1_Longitude});
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
   EXPECT_EQ(NightLightControllerImpl::AnimationDuration::kShort,
             controller->last_animation_duration());
@@ -898,7 +898,7 @@
   controller->SetCustomEndTime(TimeOfDay(22 * 60));
   controller->SetScheduleType(ScheduleType::kCustom);
 
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
   EXPECT_TRUE(controller->timer()->IsRunning());
   // NightLight should start in 2 hours.
@@ -909,7 +909,7 @@
   delegate()->SetFakeNow(TimeOfDay(19 * 60));
   controller->SuspendDone(base::TimeDelta::Max());
 
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.4f);
   EXPECT_TRUE(controller->timer()->IsRunning());
   // NightLight should end in 3 hours.
@@ -939,7 +939,7 @@
   controller->SetCustomEndTime(TimeOfDay(6 * 60));
   controller->SetScheduleType(ScheduleType::kCustom);
 
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.4f);
   EXPECT_TRUE(controller->timer()->IsRunning());
   // NightLight should end in two hours.
@@ -964,7 +964,7 @@
   controller->SetCustomEndTime(TimeOfDay(4 * 60));
   controller->SetScheduleType(ScheduleType::kCustom);
 
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.0f);
   EXPECT_TRUE(controller->timer()->IsRunning());
   // NightLight should start in 15 hours.
@@ -989,7 +989,7 @@
   controller->SetCustomEndTime(TimeOfDay(4 * 60));
   controller->SetScheduleType(ScheduleType::kCustom);
 
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   TestCompositorsTemperature(0.4f);
   EXPECT_TRUE(controller->timer()->IsRunning());
   // NightLight should end in 5 hours.
@@ -1112,7 +1112,7 @@
   // enabled.
   auto verify_night_light_state = [controller](bool expected_status,
                                                float user_temperature) {
-    EXPECT_EQ(expected_status, controller->GetEnabled());
+    EXPECT_EQ(expected_status, controller->IsNightLightEnabled());
     TestCompositorsTemperature(expected_status ? user_temperature : 0.0f);
   };
 
@@ -1178,12 +1178,12 @@
   controller->SetCustomStartTime(MakeTimeOfDay(3, kPM));
   controller->SetCustomEndTime(MakeTimeOfDay(8, kPM));
   controller->SetScheduleType(ScheduleType::kCustom);
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
 
   // Toggle the status manually and expect that NightLight is scheduled to
   // turn back off at 8:00 PM.
   controller->Toggle();
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   EXPECT_TRUE(controller->timer()->IsRunning());
   EXPECT_EQ(base::Hours(9), controller->timer()->GetCurrentDelay());
 
@@ -1191,18 +1191,18 @@
   // custom schedule). However, the manual toggle to on should be kept.
   delegate()->SetFakeNow(MakeTimeOfDay(2, kPM));
   controller->SuspendDone(base::TimeDelta{});
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
 
   // Suspend again and resume at 5:00 PM (which is within the user's custom
   // schedule). The schedule should be applied normally.
   delegate()->SetFakeNow(MakeTimeOfDay(5, kPM));
   controller->SuspendDone(base::TimeDelta{});
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
 
   // Suspend and resume at 9:00 PM and expect NightLight to be off.
   delegate()->SetFakeNow(MakeTimeOfDay(9, kPM));
   controller->SuspendDone(base::TimeDelta{});
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
 }
 
 // Fixture for testing behavior of Night Light when displays support hardware
@@ -1638,7 +1638,7 @@
   // Simulate reaching sunset.
   delegate()->SetFakeNow(TimeOfDay(20 * 60));  // Now is 8:00 PM.
   controller->timer()->FireNow();
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   auto* notification = controller->GetAutoNightLightNotificationForTesting();
   ASSERT_TRUE(notification);
   ASSERT_TRUE(notification->delegate());
@@ -1649,13 +1649,13 @@
   notification->delegate()->Click(absl::nullopt, absl::nullopt);
   controller->SetEnabled(false,
                          NightLightControllerImpl::AnimationDuration::kShort);
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   EXPECT_FALSE(controller->GetAutoNightLightNotificationForTesting());
 
   // Simulate reaching next sunset. The notification should no longer show.
   delegate()->SetFakeNow(TimeOfDay(20 * 60));  // Now is 8:00 PM.
   controller->timer()->FireNow();
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   EXPECT_FALSE(controller->GetAutoNightLightNotificationForTesting());
 }
 
@@ -1671,7 +1671,7 @@
   // Simulate reaching sunset.
   delegate()->SetFakeNow(TimeOfDay(17 * 60));  // Now is 5:00 PM.
   controller->timer()->FireNow();
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   auto* notification = controller->GetAutoNightLightNotificationForTesting();
   ASSERT_TRUE(notification);
   ASSERT_TRUE(notification->delegate());
@@ -1682,14 +1682,14 @@
   // should not affect kAutoNightLightNotificationDismissed.
   controller->SetCurrentGeoposition(
       SimpleGeoposition{kFakePosition1_Latitude, kFakePosition1_Longitude});
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   EXPECT_FALSE(controller->GetAutoNightLightNotificationForTesting());
 
   // Simulate reaching next sunset. The notification should still show, since it
   // was never dismissed by the user.
   delegate()->SetFakeNow(TimeOfDay(20 * 60));  // Now is 8:00 PM.
   controller->timer()->FireNow();
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   EXPECT_TRUE(controller->GetAutoNightLightNotificationForTesting());
 }
 TEST_F(AutoNightLightTest, CannotDisableNotificationWhenSessionIsBlocked) {
@@ -1700,7 +1700,7 @@
   NightLightControllerImpl* controller = GetController();
   delegate()->SetFakeNow(TimeOfDay(20 * 60));  // Now is 8:00 PM.
   controller->timer()->FireNow();
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   auto* notification = controller->GetAutoNightLightNotificationForTesting();
   ASSERT_TRUE(notification);
   ASSERT_TRUE(notification->delegate());
@@ -1720,23 +1720,23 @@
   // Simulate reaching sunset.
   delegate()->SetFakeNow(TimeOfDay(20 * 60));  // Now is 8:00 PM.
   controller->timer()->FireNow();
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   EXPECT_FALSE(controller->GetAutoNightLightNotificationForTesting());
 }
 
 TEST_F(AutoNightLightTest, NoNotificationWhenManuallyEnabledFromSettings) {
   NightLightControllerImpl* controller = GetController();
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   user1_pref_service()->SetBoolean(prefs::kNightLightEnabled, true);
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   EXPECT_FALSE(controller->GetAutoNightLightNotificationForTesting());
 }
 
 TEST_F(AutoNightLightTest, NoNotificationWhenManuallyEnabledFromSystemMenu) {
   NightLightControllerImpl* controller = GetController();
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   controller->Toggle();
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   EXPECT_FALSE(controller->GetAutoNightLightNotificationForTesting());
 }
 
@@ -1761,7 +1761,7 @@
 
 TEST_F(AutoNightLightOnFirstLogin, NotifyOnFirstLogin) {
   NightLightControllerImpl* controller = GetController();
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   EXPECT_TRUE(controller->GetAutoNightLightNotificationForTesting());
 }
 
diff --git a/ash/system/night_light/night_light_feature_pod_controller.cc b/ash/system/night_light/night_light_feature_pod_controller.cc
index ff16b13..e09ee45 100644
--- a/ash/system/night_light/night_light_feature_pod_controller.cc
+++ b/ash/system/night_light/night_light_feature_pod_controller.cc
@@ -85,12 +85,12 @@
 void NightLightFeaturePodController::OnIconPressed() {
   TrackToggleUMA(/*target_toggle_state=*/!Shell::Get()
                      ->night_light_controller()
-                     ->GetEnabled());
+                     ->IsNightLightEnabled());
 
   Shell::Get()->night_light_controller()->Toggle();
   Update();
 
-  if (Shell::Get()->night_light_controller()->GetEnabled()) {
+  if (Shell::Get()->night_light_controller()->IsNightLightEnabled()) {
     base::RecordAction(
         base::UserMetricsAction("StatusArea_NightLight_Enabled"));
   } else {
@@ -131,7 +131,7 @@
 
 const std::u16string NightLightFeaturePodController::GetPodSubLabel() {
   auto* controller = Shell::Get()->night_light_controller();
-  const bool is_enabled = controller->GetEnabled();
+  const bool is_enabled = controller->IsNightLightEnabled();
   const ScheduleType schedule_type = controller->GetScheduleType();
   std::u16string sublabel;
   switch (schedule_type) {
@@ -177,7 +177,7 @@
 
 void NightLightFeaturePodController::UpdateButton() {
   auto* controller = Shell::Get()->night_light_controller();
-  const bool is_enabled = controller->GetEnabled();
+  const bool is_enabled = controller->IsNightLightEnabled();
   button_->SetToggled(is_enabled);
   button_->SetSubLabel(GetPodSubLabel());
 
@@ -190,7 +190,7 @@
 
 void NightLightFeaturePodController::UpdateTile() {
   auto* controller = Shell::Get()->night_light_controller();
-  const bool is_enabled = controller->GetEnabled();
+  const bool is_enabled = controller->IsNightLightEnabled();
   tile_->SetToggled(is_enabled);
   tile_->SetSubLabel(GetPodSubLabel());
 
diff --git a/ash/system/night_light/night_light_feature_pod_controller_unittest.cc b/ash/system/night_light/night_light_feature_pod_controller_unittest.cc
index 84f9865..3f8cb108 100644
--- a/ash/system/night_light/night_light_feature_pod_controller_unittest.cc
+++ b/ash/system/night_light/night_light_feature_pod_controller_unittest.cc
@@ -119,7 +119,7 @@
   NightLightControllerImpl* controller = Shell::Get()->night_light_controller();
   // Check that the feature pod button and its label reflects the default
   // Night light off without any auto scheduling.
-  EXPECT_FALSE(controller->GetEnabled());
+  EXPECT_FALSE(controller->IsNightLightEnabled());
   EXPECT_FALSE(IsButtonToggled());
   EXPECT_EQ(ScheduleType::kNone, controller->GetScheduleType());
   EXPECT_EQ(
@@ -129,7 +129,7 @@
   // Toggling the button should enable night light and update the button label
   // correctly and maintaining no scheduling.
   PressIcon();
-  EXPECT_TRUE(controller->GetEnabled());
+  EXPECT_TRUE(controller->IsNightLightEnabled());
   EXPECT_TRUE(IsButtonToggled());
   EXPECT_EQ(ScheduleType::kNone, controller->GetScheduleType());
   EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NIGHT_LIGHT_ON_STATE),
@@ -154,10 +154,10 @@
 
   // Pressing the night light button should switch the status but keep
   // sunset-to-sunrise scheduling.
-  bool enabled = controller->GetEnabled();
+  bool enabled = controller->IsNightLightEnabled();
   PressIcon();
   EXPECT_EQ(ScheduleType::kSunsetToSunrise, controller->GetScheduleType());
-  EXPECT_EQ(!enabled, controller->GetEnabled());
+  EXPECT_EQ(!enabled, controller->IsNightLightEnabled());
   EXPECT_EQ(!enabled, IsButtonToggled());
   EXPECT_EQ(!enabled ? sublabel_on : sublabel_off, GetButtonLabelText());
 
@@ -165,7 +165,7 @@
   // sunset-to-sunrise scheduling.
   PressIcon();
   EXPECT_EQ(ScheduleType::kSunsetToSunrise, controller->GetScheduleType());
-  EXPECT_EQ(enabled, controller->GetEnabled());
+  EXPECT_EQ(enabled, controller->IsNightLightEnabled());
   EXPECT_EQ(enabled, IsButtonToggled());
   EXPECT_EQ(enabled ? sublabel_on : sublabel_off, GetButtonLabelText());
 }
@@ -197,10 +197,10 @@
 
   // Pressing the night light button should switch the status and update the
   // label but keep the custom scheduling.
-  bool enabled = controller->GetEnabled();
+  bool enabled = controller->IsNightLightEnabled();
   PressIcon();
   EXPECT_EQ(ScheduleType::kCustom, controller->GetScheduleType());
-  EXPECT_EQ(!enabled, controller->GetEnabled());
+  EXPECT_EQ(!enabled, controller->IsNightLightEnabled());
   EXPECT_EQ(!enabled, IsButtonToggled());
   EXPECT_EQ(!enabled ? sublabel_on : sublabel_off, GetButtonLabelText());
 
@@ -208,7 +208,7 @@
   // label but keep the custom scheduling.
   PressIcon();
   EXPECT_EQ(ScheduleType::kCustom, controller->GetScheduleType());
-  EXPECT_EQ(enabled, controller->GetEnabled());
+  EXPECT_EQ(enabled, controller->IsNightLightEnabled());
   EXPECT_EQ(enabled, IsButtonToggled());
   EXPECT_EQ(enabled ? sublabel_on : sublabel_off, GetButtonLabelText());
 }
diff --git a/ash/system/notification_center/notification_center_test_api.cc b/ash/system/notification_center/notification_center_test_api.cc
index 77f242c..eb620b4 100644
--- a/ash/system/notification_center/notification_center_test_api.cc
+++ b/ash/system/notification_center/notification_center_test_api.cc
@@ -157,6 +157,24 @@
   return id;
 }
 
+std::string NotificationCenterTestApi::AddNotificationWithSettingsButton() {
+  const auto id = GenerateNotificationId();
+  auto notification = std::make_unique<message_center::Notification>(
+      message_center::NOTIFICATION_TYPE_SIMPLE, id, u"test_title",
+      u"test_message", /*icon=*/ui::ImageModel(),
+      /*display_source=*/base::EmptyString16(), GURL(),
+      message_center::NotifierId(), message_center::RichNotificationData(),
+      new message_center::NotificationDelegate());
+  // Setting this to a value other than the default
+  // `message_center::SettingsButtonHandler::NONE` makes the settings control
+  // button visible.
+  notification->set_settings_button_handler(
+      message_center::SettingsButtonHandler::DELEGATE);
+  message_center::MessageCenter::Get()->AddNotification(
+      std::move(notification));
+  return id;
+}
+
 void NotificationCenterTestApi::RemoveNotification(const std::string& id) {
   message_center::MessageCenter::Get()->RemoveNotification(id,
                                                            /*by_user=*/true);
diff --git a/ash/system/notification_center/notification_center_test_api.h b/ash/system/notification_center/notification_center_test_api.h
index 13c526b..72827d5c 100644
--- a/ash/system/notification_center/notification_center_test_api.h
+++ b/ash/system/notification_center/notification_center_test_api.h
@@ -105,6 +105,10 @@
   // Adds a progress notification and returns the associated id.
   std::string AddProgressNotification();
 
+  // Adds a notification that should have the settings control button visible
+  // and returns its id.
+  std::string AddNotificationWithSettingsButton();
+
   // Removes the notification associated with the provided id.
   void RemoveNotification(const std::string& id);
 
diff --git a/ash/system/progress_indicator/progress_indicator.cc b/ash/system/progress_indicator/progress_indicator.cc
index 7dec756..3aff66e 100644
--- a/ash/system/progress_indicator/progress_indicator.cc
+++ b/ash/system/progress_indicator/progress_indicator.cc
@@ -403,6 +403,48 @@
     InvalidateLayer();
 }
 
+void ProgressIndicator::SetInnerRingVisible(bool visible) {
+  if (inner_ring_visible_ == visible) {
+    return;
+  }
+
+  inner_ring_visible_ = visible;
+
+  // It's not necessary to invalidate the `layer()` if progress is complete
+  // since the inner ring is only painted while progress is incomplete.
+  if (progress_ != kProgressComplete) {
+    InvalidateLayer();
+  }
+}
+
+void ProgressIndicator::SetOuterRingTrackVisible(bool visible) {
+  if (outer_ring_track_visible_ == visible) {
+    return;
+  }
+
+  outer_ring_track_visible_ = visible;
+
+  // It's not necessary to invalidate the `layer()` if progress is complete
+  // since the progress ring track is only painted while progress is incomplete.
+  if (progress_ != kProgressComplete) {
+    InvalidateLayer();
+  }
+}
+
+void ProgressIndicator::SetOuterRingStrokeWidth(float width) {
+  if (outer_ring_stroke_width_ == width) {
+    return;
+  }
+
+  outer_ring_stroke_width_ = width;
+
+  // It's not necessary to invalidate the `layer()` if progress is complete
+  // since the outer ring is only painted while progress is incomplete.
+  if (progress_ != kProgressComplete) {
+    InvalidateLayer();
+  }
+}
+
 void ProgressIndicator::OnDeviceScaleFactorChanged(float old_scale,
                                                    float new_scale) {
   InvalidateLayer();
@@ -457,7 +499,8 @@
     canvas->SaveLayerAlpha(SK_AlphaOPAQUE * opacity);
   }
 
-  float outer_ring_stroke_width = GetOuterRingStrokeWidth(layer(), progress_);
+  float outer_ring_stroke_width = outer_ring_stroke_width_.value_or(
+      GetOuterRingStrokeWidth(layer(), progress_));
   gfx::RectF bounds(gfx::SizeF(layer()->size()));
   bounds.Inset(gfx::InsetsF(outer_ring_stroke_width / 2.f));
   SkPath path(CreateRoundedRectPath(
@@ -476,10 +519,16 @@
           : AshColorProvider::Get()->GetControlsLayerColor(
                 AshColorProvider::ControlsLayerType::kFocusRingColor);
 
-  // Outer ring.
   flags.setColor(SkColorSetA(
       color,
       SK_AlphaOPAQUE * GetOuterRingOpacity(progress_) * outer_ring_opacity));
+
+  // Outer ring track.
+  if (outer_ring_track_visible_) {
+    canvas->DrawPath(CreatePathSegment(path, 0.f, 1.0f), flags);
+  }
+
+  // Outer ring.
   if (start <= end) {
     // If `start` <= `end`, only a single path segment is necessary.
     canvas->DrawPath(CreatePathSegment(path, start, end), flags);
@@ -504,6 +553,7 @@
   }
 
   const bool inner_ring_visible =
+      inner_ring_visible_ &&
       !cc::MathUtil::IsWithinEpsilon(inner_ring_stroke_width, 0.f);
 
   // Inner ring.
diff --git a/ash/system/progress_indicator/progress_indicator.h b/ash/system/progress_indicator/progress_indicator.h
index 0298428..a3b7b15 100644
--- a/ash/system/progress_indicator/progress_indicator.h
+++ b/ash/system/progress_indicator/progress_indicator.h
@@ -68,6 +68,19 @@
   void SetInnerIconVisible(bool visible);
   bool inner_icon_visible() const { return inner_icon_visible_; }
 
+  // Sets the visibility for this progress indicator's inner ring. Note that
+  // the inner ring will only be painted while `progress_` is incomplete,
+  // regardless of the value of `visible` provided.
+  void SetInnerRingVisible(bool visible);
+
+  // Sets the visibility of the progress indicator's outer ring track. Note that
+  // the track will only be painted while `progress_` is incomplete, regardless
+  // of the value of `visible` provided.
+  void SetOuterRingTrackVisible(bool visible);
+
+  // Sets the width for this progress indicator's outer ring stroke.
+  void SetOuterRingStrokeWidth(float width);
+
   // Returns the underlying `animation_registry_` in which to look up animations
   // for the associated `animation_key_`. NOTE: This may return `nullptr`.
   ProgressIndicatorAnimationRegistry* animation_registry() {
@@ -176,6 +189,19 @@
   // inner icon will only be painted while `progress_` is incomplete, regardless
   // of this value.
   bool inner_icon_visible_ = true;
+
+  // Whether this progress indicator's inner ring is visible. Note that the
+  // inner ring will only be painted while `progress_` is incomplete, regardless
+  // of this value.
+  bool inner_ring_visible_ = true;
+
+  // Whether this progress indicator's outer ring track is visible. Note that
+  // the track will only be painted while `progress_` is incomplete, regardless
+  // of this value.
+  bool outer_ring_track_visible_ = false;
+
+  // The width for the outer ring stroke.
+  absl::optional<float> outer_ring_stroke_width_;
 };
 
 }  // namespace ash
diff --git a/ash/user_education/holding_space_tour/holding_space_tour_controller.cc b/ash/user_education/holding_space_tour/holding_space_tour_controller.cc
index f003e07..ca008f8 100644
--- a/ash/user_education/holding_space_tour/holding_space_tour_controller.cc
+++ b/ash/user_education/holding_space_tour/holding_space_tour_controller.cc
@@ -22,6 +22,7 @@
 #include "ash/shell.h"
 #include "ash/system/holding_space/holding_space_tray.h"
 #include "ash/system/status_area_widget.h"
+#include "ash/user_education/holding_space_tour/holding_space_tour_prefs.h"
 #include "ash/user_education/user_education_help_bubble_controller.h"
 #include "ash/user_education/user_education_ping_controller.h"
 #include "ash/user_education/user_education_types.h"
@@ -129,6 +130,28 @@
       ->wallpaper_view();
 }
 
+// Indicates whether the tour should be shown based on when it was last shown
+// and how many times total it's been shown. It should be no more than once
+// in a 24 hour period, and no more than 3 times total.
+bool TourShouldBeShown() {
+  if (!features::IsHoldingSpaceTourRateLimitingEnabled()) {
+    return true;
+  }
+
+  PrefService* const prefs =
+      Shell::Get()->session_controller()->GetLastActiveUserPrefService();
+  const auto time_of_last_tour =
+      holding_space_tour_prefs::GetLastTimeTourWasShown(prefs);
+  const auto tour_shown_count =
+      holding_space_tour_prefs::GetTourShownCount(prefs);
+
+  bool tour_shown_recently =
+      time_of_last_tour.has_value() &&
+      base::Time::Now() - time_of_last_tour.value() < base::Hours(24);
+
+  return tour_shown_count < 3u && !tour_shown_recently;
+}
+
 // Highlight -------------------------------------------------------------------
 
 // A class which adds a highlight layer to the region above the associated
@@ -354,10 +377,10 @@
     Shelf* shelf = GetShelfNearestPoint(location_in_screen.value());
     CHECK(shelf);
 
-    // Ensure the shelf is visible on the active display while the observed
-    // drag-and-drop sequence is in progress.
-    if (!disable_shelf_auto_hide_ ||
-        (disable_shelf_auto_hide_->weak_shelf() != shelf)) {
+    // If the shelf is currently being force-shown on the wrong display (i.e.
+    // the file has been dragged to a new display), switch to the correct one.
+    if (disable_shelf_auto_hide_ &&
+        disable_shelf_auto_hide_->weak_shelf() != shelf) {
       disable_shelf_auto_hide_ =
           std::make_unique<Shelf::ScopedDisableAutoHide>(shelf);
     }
@@ -369,9 +392,19 @@
           std::make_unique<HoldingSpaceController::ScopedForceShowInShelf>();
     }
 
+    if (!TourShouldBeShown()) {
+      return;
+    }
+
+    // Ensure the shelf is visible on the active display while the observed
+    // drag-and-drop sequence is in progress.
+    if (!disable_shelf_auto_hide_) {
+      disable_shelf_auto_hide_ =
+          std::make_unique<Shelf::ScopedDisableAutoHide>(shelf);
+    }
+
     // Cache the `holding_space_tray` nearest the `location_in_screen` so that
     // we can show an associated help bubble.
-    // TODO(http://b/283169466): Rate limit showing the help bubble.
     HoldingSpaceTray* const holding_space_tray =
         GetHoldingSpaceTrayNearestPoint(location_in_screen.value());
 
@@ -401,6 +434,9 @@
                 views::ElementTrackerViews::GetContextForView(
                     holding_space_tray),
                 std::move(close_callback))) {
+      holding_space_tour_prefs::MarkTourShown(
+          Shell::Get()->session_controller()->GetLastActiveUserPrefService());
+
       // If we successfully created a help bubble, then it is safe to replace
       // the current `base::ScopedClosureRunner` because any previous help
       // bubbles have already closed.
diff --git a/ash/user_education/holding_space_tour/holding_space_tour_controller_unittest.cc b/ash/user_education/holding_space_tour/holding_space_tour_controller_unittest.cc
index 9b99139..25deb93 100644
--- a/ash/user_education/holding_space_tour/holding_space_tour_controller_unittest.cc
+++ b/ash/user_education/holding_space_tour/holding_space_tour_controller_unittest.cc
@@ -43,6 +43,7 @@
 #include "base/strings/strcat.h"
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
+#include "base/timer/timer.h"
 #include "base/values.h"
 #include "components/account_id/account_id.h"
 #include "components/user_education/views/help_bubble_views_test_util.h"
@@ -235,54 +236,38 @@
 // HoldingSpaceTourControllerTest ----------------------------------------------
 
 // Base class for tests of the `HoldingSpaceTourController`.
-class HoldingSpaceTourControllerTest : public UserEducationAshTestBase {
+class HoldingSpaceTourControllerTestBase : public UserEducationAshTestBase {
  public:
-  explicit HoldingSpaceTourControllerTest(
-      absl::optional<bool> drop_to_pin_enabled) {
+  HoldingSpaceTourControllerTestBase(
+      absl::optional<bool> drop_to_pin_enabled,
+      bool rate_limiting_enabled,
+      base::test::TaskEnvironment::TimeSource time_source)
+      : UserEducationAshTestBase(time_source) {
     // NOTE: The `HoldingSpaceTourController` exists only when the Holding Space
     // Tour feature is enabled. Controller existence is verified in test
     // coverage for the controller's owner.
+    std::vector<base::test::FeatureRefAndParams> enabled;
+    std::vector<base::test::FeatureRef> disabled;
+
     if (drop_to_pin_enabled.has_value()) {
-      scoped_feature_list_.InitAndEnableFeatureWithParameters(
+      enabled.push_back(base::test::FeatureRefAndParams(
           features::kHoldingSpaceTour,
-          {{"drop-to-pin", drop_to_pin_enabled.value() ? "true" : "false"}});
+          {{"drop-to-pin", drop_to_pin_enabled.value() ? "true" : "false"}}));
     } else {
-      scoped_feature_list_.InitAndEnableFeature(features::kHoldingSpaceTour);
+      enabled.emplace_back(features::kHoldingSpaceTour,
+                           base::FieldTrialParams());
     }
+
+    if (rate_limiting_enabled) {
+      disabled.emplace_back(features::kHoldingSpaceTourIgnoreRateLimiting);
+    } else {
+      enabled.emplace_back(features::kHoldingSpaceTourIgnoreRateLimiting,
+                           base::FieldTrialParams());
+    }
+
+    scoped_feature_list_.InitWithFeaturesAndParameters(enabled, disabled);
   }
 
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-// HoldingSpaceTourControllerDragAndDropTest -----------------------------------
-
-// Base class for drag-and-drop tests of the `HoldingSpaceTourController`,
-// parameterized by (a) whether the drop-to-pin param is available and enabled,
-// (b) whether to drag Files app data, and (c) whether to complete the drop (as
-// opposed to cancelling it).
-class HoldingSpaceTourControllerDragAndDropTest
-    : public HoldingSpaceTourControllerTest,
-      public testing::WithParamInterface<
-          std::tuple</*drop_to_pin_enabled=*/absl::optional<bool>,
-                     /*drag_files_app_data=*/bool,
-                     /*complete_drop=*/bool>> {
- public:
-  HoldingSpaceTourControllerDragAndDropTest()
-      : HoldingSpaceTourControllerTest(drop_to_pin_enabled()) {}
-
-  // Whether the drop-to-pin feature param is enabled.
-  absl::optional<bool> drop_to_pin_enabled() const {
-    return std::get<0>(GetParam());
-  }
-
-  // Whether to drag Files app data given test parameterization.
-  bool drag_files_app_data() const { return std::get<1>(GetParam()); }
-
-  // Whether to complete the drop (as opposed to cancelling it) given test
-  // parameterization.
-  bool complete_drop() const { return std::get<2>(GetParam()); }
-
   // Moves the mouse to the center of the specified `widget`.
   void MoveMouseTo(views::Widget* widget) {
     GetEventGenerator()->MoveMouseTo(
@@ -327,9 +312,9 @@
   }
 
  private:
-  // HoldingSpaceTourControllerTest:
+  // UserEducationAshTestBase:
   void SetUp() override {
-    HoldingSpaceTourControllerTest::SetUp();
+    UserEducationAshTestBase::SetUp();
 
     // Prevent blocking during drag-and-drop sequences.
     ShellTestApi().drag_drop_controller()->SetDisableNestedLoopForTesting(true);
@@ -373,6 +358,8 @@
             }));
   }
 
+  base::test::ScopedFeatureList scoped_feature_list_;
+
   // Used to mock help bubble creation given that user education services in
   // the browser are non-existent for unit tests in Ash.
   user_education::test::TestHelpBubbleDelegate help_bubble_delegate_;
@@ -388,6 +375,38 @@
       scoped_animation_duration_scale_mode_;
 };
 
+// HoldingSpaceTourControllerDragAndDropTest -----------------------------------
+
+// Base class for drag-and-drop tests of the `HoldingSpaceTourController`,
+// parameterized by (a) whether the drop-to-pin param is available and enabled,
+// (b) whether to drag Files app data, and (c) whether to complete the drop (as
+// opposed to cancelling it).
+class HoldingSpaceTourControllerDragAndDropTest
+    : public HoldingSpaceTourControllerTestBase,
+      public testing::WithParamInterface<
+          std::tuple</*drop_to_pin_enabled=*/absl::optional<bool>,
+                     /*drag_files_app_data=*/bool,
+                     /*complete_drop=*/bool>> {
+ public:
+  HoldingSpaceTourControllerDragAndDropTest()
+      : HoldingSpaceTourControllerTestBase(
+            drop_to_pin_enabled(),
+            /*rate_limiting_enabled=*/false,
+            base::test::TaskEnvironment::TimeSource::SYSTEM_TIME) {}
+
+  // Whether the drop-to-pin feature param is enabled.
+  absl::optional<bool> drop_to_pin_enabled() const {
+    return std::get<0>(GetParam());
+  }
+
+  // Whether to drag Files app data given test parameterization.
+  bool drag_files_app_data() const { return std::get<1>(GetParam()); }
+
+  // Whether to complete the drop (as opposed to cancelling it) given test
+  // parameterization.
+  bool complete_drop() const { return std::get<2>(GetParam()); }
+};
+
 INSTANTIATE_TEST_SUITE_P(
     All,
     HoldingSpaceTourControllerDragAndDropTest,
@@ -632,4 +651,153 @@
       account_id, /*client=*/nullptr, /*model=*/nullptr);
 }
 
+// HoldingSpaceTourControllerRateLimitingTest ----------------------------------
+
+// Base class for tests that verify the Holding Space Tour is properly rate
+// limited to avoid spamming the user.
+class HoldingSpaceTourControllerRateLimitingTest
+    : public HoldingSpaceTourControllerTestBase,
+      public testing::WithParamInterface<
+          /*drop_to_pin_enabled=*/absl::optional<bool>> {
+ public:
+  HoldingSpaceTourControllerRateLimitingTest()
+      : HoldingSpaceTourControllerTestBase(
+            drop_to_pin_enabled(),
+            /*rate_limiting_enabled=*/true,
+            base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
+
+  // Whether the drop-to-pin feature param is enabled.
+  absl::optional<bool> drop_to_pin_enabled() const { return GetParam(); }
+};
+
+INSTANTIATE_TEST_SUITE_P(All,
+                         HoldingSpaceTourControllerRateLimitingTest,
+                         testing::Values(absl::nullopt, false, true));
+
+// Tests -----------------------------------------------------------------------
+
+// Verifies that the Holding Space Tour is only shown once per day, and a
+// maximum total of three times.
+TEST_P(HoldingSpaceTourControllerRateLimitingTest, RateLimiting) {
+  const int64_t display_id = GetPrimaryDisplay().id();
+
+  // Log in a regular user.
+  const AccountId& account_id = AccountId::FromUserEmail("user@test");
+  SimulateUserLogin(account_id);
+
+  // Register a model and client for holding space.
+  HoldingSpaceModel holding_space_model;
+  testing::StrictMock<MockHoldingSpaceClient> holding_space_client;
+  HoldingSpaceController::Get()->RegisterClientAndModelForUser(
+      account_id, &holding_space_client, &holding_space_model);
+
+  // Configure the client to crack file system URLs.
+  EXPECT_CALL(holding_space_client, CrackFileSystemUrl)
+      .WillRepeatedly(Invoke([](const GURL& file_system_url) {
+        return base::FilePath(base::StrCat(
+            {"//path/to/", std::string(&file_system_url.spec().back())}));
+      }));
+
+  // Create and show a widget from which data can be drag-and-dropped.
+  auto widget = CreateTestWidgetForDisplayId(display_id);
+  widget->SetContentsView(std::make_unique<DraggableView>(
+      base::BindLambdaForTesting([&](ui::OSExchangeData* data) {
+        data->SetString(u"Payload");
+        SetFilesAppData(data, u"file-system:a\nfile-system:b");
+      })));
+  widget->CenterWindow(gfx::Size(100, 100));
+  widget->Show();
+
+  auto* const shelf = GetShelfForDisplayId(display_id);
+  auto* const tray = GetHoldingSpaceTrayForShelf(shelf);
+
+  // Autohide the shelf so that the shelf visibility behavior can be verified.
+  shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
+  EXPECT_FALSE(shelf->IsVisible());
+  EXPECT_FALSE(tray->GetVisible());
+
+  for (size_t day = 0; day < 3; ++day) {
+    // Ensure a non-zero animation duration so there is sufficient time to
+    // detect pings before they are automatically destroyed on animation
+    // completion.
+    SetAnimationDurationMultiplier(
+        ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
+
+    // Drag data from the `widget` to the wallpaper.
+    MoveMouseTo(widget.get());
+    PressLeftButton();
+    MoveMouseBy(/*x=*/widget->GetWindowBoundsInScreen().width(), /*y=*/0);
+
+    // Expect the holding space tray to have a help bubble and a ping.
+    EXPECT_TRUE(HasHelpBubble(tray));
+    EXPECT_TRUE(HasPing(tray));
+
+    // The shelf and holding space tray should show if the tour is showing.
+    EXPECT_TRUE(shelf->IsVisible());
+    EXPECT_TRUE(tray->GetVisible());
+
+    // The wallpaper highlight should also show if drop-to-pin is enabled.
+    EXPECT_EQ(HasWallpaperHighlight(display_id),
+              drop_to_pin_enabled().value_or(false));
+
+    // Reset the UI state, using zero-scaled animations to save time.
+    SetAnimationDurationMultiplier(
+        ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
+    PressAndReleaseKey(ui::VKEY_ESCAPE);
+    ReleaseLeftButton();
+    WaitForHelpBubbleClose();
+    FlushMessageLoop();
+
+    // Drag data again, now that the tour has already been shown recently.
+    SetAnimationDurationMultiplier(
+        ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
+    MoveMouseTo(widget.get());
+    PressLeftButton();
+    MoveMouseBy(/*x=*/widget->GetWindowBoundsInScreen().width(), /*y=*/0);
+
+    // Now the tour should not be shown, as it was shown in the last 24 hours.
+    EXPECT_FALSE(HasHelpBubble(tray));
+    EXPECT_FALSE(HasPing(tray));
+
+    // The shelf should be hidden if the tour is not showing, but the tray
+    // should always be visible so users can use the holding space after
+    // learning about it.
+    EXPECT_FALSE(shelf->IsVisible());
+    EXPECT_TRUE(tray->GetVisible());
+
+    // Even if not showing the tour, the wallpaper highlight should be shown if
+    // drop-to-pin is enabled.
+    EXPECT_EQ(HasWallpaperHighlight(display_id),
+              drop_to_pin_enabled().value_or(false));
+
+    // Reset the UI state, using zero-scaled animations to save time.
+    SetAnimationDurationMultiplier(
+        ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
+    PressAndReleaseKey(ui::VKEY_ESCAPE);
+    ReleaseLeftButton();
+    FlushMessageLoop();
+
+    // Every 24 hours, it should be possible for the tour to show again once.
+    task_environment()->AdvanceClock(base::Hours(24));
+  }
+
+  // After the 3rd time, the tour should not show again even after 24 hours.
+  SetAnimationDurationMultiplier(
+      ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
+  MoveMouseTo(widget.get());
+  PressLeftButton();
+  MoveMouseBy(/*x=*/widget->GetWindowBoundsInScreen().width(), /*y=*/0);
+
+  EXPECT_FALSE(HasHelpBubble(tray));
+  EXPECT_FALSE(HasPing(tray));
+  EXPECT_FALSE(shelf->IsVisible());
+  EXPECT_TRUE(tray->GetVisible());
+  EXPECT_EQ(HasWallpaperHighlight(display_id),
+            drop_to_pin_enabled().value_or(false));
+
+  // Clean up holding space controller.
+  HoldingSpaceController::Get()->RegisterClientAndModelForUser(
+      account_id, /*client=*/nullptr, /*model=*/nullptr);
+}
+
 }  // namespace ash
diff --git a/ash/user_education/user_education_ash_test_base.cc b/ash/user_education/user_education_ash_test_base.cc
index d7d49db..e957c8d 100644
--- a/ash/user_education/user_education_ash_test_base.cc
+++ b/ash/user_education/user_education_ash_test_base.cc
@@ -47,6 +47,10 @@
 
 // UserEducationAshTestBase ----------------------------------------------------
 
+UserEducationAshTestBase::UserEducationAshTestBase(
+    base::test::TaskEnvironment::TimeSource time_source)
+    : NoSessionAshTestBase(time_source) {}
+
 void UserEducationAshTestBase::SetUp() {
   // Mock the `user_education_delegate_`.
   auto shell_delegate = std::make_unique<TestShellDelegate>();
diff --git a/ash/user_education/user_education_ash_test_base.h b/ash/user_education/user_education_ash_test_base.h
index 5ab3cf7..eed1f4af 100644
--- a/ash/user_education/user_education_ash_test_base.h
+++ b/ash/user_education/user_education_ash_test_base.h
@@ -18,6 +18,11 @@
 // * Installs a `MockUserEducationDelegate` during `SetUp()`.
 // * Does NOT add user sessions during `SetUp()`.
 class UserEducationAshTestBase : public NoSessionAshTestBase {
+ public:
+  explicit UserEducationAshTestBase(
+      base::test::TaskEnvironment::TimeSource time_source =
+          base::test::TaskEnvironment::TimeSource::SYSTEM_TIME);
+
  protected:
   // NoSessionAshTestBase:
   void SetUp() override;
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc
index e7062cd..122645d 100644
--- a/ash/wallpaper/wallpaper_controller_unittest.cc
+++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -58,6 +58,8 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_callback.h"
 #include "base/test/scoped_feature_list.h"
+#include "base/test/simple_test_clock.h"
+#include "base/test/simple_test_tick_clock.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_future.h"
 #include "base/threading/thread_restrictions.h"
@@ -5554,7 +5556,81 @@
   EXPECT_EQ(WallpaperType::kDefault, current_info.type);
 }
 
-TEST_P(WallpaperControllerTest,
+class WallpaperControllerDailyRefreshSchedulerTest
+    : public WallpaperControllerTest,
+      public ScheduledFeature::Clock {
+ public:
+  WallpaperControllerDailyRefreshSchedulerTest() {
+    base::Time start_time = base::Time::Now();
+    clock_.SetNow(start_time);
+    tick_clock_.SetNowTicks(base::TimeTicks() + (start_time - base::Time()));
+  }
+
+  void SetUp() override {
+    WallpaperControllerTest::SetUp();
+
+    auto daily_refresh_scheduler =
+        controller_->daily_refresh_scheduler_for_testing();
+    // Disable any running timers to set a fake clock.
+    daily_refresh_scheduler->SetScheduleType(ScheduleType::kNone);
+    daily_refresh_scheduler->SetClockForTesting(this);
+    daily_refresh_scheduler->SetScheduleType(ScheduleType::kCustom);
+  }
+
+  void TearDown() override { WallpaperControllerTest::TearDown(); }
+
+  // ScheduledFeature::Clock:
+  base::Time Now() const override { return clock_.Now(); }
+
+  base::TimeTicks NowTicks() const override { return tick_clock_.NowTicks(); }
+
+  // Returns whether the total triggered a checkpoint change. This method only
+  // triggers the checkpoints and does not run any tasks.
+  bool AdvanceClock(base::TimeDelta total) {
+    const auto advance_time = [this](base::TimeDelta advancement) {
+      clock_.Advance(advancement);
+      tick_clock_.Advance(advancement);
+    };
+
+    bool checkpoint_reached = false;
+    auto* timer = Shell::Get()
+                      ->wallpaper_controller()
+                      ->daily_refresh_scheduler_for_testing()
+                      ->timer();
+    while (total.is_positive()) {
+      base::TimeDelta advance_increment;
+      if (timer->IsRunning() &&
+          timer->desired_run_time() <= NowTicks() + total) {
+        // Emulates the internal timer firing at its scheduled time.
+        advance_increment = timer->desired_run_time() - NowTicks();
+        advance_time(advance_increment);
+        timer->FireNow();
+        checkpoint_reached = true;
+      } else {
+        advance_increment = total;
+        advance_time(advance_increment);
+      }
+      CHECK_LE(advance_increment, total);
+      total -= advance_increment;
+    }
+    return checkpoint_reached;
+  }
+
+ private:
+  base::SimpleTestClock clock_;
+  base::SimpleTestTickClock tick_clock_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    // Empty to simplify gtest output
+    ,
+    WallpaperControllerDailyRefreshSchedulerTest,
+    ::testing::Values(JellyFeatureCombination::kDisabled,
+                      JellyFeatureCombination::kEnabled,
+                      JellyFeatureCombination::kEnabledWithTimeOfDay),
+    WallpaperControllerTest::PrintToStringParamName());
+
+TEST_P(WallpaperControllerDailyRefreshSchedulerTest,
        OnCheckpointChanged_WallpaperDailyRefreshScheduler) {
   TestWallpaperControllerObserver observer(controller_);
   EXPECT_EQ(0, observer.daily_refresh_checkpoint_count());
@@ -5564,13 +5640,13 @@
   SimulateUserLogin(kAccountId1);
   // Clears signal on login.
   observer.ClearDailyRefreshCheckpointCount();
-  task_environment()->FastForwardBy(base::Days(1));
+  EXPECT_TRUE(AdvanceClock(base::Days(1)));
   // Expect that 2 signals are sent every day by WallpaperDailyRefreshScheduler.
   EXPECT_EQ(2, observer.daily_refresh_checkpoint_count());
 }
 
-TEST_P(WallpaperControllerTest,
-       OnCheckpointChanged_CalledOnLogin_WallpaperDailyRefreshScheduler) {
+TEST_P(WallpaperControllerDailyRefreshSchedulerTest,
+       OnCheckpointChanged_CalledOnLogin) {
   TestWallpaperControllerObserver observer(controller_);
   EXPECT_EQ(0, observer.daily_refresh_checkpoint_count());
   // User's wallpaper info should exist.
@@ -5584,9 +5660,8 @@
   EXPECT_GE(observer.daily_refresh_checkpoint_count(), 1);
 }
 
-TEST_P(
-    WallpaperControllerTest,
-    SetDailyRefreshCollectionId_UpdatesCheckTimes_WallpaperDailyRefreshScheduler) {
+TEST_P(WallpaperControllerDailyRefreshSchedulerTest,
+       SetDailyRefreshCollectionId_UpdatesCheckTimes) {
   auto daily_refresh_scheduler =
       controller_->daily_refresh_scheduler_for_testing();
   auto first_check_time = daily_refresh_scheduler->GetCustomStartTime();
@@ -5612,9 +5687,8 @@
   EXPECT_NE(second_check_time, daily_refresh_scheduler->GetCustomEndTime());
 }
 
-TEST_P(
-    WallpaperControllerTest,
-    SetGooglePhotosDailyRefreshAlbumId_UpdatesCheckTimes_WallpaperDailyRefreshScheduler) {
+TEST_P(WallpaperControllerDailyRefreshSchedulerTest,
+       SetGooglePhotosDailyRefreshAlbumId_UpdatesCheckTimes) {
   auto daily_refresh_scheduler =
       controller_->daily_refresh_scheduler_for_testing();
   auto first_check_time = daily_refresh_scheduler->GetCustomStartTime();
@@ -5638,8 +5712,8 @@
   EXPECT_NE(second_check_time, daily_refresh_scheduler->GetCustomEndTime());
 }
 
-TEST_P(WallpaperControllerTest,
-       UpdateDailyRefreshWallpaper_OnLogin_WallpaperDailyRefreshScheduler) {
+TEST_P(WallpaperControllerDailyRefreshSchedulerTest,
+       UpdateDailyRefreshWallpaper_OnLogin) {
   base::test::ScopedFeatureList feature_list(features::kWallpaperRefreshRevamp);
   SimulateUserLogin(kAccountId1);
 
@@ -5658,7 +5732,7 @@
 
   // Info is set as over a day old so we expect one task to run in under an hour
   // (due to fuzzing) then it will idle.
-  task_environment()->FastForwardBy(base::Hours(1));
+  AdvanceClock(base::Hours(1));
   // Make sure all the tasks such as syncing, setting wallpaper complete.
   RunAllTasksUntilIdle();
 
@@ -5666,9 +5740,8 @@
             client_.get_fetch_daily_refresh_wallpaper_param());
 }
 
-TEST_P(
-    WallpaperControllerTest,
-    UpdateDailyRefreshWallpaper_OnCheckpointChanged_WallpaperDailyRefreshScheduler) {
+TEST_P(WallpaperControllerDailyRefreshSchedulerTest,
+       UpdateDailyRefreshWallpaper_OnCheckpointChanged) {
   base::test::ScopedFeatureList feature_list(features::kWallpaperRefreshRevamp);
   auto images = ImageSet();
   std::string collection_id{"my_wallpaper_collection"};
@@ -5697,7 +5770,8 @@
   EXPECT_EQ(WallpaperType::kDaily, wallpaper_info_1.type);
 
   // Forward time to trigger checkpoints.
-  task_environment()->FastForwardBy(base::Hours(25));
+  EXPECT_TRUE(AdvanceClock(base::Hours(25)));
+  RunAllTasksUntilIdle();
 
   WallpaperInfo wallpaper_info_2;
   ASSERT_TRUE(
@@ -5708,9 +5782,8 @@
   EXPECT_EQ(WallpaperType::kDaily, wallpaper_info_2.type);
 }
 
-TEST_P(
-    WallpaperControllerTest,
-    CheckGooglePhotosStaleness_OnCheckpointChanged_WallpaperDailyRefreshScheduler) {
+TEST_P(WallpaperControllerDailyRefreshSchedulerTest,
+       CheckGooglePhotosStaleness_OnCheckpointChanged) {
   base::test::ScopedFeatureList feature_list(features::kWallpaperRefreshRevamp);
   SimulateUserLogin(kAccountId1);
 
@@ -5721,7 +5794,8 @@
   client_.set_google_photo_has_been_deleted(true);
 
   // Forward time to trigger checkpoints.
-  task_environment()->FastForwardBy(base::Hours(25));
+  EXPECT_TRUE(AdvanceClock(base::Hours(25)));
+  RunAllTasksUntilIdle();
 
   EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kDefault);
 }
diff --git a/ash/webui/common/resources/cellular_setup/confirmation_code_page.js b/ash/webui/common/resources/cellular_setup/confirmation_code_page.js
index 44f64bc..91652af 100644
--- a/ash/webui/common/resources/cellular_setup/confirmation_code_page.js
+++ b/ash/webui/common/resources/cellular_setup/confirmation_code_page.js
@@ -40,14 +40,6 @@
     showError: {
       type: Boolean,
     },
-
-    /**
-     * Indicates the UI is busy with an operation and cannot be interacted with.
-     */
-    showBusy: {
-      type: Boolean,
-      value: false,
-    },
   },
 
   /**
diff --git a/ash/webui/common/resources/cellular_setup/esim_flow_ui.html b/ash/webui/common/resources/cellular_setup/esim_flow_ui.html
index 41b98c997..b80b44ef 100644
--- a/ash/webui/common/resources/cellular_setup/esim_flow_ui.html
+++ b/ash/webui/common/resources/cellular_setup/esim_flow_ui.html
@@ -17,8 +17,7 @@
       if="[[smdsSupportEnabled_]]" restamp>
       <profile-discovery-list-page id="profileDiscoveryPage"
           pending-profile-properties="[[pendingProfileProperties_]]"
-          selected-profile-properties="{{selectedProfileProperties_}}"
-          show-busy="[[shouldShowSubpageBusy_(state_)]]">
+          selected-profile-properties="{{selectedProfileProperties_}}">
       </profile-discovery-list-page>
   </template>
   <template is="dom-if"
@@ -42,8 +41,7 @@
       <confirmation-code-page id="confirmationCodePage"
           confirmation-code="{{confirmationCode_}}"
           profile-properties="[[selectedProfileProperties_]]"
-          show-error="{{showError_}}"
-          show-busy="[[shouldShowSubpageBusy_(state_)]]">
+          show-error="{{showError_}}">
       </confirmation-code-page>
   </template>
   <template is="dom-if"
diff --git a/ash/webui/common/resources/cellular_setup/esim_flow_ui.js b/ash/webui/common/resources/cellular_setup/esim_flow_ui.js
index 296782d..5d0966c 100644
--- a/ash/webui/common/resources/cellular_setup/esim_flow_ui.js
+++ b/ash/webui/common/resources/cellular_setup/esim_flow_ui.js
@@ -547,7 +547,7 @@
       enableForwardBtn, cancelButtonStateIfEnabled, isInstalling) {
     this.forwardButtonLabel = this.i18n('next');
     let backBtnState = ButtonState.HIDDEN;
-    if (this.profilesFound_()) {
+    if (this.profilesFound_() && !this.smdsSupportEnabled_) {
       backBtnState = isInstalling ? ButtonState.DISABLED : ButtonState.ENABLED;
     }
     return {
@@ -567,8 +567,12 @@
   generateButtonStateForConfirmationPage_(
       enableForwardBtn, cancelButtonStateIfEnabled, isInstalling) {
     this.forwardButtonLabel = this.i18n('confirm');
+    let backBtnState = isInstalling ? ButtonState.DISABLED : ButtonState.ENABLED;
+    if (this.smdsSupportEnabled_) {
+      backBtnState = ButtonState.HIDDEN;
+    }
     return {
-      backward: isInstalling ? ButtonState.DISABLED : ButtonState.ENABLED,
+      backward: backBtnState,
       cancel: cancelButtonStateIfEnabled,
       forward: enableForwardBtn ? ButtonState.ENABLED : ButtonState.DISABLED,
     };
diff --git a/ash/webui/common/resources/cellular_setup/profile_discovery_list_item.html b/ash/webui/common/resources/cellular_setup/profile_discovery_list_item.html
index 96fb9378..33c30ab 100644
--- a/ash/webui/common/resources/cellular_setup/profile_discovery_list_item.html
+++ b/ash/webui/common/resources/cellular_setup/profile_discovery_list_item.html
@@ -47,12 +47,6 @@
     #checkmark {
       --iron-icon-fill-color: var(--cros-icon-color-prominent);
     }
-
-    paper-spinner-lite {
-      height: 16px;
-      vertical-align: middle;
-      width: 16px;
-    }
 </style>
 <div id="container" class="flex layout horizontal center" selectable>
   <div id="details">
@@ -67,12 +61,7 @@
       hidden$="[[!selected]]">
     <iron-icon id="checkmark"
         icon="cellular-setup:checked"
-        tabindex="-1"
-        hidden$="[[showLoadingIndicator]]">
+        tabindex="-1">
     </iron-icon>
-    <!-- TODO(b/281904820): Remove me. -->
-    <paper-spinner-lite active
-        hidden$="[[!showLoadingIndicator]]">
-    </paper-spinner-lite>
   </div>
 </div>
diff --git a/ash/webui/common/resources/cellular_setup/profile_discovery_list_item.js b/ash/webui/common/resources/cellular_setup/profile_discovery_list_item.js
index 7494a2e..fbcc015 100644
--- a/ash/webui/common/resources/cellular_setup/profile_discovery_list_item.js
+++ b/ash/webui/common/resources/cellular_setup/profile_discovery_list_item.js
@@ -42,11 +42,6 @@
       reflectToAttribute: true,
     },
 
-    /** TODO(b/281904820): Remove me. */
-    showLoadingIndicator: {
-      type: Boolean,
-    },
-
     /**
      * @type {boolean}
      * @private
diff --git a/ash/webui/common/resources/cellular_setup/profile_discovery_list_page.html b/ash/webui/common/resources/cellular_setup/profile_discovery_list_page.html
index fee9aa1fd..793fcedd 100644
--- a/ash/webui/common/resources/cellular_setup/profile_discovery_list_page.html
+++ b/ash/webui/common/resources/cellular_setup/profile_discovery_list_page.html
@@ -26,8 +26,8 @@
       <div id="container" class="layout vertical flex" scrollable>
         <iron-list id="profileList" items="[[pendingProfileProperties]]"
             scroll-target="container"
-            selection-enabled="[[!showBusy]]"
             preserve-focus
+            selection-enabled
             selected-item="{{selectedProfileProperties}}"
             role="listbox">
           <template>
@@ -35,8 +35,7 @@
                 selected="[[isProfilePropertiesSelected_(item, selectedProfileProperties)]]"
                 tabindex="0"
                 role="option"
-                aria-selected="[[isProfilePropertiesSelected_(item, selectedProfileProperties)]]"
-                show-loading-indicator="[[showBusy]]">
+                aria-selected="[[isProfilePropertiesSelected_(item, selectedProfileProperties)]]">
             </profile-discovery-list-item>
           </template>
         </iron-list>
diff --git a/ash/webui/common/resources/cellular_setup/profile_discovery_list_page.js b/ash/webui/common/resources/cellular_setup/profile_discovery_list_page.js
index d0283116..047ea241 100644
--- a/ash/webui/common/resources/cellular_setup/profile_discovery_list_page.js
+++ b/ash/webui/common/resources/cellular_setup/profile_discovery_list_page.js
@@ -42,14 +42,6 @@
       type: Object,
       notify: true,
     },
-
-    /**
-     * Indicates the UI is busy with an operation and cannot be interacted with.
-     */
-    showBusy: {
-      type: Boolean,
-      value: false,
-    },
   },
 
   /**
diff --git a/ash/webui/common/resources/network/apn_detail_dialog.html b/ash/webui/common/resources/network/apn_detail_dialog.html
index 0b2f1c9e..4b5cbce 100644
--- a/ash/webui/common/resources/network/apn_detail_dialog.html
+++ b/ash/webui/common/resources/network/apn_detail_dialog.html
@@ -61,7 +61,7 @@
   }
 </style>
 <cr-dialog id="apnDetailDialog" show-on-attach>
-  <div id="apnDetailDialogTitle" slot="title">
+  <div id="apnDetailDialogTitle" slot="title" aria-live="polite">
     [[getDialogTitle_(mode)]]
   </div>
   <div slot="body">
@@ -103,12 +103,12 @@
           </template>
         </select>
       </div>
-      <div class="cr-form-field-label">
+      <div id="apnDetailApnTypesLabel" class="cr-form-field-label">
         [[i18n('apnDetailApnTypes')]]
       </div>
       <div id="checkboxContainer" class="checkbox-section">
         <cr-checkbox id="apnDefaultTypeCheckbox"
-            aria-labelledby="apnDefaultTypelabel"
+            aria-describedby="apnDetailApnTypesLabel"
             disabled="[[isUiElementDisabled_(UiElement.INPUT, mode)]]"
             checked="{{isDefaultApnType_}}">
           <div id="apnDefaultTypelabel" class="checkbox-text-area">
@@ -117,7 +117,7 @@
         </cr-checkbox>
         <cr-checkbox id="apnAttachTypeCheckbox"
             disabled="[[isUiElementDisabled_(UiElement.INPUT, mode)]]"
-            aria-labelledby="apnAttachTypeLabel"
+            aria-describedby="apnDetailApnTypesLabel"
             checked="{{isAttachApnType_}}">
           <div id="apnAttachTypeLabel" class="checkbox-text-area">
             [[i18n('apnDetailApnTypeAttach')]]
diff --git a/ash/webui/personalization_app/personalization_app_ui.cc b/ash/webui/personalization_app/personalization_app_ui.cc
index 452c5388..fdc258b 100644
--- a/ash/webui/personalization_app/personalization_app_ui.cc
+++ b/ash/webui/personalization_app/personalization_app_ui.cc
@@ -241,9 +241,9 @@
       {"ambientModeAlbumsSubpageAlbumUnselected",
        IDS_PERSONALIZATION_APP_AMBIENT_MODE_ALBUMS_SUBPAGE_ALBUM_UNSELECTED},
       {"ambientModeLastArtAlbumMessage",
-       IDS_PERONSONALIZATION_APP_AMBIENT_MODE_LAST_ART_ALBUM_MESSAGE},
+       IDS_PERSONALIZATION_APP_AMBIENT_MODE_LAST_ART_ALBUM_MESSAGE},
       {"ambientModeArtAlbumDialogCloseButtonLabel",
-       IDS_PERONSONALIZATION_APP_AMBIENT_MODE_ART_ALBUM_DIALOG_CLOSE_BUTTON_LABEL},
+       IDS_PERSONALIZATION_APP_AMBIENT_MODE_ART_ALBUM_DIALOG_CLOSE_BUTTON_LABEL},
       {"ambientModeAnimationTitle",
        IDS_PERSONALIZATION_APP_AMBIENT_MODE_ANIMATION_TITLE},
       {"ambientModeAnimationSlideshowLabel",
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc
index 228c302a..8f10c9da 100644
--- a/ash/wm/desks/desks_unittests.cc
+++ b/ash/wm/desks/desks_unittests.cc
@@ -6438,29 +6438,8 @@
   EXPECT_TRUE(left_button->GetVisible());
   EXPECT_TRUE(right_button->GetVisible());
 
-  // Wait for 1s, there will be another scroll.
-  WaitForMilliseconds(1000);
-  current_index += desks_in_one_page;
-
-  // When `Jellyroll` is enabled and the maximum number of desks is 8, the new
-  // desk button is smaller, two scrolls will reach the end of the desks bar
-  // view, thus we verify the right of the visible scroll view.
-  if (chromeos::features::IsJellyrollEnabled() &&
-      !features::Is16DesksEnabled()) {
-    EXPECT_EQ(
-        scroll_view->GetVisibleRect().right() - focus_ring_width_and_padding,
-        GetExpandedStateNewDeskButton(desks_bar)->bounds().right());
-  } else {
-    EXPECT_EQ(scroll_view->GetVisibleRect().x() + focus_ring_width_and_padding,
-              mini_views[current_index]->bounds().x());
-  }
-
-  // Release and click a few times to make sure we end up at the maximum offset.
-  event_generator->ReleaseLeftButton();
-  for (int i = 0; i != 3; ++i) {
-    event_generator->ClickLeftButton();
-  }
-
+  // Wait for a bit to scroll to the end.
+  WaitForMilliseconds(200);
   EXPECT_EQ(scroll_view->GetVisibleRect().x(),
             scroll_view->contents()->width() - page_size);
 
@@ -6469,30 +6448,15 @@
   EXPECT_TRUE(left_button->GetVisible());
   EXPECT_FALSE(right_button->GetVisible());
 
-  // Since we're scrolled all the way to the right and the new desk button is
-  // visible, this is the index of the leftmost visible mini view.
-  current_index = max_desks_size - 1;
-
   // Press on left scroll button by gesture should scroll to the previous page.
   // And the final scroll position should also be adjusted while scrolling to
   // previous page to make sure the desk preview will not be cropped.
   event_generator->MoveTouch(left_button->GetBoundsInScreen().CenterPoint());
   event_generator->PressTouch();
-  // When the feature flag `Jellyroll` is enabled, the new desk button and the
-  // library button become smaller, thus when scroll to the left from the right
-  // mode, the index of desk mini view on the left is smaller than it when
-  // `Jellyroll` is not enabled.
-  if (chromeos::features::IsJellyrollEnabled()) {
-    current_index -= (desks_in_one_page + 1);
-  } else {
-    current_index -= desks_in_one_page;
-  }
-  EXPECT_EQ(scroll_view->GetVisibleRect().x() + focus_ring_width_and_padding,
-            mini_views[current_index]->bounds().x());
 
-  // Wait for 1s, there is another scroll.
-  WaitForMilliseconds(1000);
-  current_index -= desks_in_one_page;
+  // Wait for a bit to scroll to the start.
+  WaitForMilliseconds(200);
+  current_index = 0;
   EXPECT_EQ(scroll_view->GetVisibleRect().x() + focus_ring_width_and_padding,
             mini_views[current_index]->bounds().x());
 
@@ -7486,8 +7450,7 @@
   views::ScrollView* scroll_view =
       DesksTestApi::GetDeskBarScrollView(DeskBarViewBase::Type::kOverview);
   const int page_size = scroll_view->width();
-  auto mini_views = desks_bar->mini_views();
-  const int mini_view_width = mini_views[0]->bounds().width();
+  const int mini_view_width = desks_bar->mini_views()[0]->bounds().width();
   int desks_in_one_page = page_size / mini_view_width;
   float fractional_page = static_cast<float>(page_size % mini_view_width) /
                           static_cast<float>(mini_view_width);
@@ -7509,7 +7472,7 @@
   // And the final scroll position should be adjusted to make sure the desk
   // preview will not be cropped.
   auto* event_generator = GetEventGenerator();
-  DeskMiniView* mini_view_0 = mini_views[0];
+  DeskMiniView* mini_view_0 = desks_bar->mini_views()[0];
   Desk* desk_0 = mini_view_0->desk();
 
   const int focus_ring_width_and_padding = 4;
@@ -7519,35 +7482,17 @@
   event_generator->MoveMouseTo(right_button->GetBoundsInScreen().CenterPoint());
   current_index += desks_in_one_page;
   EXPECT_EQ(scroll_view->GetVisibleRect().x() + focus_ring_width_and_padding,
-            mini_views[current_index]->bounds().x());
+            desks_bar->mini_views()[current_index]->bounds().x());
 
   // Both scroll buttons should be visible.
   EXPECT_TRUE(left_button->GetVisible());
   EXPECT_TRUE(right_button->GetVisible());
 
-  // Wait for 1s, there will be another scroll.
-  WaitForMilliseconds(1000);
-  current_index += desks_in_one_page;
-
-  // When `Jellyroll` is enabled and the maximum number of desks is 8, the new
-  // desk button is smaller, two scrolls will reach the end of the desks bar
-  // view, thus we verify the right of the visible scroll view.
-  if (chromeos::features::IsJellyrollEnabled() &&
-      !features::Is16DesksEnabled()) {
-    EXPECT_EQ(
-        scroll_view->GetVisibleRect().right() - focus_ring_width_and_padding,
-        GetExpandedStateNewDeskButton(desks_bar)->bounds().right());
-  } else {
-    EXPECT_EQ(scroll_view->GetVisibleRect().x() + focus_ring_width_and_padding,
-              mini_views[current_index]->bounds().x());
-  }
+  // Wait for a bit to scroll to the end.
+  WaitForMilliseconds(200);
 
   // While scrolling, the desk cannot be reordered.
   EXPECT_EQ(0, desks_controller->GetDeskIndex(desk_0));
-
-  // Wait longer, it will scroll to the maximum offset. When 16 desks are
-  // enabled, we need to allow more time for scrolling.
-  WaitForMilliseconds(GetParam().use_16_desks ? 4000 : 1000);
   EXPECT_EQ(scroll_view->GetVisibleRect().x(),
             scroll_view->contents()->width() - page_size);
 
@@ -7557,8 +7502,9 @@
   EXPECT_FALSE(right_button->GetVisible());
 
   // Move the dragged desk to the center of the last desk.
-  event_generator->MoveMouseTo(
-      mini_views[max_desks_size - 1]->GetBoundsInScreen().CenterPoint());
+  event_generator->MoveMouseTo(desks_bar->mini_views()[max_desks_size - 1]
+                                   ->GetBoundsInScreen()
+                                   .CenterPoint());
   // The dragged desk is reordered to the end.
   const int max_index = static_cast<int>(max_desks_size) - 1;
   // Now the desk is reordered to the last position.
@@ -7570,37 +7516,25 @@
   // Dragging the desk to left scroll button should scroll to the previous page.
   // And the final scroll position should also be adjusted while scrolling to
   // the previous page to make sure the desk preview will not be cropped.
-  mini_views = desks_bar->mini_views();
-  StartDragDeskPreview(mini_views[max_desks_size - 1], event_generator);
+  StartDragDeskPreview(desks_bar->mini_views()[max_desks_size - 1],
+                       event_generator);
   event_generator->MoveMouseTo(left_button->GetBoundsInScreen().CenterPoint());
-  // When the feature flag `Jellyroll` is enabled, the new desk button and the
-  // library button become smaller, thus when scroll to the left from the right
-  // most, the index of desk mini view on the left is smaller than it when
-  // `Jellyroll` is not enabled.
-  if (chromeos::features::IsJellyrollEnabled()) {
-    current_index -= (desks_in_one_page + 1);
-  } else {
-    current_index -= desks_in_one_page;
-  }
-  EXPECT_EQ(scroll_view->GetVisibleRect().x() + focus_ring_width_and_padding,
-            mini_views[current_index]->bounds().x());
 
-  // Wait for 1s, there is another scroll.
-  WaitForMilliseconds(1000);
-  current_index -= desks_in_one_page;
+  // Wait for a while to scroll to the start.
+  WaitForMilliseconds(200);
   EXPECT_EQ(scroll_view->GetVisibleRect().x() + focus_ring_width_and_padding,
-            mini_views[current_index]->bounds().x());
+            desks_bar->mini_views()[0]->bounds().x());
 
   // The desk is still not reordered while scrolling backward.
   EXPECT_EQ(max_index, desks_controller->GetDeskIndex(desk_0));
 
   // Drop the desk. Desks bar will scroll to show the desk's target position.
   event_generator->ReleaseLeftButton();
-  // Wait 100 milliseconds for the animation of the scrollable bar to end.
+  // Wait 200 milliseconds for the animation of the scrollable bar to end.
   // Otherwise, the test could be flaky, i.e, the visible bounds of the scroll
   // bar is not updated yet if we get its bounds immediately after the desk is
   // dropped.
-  WaitForMilliseconds(100);
+  WaitForMilliseconds(200);
   gfx::Rect bounds_0 = mini_view_0->bounds();
   gfx::Rect bounds_visible = scroll_view->GetVisibleRect();
   EXPECT_LE(bounds_visible.x(), bounds_0.x());
diff --git a/ash/wm/desks/scroll_arrow_button.cc b/ash/wm/desks/scroll_arrow_button.cc
index 6cc9386..fa2ca62 100644
--- a/ash/wm/desks/scroll_arrow_button.cc
+++ b/ash/wm/desks/scroll_arrow_button.cc
@@ -9,11 +9,17 @@
 #include "ash/wm/desks/desk_preview_view.h"
 #include "ash/wm/desks/legacy_desk_bar_view.h"
 #include "base/functional/bind.h"
+#include "ui/compositor/scoped_animation_duration_scale_mode.h"
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/paint_vector_icon.h"
 
 namespace {
-base::TimeDelta kScrollTimeInterval = base::Seconds(1);
+base::TimeDelta GetScrollTimeInteval() {
+  return std::max(
+      base::Seconds(1) *
+          ui::ScopedAnimationDurationScaleMode::duration_multiplier(),
+      base::Milliseconds(5));
+}
 }
 
 namespace ash {
@@ -57,7 +63,7 @@
   if (timer_.IsRunning())
     return;
 
-  timer_.Start(FROM_HERE, kScrollTimeInterval, on_scroll_);
+  timer_.Start(FROM_HERE, GetScrollTimeInteval(), on_scroll_);
   on_scroll_.Run();
 }
 
@@ -72,7 +78,7 @@
     // of the scroll arrow button will be set to |FALSE|, at the same time, the
     // state of the button will be set to |STATE_NORMAL|. In this case, stopping
     // timer will be called before starting timer.
-    timer_.Start(FROM_HERE, kScrollTimeInterval, on_scroll_);
+    timer_.Start(FROM_HERE, GetScrollTimeInteval(), on_scroll_);
     on_scroll_.Run();
   } else {
     timer_.Stop();
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc
index 467f73e..9f9630d 100644
--- a/ash/wm/overview/overview_grid.cc
+++ b/ash/wm/overview/overview_grid.cc
@@ -182,7 +182,7 @@
                          bool single_animation_in_clamshell,
                          bool minimized_in_tablet)
       : tracker_(compositor->RequestNewThroughputTracker()) {
-    tracker_.Start(metrics_util::ForSmoothness(base::BindRepeating(
+    tracker_.Start(metrics_util::ForSmoothnessV3(base::BindRepeating(
         &OverviewMetricsTracker::ReportOverviewSmoothness, in_split_view,
         single_animation_in_clamshell, minimized_in_tablet)));
   }
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc
index 29941a4..6afa5f0f 100644
--- a/ash/wm/overview/overview_session_unittest.cc
+++ b/ash/wm/overview/overview_session_unittest.cc
@@ -946,7 +946,8 @@
 // maximized and fullscreen window.
 #if defined(NDEBUG) && !defined(ADDRESS_SANITIZER) && \
     !defined(LEAK_SANITIZER) && !defined(THREAD_SANITIZER)
-TEST_P(OverviewSessionTest, MaximizedFullscreenHistograms) {
+// TODO(crbug.com/1493835): Re-enable this test. Disabled because of flakiness.
+TEST_P(OverviewSessionTest, DISABLED_MaximizedFullscreenHistograms) {
   std::unique_ptr<aura::Window> maximized_window(CreateTestWindow());
   std::unique_ptr<aura::Window> fullscreen_window(CreateTestWindow());
 
@@ -986,7 +987,8 @@
 }
 #endif
 
-TEST_P(OverviewSessionTest, TabletModeHistograms) {
+// TODO(crbug.com/1493835): Re-enable this test. Disabled because of flakiness.
+TEST_P(OverviewSessionTest, DISABLED_TabletModeHistograms) {
   ui::ScopedAnimationDurationScaleMode anmatin_scale(
       ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
 
@@ -1019,7 +1021,8 @@
 // Tests that entering overview when a fullscreen window is active in maximized
 // mode correctly applies the transformations to the window and correctly
 // updates the window bounds on exiting overview mode: http://crbug.com/401664.
-TEST_P(OverviewSessionTest, FullscreenWindowTabletMode) {
+// TODO(crbug.com/1493835): Re-enable this test. Disabled because of flakiness.
+TEST_P(OverviewSessionTest, DISABLED_FullscreenWindowTabletMode) {
   ui::ScopedAnimationDurationScaleMode anmatin_scale(
       ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
 
diff --git a/ash/wm/overview/scoped_overview_animation_settings.cc b/ash/wm/overview/scoped_overview_animation_settings.cc
index 62c6a8f..f51cbe9 100644
--- a/ash/wm/overview/scoped_overview_animation_settings.cc
+++ b/ash/wm/overview/scoped_overview_animation_settings.cc
@@ -186,7 +186,7 @@
   if (animation_type == OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM ||
       animation_type == OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM) {
     close_reporter_.emplace(animation_settings_->GetAnimator(),
-                            metrics_util::ForSmoothness(
+                            metrics_util::ForSmoothnessV3(
                                 base::BindRepeating(&ReportCloseSmoothness)));
   }
 }
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc
index d6ce72a..2636b29 100644
--- a/ash/wm/splitview/split_view_controller.cc
+++ b/ash/wm/splitview/split_view_controller.cc
@@ -1264,16 +1264,13 @@
     return;
   }
 
+  // Save the overview enter/exit types to be used if the window is snapped.
+  overview_start_action_ = OverviewStartAction::kOverviewButtonLongPress;
+  enter_exit_overview_type_ = OverviewEnterExitType::kImmediateEnter;
   SnapWindow(target_window, SnapPosition::kPrimary,
              WindowSnapActionSource::kLongPressOverviewButtonToSnap,
              /*activate_window=*/true);
 
-  // Start overview mode if we aren't already in it.
-  RootWindowController::ForWindow(target_window)
-      ->StartSplitViewOverviewSession(
-          target_window, OverviewStartAction::kOverviewButtonLongPress,
-          OverviewEnterExitType::kImmediateEnter);
-
   base::RecordAction(
       base::UserMetricsAction("Tablet_LongPressOverviewButtonEnterSplitView"));
 }
@@ -2330,8 +2327,9 @@
   // `OverviewController`.
   if (WillStartOverview()) {
     RootWindowController::ForWindow(window)->StartSplitViewOverviewSession(
-        window, OverviewStartAction::kSplitView,
-        OverviewEnterExitType::kNormal);
+        window, overview_start_action_, enter_exit_overview_type_);
+    overview_start_action_.reset();
+    enter_exit_overview_type_.reset();
     return;
   }
 
diff --git a/ash/wm/splitview/split_view_controller.h b/ash/wm/splitview/split_view_controller.h
index 1cefab7..9fc9dec9 100644
--- a/ash/wm/splitview/split_view_controller.h
+++ b/ash/wm/splitview/split_view_controller.h
@@ -14,7 +14,9 @@
 #include "ash/public/cpp/keyboard/keyboard_controller_observer.h"
 #include "ash/public/cpp/tablet_mode_observer.h"
 #include "ash/shell_observer.h"
+#include "ash/wm/overview/overview_metrics.h"
 #include "ash/wm/overview/overview_observer.h"
+#include "ash/wm/overview/overview_types.h"
 #include "ash/wm/snap_group/snap_group_controller.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "ash/wm/window_state_observer.h"
@@ -24,6 +26,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/observer_list.h"
 #include "base/time/time.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/aura/window_observer.h"
 #include "ui/display/display.h"
 #include "ui/display/display_observer.h"
@@ -735,6 +738,10 @@
   // Stores the reason which cause splitview to end.
   EndReason end_reason_ = EndReason::kNormal;
 
+  // Stores the overview start and enter/exit type.
+  absl::optional<OverviewStartAction> overview_start_action_;
+  absl::optional<OverviewEnterExitType> enter_exit_overview_type_;
+
   // The split view type. See SplitViewType for the differences between tablet
   // split view and clamshell split view.
   SplitViewType split_view_type_ = SplitViewType::kTabletType;
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc
index 1eefd13..7eced63 100644
--- a/ash/wm/splitview/split_view_controller_unittest.cc
+++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -2562,7 +2562,8 @@
 // windows in overview mode to snap to both side of the screen), or toggle
 // overview to end overview causes a window to snap, we should not have the
 // exiting animation.
-TEST_F(SplitViewControllerTest, OverviewExitAnimationTest) {
+// TODO(crbug.com/1493835): Re-enable this test
+TEST_F(SplitViewControllerTest, DISABLED_OverviewExitAnimationTest) {
   ui::ScopedAnimationDurationScaleMode anmatin_scale(
       ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
 
diff --git a/ash/wm/splitview/split_view_overview_session.cc b/ash/wm/splitview/split_view_overview_session.cc
index aed95b32..81523b5 100644
--- a/ash/wm/splitview/split_view_overview_session.cc
+++ b/ash/wm/splitview/split_view_overview_session.cc
@@ -50,9 +50,7 @@
     : window_(window) {
   CHECK(window);
   window_observation_.Observe(window);
-  auto* window_state = WindowState::Get(window);
-  CHECK(window_state && window_state->IsSnapped());
-  window_state->AddObserver(this);
+  WindowState::Get(window)->AddObserver(this);
 
   if (IsSnapGroupEnabledInClamshellMode()) {
     auto_snap_controller_ =
diff --git a/ash/wm/window_cycle/window_cycle_view.cc b/ash/wm/window_cycle/window_cycle_view.cc
index 9b5a907..79f0d249 100644
--- a/ash/wm/window_cycle/window_cycle_view.cc
+++ b/ash/wm/window_cycle/window_cycle_view.cc
@@ -399,7 +399,7 @@
   settings.CacheRenderSurface();
   ui::AnimationThroughputReporter reporter(
       settings.GetAnimator(),
-      metrics_util::ForSmoothness(base::BindRepeating([](int smoothness) {
+      metrics_util::ForSmoothnessV3(base::BindRepeating([](int smoothness) {
         UMA_HISTOGRAM_PERCENTAGE(kShowAnimationSmoothness, smoothness);
       })));
 
@@ -694,7 +694,7 @@
     settings->SetTransitionDuration(kContainerSlideDuration);
     reporter.emplace(
         settings->GetAnimator(),
-        metrics_util::ForSmoothness(base::BindRepeating([](int smoothness) {
+        metrics_util::ForSmoothnessV3(base::BindRepeating([](int smoothness) {
           // Reports animation metrics when the mirror container, which holds
           // all the preview views slides along the x-axis. This can happen
           // while tabbing through windows, if the window cycle ui spans the
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 03cc1ef..e1429fd 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -4253,18 +4253,8 @@
 }  # is_android || is_robolectric
 
 if (is_android) {
-  java_library("jni_java") {
-    supports_android = true
-    sources = [
-      "android/java/src/org/chromium/base/annotations/AccessedByNative.java",
-      "android/java/src/org/chromium/base/annotations/CalledByNative.java",
-      "android/java/src/org/chromium/base/annotations/CalledByNativeForTesting.java",
-      "android/java/src/org/chromium/base/annotations/CalledByNativeUnchecked.java",
-      "android/java/src/org/chromium/base/annotations/JNINamespace.java",
-      "android/java/src/org/chromium/base/annotations/NativeClassQualifiedName.java",
-      "android/java/src/org/chromium/base/annotations/NativeMethods.java",
-    ]
-
+  # TODO(smaier): delete this once deps have been correctly added everywhere.
+  java_group("jni_java") {
     public_deps = [
       # Public because @CheckDiscard is added to generated *Jni.java files.
       "//build/android:build_java",
@@ -4338,6 +4328,7 @@
       "//third_party/android_deps:guava_android_java",
       "//third_party/androidx:androidx_annotation_annotation_experimental_java",
       "//third_party/androidx:androidx_annotation_annotation_java",
+      "//third_party/jni_zero:jni_zero_java",
     ]
 
     sources = [
diff --git a/base/allocator/partition_alloc_features.cc b/base/allocator/partition_alloc_features.cc
index 6d8363b..4ad1444 100644
--- a/base/allocator/partition_alloc_features.cc
+++ b/base/allocator/partition_alloc_features.cc
@@ -4,6 +4,7 @@
 
 #include "base/allocator/partition_alloc_features.h"
 
+#include "base/allocator/miracle_parameter.h"
 #include "base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/time/time.h"
 #include "base/allocator/partition_allocator/src/partition_alloc/partition_alloc_buildflags.h"
 #include "base/allocator/partition_allocator/src/partition_alloc/partition_root.h"
@@ -94,16 +95,17 @@
              "PartitionAllocLargeThreadCacheSize",
              FEATURE_ENABLED_BY_DEFAULT);
 
-const base::FeatureParam<int> kPartitionAllocLargeThreadCacheSizeValue{
-    &kPartitionAllocLargeThreadCacheSize,
+MIRACLE_PARAMETER_FOR_INT(
+    GetPartitionAllocLargeThreadCacheSizeValue,
+    kPartitionAllocLargeThreadCacheSize,
     "PartitionAllocLargeThreadCacheSizeValue",
-    ::partition_alloc::ThreadCacheLimits::kLargeSizeThreshold};
+    ::partition_alloc::ThreadCacheLimits::kLargeSizeThreshold)
 
-const base::FeatureParam<int>
-    kPartitionAllocLargeThreadCacheSizeValueForLowRAMAndroid{
-        &kPartitionAllocLargeThreadCacheSize,
-        "PartitionAllocLargeThreadCacheSizeValueForLowRAMAndroid",
-        ::partition_alloc::ThreadCacheLimits::kDefaultSizeThreshold};
+MIRACLE_PARAMETER_FOR_INT(
+    GetPartitionAllocLargeThreadCacheSizeValueForLowRAMAndroid,
+    kPartitionAllocLargeThreadCacheSize,
+    "PartitionAllocLargeThreadCacheSizeValueForLowRAMAndroid",
+    ::partition_alloc::ThreadCacheLimits::kDefaultSizeThreshold)
 
 BASE_FEATURE(kPartitionAllocLargeEmptySlotSpanRing,
              "PartitionAllocLargeEmptySlotSpanRing",
@@ -345,12 +347,15 @@
              "EnableConfigurableThreadCacheMultiplier",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-const base::FeatureParam<double> kThreadCacheMultiplier{
-    &kEnableConfigurableThreadCacheMultiplier, "ThreadCacheMultiplier", 2.};
+MIRACLE_PARAMETER_FOR_DOUBLE(GetThreadCacheMultiplier,
+                             kEnableConfigurableThreadCacheMultiplier,
+                             "ThreadCacheMultiplier",
+                             2.)
 
-const base::FeatureParam<double> kThreadCacheMultiplierForAndroid{
-    &kEnableConfigurableThreadCacheMultiplier,
-    "ThreadCacheMultiplierForAndroid", 1.};
+MIRACLE_PARAMETER_FOR_DOUBLE(GetThreadCacheMultiplierForAndroid,
+                             kEnableConfigurableThreadCacheMultiplier,
+                             "ThreadCacheMultiplierForAndroid",
+                             1.)
 
 constexpr partition_alloc::internal::base::TimeDelta ToPartitionAllocTimeDelta(
     base::TimeDelta time_delta) {
diff --git a/base/allocator/partition_alloc_features.h b/base/allocator/partition_alloc_features.h
index 27ae62d..4b0e9a9 100644
--- a/base/allocator/partition_alloc_features.h
+++ b/base/allocator/partition_alloc_features.h
@@ -67,10 +67,8 @@
 BASE_EXPORT BASE_DECLARE_FEATURE(kPartitionAllocPCScanRendererOnly);
 
 BASE_EXPORT BASE_DECLARE_FEATURE(kPartitionAllocLargeThreadCacheSize);
-extern const BASE_EXPORT base::FeatureParam<int>
-    kPartitionAllocLargeThreadCacheSizeValue;
-extern const BASE_EXPORT base::FeatureParam<int>
-    kPartitionAllocLargeThreadCacheSizeValueForLowRAMAndroid;
+BASE_EXPORT int GetPartitionAllocLargeThreadCacheSizeValue();
+BASE_EXPORT int GetPartitionAllocLargeThreadCacheSizeValueForLowRAMAndroid();
 
 BASE_EXPORT BASE_DECLARE_FEATURE(kPartitionAllocLargeEmptySlotSpanRing);
 #endif  // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
@@ -202,9 +200,8 @@
     "BackupRefPtrRendererLive";
 
 BASE_EXPORT BASE_DECLARE_FEATURE(kEnableConfigurableThreadCacheMultiplier);
-extern const BASE_EXPORT base::FeatureParam<double> kThreadCacheMultiplier;
-extern const BASE_EXPORT base::FeatureParam<double>
-    kThreadCacheMultiplierForAndroid;
+BASE_EXPORT double GetThreadCacheMultiplier();
+BASE_EXPORT double GetThreadCacheMultiplierForAndroid();
 
 BASE_EXPORT BASE_DECLARE_FEATURE(kEnableConfigurableThreadCachePurgeInterval);
 extern const partition_alloc::internal::base::TimeDelta
diff --git a/base/allocator/partition_alloc_support.cc b/base/allocator/partition_alloc_support.cc
index aec8f7e..35caf54 100644
--- a/base/allocator/partition_alloc_support.cc
+++ b/base/allocator/partition_alloc_support.cc
@@ -1297,10 +1297,10 @@
     // multiplier value with the corresponding feature param.
 #if BUILDFLAG(IS_ANDROID)
     ::partition_alloc::ThreadCacheRegistry::Instance().SetThreadCacheMultiplier(
-        base::features::kThreadCacheMultiplierForAndroid.Get());
+        base::features::GetThreadCacheMultiplierForAndroid());
 #else   // BUILDFLAG(IS_ANDROID)
     ::partition_alloc::ThreadCacheRegistry::Instance().SetThreadCacheMultiplier(
-        base::features::kThreadCacheMultiplier.Get());
+        base::features::GetThreadCacheMultiplier());
 #endif  // BUILDFLAG(IS_ANDROID)
   } else {
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
@@ -1322,7 +1322,7 @@
       base::FeatureList::IsEnabled(
           base::features::kPartitionAllocLargeThreadCacheSize)) {
     largest_cached_size_ =
-        size_t(base::features::kPartitionAllocLargeThreadCacheSizeValue.Get());
+        size_t(base::features::GetPartitionAllocLargeThreadCacheSizeValue());
 
 #if BUILDFLAG(IS_ANDROID)
     // Use appropriately lower amount for Android devices with 3GB or less.
@@ -1332,7 +1332,7 @@
     if (base::SysInfo::AmountOfPhysicalMemoryMB() < 3.2 * 1024) {
       largest_cached_size_ = size_t(
           base::features::
-              kPartitionAllocLargeThreadCacheSizeValueForLowRAMAndroid.Get());
+              GetPartitionAllocLargeThreadCacheSizeValueForLowRAMAndroid());
     }
 #endif  // BUILDFLAG(IS_ANDROID)
 
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/bits.h b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/bits.h
index 8e4da95b..2af5acd 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/bits.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/bits.h
@@ -18,7 +18,7 @@
 namespace partition_alloc::internal::base::bits {
 
 // Returns true iff |value| is a power of 2.
-template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
+template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
 constexpr bool IsPowerOfTwo(T value) {
   // From "Hacker's Delight": Section 2.1 Manipulating Rightmost Bits.
   //
@@ -75,8 +75,7 @@
 // do better, but we'll avoid doing that unless we see proof that we need to.
 template <typename T, int bits = sizeof(T) * 8>
 PA_ALWAYS_INLINE constexpr
-    typename std::enable_if<std::is_unsigned<T>::value && sizeof(T) <= 8,
-                            int>::type
+    typename std::enable_if<std::is_unsigned_v<T> && sizeof(T) <= 8, int>::type
     CountLeadingZeroBits(T value) {
   static_assert(bits > 0, "invalid instantiation");
 #if defined(COMPILER_MSVC) && !defined(__clang__)
@@ -101,8 +100,7 @@
 
 template <typename T, int bits = sizeof(T) * 8>
 PA_ALWAYS_INLINE constexpr
-    typename std::enable_if<std::is_unsigned<T>::value && sizeof(T) <= 8,
-                            int>::type
+    typename std::enable_if<std::is_unsigned_v<T> && sizeof(T) <= 8, int>::type
     CountTrailingZeroBits(T value) {
 #if defined(COMPILER_MSVC) && !defined(__clang__)
   // We would prefer to use the _BitScanForward(64) intrinsics, but they
@@ -145,7 +143,7 @@
 // Can be used instead of manually shifting a 1 to the left.
 template <typename T>
 constexpr T LeftmostBit() {
-  static_assert(std::is_integral<T>::value,
+  static_assert(std::is_integral_v<T>,
                 "This function can only be used with integral types.");
   T one(1u);
   return one << (8 * sizeof(T) - 1);
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/memory/scoped_refptr.h b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/memory/scoped_refptr.h
index ccde377..62b974a 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/memory/scoped_refptr.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/memory/scoped_refptr.h
@@ -67,7 +67,7 @@
 template <typename T>
 scoped_refptr<T> AdoptRef(T* obj) {
   using Tag = std::decay_t<decltype(T::kRefCountPreference)>;
-  static_assert(std::is_same<subtle::StartRefCountFromOneTag, Tag>::value,
+  static_assert(std::is_same_v<subtle::StartRefCountFromOneTag, Tag>,
                 "Use AdoptRef only if the reference count starts from one.");
 
   PA_BASE_DCHECK(obj);
@@ -196,9 +196,9 @@
   scoped_refptr(const scoped_refptr& r) : scoped_refptr(r.ptr_) {}
 
   // Copy conversion constructor.
-  template <typename U,
-            typename = typename std::enable_if<
-                std::is_convertible<U*, T*>::value>::type>
+  template <
+      typename U,
+      typename = typename std::enable_if<std::is_convertible_v<U*, T*>>::type>
   scoped_refptr(const scoped_refptr<U>& r) : scoped_refptr(r.ptr_) {}
 
   // Move constructor. This is required in addition to the move conversion
@@ -206,9 +206,9 @@
   scoped_refptr(scoped_refptr&& r) noexcept : ptr_(r.ptr_) { r.ptr_ = nullptr; }
 
   // Move conversion constructor.
-  template <typename U,
-            typename = typename std::enable_if<
-                std::is_convertible<U*, T*>::value>::type>
+  template <
+      typename U,
+      typename = typename std::enable_if<std::is_convertible_v<U*, T*>>::type>
   scoped_refptr(scoped_refptr<U>&& r) noexcept : ptr_(r.ptr_) {
     r.ptr_ = nullptr;
   }
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/checked_math.h b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/checked_math.h
index ac14df8..3d1c765 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/checked_math.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/checked_math.h
@@ -17,7 +17,7 @@
 
 template <typename T>
 class CheckedNumeric {
-  static_assert(std::is_arithmetic<T>::value,
+  static_assert(std::is_arithmetic_v<T>,
                 "CheckedNumeric<T>: T must be a numeric type.");
 
  public:
@@ -139,14 +139,14 @@
 
   constexpr CheckedNumeric operator-() const {
     // Use an optimized code path for a known run-time variable.
-    if (!PA_IsConstantEvaluated() && std::is_signed<T>::value &&
-        std::is_floating_point<T>::value) {
+    if (!PA_IsConstantEvaluated() && std::is_signed_v<T> &&
+        std::is_floating_point_v<T>) {
       return FastRuntimeNegate();
     }
     // The negation of two's complement int min is int min.
     const bool is_valid =
         IsValid() &&
-        (!std::is_signed<T>::value || std::is_floating_point<T>::value ||
+        (!std::is_signed_v<T> || std::is_floating_point_v<T> ||
          NegateWrapper(state_.value()) != std::numeric_limits<T>::lowest());
     return CheckedNumeric<T>(NegateWrapper(state_.value()), is_valid);
   }
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/checked_math_impl.h b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/checked_math_impl.h
index c7efa021..ea32015 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/checked_math_impl.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/checked_math_impl.h
@@ -21,7 +21,7 @@
 
 template <typename T>
 constexpr bool CheckedAddImpl(T x, T y, T* result) {
-  static_assert(std::is_integral<T>::value, "Type must be integral");
+  static_assert(std::is_integral_v<T>, "Type must be integral");
   // Since the value of x+y is undefined if we have a signed type, we compute
   // it using the unsigned type of the same size.
   using UnsignedDst = typename std::make_unsigned<T>::type;
@@ -31,7 +31,7 @@
   const UnsignedDst uresult = static_cast<UnsignedDst>(ux + uy);
   // Addition is valid if the sign of (x + y) is equal to either that of x or
   // that of y.
-  if (std::is_signed<T>::value
+  if (std::is_signed_v<T>
           ? static_cast<SignedDst>((uresult ^ ux) & (uresult ^ uy)) < 0
           : uresult < uy) {  // Unsigned is either valid or underflow.
     return false;
@@ -46,8 +46,8 @@
 template <typename T, typename U>
 struct CheckedAddOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V>
   static constexpr bool Do(T x, U y, V* result) {
@@ -88,7 +88,7 @@
 
 template <typename T>
 constexpr bool CheckedSubImpl(T x, T y, T* result) {
-  static_assert(std::is_integral<T>::value, "Type must be integral");
+  static_assert(std::is_integral_v<T>, "Type must be integral");
   // Since the value of x+y is undefined if we have a signed type, we compute
   // it using the unsigned type of the same size.
   using UnsignedDst = typename std::make_unsigned<T>::type;
@@ -98,7 +98,7 @@
   const UnsignedDst uresult = static_cast<UnsignedDst>(ux - uy);
   // Subtraction is valid if either x and y have same sign, or (x-y) and x have
   // the same sign.
-  if (std::is_signed<T>::value
+  if (std::is_signed_v<T>
           ? static_cast<SignedDst>((uresult ^ ux) & (ux ^ uy)) < 0
           : x < y) {
     return false;
@@ -113,8 +113,8 @@
 template <typename T, typename U>
 struct CheckedSubOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V>
   static constexpr bool Do(T x, U y, V* result) {
@@ -155,7 +155,7 @@
 
 template <typename T>
 constexpr bool CheckedMulImpl(T x, T y, T* result) {
-  static_assert(std::is_integral<T>::value, "Type must be integral");
+  static_assert(std::is_integral_v<T>, "Type must be integral");
   // Since the value of x*y is potentially undefined if we have a signed type,
   // we compute it using the unsigned type of the same size.
   using UnsignedDst = typename std::make_unsigned<T>::type;
@@ -164,11 +164,11 @@
   const UnsignedDst uy = SafeUnsignedAbs(y);
   const UnsignedDst uresult = static_cast<UnsignedDst>(ux * uy);
   const bool is_negative =
-      std::is_signed<T>::value && static_cast<SignedDst>(x ^ y) < 0;
+      std::is_signed_v<T> && static_cast<SignedDst>(x ^ y) < 0;
   // We have a fast out for unsigned identity or zero on the second operand.
   // After that it's an unsigned overflow check on the absolute value, with
   // a +1 bound for a negative result.
-  if (uy > UnsignedDst(!std::is_signed<T>::value || is_negative) &&
+  if (uy > UnsignedDst(!std::is_signed_v<T> || is_negative) &&
       ux > (std::numeric_limits<T>::max() + UnsignedDst(is_negative)) / uy) {
     return false;
   }
@@ -182,8 +182,8 @@
 template <typename T, typename U>
 struct CheckedMulOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V>
   static constexpr bool Do(T x, U y, V* result) {
@@ -228,8 +228,8 @@
 template <typename T, typename U>
 struct CheckedDivOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V>
   static constexpr bool Do(T x, U y, V* result) {
@@ -241,7 +241,7 @@
     // combination of types needed to trigger this case.
     using Promotion = typename BigEnoughPromotion<T, U>::type;
     if (PA_BASE_NUMERICS_UNLIKELY(
-            (std::is_signed<T>::value && std::is_signed<U>::value &&
+            (std::is_signed_v<T> && std::is_signed_v<U> &&
              IsTypeInRangeForNumericType<T, Promotion>::value &&
              static_cast<Promotion>(x) ==
                  std::numeric_limits<Promotion>::lowest() &&
@@ -272,8 +272,8 @@
 template <typename T, typename U>
 struct CheckedModOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V>
   static constexpr bool Do(T x, U y, V* result) {
@@ -283,7 +283,7 @@
 
     using Promotion = typename BigEnoughPromotion<T, U>::type;
     if (PA_BASE_NUMERICS_UNLIKELY(
-            (std::is_signed<T>::value && std::is_signed<U>::value &&
+            (std::is_signed_v<T> && std::is_signed_v<U> &&
              IsTypeInRangeForNumericType<T, Promotion>::value &&
              static_cast<Promotion>(x) ==
                  std::numeric_limits<Promotion>::lowest() &&
@@ -311,8 +311,8 @@
 template <typename T, typename U>
 struct CheckedLshOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = T;
   template <typename V>
   static constexpr bool Do(T x, U shift, V* result) {
@@ -327,7 +327,7 @@
     }
 
     // Handle the legal corner-case of a full-width signed shift of zero.
-    if (!std::is_signed<T>::value || x ||
+    if (!std::is_signed_v<T> || x ||
         as_unsigned(shift) != as_unsigned(std::numeric_limits<T>::digits)) {
       return false;
     }
@@ -345,8 +345,8 @@
 template <typename T, typename U>
 struct CheckedRshOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = T;
   template <typename V>
   static constexpr bool Do(T x, U shift, V* result) {
@@ -372,8 +372,8 @@
 template <typename T, typename U>
 struct CheckedAndOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = typename std::make_unsigned<
       typename MaxExponentPromotion<T, U>::type>::type;
   template <typename V>
@@ -395,8 +395,8 @@
 template <typename T, typename U>
 struct CheckedOrOp<T,
                    U,
-                   typename std::enable_if<std::is_integral<T>::value &&
-                                           std::is_integral<U>::value>::type> {
+                   typename std::enable_if<std::is_integral_v<T> &&
+                                           std::is_integral_v<U>>::type> {
   using result_type = typename std::make_unsigned<
       typename MaxExponentPromotion<T, U>::type>::type;
   template <typename V>
@@ -418,8 +418,8 @@
 template <typename T, typename U>
 struct CheckedXorOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = typename std::make_unsigned<
       typename MaxExponentPromotion<T, U>::type>::type;
   template <typename V>
@@ -440,11 +440,10 @@
 struct CheckedMaxOp {};
 
 template <typename T, typename U>
-struct CheckedMaxOp<
-    T,
-    U,
-    typename std::enable_if<std::is_arithmetic<T>::value &&
-                            std::is_arithmetic<U>::value>::type> {
+struct CheckedMaxOp<T,
+                    U,
+                    typename std::enable_if<std::is_arithmetic_v<T> &&
+                                            std::is_arithmetic_v<U>>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V>
   static constexpr bool Do(T x, U y, V* result) {
@@ -465,11 +464,10 @@
 struct CheckedMinOp {};
 
 template <typename T, typename U>
-struct CheckedMinOp<
-    T,
-    U,
-    typename std::enable_if<std::is_arithmetic<T>::value &&
-                            std::is_arithmetic<U>::value>::type> {
+struct CheckedMinOp<T,
+                    U,
+                    typename std::enable_if<std::is_arithmetic_v<T> &&
+                                            std::is_arithmetic_v<U>>::type> {
   using result_type = typename LowestValuePromotion<T, U>::type;
   template <typename V>
   static constexpr bool Do(T x, U y, V* result) {
@@ -486,22 +484,22 @@
 
 // This is just boilerplate that wraps the standard floating point arithmetic.
 // A macro isn't the nicest solution, but it beats rewriting these repeatedly.
-#define PA_BASE_FLOAT_ARITHMETIC_OPS(NAME, OP)                           \
-  template <typename T, typename U>                                      \
-  struct Checked##NAME##Op<                                              \
-      T, U,                                                              \
-      typename std::enable_if<std::is_floating_point<T>::value ||        \
-                              std::is_floating_point<U>::value>::type> { \
-    using result_type = typename MaxExponentPromotion<T, U>::type;       \
-    template <typename V>                                                \
-    static constexpr bool Do(T x, U y, V* result) {                      \
-      using Promotion = typename MaxExponentPromotion<T, U>::type;       \
-      const Promotion presult = x OP y;                                  \
-      if (!IsValueInRangeForNumericType<V>(presult))                     \
-        return false;                                                    \
-      *result = static_cast<V>(presult);                                 \
-      return true;                                                       \
-    }                                                                    \
+#define PA_BASE_FLOAT_ARITHMETIC_OPS(NAME, OP)                      \
+  template <typename T, typename U>                                 \
+  struct Checked##NAME##Op<                                         \
+      T, U,                                                         \
+      typename std::enable_if<std::is_floating_point_v<T> ||        \
+                              std::is_floating_point_v<U>>::type> { \
+    using result_type = typename MaxExponentPromotion<T, U>::type;  \
+    template <typename V>                                           \
+    static constexpr bool Do(T x, U y, V* result) {                 \
+      using Promotion = typename MaxExponentPromotion<T, U>::type;  \
+      const Promotion presult = x OP y;                             \
+      if (!IsValueInRangeForNumericType<V>(presult))                \
+        return false;                                               \
+      *result = static_cast<V>(presult);                            \
+      return true;                                                  \
+    }                                                               \
   };
 
 PA_BASE_FLOAT_ARITHMETIC_OPS(Add, +)
@@ -523,10 +521,10 @@
 template <typename NumericType>
 struct GetNumericRepresentation {
   static const NumericRepresentation value =
-      std::is_integral<NumericType>::value
+      std::is_integral_v<NumericType>
           ? NUMERIC_INTEGER
-          : (std::is_floating_point<NumericType>::value ? NUMERIC_FLOATING
-                                                        : NUMERIC_UNKNOWN);
+          : (std::is_floating_point_v<NumericType> ? NUMERIC_FLOATING
+                                                   : NUMERIC_UNKNOWN);
 };
 
 template <typename T,
@@ -541,7 +539,7 @@
   constexpr explicit CheckedNumericState(Src value = 0, bool is_valid = true)
       : is_valid_(is_valid && IsValueInRangeForNumericType<T>(value)),
         value_(WellDefinedConversionOrZero(value, is_valid_)) {
-    static_assert(std::is_arithmetic<Src>::value, "Argument must be numeric.");
+    static_assert(std::is_arithmetic_v<Src>, "Argument must be numeric.");
   }
 
   template <typename Src>
@@ -557,9 +555,8 @@
   template <typename Src>
   static constexpr T WellDefinedConversionOrZero(Src value, bool is_valid) {
     using SrcType = typename internal::UnderlyingType<Src>::type;
-    return (std::is_integral<SrcType>::value || is_valid)
-               ? static_cast<T>(value)
-               : 0;
+    return (std::is_integral_v<SrcType> || is_valid) ? static_cast<T>(value)
+                                                     : 0;
   }
 
   // is_valid_ precedes value_ because member initializers in the constructors
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/clamped_math.h b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/clamped_math.h
index ead86487..ec382b24 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/clamped_math.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/clamped_math.h
@@ -17,7 +17,7 @@
 
 template <typename T>
 class ClampedNumeric {
-  static_assert(std::is_arithmetic<T>::value,
+  static_assert(std::is_arithmetic_v<T>,
                 "ClampedNumeric<T>: T must be a numeric type.");
 
  public:
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/clamped_math_impl.h b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/clamped_math_impl.h
index a723bbd..ef96b9e 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/clamped_math_impl.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/clamped_math_impl.h
@@ -21,8 +21,8 @@
 namespace partition_alloc::internal::base::internal {
 
 template <typename T,
-          typename std::enable_if<std::is_integral<T>::value &&
-                                  std::is_signed<T>::value>::type* = nullptr>
+          typename std::enable_if<std::is_integral_v<T> &&
+                                  std::is_signed_v<T>>::type* = nullptr>
 constexpr T SaturatedNegWrapper(T value) {
   return PA_IsConstantEvaluated() || !ClampedNegFastOp<T>::is_supported
              ? (NegateWrapper(value) != std::numeric_limits<T>::lowest()
@@ -32,21 +32,20 @@
 }
 
 template <typename T,
-          typename std::enable_if<std::is_integral<T>::value &&
-                                  !std::is_signed<T>::value>::type* = nullptr>
+          typename std::enable_if<std::is_integral_v<T> &&
+                                  !std::is_signed_v<T>>::type* = nullptr>
 constexpr T SaturatedNegWrapper(T value) {
   return T(0);
 }
 
-template <
-    typename T,
-    typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
+template <typename T,
+          typename std::enable_if<std::is_floating_point_v<T>>::type* = nullptr>
 constexpr T SaturatedNegWrapper(T value) {
   return -value;
 }
 
 template <typename T,
-          typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
+          typename std::enable_if<std::is_integral_v<T>>::type* = nullptr>
 constexpr T SaturatedAbsWrapper(T value) {
   // The calculation below is a static identity for unsigned types, but for
   // signed integer types it provides a non-branching, saturated absolute value.
@@ -61,9 +60,8 @@
       IsValueNegative<T>(static_cast<T>(SafeUnsignedAbs(value))));
 }
 
-template <
-    typename T,
-    typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
+template <typename T,
+          typename std::enable_if<std::is_floating_point_v<T>>::type* = nullptr>
 constexpr T SaturatedAbsWrapper(T value) {
   return value < 0 ? -value : value;
 }
@@ -74,8 +72,8 @@
 template <typename T, typename U>
 struct ClampedAddOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V = result_type>
   static constexpr V Do(T x, U y) {
@@ -83,7 +81,7 @@
       return ClampedAddFastOp<T, U>::template Do<V>(x, y);
     }
 
-    static_assert(std::is_same<V, result_type>::value ||
+    static_assert(std::is_same_v<V, result_type> ||
                       IsTypeInRangeForNumericType<U, V>::value,
                   "The saturation result cannot be determined from the "
                   "provided types.");
@@ -101,8 +99,8 @@
 template <typename T, typename U>
 struct ClampedSubOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V = result_type>
   static constexpr V Do(T x, U y) {
@@ -110,7 +108,7 @@
       return ClampedSubFastOp<T, U>::template Do<V>(x, y);
     }
 
-    static_assert(std::is_same<V, result_type>::value ||
+    static_assert(std::is_same_v<V, result_type> ||
                       IsTypeInRangeForNumericType<U, V>::value,
                   "The saturation result cannot be determined from the "
                   "provided types.");
@@ -128,8 +126,8 @@
 template <typename T, typename U>
 struct ClampedMulOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V = result_type>
   static constexpr V Do(T x, U y) {
@@ -152,8 +150,8 @@
 template <typename T, typename U>
 struct ClampedDivOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V = result_type>
   static constexpr V Do(T x, U y) {
@@ -173,8 +171,8 @@
 template <typename T, typename U>
 struct ClampedModOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V = result_type>
   static constexpr V Do(T x, U y) {
@@ -193,12 +191,12 @@
 template <typename T, typename U>
 struct ClampedLshOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = T;
   template <typename V = result_type>
   static constexpr V Do(T x, U shift) {
-    static_assert(!std::is_signed<U>::value, "Shift value must be unsigned.");
+    static_assert(!std::is_signed_v<U>, "Shift value must be unsigned.");
     if (PA_BASE_NUMERICS_LIKELY(shift < std::numeric_limits<T>::digits)) {
       // Shift as unsigned to avoid undefined behavior.
       V result = static_cast<V>(as_unsigned(x) << shift);
@@ -218,12 +216,12 @@
 template <typename T, typename U>
 struct ClampedRshOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = T;
   template <typename V = result_type>
   static constexpr V Do(T x, U shift) {
-    static_assert(!std::is_signed<U>::value, "Shift value must be unsigned.");
+    static_assert(!std::is_signed_v<U>, "Shift value must be unsigned.");
     // Signed right shift is odd, because it saturates to -1 or 0.
     const V saturated = as_unsigned(V(0)) - IsValueNegative(x);
     return PA_BASE_NUMERICS_LIKELY(shift < IntegerBitsPlusSign<T>::value)
@@ -238,8 +236,8 @@
 template <typename T, typename U>
 struct ClampedAndOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = typename std::make_unsigned<
       typename MaxExponentPromotion<T, U>::type>::type;
   template <typename V>
@@ -255,8 +253,8 @@
 template <typename T, typename U>
 struct ClampedOrOp<T,
                    U,
-                   typename std::enable_if<std::is_integral<T>::value &&
-                                           std::is_integral<U>::value>::type> {
+                   typename std::enable_if<std::is_integral_v<T> &&
+                                           std::is_integral_v<U>>::type> {
   using result_type = typename std::make_unsigned<
       typename MaxExponentPromotion<T, U>::type>::type;
   template <typename V>
@@ -272,8 +270,8 @@
 template <typename T, typename U>
 struct ClampedXorOp<T,
                     U,
-                    typename std::enable_if<std::is_integral<T>::value &&
-                                            std::is_integral<U>::value>::type> {
+                    typename std::enable_if<std::is_integral_v<T> &&
+                                            std::is_integral_v<U>>::type> {
   using result_type = typename std::make_unsigned<
       typename MaxExponentPromotion<T, U>::type>::type;
   template <typename V>
@@ -286,11 +284,10 @@
 struct ClampedMaxOp {};
 
 template <typename T, typename U>
-struct ClampedMaxOp<
-    T,
-    U,
-    typename std::enable_if<std::is_arithmetic<T>::value &&
-                            std::is_arithmetic<U>::value>::type> {
+struct ClampedMaxOp<T,
+                    U,
+                    typename std::enable_if<std::is_arithmetic_v<T> &&
+                                            std::is_arithmetic_v<U>>::type> {
   using result_type = typename MaxExponentPromotion<T, U>::type;
   template <typename V = result_type>
   static constexpr V Do(T x, U y) {
@@ -303,11 +300,10 @@
 struct ClampedMinOp {};
 
 template <typename T, typename U>
-struct ClampedMinOp<
-    T,
-    U,
-    typename std::enable_if<std::is_arithmetic<T>::value &&
-                            std::is_arithmetic<U>::value>::type> {
+struct ClampedMinOp<T,
+                    U,
+                    typename std::enable_if<std::is_arithmetic_v<T> &&
+                                            std::is_arithmetic_v<U>>::type> {
   using result_type = typename LowestValuePromotion<T, U>::type;
   template <typename V = result_type>
   static constexpr V Do(T x, U y) {
@@ -318,17 +314,17 @@
 
 // This is just boilerplate that wraps the standard floating point arithmetic.
 // A macro isn't the nicest solution, but it beats rewriting these repeatedly.
-#define PA_BASE_FLOAT_ARITHMETIC_OPS(NAME, OP)                           \
-  template <typename T, typename U>                                      \
-  struct Clamped##NAME##Op<                                              \
-      T, U,                                                              \
-      typename std::enable_if<std::is_floating_point<T>::value ||        \
-                              std::is_floating_point<U>::value>::type> { \
-    using result_type = typename MaxExponentPromotion<T, U>::type;       \
-    template <typename V = result_type>                                  \
-    static constexpr V Do(T x, U y) {                                    \
-      return saturated_cast<V>(x OP y);                                  \
-    }                                                                    \
+#define PA_BASE_FLOAT_ARITHMETIC_OPS(NAME, OP)                      \
+  template <typename T, typename U>                                 \
+  struct Clamped##NAME##Op<                                         \
+      T, U,                                                         \
+      typename std::enable_if<std::is_floating_point_v<T> ||        \
+                              std::is_floating_point_v<U>>::type> { \
+    using result_type = typename MaxExponentPromotion<T, U>::type;  \
+    template <typename V = result_type>                             \
+    static constexpr V Do(T x, U y) {                               \
+      return saturated_cast<V>(x OP y);                             \
+    }                                                               \
   };
 
 PA_BASE_FLOAT_ARITHMETIC_OPS(Add, +)
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_conversions.h b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_conversions.h
index 8483fe5..fd00d10 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_conversions.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_conversions.h
@@ -56,8 +56,8 @@
     Dst,
     Src,
     typename std::enable_if<
-        std::is_integral<Dst>::value && std::is_integral<Src>::value &&
-        std::is_signed<Dst>::value && std::is_signed<Src>::value &&
+        std::is_integral_v<Dst> && std::is_integral_v<Src> &&
+        std::is_signed_v<Dst> && std::is_signed_v<Src> &&
         !IsTypeInRangeForNumericType<Dst, Src>::value>::type> {
   static constexpr bool is_supported = true;
 
@@ -74,8 +74,8 @@
     Dst,
     Src,
     typename std::enable_if<
-        std::is_integral<Dst>::value && std::is_integral<Src>::value &&
-        !std::is_signed<Dst>::value && std::is_signed<Src>::value &&
+        std::is_integral_v<Dst> && std::is_integral_v<Src> &&
+        !std::is_signed_v<Dst> && std::is_signed_v<Src> &&
         !IsTypeInRangeForNumericType<Dst, Src>::value>::type> {
   static constexpr bool is_supported = true;
 
@@ -146,7 +146,7 @@
              ? (!constraint.IsUnderflowFlagSet() ? static_cast<Dst>(value)
                                                  : S<Dst>::Underflow())
              // Skip this check for integral Src, which cannot be NaN.
-             : (std::is_integral<Src>::value || !constraint.IsUnderflowFlagSet()
+             : (std::is_integral_v<Src> || !constraint.IsUnderflowFlagSet()
                     ? S<Dst>::Overflow()
                     : S<Dst>::NaN());
 }
@@ -164,12 +164,11 @@
 };
 
 template <typename Dst, typename Src>
-struct SaturateFastOp<
-    Dst,
-    Src,
-    typename std::enable_if<std::is_integral<Src>::value &&
-                            std::is_integral<Dst>::value &&
-                            SaturateFastAsmOp<Dst, Src>::is_supported>::type> {
+struct SaturateFastOp<Dst,
+                      Src,
+                      typename std::enable_if<
+                          std::is_integral_v<Src> && std::is_integral_v<Dst> &&
+                          SaturateFastAsmOp<Dst, Src>::is_supported>::type> {
   static constexpr bool is_supported = true;
   static constexpr Dst Do(Src value) {
     return SaturateFastAsmOp<Dst, Src>::Do(value);
@@ -177,12 +176,11 @@
 };
 
 template <typename Dst, typename Src>
-struct SaturateFastOp<
-    Dst,
-    Src,
-    typename std::enable_if<std::is_integral<Src>::value &&
-                            std::is_integral<Dst>::value &&
-                            !SaturateFastAsmOp<Dst, Src>::is_supported>::type> {
+struct SaturateFastOp<Dst,
+                      Src,
+                      typename std::enable_if<
+                          std::is_integral_v<Src> && std::is_integral_v<Dst> &&
+                          !SaturateFastAsmOp<Dst, Src>::is_supported>::type> {
   static constexpr bool is_supported = true;
   static constexpr Dst Do(Src value) {
     // The exact order of the following is structured to hit the correct
@@ -224,7 +222,7 @@
 constexpr Dst strict_cast(Src value) {
   using SrcType = typename UnderlyingType<Src>::type;
   static_assert(UnderlyingType<Src>::is_numeric, "Argument must be numeric.");
-  static_assert(std::is_arithmetic<Dst>::value, "Result must be numeric.");
+  static_assert(std::is_arithmetic_v<Dst>, "Result must be numeric.");
 
   // If you got here from a compiler error, it's because you tried to assign
   // from a source type to a destination type that has insufficient range.
@@ -354,22 +352,22 @@
 // versions.
 template <typename Dst = int,
           typename Src,
-          typename = std::enable_if_t<std::is_integral<Dst>::value &&
-                                      std::is_floating_point<Src>::value>>
+          typename = std::enable_if_t<std::is_integral_v<Dst> &&
+                                      std::is_floating_point_v<Src>>>
 Dst ClampFloor(Src value) {
   return saturated_cast<Dst>(std::floor(value));
 }
 template <typename Dst = int,
           typename Src,
-          typename = std::enable_if_t<std::is_integral<Dst>::value &&
-                                      std::is_floating_point<Src>::value>>
+          typename = std::enable_if_t<std::is_integral_v<Dst> &&
+                                      std::is_floating_point_v<Src>>>
 Dst ClampCeil(Src value) {
   return saturated_cast<Dst>(std::ceil(value));
 }
 template <typename Dst = int,
           typename Src,
-          typename = std::enable_if_t<std::is_integral<Dst>::value &&
-                                      std::is_floating_point<Src>::value>>
+          typename = std::enable_if_t<std::is_integral_v<Dst> &&
+                                      std::is_floating_point_v<Src>>>
 Dst ClampRound(Src value) {
   const Src rounded =
       (value >= 0.0f) ? std::floor(value + 0.5f) : std::ceil(value - 0.5f);
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_conversions_arm_impl.h b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_conversions_arm_impl.h
index 36b30d5..25c24c9f 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_conversions_arm_impl.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_conversions_arm_impl.h
@@ -17,17 +17,17 @@
 template <typename Dst, typename Src>
 struct SaturateFastAsmOp {
   static constexpr bool is_supported =
-      kEnableAsmCode && std::is_signed<Src>::value &&
-      std::is_integral<Dst>::value && std::is_integral<Src>::value &&
+      kEnableAsmCode && std::is_signed_v<Src> && std::is_integral_v<Dst> &&
+      std::is_integral_v<Src> &&
       IntegerBitsPlusSign<Src>::value <= IntegerBitsPlusSign<int32_t>::value &&
       IntegerBitsPlusSign<Dst>::value <= IntegerBitsPlusSign<int32_t>::value &&
       !IsTypeInRangeForNumericType<Dst, Src>::value;
 
   __attribute__((always_inline)) static Dst Do(Src value) {
     int32_t src = value;
-    typename std::conditional<std::is_signed<Dst>::value, int32_t,
-                              uint32_t>::type result;
-    if (std::is_signed<Dst>::value) {
+    typename std::conditional<std::is_signed_v<Dst>, int32_t, uint32_t>::type
+        result;
+    if (std::is_signed_v<Dst>) {
       asm("ssat %[dst], %[shift], %[src]"
           : [dst] "=r"(result)
           : [src] "r"(src), [shift] "n"(IntegerBitsPlusSign<Dst>::value <= 32
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_conversions_impl.h b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_conversions_impl.h
index 89c9067..dd83d0e 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_conversions_impl.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_conversions_impl.h
@@ -24,7 +24,7 @@
 // we can compute an analog using std::numeric_limits<>::digits.
 template <typename NumericType>
 struct MaxExponent {
-  static const int value = std::is_floating_point<NumericType>::value
+  static const int value = std::is_floating_point_v<NumericType>
                                ? std::numeric_limits<NumericType>::max_exponent
                                : std::numeric_limits<NumericType>::digits + 1;
 };
@@ -33,8 +33,8 @@
 // hacks.
 template <typename NumericType>
 struct IntegerBitsPlusSign {
-  static const int value = std::numeric_limits<NumericType>::digits +
-                           std::is_signed<NumericType>::value;
+  static const int value =
+      std::numeric_limits<NumericType>::digits + std::is_signed_v<NumericType>;
 };
 
 // Helper templates for integer manipulations.
@@ -47,16 +47,16 @@
 // Determines if a numeric value is negative without throwing compiler
 // warnings on: unsigned(value) < 0.
 template <typename T,
-          typename std::enable_if<std::is_signed<T>::value>::type* = nullptr>
+          typename std::enable_if<std::is_signed_v<T>>::type* = nullptr>
 constexpr bool IsValueNegative(T value) {
-  static_assert(std::is_arithmetic<T>::value, "Argument must be numeric.");
+  static_assert(std::is_arithmetic_v<T>, "Argument must be numeric.");
   return value < 0;
 }
 
 template <typename T,
-          typename std::enable_if<!std::is_signed<T>::value>::type* = nullptr>
+          typename std::enable_if<!std::is_signed_v<T>>::type* = nullptr>
 constexpr bool IsValueNegative(T) {
-  static_assert(std::is_arithmetic<T>::value, "Argument must be numeric.");
+  static_assert(std::is_arithmetic_v<T>, "Argument must be numeric.");
   return false;
 }
 
@@ -67,7 +67,7 @@
 constexpr typename std::make_signed<T>::type ConditionalNegate(
     T x,
     bool is_negative) {
-  static_assert(std::is_integral<T>::value, "Type must be integral");
+  static_assert(std::is_integral_v<T>, "Type must be integral");
   using SignedT = typename std::make_signed<T>::type;
   using UnsignedT = typename std::make_unsigned<T>::type;
   return static_cast<SignedT>((static_cast<UnsignedT>(x) ^
@@ -78,7 +78,7 @@
 // This performs a safe, absolute value via unsigned overflow.
 template <typename T>
 constexpr typename std::make_unsigned<T>::type SafeUnsignedAbs(T value) {
-  static_assert(std::is_integral<T>::value, "Type must be integral");
+  static_assert(std::is_integral_v<T>, "Type must be integral");
   using UnsignedT = typename std::make_unsigned<T>::type;
   return IsValueNegative(value)
              ? static_cast<UnsignedT>(0u - static_cast<UnsignedT>(value))
@@ -135,10 +135,10 @@
 
 template <typename Dst,
           typename Src,
-          IntegerRepresentation DstSign = std::is_signed<Dst>::value
+          IntegerRepresentation DstSign = std::is_signed_v<Dst>
                                               ? INTEGER_REPRESENTATION_SIGNED
                                               : INTEGER_REPRESENTATION_UNSIGNED,
-          IntegerRepresentation SrcSign = std::is_signed<Src>::value
+          IntegerRepresentation SrcSign = std::is_signed_v<Src>
                                               ? INTEGER_REPRESENTATION_SIGNED
                                               : INTEGER_REPRESENTATION_UNSIGNED>
 struct StaticDstRangeRelationToSrcRange;
@@ -235,14 +235,13 @@
        SrcLimits::digits < DstLimits::digits)
           ? (DstLimits::digits - SrcLimits::digits)
           : 0;
-  template <
-      typename T,
-      typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
+  template <typename T,
+            typename std::enable_if<std::is_integral_v<T>>::type* = nullptr>
 
   // Masks out the integer bits that are beyond the precision of the
   // intermediate type used for comparison.
   static constexpr T Adjust(T value) {
-    static_assert(std::is_same<T, Dst>::value, "");
+    static_assert(std::is_same_v<T, Dst>, "");
     static_assert(kShift < DstLimits::digits, "");
     using UnsignedDst = typename std::make_unsigned_t<T>;
     return static_cast<T>(ConditionalNegate(
@@ -250,11 +249,11 @@
         IsValueNegative(value)));
   }
 
-  template <typename T,
-            typename std::enable_if<std::is_floating_point<T>::value>::type* =
-                nullptr>
+  template <
+      typename T,
+      typename std::enable_if<std::is_floating_point_v<T>>::type* = nullptr>
   static constexpr T Adjust(T value) {
-    static_assert(std::is_same<T, Dst>::value, "");
+    static_assert(std::is_same_v<T, Dst>, "");
     static_assert(kShift == 0, "");
     return value;
   }
@@ -267,10 +266,10 @@
           typename Src,
           template <typename>
           class Bounds,
-          IntegerRepresentation DstSign = std::is_signed<Dst>::value
+          IntegerRepresentation DstSign = std::is_signed_v<Dst>
                                               ? INTEGER_REPRESENTATION_SIGNED
                                               : INTEGER_REPRESENTATION_UNSIGNED,
-          IntegerRepresentation SrcSign = std::is_signed<Src>::value
+          IntegerRepresentation SrcSign = std::is_signed_v<Src>
                                               ? INTEGER_REPRESENTATION_SIGNED
                                               : INTEGER_REPRESENTATION_UNSIGNED,
           NumericRangeRepresentation DstRange =
@@ -372,7 +371,7 @@
     bool ge_zero = false;
     // Converting floating-point to integer will discard fractional part, so
     // values in (-1.0, -0.0) will truncate to 0 and fit in Dst.
-    if (std::is_floating_point<Src>::value) {
+    if (std::is_floating_point_v<Src>) {
       ge_zero = value > Src(-1);
     } else {
       ge_zero = value >= Src(0);
@@ -398,8 +397,8 @@
           template <typename> class Bounds = std::numeric_limits,
           typename Src>
 constexpr RangeCheck DstRangeRelationToSrcRange(Src value) {
-  static_assert(std::is_arithmetic<Src>::value, "Argument must be numeric.");
-  static_assert(std::is_arithmetic<Dst>::value, "Result must be numeric.");
+  static_assert(std::is_arithmetic_v<Src>, "Argument must be numeric.");
+  static_assert(std::is_arithmetic_v<Dst>, "Result must be numeric.");
   static_assert(Bounds<Dst>::lowest() < Bounds<Dst>::max(), "");
   return DstRangeRelationToSrcRangeImpl<Dst, Src, Bounds>::Check(value);
 }
@@ -411,7 +410,7 @@
 #define PA_INTEGER_FOR_DIGITS_AND_SIGN(I)                       \
   template <>                                                   \
   struct IntegerForDigitsAndSign<IntegerBitsPlusSign<I>::value, \
-                                 std::is_signed<I>::value> {    \
+                                 std::is_signed_v<I>> {         \
     using type = I;                                             \
   }
 
@@ -431,7 +430,7 @@
 static_assert(IntegerBitsPlusSign<intmax_t>::value == 64,
               "Max integer size not supported for this toolchain.");
 
-template <typename Integer, bool IsSigned = std::is_signed<Integer>::value>
+template <typename Integer, bool IsSigned = std::is_signed_v<Integer>>
 struct TwiceWiderInteger {
   using type =
       typename IntegerForDigitsAndSign<IntegerBitsPlusSign<Integer>::value * 2,
@@ -466,13 +465,13 @@
 template <typename Lhs,
           typename Rhs,
           ArithmeticPromotionCategory Promotion =
-              std::is_signed<Lhs>::value
-                  ? (std::is_signed<Rhs>::value
+              std::is_signed_v<Lhs>
+                  ? (std::is_signed_v<Rhs>
                          ? (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value
                                 ? LEFT_PROMOTION
                                 : RIGHT_PROMOTION)
                          : LEFT_PROMOTION)
-                  : (std::is_signed<Rhs>::value
+                  : (std::is_signed_v<Rhs>
                          ? RIGHT_PROMOTION
                          : (MaxExponent<Lhs>::value < MaxExponent<Rhs>::value
                                 ? LEFT_PROMOTION
@@ -518,8 +517,8 @@
 struct BigEnoughPromotion<Lhs, Rhs, false, false> {
   using type =
       typename TwiceWiderInteger<typename MaxExponentPromotion<Lhs, Rhs>::type,
-                                 std::is_signed<Lhs>::value ||
-                                     std::is_signed<Rhs>::value>::type;
+                                 std::is_signed_v<Lhs> ||
+                                     std::is_signed_v<Rhs>>::type;
   static const bool is_contained = true;
 };
 
@@ -537,12 +536,11 @@
 template <typename T, typename Lhs, typename Rhs = Lhs>
 struct IsIntegerArithmeticSafe {
   static const bool value =
-      !std::is_floating_point<T>::value &&
-      !std::is_floating_point<Lhs>::value &&
-      !std::is_floating_point<Rhs>::value &&
-      std::is_signed<T>::value >= std::is_signed<Lhs>::value &&
+      !std::is_floating_point_v<T> && !std::is_floating_point_v<Lhs> &&
+      !std::is_floating_point_v<Rhs> &&
+      std::is_signed_v<T> >= std::is_signed_v<Lhs> &&
       IntegerBitsPlusSign<T>::value >= (2 * IntegerBitsPlusSign<Lhs>::value) &&
-      std::is_signed<T>::value >= std::is_signed<Rhs>::value &&
+      std::is_signed_v<T> >= std::is_signed_v<Rhs> &&
       IntegerBitsPlusSign<T>::value >= (2 * IntegerBitsPlusSign<Rhs>::value);
 };
 
@@ -551,8 +549,8 @@
 template <typename Lhs,
           typename Rhs,
           bool is_promotion_possible = IsIntegerArithmeticSafe<
-              typename std::conditional<std::is_signed<Lhs>::value ||
-                                            std::is_signed<Rhs>::value,
+              typename std::conditional<std::is_signed_v<Lhs> ||
+                                            std::is_signed_v<Rhs>,
                                         intmax_t,
                                         uintmax_t>::type,
               typename MaxExponentPromotion<Lhs, Rhs>::type>::value>
@@ -562,8 +560,8 @@
 struct FastIntegerArithmeticPromotion<Lhs, Rhs, true> {
   using type =
       typename TwiceWiderInteger<typename MaxExponentPromotion<Lhs, Rhs>::type,
-                                 std::is_signed<Lhs>::value ||
-                                     std::is_signed<Rhs>::value>::type;
+                                 std::is_signed_v<Lhs> ||
+                                     std::is_signed_v<Rhs>>::type;
   static_assert(IsIntegerArithmeticSafe<type, Lhs, Rhs>::value, "");
   static const bool is_contained = true;
 };
@@ -575,19 +573,19 @@
 };
 
 // Extracts the underlying type from an enum.
-template <typename T, bool is_enum = std::is_enum<T>::value>
+template <typename T, bool is_enum = std::is_enum_v<T>>
 struct ArithmeticOrUnderlyingEnum;
 
 template <typename T>
 struct ArithmeticOrUnderlyingEnum<T, true> {
   using type = typename std::underlying_type<T>::type;
-  static const bool value = std::is_arithmetic<type>::value;
+  static const bool value = std::is_arithmetic_v<type>;
 };
 
 template <typename T>
 struct ArithmeticOrUnderlyingEnum<T, false> {
   using type = T;
-  static const bool value = std::is_arithmetic<type>::value;
+  static const bool value = std::is_arithmetic_v<type>;
 };
 
 // The following are helper templates used in the CheckedNumeric class.
@@ -604,7 +602,7 @@
 template <typename T>
 struct UnderlyingType {
   using type = typename ArithmeticOrUnderlyingEnum<T>::type;
-  static const bool is_numeric = std::is_arithmetic<type>::value;
+  static const bool is_numeric = std::is_arithmetic_v<type>;
   static const bool is_checked = false;
   static const bool is_clamped = false;
   static const bool is_strict = false;
@@ -668,7 +666,7 @@
 constexpr typename std::make_signed<
     typename base::internal::UnderlyingType<Src>::type>::type
 as_signed(const Src value) {
-  static_assert(std::is_integral<decltype(as_signed(value))>::value,
+  static_assert(std::is_integral_v<decltype(as_signed(value))>,
                 "Argument must be a signed or unsigned integer type.");
   return static_cast<decltype(as_signed(value))>(value);
 }
@@ -680,7 +678,7 @@
 constexpr typename std::make_unsigned<
     typename base::internal::UnderlyingType<Src>::type>::type
 as_unsigned(const Src value) {
-  static_assert(std::is_integral<decltype(as_unsigned(value))>::value,
+  static_assert(std::is_integral_v<decltype(as_unsigned(value))>,
                 "Argument must be a signed or unsigned integer type.");
   return static_cast<decltype(as_unsigned(value))>(value);
 }
@@ -697,7 +695,7 @@
 
 template <typename L, typename R>
 struct IsLess {
-  static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value,
+  static_assert(std::is_arithmetic_v<L> && std::is_arithmetic_v<R>,
                 "Types must be numeric.");
   static constexpr bool Test(const L lhs, const R rhs) {
     return IsLessImpl(lhs, rhs, DstRangeRelationToSrcRange<R>(lhs),
@@ -717,7 +715,7 @@
 
 template <typename L, typename R>
 struct IsLessOrEqual {
-  static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value,
+  static_assert(std::is_arithmetic_v<L> && std::is_arithmetic_v<R>,
                 "Types must be numeric.");
   static constexpr bool Test(const L lhs, const R rhs) {
     return IsLessOrEqualImpl(lhs, rhs, DstRangeRelationToSrcRange<R>(lhs),
@@ -737,7 +735,7 @@
 
 template <typename L, typename R>
 struct IsGreater {
-  static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value,
+  static_assert(std::is_arithmetic_v<L> && std::is_arithmetic_v<R>,
                 "Types must be numeric.");
   static constexpr bool Test(const L lhs, const R rhs) {
     return IsGreaterImpl(lhs, rhs, DstRangeRelationToSrcRange<R>(lhs),
@@ -757,7 +755,7 @@
 
 template <typename L, typename R>
 struct IsGreaterOrEqual {
-  static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value,
+  static_assert(std::is_arithmetic_v<L> && std::is_arithmetic_v<R>,
                 "Types must be numeric.");
   static constexpr bool Test(const L lhs, const R rhs) {
     return IsGreaterOrEqualImpl(lhs, rhs, DstRangeRelationToSrcRange<R>(lhs),
@@ -767,7 +765,7 @@
 
 template <typename L, typename R>
 struct IsEqual {
-  static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value,
+  static_assert(std::is_arithmetic_v<L> && std::is_arithmetic_v<R>,
                 "Types must be numeric.");
   static constexpr bool Test(const L lhs, const R rhs) {
     return DstRangeRelationToSrcRange<R>(lhs) ==
@@ -779,7 +777,7 @@
 
 template <typename L, typename R>
 struct IsNotEqual {
-  static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value,
+  static_assert(std::is_arithmetic_v<L> && std::is_arithmetic_v<R>,
                 "Types must be numeric.");
   static constexpr bool Test(const L lhs, const R rhs) {
     return DstRangeRelationToSrcRange<R>(lhs) !=
@@ -793,7 +791,7 @@
 // Binary arithmetic operations.
 template <template <typename, typename> class C, typename L, typename R>
 constexpr bool SafeCompare(const L lhs, const R rhs) {
-  static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value,
+  static_assert(std::is_arithmetic_v<L> && std::is_arithmetic_v<R>,
                 "Types must be numeric.");
   using Promotion = BigEnoughPromotion<L, R>;
   using BigType = typename Promotion::type;
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_math_clang_gcc_impl.h b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_math_clang_gcc_impl.h
index c76bf3d..49fd9be 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_math_clang_gcc_impl.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_math_clang_gcc_impl.h
@@ -135,7 +135,7 @@
 
 template <typename T>
 struct ClampedNegFastOp {
-  static const bool is_supported = std::is_signed<T>::value;
+  static const bool is_supported = std::is_signed_v<T>;
   __attribute__((always_inline)) static T Do(T value) {
     // Use this when there is no assembler path available.
     if (!ClampedSubFastAsmOp<T, T>::is_supported) {
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_math_shared_impl.h b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_math_shared_impl.h
index e1f2365..0d4846ad 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_math_shared_impl.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/numerics/safe_math_shared_impl.h
@@ -114,8 +114,8 @@
 // However, there is no corresponding implementation of e.g. SafeUnsignedAbs,
 // so the float versions will not compile.
 template <typename Numeric,
-          bool IsInteger = std::is_integral<Numeric>::value,
-          bool IsFloat = std::is_floating_point<Numeric>::value>
+          bool IsInteger = std::is_integral_v<Numeric>,
+          bool IsFloat = std::is_floating_point_v<Numeric>>
 struct UnsignedOrFloatForSize;
 
 template <typename Numeric>
@@ -134,35 +134,33 @@
 // if an overflow occurred.
 
 template <typename T,
-          typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
+          typename std::enable_if<std::is_integral_v<T>>::type* = nullptr>
 constexpr T NegateWrapper(T value) {
   using UnsignedT = typename std::make_unsigned<T>::type;
   // This will compile to a NEG on Intel, and is normal negation on ARM.
   return static_cast<T>(UnsignedT(0) - static_cast<UnsignedT>(value));
 }
 
-template <
-    typename T,
-    typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
+template <typename T,
+          typename std::enable_if<std::is_floating_point_v<T>>::type* = nullptr>
 constexpr T NegateWrapper(T value) {
   return -value;
 }
 
 template <typename T,
-          typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
+          typename std::enable_if<std::is_integral_v<T>>::type* = nullptr>
 constexpr typename std::make_unsigned<T>::type InvertWrapper(T value) {
   return ~value;
 }
 
 template <typename T,
-          typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
+          typename std::enable_if<std::is_integral_v<T>>::type* = nullptr>
 constexpr T AbsWrapper(T value) {
   return static_cast<T>(SafeUnsignedAbs(value));
 }
 
-template <
-    typename T,
-    typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
+template <typename T,
+          typename std::enable_if<std::is_floating_point_v<T>>::type* = nullptr>
 constexpr T AbsWrapper(T value) {
   return value < 0 ? -value : value;
 }
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_lock.h b/base/allocator/partition_allocator/src/partition_alloc/partition_lock.h
index ebc5a81..b3b28db 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/partition_lock.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/partition_lock.h
@@ -133,7 +133,7 @@
 
 // We want PartitionRoot to not have a global destructor, so this should not
 // have one.
-static_assert(std::is_trivially_destructible<Lock>::value, "");
+static_assert(std::is_trivially_destructible_v<Lock>, "");
 
 }  // namespace partition_alloc::internal
 
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr.h b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr.h
index 105ac669..a70a181 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr.h
@@ -160,7 +160,7 @@
 // raw_ptr<T> is not compatible with function pointer types. Also, they don't
 // even need the raw_ptr protection, because they don't point on heap.
 template <typename T>
-struct IsSupportedType<T, std::enable_if_t<std::is_function<T>::value>> {
+struct IsSupportedType<T, std::enable_if_t<std::is_function_v<T>>> {
   static constexpr bool value = false;
 };
 
@@ -188,8 +188,7 @@
 //
 // Such pointers are detected by checking if they're convertible to |id| type.
 template <typename T>
-struct IsSupportedType<T,
-                       std::enable_if_t<std::is_convertible<T*, id>::value>> {
+struct IsSupportedType<T, std::enable_if_t<std::is_convertible_v<T*, id>>> {
   static constexpr bool value = false;
 };
 #endif  // __OBJC__
@@ -458,8 +457,8 @@
   // Deliberately implicit in order to support implicit upcast.
   template <typename U,
             typename Unused = std::enable_if_t<
-                std::is_convertible<U*, T*>::value &&
-                !std::is_void<typename std::remove_cv<T>::type>::value>>
+                std::is_convertible_v<U*, T*> &&
+                !std::is_void_v<typename std::remove_cv<T>::type>>>
   // NOLINTNEXTLINE(google-explicit-constructor)
   PA_ALWAYS_INLINE constexpr raw_ptr(const raw_ptr<U, Traits>& ptr) noexcept
       : wrapped_ptr_(
@@ -467,8 +466,8 @@
   // Deliberately implicit in order to support implicit upcast.
   template <typename U,
             typename Unused = std::enable_if_t<
-                std::is_convertible<U*, T*>::value &&
-                !std::is_void<typename std::remove_cv<T>::type>::value>>
+                std::is_convertible_v<U*, T*> &&
+                !std::is_void_v<typename std::remove_cv<T>::type>>>
   // NOLINTNEXTLINE(google-explicit-constructor)
   PA_ALWAYS_INLINE constexpr raw_ptr(raw_ptr<U, Traits>&& ptr) noexcept
       : wrapped_ptr_(Impl::template Upcast<T, U>(ptr.wrapped_ptr_)) {
@@ -491,8 +490,8 @@
   // Upcast assignment
   template <typename U,
             typename Unused = std::enable_if_t<
-                std::is_convertible<U*, T*>::value &&
-                !std::is_void<typename std::remove_cv<T>::type>::value>>
+                std::is_convertible_v<U*, T*> &&
+                !std::is_void_v<typename std::remove_cv<T>::type>>>
   PA_ALWAYS_INLINE constexpr raw_ptr& operator=(
       const raw_ptr<U, Traits>& ptr) noexcept {
     // Make sure that pointer isn't assigned to itself (look at raw_ptr address,
@@ -510,8 +509,8 @@
   }
   template <typename U,
             typename Unused = std::enable_if_t<
-                std::is_convertible<U*, T*>::value &&
-                !std::is_void<typename std::remove_cv<T>::type>::value>>
+                std::is_convertible_v<U*, T*> &&
+                !std::is_void_v<typename std::remove_cv<T>::type>>>
   PA_ALWAYS_INLINE constexpr raw_ptr& operator=(
       raw_ptr<U, Traits>&& ptr) noexcept {
     // Make sure that pointer isn't assigned to itself (look at raw_ptr address,
@@ -570,7 +569,7 @@
 
   template <typename U = T,
             typename Unused = std::enable_if_t<
-                !std::is_void<typename std::remove_cv<U>::type>::value>>
+                !std::is_void_v<typename std::remove_cv<U>::type>>>
   PA_ALWAYS_INLINE constexpr U& operator*() const {
     return *GetForDereference();
   }
@@ -643,7 +642,7 @@
             typename U = T,
             RawPtrTraits CopyTraits = Traits,
             typename Unused = std::enable_if_t<
-                !std::is_void<typename std::remove_cv<U>::type>::value &&
+                !std::is_void_v<typename std::remove_cv<U>::type> &&
                 partition_alloc::internal::is_offset_type<Z>>>
   U& operator[](Z delta_elems) const {
     static_assert(
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_asan_unowned_impl.h b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_asan_unowned_impl.h
index 4a05e0f..536d7ec3 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_asan_unowned_impl.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_asan_unowned_impl.h
@@ -76,7 +76,7 @@
   // Upcasts the wrapped pointer.
   template <typename To, typename From>
   PA_ALWAYS_INLINE static constexpr To* Upcast(From* wrapped_ptr) {
-    static_assert(std::is_convertible<From*, To*>::value,
+    static_assert(std::is_convertible_v<From*, To*>,
                   "From must be convertible to To.");
     // Note, this cast may change the address if upcasting to base that lies in
     // the middle of the derived object.
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_backup_ref_impl.h b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_backup_ref_impl.h
index b5727e8a..34fffbfa 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_backup_ref_impl.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_backup_ref_impl.h
@@ -302,7 +302,7 @@
   // Upcasts the wrapped pointer.
   template <typename To, typename From>
   PA_ALWAYS_INLINE static constexpr To* Upcast(From* wrapped_ptr) {
-    static_assert(std::is_convertible<From*, To*>::value,
+    static_assert(std::is_convertible_v<From*, To*>,
                   "From must be convertible to To.");
     // Note, this cast may change the address if upcasting to base that lies in
     // the middle of the derived object.
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_hookable_impl.h b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_hookable_impl.h
index a4dc462..2a1430c 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_hookable_impl.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_hookable_impl.h
@@ -120,7 +120,7 @@
   // Upcasts the wrapped pointer.
   template <typename To, typename From>
   PA_ALWAYS_INLINE static constexpr To* Upcast(From* wrapped_ptr) {
-    static_assert(std::is_convertible<From*, To*>::value,
+    static_assert(std::is_convertible_v<From*, To*>,
                   "From must be convertible to To.");
     // Note, this cast may change the address if upcasting to base that lies in
     // the middle of the derived object.
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_noop_impl.h b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_noop_impl.h
index 607251b..2fc12c6 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_noop_impl.h
+++ b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_noop_impl.h
@@ -55,7 +55,7 @@
   // Upcasts the wrapped pointer.
   template <typename To, typename From>
   PA_ALWAYS_INLINE static constexpr To* Upcast(From* wrapped_ptr) {
-    static_assert(std::is_convertible<From*, To*>::value,
+    static_assert(std::is_convertible_v<From*, To*>,
                   "From must be convertible to To.");
     // Note, this cast may change the address if upcasting to base that lies
     // in the middle of the derived object.
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc
index beb332eb..462ee6d 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc
+++ b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc
@@ -67,11 +67,11 @@
     !BUILDFLAG(RAW_PTR_ZERO_ON_MOVE) && !BUILDFLAG(RAW_PTR_ZERO_ON_DESTRUCT)
 // |is_trivially_copyable| assertion means that arrays/vectors of raw_ptr can
 // be copied by memcpy.
-static_assert(std::is_trivially_copyable<raw_ptr<void>>::value,
+static_assert(std::is_trivially_copyable_v<raw_ptr<void>>,
               "raw_ptr should be trivially copyable");
-static_assert(std::is_trivially_copyable<raw_ptr<int>>::value,
+static_assert(std::is_trivially_copyable_v<raw_ptr<int>>,
               "raw_ptr should be trivially copyable");
-static_assert(std::is_trivially_copyable<raw_ptr<std::string>>::value,
+static_assert(std::is_trivially_copyable_v<raw_ptr<std::string>>,
               "raw_ptr should be trivially copyable");
 #endif  // !BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) &&
         // !BUILDFLAG(USE_ASAN_UNOWNED_PTR) &&
@@ -95,13 +95,12 @@
 //     constructor of 'TraceValue' is implicitly deleted because variant field
 //     'as_pointer' has a non-trivial default constructor
 //       raw_ptr<const void> as_pointer;
-static_assert(std::is_trivially_default_constructible<raw_ptr<void>>::value,
+static_assert(std::is_trivially_default_constructible_v<raw_ptr<void>>,
               "raw_ptr should be trivially default constructible");
-static_assert(std::is_trivially_default_constructible<raw_ptr<int>>::value,
+static_assert(std::is_trivially_default_constructible_v<raw_ptr<int>>,
               "raw_ptr should be trivially default constructible");
-static_assert(
-    std::is_trivially_default_constructible<raw_ptr<std::string>>::value,
-    "raw_ptr should be trivially default constructible");
+static_assert(std::is_trivially_default_constructible_v<raw_ptr<std::string>>,
+              "raw_ptr should be trivially default constructible");
 #endif  // !BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) &&
         // !BUILDFLAG(USE_ASAN_UNOWNED_PTR) &&
         // !BUILDFLAG(USE_HOOKABLE_RAW_PTR) &&
@@ -846,14 +845,12 @@
   class Base {};
   class Derived : private Base {};
   class Unrelated {};
-  EXPECT_FALSE((std::is_convertible<raw_ptr<Derived>, raw_ptr<Base>>::value));
-  EXPECT_FALSE((std::is_convertible<raw_ptr<Unrelated>, raw_ptr<Base>>::value));
-  EXPECT_FALSE((std::is_convertible<raw_ptr<Unrelated>, raw_ptr<void>>::value));
-  EXPECT_FALSE((std::is_convertible<raw_ptr<void>, raw_ptr<Unrelated>>::value));
-  EXPECT_FALSE(
-      (std::is_convertible<raw_ptr<int64_t>, raw_ptr<int32_t>>::value));
-  EXPECT_FALSE(
-      (std::is_convertible<raw_ptr<int16_t>, raw_ptr<int32_t>>::value));
+  EXPECT_FALSE((std::is_convertible_v<raw_ptr<Derived>, raw_ptr<Base>>));
+  EXPECT_FALSE((std::is_convertible_v<raw_ptr<Unrelated>, raw_ptr<Base>>));
+  EXPECT_FALSE((std::is_convertible_v<raw_ptr<Unrelated>, raw_ptr<void>>));
+  EXPECT_FALSE((std::is_convertible_v<raw_ptr<void>, raw_ptr<Unrelated>>));
+  EXPECT_FALSE((std::is_convertible_v<raw_ptr<int64_t>, raw_ptr<int32_t>>));
+  EXPECT_FALSE((std::is_convertible_v<raw_ptr<int16_t>, raw_ptr<int32_t>>));
 }
 
 TEST_F(RawPtrTest, UpcastPerformance) {
diff --git a/base/allocator/partition_allocator/src/partition_alloc/random.cc b/base/allocator/partition_allocator/src/partition_alloc/random.cc
index 784272f..db5fa4c 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/random.cc
+++ b/base/allocator/partition_allocator/src/partition_alloc/random.cc
@@ -47,7 +47,7 @@
 
 // Note: this is redundant, since the anonymous union is incompatible with a
 // non-trivial default destructor. Not meant to be destructed anyway.
-static_assert(std::is_trivially_destructible<RandomGenerator>::value, "");
+static_assert(std::is_trivially_destructible_v<RandomGenerator>, "");
 
 namespace {
 
diff --git a/base/allocator/partition_allocator/src/partition_alloc/shim/malloc_zone_functions_apple.cc b/base/allocator/partition_allocator/src/partition_alloc/shim/malloc_zone_functions_apple.cc
index 5445121c..1c786b1 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/shim/malloc_zone_functions_apple.cc
+++ b/base/allocator/partition_allocator/src/partition_alloc/shim/malloc_zone_functions_apple.cc
@@ -13,7 +13,7 @@
 namespace allocator_shim {
 
 MallocZoneFunctions g_malloc_zones[kMaxZoneCount];
-static_assert(std::is_pod<MallocZoneFunctions>::value,
+static_assert(std::is_pod_v<MallocZoneFunctions>,
               "MallocZoneFunctions must be POD");
 
 void StoreZoneFunctions(const ChromeMallocZone* zone,
diff --git a/base/allocator/partition_allocator/src/partition_alloc/starscan/pcscan_internal.cc b/base/allocator/partition_allocator/src/partition_alloc/starscan/pcscan_internal.cc
index 6c737be..8b25637 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/starscan/pcscan_internal.cc
+++ b/base/allocator/partition_allocator/src/partition_alloc/starscan/pcscan_internal.cc
@@ -383,7 +383,7 @@
     size_t size_;
   };
 
-  static_assert(std::is_trivially_default_constructible<ScanAreas>::value,
+  static_assert(std::is_trivially_default_constructible_v<ScanAreas>,
                 "ScanAreas must be trivially default constructible to ensure "
                 "that no memsets are generated by the compiler as a "
                 "result of value-initialization (or zero-initialization)");
diff --git a/base/android/java/src/org/chromium/base/BuildInfo.java b/base/android/java/src/org/chromium/base/BuildInfo.java
index 533a96d..f4247a0 100644
--- a/base/android/java/src/org/chromium/base/BuildInfo.java
+++ b/base/android/java/src/org/chromium/base/BuildInfo.java
@@ -18,7 +18,8 @@
 import android.os.Process;
 import android.text.TextUtils;
 
-import org.chromium.base.annotations.CalledByNative;
+import org.jni_zero.CalledByNative;
+
 import org.chromium.base.compat.ApiHelperForP;
 import org.chromium.build.BuildConfig;
 
diff --git a/base/android/java/src/org/chromium/base/annotations/AccessedByNative.java b/base/android/java/src/org/chromium/base/annotations/AccessedByNative.java
deleted file mode 100644
index 24acba5..0000000
--- a/base/android/java/src/org/chromium/base/annotations/AccessedByNative.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.base.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Applied to fields that are accessed from native via JNI. Causes R8 to not
- * rename them.
- */
-@Target(ElementType.FIELD)
-@Retention(RetentionPolicy.CLASS)
-public @interface AccessedByNative {
-    public String value() default "";
-}
diff --git a/base/android/java/src/org/chromium/base/annotations/CalledByNative.java b/base/android/java/src/org/chromium/base/annotations/CalledByNative.java
deleted file mode 100644
index 5da03a2..0000000
--- a/base/android/java/src/org/chromium/base/annotations/CalledByNative.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.base.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Used by the JNI generator to create the necessary JNI bindings and expose this method to native
- * code.
- *
- * <p>Any uncaught Java exceptions will crash the current process. This is generally the desired
- * behavior, since most exceptions indicate an unexpected error. If your java method expects an
- * exception, we recommend refactoring to catch exceptions and indicate errors with special return
- * values instead. If this is not possible, see {@link CalledByNativeUnchecked} instead.
- */
-@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
-@Retention(RetentionPolicy.CLASS)
-public @interface CalledByNative {
-    /*
-     *  If present, tells which inner class the method belongs to.
-     */
-    public String value() default "";
-}
diff --git a/base/android/java/src/org/chromium/base/annotations/CalledByNativeForTesting.java b/base/android/java/src/org/chromium/base/annotations/CalledByNativeForTesting.java
deleted file mode 100644
index b2c7a85..0000000
--- a/base/android/java/src/org/chromium/base/annotations/CalledByNativeForTesting.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.base.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Used by the JNI generator to create the necessary JNI bindings and expose this method to native
- * test-only code.
- *
- * Any method annotated by this will be kept around for tests only. If you wish to call your method
- * from non-test code, see {@link CalledByNative} instead.
- */
-@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
-@Retention(RetentionPolicy.CLASS)
-public @interface CalledByNativeForTesting {
-    /*
-     *  If present, tells which inner class the method belongs to.
-     */
-    public String value() default "";
-}
diff --git a/base/android/java/src/org/chromium/base/annotations/CalledByNativeUnchecked.java b/base/android/java/src/org/chromium/base/annotations/CalledByNativeUnchecked.java
deleted file mode 100644
index 563d8c4..0000000
--- a/base/android/java/src/org/chromium/base/annotations/CalledByNativeUnchecked.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.base.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Similar to {@link CalledByNative}, this also exposes JNI bindings to native code. The main
- * difference is this <b>will not</b> crash the browser process if the Java method throws an
- * exception. However, the C++ caller <b>must</b> handle and clear the exception before calling into
- * any other Java code, otherwise the next Java method call will crash (with the previous call's
- * exception, which leads to a very confusing debugging experience).
- *
- * <p>Usage of this annotation should be very rare; due to the complexity of correctly handling
- * exceptions in C++, prefer using {@link CalledByNative}.
- */
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.CLASS)
-public @interface CalledByNativeUnchecked {
-    /*
-     *  If present, tells which inner class the method belongs to.
-     */
-    public String value() default "";
-}
diff --git a/base/android/java/src/org/chromium/base/annotations/JNINamespace.java b/base/android/java/src/org/chromium/base/annotations/JNINamespace.java
deleted file mode 100644
index 7d98448d..0000000
--- a/base/android/java/src/org/chromium/base/annotations/JNINamespace.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.base.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * @JNINamespace is used by the JNI generator to create the necessary JNI
- * bindings and expose this method to native code using the specified namespace.
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface JNINamespace {
-    public String value();
-}
diff --git a/base/android/java/src/org/chromium/base/annotations/NativeClassQualifiedName.java b/base/android/java/src/org/chromium/base/annotations/NativeClassQualifiedName.java
deleted file mode 100644
index d13e051f..0000000
--- a/base/android/java/src/org/chromium/base/annotations/NativeClassQualifiedName.java
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.base.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * @NativeClassQualifiedName is used by the JNI generator to create the necessary JNI
- * bindings to call into the specified native class name.
- */
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface NativeClassQualifiedName {
-    /*
-     * Tells which native class the method is going to be bound to.
-     * The first parameter of the annotated method must be an int nativePtr pointing to
-     * an instance of this class.
-     */
-    public String value();
-}
diff --git a/base/android/java/src/org/chromium/base/annotations/NativeMethods.java b/base/android/java/src/org/chromium/base/annotations/NativeMethods.java
deleted file mode 100644
index edf6930..0000000
--- a/base/android/java/src/org/chromium/base/annotations/NativeMethods.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-package org.chromium.base.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.SOURCE)
-public @interface NativeMethods {
-    /**
-     * Tells the build system to call a different GEN_JNI, prefixed by the value we put here. This
-     * should only be used for feature modules where we need a different GEN_JNI. For example, if
-     * you did @NativeMethods("dfmname"), this would call into dfmname_GEN_JNI.java.
-     */
-    public String value() default "";
-}
diff --git a/base/atomicops_unittest.cc b/base/atomicops_unittest.cc
index d75651d..b494bd1 100644
--- a/base/atomicops_unittest.cc
+++ b/base/atomicops_unittest.cc
@@ -177,7 +177,7 @@
 
   AtomicType value;
 
-  if constexpr (std::is_same<AtomicType, base::subtle::Atomic32>::value) {
+  if constexpr (std::is_same_v<AtomicType, base::subtle::Atomic32>) {
     base::subtle::NoBarrier_Store(&value, kVal1);
     EXPECT_EQ(kVal1, value);
     base::subtle::NoBarrier_Store(&value, kVal2);
diff --git a/base/big_endian.h b/base/big_endian.h
index b741ad1..c7845fb 100644
--- a/base/big_endian.h
+++ b/base/big_endian.h
@@ -59,7 +59,7 @@
 // This would cause SIGBUS on ARMv5 or earlier and ARMv6-M.
 template <typename T>
 inline void ReadBigEndian(const uint8_t buf[], T* out) {
-  static_assert(std::is_integral<T>::value, "T has to be an integral type.");
+  static_assert(std::is_integral_v<T>, "T has to be an integral type.");
   // Make an unsigned version of the output type to make shift possible
   // without UB.
   typename std::make_unsigned<T>::type raw;
@@ -71,7 +71,7 @@
 // Note: this loop is unrolled with -O1 and above.
 template<typename T>
 inline void WriteBigEndian(char buf[], T val) {
-  static_assert(std::is_integral<T>::value, "T has to be an integral type.");
+  static_assert(std::is_integral_v<T>, "T has to be an integral type.");
   const auto unsigned_val =
       static_cast<typename std::make_unsigned<T>::type>(val);
   const auto raw = internal::ByteSwapIfLittleEndian(unsigned_val);
diff --git a/base/bits.h b/base/bits.h
index dfe6dfd..b21beebf 100644
--- a/base/bits.h
+++ b/base/bits.h
@@ -22,7 +22,7 @@
 // Returns true iff |value| is a power of 2.
 //
 // TODO(pkasting): When C++20 is available, replace with std::has_single_bit().
-template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
+template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
 constexpr bool IsPowerOfTwo(T value) {
   // From "Hacker's Delight": Section 2.1 Manipulating Rightmost Bits.
   //
@@ -85,8 +85,7 @@
 // do better, but we'll avoid doing that unless we see proof that we need to.
 template <typename T, int bits = sizeof(T) * 8>
 ALWAYS_INLINE constexpr
-    typename std::enable_if<std::is_unsigned<T>::value && sizeof(T) <= 8,
-                            int>::type
+    typename std::enable_if<std::is_unsigned_v<T> && sizeof(T) <= 8, int>::type
     CountLeadingZeroBits(T value) {
   static_assert(bits > 0, "invalid instantiation");
   return LIKELY(value)
@@ -98,8 +97,7 @@
 
 template <typename T, int bits = sizeof(T) * 8>
 ALWAYS_INLINE constexpr
-    typename std::enable_if<std::is_unsigned<T>::value && sizeof(T) <= 8,
-                            int>::type
+    typename std::enable_if<std::is_unsigned_v<T> && sizeof(T) <= 8, int>::type
     CountTrailingZeroBits(T value) {
   return LIKELY(value) ? bits == 64
                              ? __builtin_ctzll(static_cast<uint64_t>(value))
@@ -130,7 +128,7 @@
 // Can be used instead of manually shifting a 1 to the left.
 template <typename T>
 constexpr T LeftmostBit() {
-  static_assert(std::is_integral<T>::value,
+  static_assert(std::is_integral_v<T>,
                 "This function can only be used with integral types.");
   T one(1u);
   return one << (8 * sizeof(T) - 1);
diff --git a/base/check_op.h b/base/check_op.h
index 1fba78d..53eb17b6 100644
--- a/base/check_op.h
+++ b/base/check_op.h
@@ -71,7 +71,7 @@
 template <typename T>
 inline typename std::enable_if<
     base::internal::SupportsOstreamOperator<const T&> &&
-        !std::is_function<typename std::remove_pointer<T>::type>::value,
+        !std::is_function_v<typename std::remove_pointer<T>::type>,
     char*>::type
 CheckOpValueStr(const T& v) {
   auto f = [](std::ostream& s, const void* p) {
@@ -111,7 +111,7 @@
 // pointers, so this is a no-op for MSVC.)
 template <typename T>
 inline typename std::enable_if<
-    std::is_function<typename std::remove_pointer<T>::type>::value,
+    std::is_function_v<typename std::remove_pointer<T>::type>,
     char*>::type
 CheckOpValueStr(const T& v) {
   return CheckOpValueStr(reinterpret_cast<const void*>(v));
@@ -121,8 +121,7 @@
 // (i.e. scoped enums where no operator<< overload was declared).
 template <typename T>
 inline typename std::enable_if<
-    !base::internal::SupportsOstreamOperator<const T&> &&
-        std::is_enum<T>::value,
+    !base::internal::SupportsOstreamOperator<const T&> && std::is_enum_v<T>,
     char*>::type
 CheckOpValueStr(const T& v) {
   return CheckOpValueStr(
@@ -169,27 +168,27 @@
 
 // The second overload avoids address-taking of static members for
 // fundamental types.
-#define DEFINE_CHECK_OP_IMPL(name, op)                                  \
-  template <typename T, typename U,                                     \
-            std::enable_if_t<!std::is_fundamental<T>::value ||          \
-                                 !std::is_fundamental<U>::value,        \
-                             int> = 0>                                  \
-  constexpr char* Check##name##Impl(const T& v1, const U& v2,           \
-                                    const char* expr_str) {             \
-    if (LIKELY(ANALYZER_ASSUME_TRUE(v1 op v2)))                         \
-      return nullptr;                                                   \
-    return CreateCheckOpLogMessageString(expr_str, CheckOpValueStr(v1), \
-                                         CheckOpValueStr(v2));          \
-  }                                                                     \
-  template <typename T, typename U,                                     \
-            std::enable_if_t<std::is_fundamental<T>::value &&           \
-                                 std::is_fundamental<U>::value,         \
-                             int> = 0>                                  \
-  constexpr char* Check##name##Impl(T v1, U v2, const char* expr_str) { \
-    if (LIKELY(ANALYZER_ASSUME_TRUE(v1 op v2)))                         \
-      return nullptr;                                                   \
-    return CreateCheckOpLogMessageString(expr_str, CheckOpValueStr(v1), \
-                                         CheckOpValueStr(v2));          \
+#define DEFINE_CHECK_OP_IMPL(name, op)                                         \
+  template <                                                                   \
+      typename T, typename U,                                                  \
+      std::enable_if_t<!std::is_fundamental_v<T> || !std::is_fundamental_v<U>, \
+                       int> = 0>                                               \
+  constexpr char* Check##name##Impl(const T& v1, const U& v2,                  \
+                                    const char* expr_str) {                    \
+    if (LIKELY(ANALYZER_ASSUME_TRUE(v1 op v2)))                                \
+      return nullptr;                                                          \
+    return CreateCheckOpLogMessageString(expr_str, CheckOpValueStr(v1),        \
+                                         CheckOpValueStr(v2));                 \
+  }                                                                            \
+  template <                                                                   \
+      typename T, typename U,                                                  \
+      std::enable_if_t<std::is_fundamental_v<T> && std::is_fundamental_v<U>,   \
+                       int> = 0>                                               \
+  constexpr char* Check##name##Impl(T v1, U v2, const char* expr_str) {        \
+    if (LIKELY(ANALYZER_ASSUME_TRUE(v1 op v2)))                                \
+      return nullptr;                                                          \
+    return CreateCheckOpLogMessageString(expr_str, CheckOpValueStr(v1),        \
+                                         CheckOpValueStr(v2));                 \
   }
 
 // clang-format off
diff --git a/base/cxx20_to_address.h b/base/cxx20_to_address.h
index b9158d2..2582c194 100644
--- a/base/cxx20_to_address.h
+++ b/base/cxx20_to_address.h
@@ -31,7 +31,7 @@
 // Reference: https://wg21.link/pointer.conversion#lib:to_address
 template <typename T>
 constexpr T* to_address(T* p) noexcept {
-  static_assert(!std::is_function<T>::value,
+  static_assert(!std::is_function_v<T>,
                 "Error: T must not be a function type.");
   return p;
 }
diff --git a/base/files/memory_mapped_file.cc b/base/files/memory_mapped_file.cc
index 132c3a98..985c3ae 100644
--- a/base/files/memory_mapped_file.cc
+++ b/base/files/memory_mapped_file.cc
@@ -41,6 +41,14 @@
     case READ_ONLY:
       flags = File::FLAG_OPEN | File::FLAG_READ;
       break;
+    case READ_WRITE_COPY:
+      flags = File::FLAG_OPEN | File::FLAG_READ;
+#if BUILDFLAG(IS_FUCHSIA)
+      // Fuchsia's mmap() implementation does not allow us to create a
+      // copy-on-write mapping of a file opened as read-only.
+      flags |= File::FLAG_WRITE;
+#endif
+      break;
     case READ_WRITE:
       flags = File::FLAG_OPEN | File::FLAG_READ | File::FLAG_WRITE;
       break;
@@ -92,6 +100,7 @@
       [[fallthrough]];
     case READ_ONLY:
     case READ_WRITE:
+    case READ_WRITE_COPY:
       // Ensure that the region values are valid.
       if (region.offset < 0) {
         DLOG(ERROR) << "Region bounds are not valid.";
diff --git a/base/files/memory_mapped_file.h b/base/files/memory_mapped_file.h
index d099ce4..b63fa8c8 100644
--- a/base/files/memory_mapped_file.h
+++ b/base/files/memory_mapped_file.h
@@ -11,6 +11,7 @@
 #include <utility>
 
 #include "base/base_export.h"
+#include "base/containers/span.h"
 #include "base/files/file.h"
 #include "base/memory/raw_ptr.h"
 #include "build/build_config.h"
@@ -39,6 +40,11 @@
     // be as much as 1s on some systems.
     READ_WRITE,
 
+    // This provides read/write access to the mapped file contents as above, but
+    // applies a copy-on-write policy such that no writes are carried through to
+    // the underlying file.
+    READ_WRITE_COPY,
+
     // This provides read/write access but with the ability to write beyond
     // the end of the existing file up to a maximum size specified as the
     // "region". Depending on the OS, the file may or may not be immediately
@@ -109,6 +115,12 @@
   uint8_t* data() { return data_; }
   size_t length() const { return length_; }
 
+  span<const uint8_t> bytes() const { return make_span(data_.get(), length_); }
+
+  span<uint8_t> mutable_bytes() const {
+    return make_span(data_.get(), length_);
+  }
+
   // Is file_ a valid file handle that points to an open, memory mapped file?
   bool IsValid() const;
 
diff --git a/base/files/memory_mapped_file_posix.cc b/base/files/memory_mapped_file_posix.cc
index be5084bb..99dbedc 100644
--- a/base/files/memory_mapped_file_posix.cc
+++ b/base/files/memory_mapped_file_posix.cc
@@ -66,18 +66,24 @@
     length_ = region.size;
   }
 
-  int flags = 0;
+  int prot = 0;
+  int flags = MAP_SHARED;
   switch (access) {
     case READ_ONLY:
-      flags |= PROT_READ;
+      prot |= PROT_READ;
       break;
 
     case READ_WRITE:
-      flags |= PROT_READ | PROT_WRITE;
+      prot |= PROT_READ | PROT_WRITE;
+      break;
+
+    case READ_WRITE_COPY:
+      prot |= PROT_READ | PROT_WRITE;
+      flags = MAP_PRIVATE;
       break;
 
     case READ_WRITE_EXTEND:
-      flags |= PROT_READ | PROT_WRITE;
+      prot |= PROT_READ | PROT_WRITE;
 
       if (!AllocateFileRegion(&file_, region.offset, region.size))
         return false;
@@ -85,8 +91,8 @@
       break;
   }
 
-  data_ = static_cast<uint8_t*>(mmap(nullptr, map_size, flags, MAP_SHARED,
-                                     file_.GetPlatformFile(), map_start));
+  data_ = static_cast<uint8_t*>(
+      mmap(nullptr, map_size, prot, flags, file_.GetPlatformFile(), map_start));
   if (data_ == MAP_FAILED) {
     DPLOG(ERROR) << "mmap " << file_.GetPlatformFile();
     return false;
diff --git a/base/files/memory_mapped_file_unittest.cc b/base/files/memory_mapped_file_unittest.cc
index dc9b9b6..93969ba 100644
--- a/base/files/memory_mapped_file_unittest.cc
+++ b/base/files/memory_mapped_file_unittest.cc
@@ -27,9 +27,9 @@
 }
 
 // Check that the watermark sequence is consistent with the |offset| provided.
-bool CheckBufferContents(const uint8_t* data, size_t size, size_t offset) {
-  std::unique_ptr<uint8_t[]> test_data(CreateTestBuffer(size, offset));
-  return memcmp(test_data.get(), data, size) == 0;
+bool CheckBufferContents(span<const uint8_t> bytes, size_t offset) {
+  std::unique_ptr<uint8_t[]> test_data(CreateTestBuffer(bytes.size(), offset));
+  return memcmp(test_data.get(), bytes.data(), bytes.size()) == 0;
 }
 
 class MemoryMappedFileTest : public PlatformTest {
@@ -67,7 +67,7 @@
   ASSERT_EQ(kFileSize, map.length());
   ASSERT_TRUE(map.data() != nullptr);
   EXPECT_TRUE(map.IsValid());
-  ASSERT_TRUE(CheckBufferContents(map.data(), kFileSize, 0));
+  ASSERT_TRUE(CheckBufferContents(map.bytes(), 0));
 }
 
 TEST_F(MemoryMappedFileTest, MapWholeFileByFD) {
@@ -79,7 +79,7 @@
   ASSERT_EQ(kFileSize, map.length());
   ASSERT_TRUE(map.data() != nullptr);
   EXPECT_TRUE(map.IsValid());
-  ASSERT_TRUE(CheckBufferContents(map.data(), kFileSize, 0));
+  ASSERT_TRUE(CheckBufferContents(map.bytes(), 0));
 }
 
 TEST_F(MemoryMappedFileTest, MapSmallFile) {
@@ -90,7 +90,7 @@
   ASSERT_EQ(kFileSize, map.length());
   ASSERT_TRUE(map.data() != nullptr);
   EXPECT_TRUE(map.IsValid());
-  ASSERT_TRUE(CheckBufferContents(map.data(), kFileSize, 0));
+  ASSERT_TRUE(CheckBufferContents(map.bytes(), 0));
 }
 
 TEST_F(MemoryMappedFileTest, MapWholeFileUsingRegion) {
@@ -104,7 +104,7 @@
   ASSERT_EQ(kFileSize, map.length());
   ASSERT_TRUE(map.data() != nullptr);
   EXPECT_TRUE(map.IsValid());
-  ASSERT_TRUE(CheckBufferContents(map.data(), kFileSize, 0));
+  ASSERT_TRUE(CheckBufferContents(map.bytes(), 0));
 }
 
 TEST_F(MemoryMappedFileTest, MapPartialRegionAtBeginning) {
@@ -119,7 +119,7 @@
   ASSERT_EQ(kPartialSize, map.length());
   ASSERT_TRUE(map.data() != nullptr);
   EXPECT_TRUE(map.IsValid());
-  ASSERT_TRUE(CheckBufferContents(map.data(), kPartialSize, 0));
+  ASSERT_TRUE(CheckBufferContents(map.bytes().first(kPartialSize), 0));
 }
 
 TEST_F(MemoryMappedFileTest, MapPartialRegionAtEnd) {
@@ -135,7 +135,7 @@
   ASSERT_EQ(kPartialSize, map.length());
   ASSERT_TRUE(map.data() != nullptr);
   EXPECT_TRUE(map.IsValid());
-  ASSERT_TRUE(CheckBufferContents(map.data(), kPartialSize, kOffset));
+  ASSERT_TRUE(CheckBufferContents(map.bytes().first(kPartialSize), kOffset));
 }
 
 TEST_F(MemoryMappedFileTest, MapSmallPartialRegionInTheMiddle) {
@@ -152,7 +152,7 @@
   ASSERT_EQ(kPartialSize, map.length());
   ASSERT_TRUE(map.data() != nullptr);
   EXPECT_TRUE(map.IsValid());
-  ASSERT_TRUE(CheckBufferContents(map.data(), kPartialSize, kOffset));
+  ASSERT_TRUE(CheckBufferContents(map.bytes().first(kPartialSize), kOffset));
 }
 
 TEST_F(MemoryMappedFileTest, MapLargePartialRegionInTheMiddle) {
@@ -169,7 +169,7 @@
   ASSERT_EQ(kPartialSize, map.length());
   ASSERT_TRUE(map.data() != nullptr);
   EXPECT_TRUE(map.IsValid());
-  ASSERT_TRUE(CheckBufferContents(map.data(), kPartialSize, kOffset));
+  ASSERT_TRUE(CheckBufferContents(map.bytes().first(kPartialSize), kOffset));
 }
 
 TEST_F(MemoryMappedFileTest, WriteableFile) {
@@ -182,15 +182,16 @@
     ASSERT_EQ(kFileSize, map.length());
     ASSERT_TRUE(map.data() != nullptr);
     EXPECT_TRUE(map.IsValid());
-    ASSERT_TRUE(CheckBufferContents(map.data(), kFileSize, 0));
+    ASSERT_TRUE(CheckBufferContents(map.bytes(), 0));
 
-    uint8_t* bytes = map.data();
+    span<uint8_t> bytes = map.mutable_bytes();
     bytes[0] = 'B';
     bytes[1] = 'a';
     bytes[2] = 'r';
     bytes[kFileSize - 1] = '!';
-    EXPECT_FALSE(CheckBufferContents(map.data(), kFileSize, 0));
-    EXPECT_TRUE(CheckBufferContents(map.data() + 3, kFileSize - 4, 3));
+    EXPECT_FALSE(CheckBufferContents(map.bytes(), 0));
+    EXPECT_TRUE(
+        CheckBufferContents(map.bytes().first(kFileSize - 1).subspan(3), 3));
   }
 
   int64_t file_size;
@@ -203,6 +204,39 @@
   EXPECT_EQ("!", contents.substr(kFileSize - 1, 1));
 }
 
+TEST_F(MemoryMappedFileTest, CopyOnWrite) {
+  const size_t kFileSize = 127;
+  CreateTemporaryTestFile(kFileSize);
+
+  {
+    MemoryMappedFile map;
+    ASSERT_TRUE(
+        map.Initialize(temp_file_path(), MemoryMappedFile::READ_WRITE_COPY));
+    ASSERT_EQ(kFileSize, map.length());
+    ASSERT_TRUE(map.data() != nullptr);
+    EXPECT_TRUE(map.IsValid());
+    ASSERT_TRUE(CheckBufferContents(map.bytes(), 0));
+
+    span<uint8_t> bytes = map.mutable_bytes();
+    bytes[0] = 'B';
+    bytes[1] = 'a';
+    bytes[2] = 'r';
+    bytes[kFileSize - 1] = '!';
+    EXPECT_FALSE(CheckBufferContents(map.bytes(), 0));
+    EXPECT_TRUE(
+        CheckBufferContents(map.bytes().first(kFileSize - 1).subspan(3), 3));
+  }
+
+  int64_t file_size;
+  ASSERT_TRUE(GetFileSize(temp_file_path(), &file_size));
+  EXPECT_EQ(static_cast<int64_t>(kFileSize), file_size);
+
+  // Although the buffer has been modified in memory, the file is unchanged.
+  std::string contents;
+  ASSERT_TRUE(ReadFileToString(temp_file_path(), &contents));
+  EXPECT_TRUE(CheckBufferContents(as_bytes(span(contents)), 0));
+}
+
 TEST_F(MemoryMappedFileTest, ExtendableFile) {
   const size_t kFileSize = 127;
   const size_t kFileExtend = 100;
@@ -218,16 +252,16 @@
     EXPECT_EQ(kFileSize + kFileExtend, map.length());
     ASSERT_TRUE(map.data() != nullptr);
     EXPECT_TRUE(map.IsValid());
-    ASSERT_TRUE(CheckBufferContents(map.data(), kFileSize, 0));
+    ASSERT_TRUE(CheckBufferContents(map.bytes().first(kFileSize), 0));
 
-    uint8_t* bytes = map.data();
+    span<uint8_t> bytes = map.mutable_bytes();
     EXPECT_EQ(0, bytes[kFileSize + 0]);
     EXPECT_EQ(0, bytes[kFileSize + 1]);
     EXPECT_EQ(0, bytes[kFileSize + 2]);
     bytes[kFileSize + 0] = 'B';
     bytes[kFileSize + 1] = 'A';
     bytes[kFileSize + 2] = 'Z';
-    EXPECT_TRUE(CheckBufferContents(map.data(), kFileSize, 0));
+    EXPECT_TRUE(CheckBufferContents(map.bytes().first(kFileSize), 0));
   }
 
   int64_t file_size;
diff --git a/base/files/memory_mapped_file_win.cc b/base/files/memory_mapped_file_win.cc
index 7169fba5..57147fe 100644
--- a/base/files/memory_mapped_file_win.cc
+++ b/base/files/memory_mapped_file_win.cc
@@ -62,17 +62,25 @@
   if (!file_.IsValid())
     return false;
 
+  DWORD view_access;
   DWORD flags = 0;
   ULARGE_INTEGER size = {};
   switch (access) {
     case READ_ONLY:
       flags |= PAGE_READONLY;
+      view_access = FILE_MAP_READ;
       break;
     case READ_WRITE:
       flags |= PAGE_READWRITE;
+      view_access = FILE_MAP_WRITE;
+      break;
+    case READ_WRITE_COPY:
+      flags |= PAGE_WRITECOPY;
+      view_access = FILE_MAP_COPY;
       break;
     case READ_WRITE_EXTEND:
       flags |= PAGE_READWRITE;
+      view_access = FILE_MAP_WRITE;
       size.QuadPart = region.size;
       break;
     case READ_CODE_IMAGE:
@@ -119,10 +127,9 @@
     length_ = region.size;
   }
 
-  data_ = static_cast<uint8_t*>(
-      ::MapViewOfFile(file_mapping_.get(),
-                      (flags & PAGE_READONLY) ? FILE_MAP_READ : FILE_MAP_WRITE,
-                      map_start.HighPart, map_start.LowPart, map_size));
+  data_ = static_cast<uint8_t*>(::MapViewOfFile(file_mapping_.get(),
+                                                view_access, map_start.HighPart,
+                                                map_start.LowPart, map_size));
   if (data_ == nullptr)
     return false;
   data_ += data_offset;
diff --git a/base/moving_window.h b/base/moving_window.h
index 06c3240..21f8157 100644
--- a/base/moving_window.h
+++ b/base/moving_window.h
@@ -699,9 +699,8 @@
   typename std::conditional<
       internal::has_member_mean<EnabledFeatures>::value ||
           internal::has_memeber_deviation<EnabledFeatures>::value,
-      internal::MovingMeanBase<T,
-                               MeanSumType,
-                               std::is_floating_point<MeanSumType>::value>,
+      internal::
+          MovingMeanBase<T, MeanSumType, std::is_floating_point_v<MeanSumType>>,
       internal::NullMeanImpl<T>>::type mean_impl_;
 
   // Member for calculating deviation.
diff --git a/base/observer_list_internal.h b/base/observer_list_internal.h
index d19d2c75..9d8e6762 100644
--- a/base/observer_list_internal.h
+++ b/base/observer_list_internal.h
@@ -42,7 +42,7 @@
   template <class ObserverType>
   static ObserverType* Get(const UncheckedObserverAdapter& adapter) {
     static_assert(
-        !std::is_base_of<CheckedObserver, ObserverType>::value,
+        !std::is_base_of_v<CheckedObserver, ObserverType>,
         "CheckedObserver classes must not use ObserverList<T>::Unchecked.");
     return static_cast<ObserverType*>(adapter.ptr_);
   }
@@ -102,7 +102,7 @@
   template <class ObserverType>
   static ObserverType* Get(const CheckedObserverAdapter& adapter) {
     static_assert(
-        std::is_base_of<CheckedObserver, ObserverType>::value,
+        std::is_base_of_v<CheckedObserver, ObserverType>,
         "Observers should inherit from base::CheckedObserver. "
         "Use ObserverList<T>::Unchecked to observe with raw pointers.");
     DCHECK(adapter.weak_ptr_);
diff --git a/base/observer_list_unittest.nc b/base/observer_list_unittest.nc
index 172337a..557de54 100644
--- a/base/observer_list_unittest.nc
+++ b/base/observer_list_unittest.nc
@@ -11,7 +11,7 @@
 
 namespace base {
 
-#if defined(NCTEST_CHECKED_OBSERVER_USING_UNCHECKED_LIST)  // [r"fatal error: static assertion failed due to requirement '!std::is_base_of<base::CheckedObserver, Observer>::value': CheckedObserver classes must not use ObserverList<T>::Unchecked."]
+#if defined(NCTEST_CHECKED_OBSERVER_USING_UNCHECKED_LIST)  // [r"fatal error: static assertion failed due to requirement '!std::is_base_of_v<base::CheckedObserver, Observer>': CheckedObserver classes must not use ObserverList<T>::Unchecked."]
 
 void WontCompile() {
   struct Observer : public CheckedObserver {
@@ -22,7 +22,7 @@
     observer.OnObserve();
 }
 
-#elif defined(NCTEST_UNCHECKED_OBSERVER_USING_CHECKED_LIST)  // [r"fatal error: static assertion failed due to requirement 'std::is_base_of<base::CheckedObserver, UncheckedObserver>::value': Observers should inherit from base::CheckedObserver. Use ObserverList<T>::Unchecked to observe with raw pointers."]
+#elif defined(NCTEST_UNCHECKED_OBSERVER_USING_CHECKED_LIST)  // [r"fatal error: static assertion failed due to requirement 'std::is_base_of_v<base::CheckedObserver, UncheckedObserver>': Observers should inherit from base::CheckedObserver. Use ObserverList<T>::Unchecked to observe with raw pointers."]
 
 void WontCompile() {
   struct UncheckedObserver {
diff --git a/base/parameter_pack.h b/base/parameter_pack.h
index 3eef16e6..450718b 100644
--- a/base/parameter_pack.h
+++ b/base/parameter_pack.h
@@ -42,25 +42,23 @@
 struct ParameterPack {
   // Checks if |Type| occurs in the parameter pack.
   template <typename Type>
-  using HasType =
-      std::bool_constant<any_of({std::is_same<Type, Ts>::value...})>;
+  using HasType = std::bool_constant<any_of({std::is_same_v<Type, Ts>...})>;
 
   // Checks if the parameter pack only contains |Type|.
   template <typename Type>
-  using OnlyHasType =
-      std::bool_constant<all_of({std::is_same<Type, Ts>::value...})>;
+  using OnlyHasType = std::bool_constant<all_of({std::is_same_v<Type, Ts>...})>;
 
   // Checks if |Type| occurs only once in the parameter pack.
   template <typename Type>
   using IsUniqueInPack =
-      std::bool_constant<count({std::is_same<Type, Ts>::value...}, true) == 1>;
+      std::bool_constant<count({std::is_same_v<Type, Ts>...}, true) == 1>;
 
   // Returns the zero-based index of |Type| within |Pack...| or |pack_npos| if
   // it's not within the pack.
   template <typename Type>
   static constexpr size_t IndexInPack() {
     size_t index = 0;
-    for (bool value : {std::is_same<Type, Ts>::value...}) {
+    for (bool value : {std::is_same_v<Type, Ts>...}) {
       if (value)
         return index;
       index++;
@@ -74,7 +72,7 @@
 
   // Checks if every type in the parameter pack is the same.
   using IsAllSameType =
-      std::bool_constant<all_of({std::is_same<NthType<0>, Ts>::value...})>;
+      std::bool_constant<all_of({std::is_same_v<NthType<0>, Ts>...})>;
 };
 
 }  // namespace base
diff --git a/base/parameter_pack_unittest.cc b/base/parameter_pack_unittest.cc
index 4f06f8a0..8d3172b5 100644
--- a/base/parameter_pack_unittest.cc
+++ b/base/parameter_pack_unittest.cc
@@ -57,14 +57,11 @@
 
 TEST(ParameterPack, NthType) {
   static_assert(
-      std::is_same<int, ParameterPack<int, float, bool>::NthType<0>>::value,
-      "");
+      std::is_same_v<int, ParameterPack<int, float, bool>::NthType<0>>, "");
   static_assert(
-      std::is_same<float, ParameterPack<int, float, bool>::NthType<1>>::value,
-      "");
+      std::is_same_v<float, ParameterPack<int, float, bool>::NthType<1>>, "");
   static_assert(
-      std::is_same<bool, ParameterPack<int, float, bool>::NthType<2>>::value,
-      "");
+      std::is_same_v<bool, ParameterPack<int, float, bool>::NthType<2>>, "");
 }
 
 TEST(ParameterPack, IsAllSameType) {
diff --git a/base/safe_numerics_unittest.cc b/base/safe_numerics_unittest.cc
index 0d1f6723..34a7e4f 100644
--- a/base/safe_numerics_unittest.cc
+++ b/base/safe_numerics_unittest.cc
@@ -71,16 +71,16 @@
 static_assert(BigEnoughPromotion<intmax_t, int8_t>::is_contained, "");
 static_assert(!BigEnoughPromotion<uintmax_t, int8_t>::is_contained, "");
 static_assert(
-    std::is_same<BigEnoughPromotion<int16_t, int8_t>::type, int16_t>::value,
+    std::is_same_v<BigEnoughPromotion<int16_t, int8_t>::type, int16_t>,
     "");
 static_assert(
-    std::is_same<BigEnoughPromotion<int32_t, uint32_t>::type, int64_t>::value,
+    std::is_same_v<BigEnoughPromotion<int32_t, uint32_t>::type, int64_t>,
     "");
 static_assert(
-    std::is_same<BigEnoughPromotion<intmax_t, int8_t>::type, intmax_t>::value,
+    std::is_same_v<BigEnoughPromotion<intmax_t, int8_t>::type, intmax_t>,
     "");
 static_assert(
-    std::is_same<BigEnoughPromotion<uintmax_t, int8_t>::type, uintmax_t>::value,
+    std::is_same_v<BigEnoughPromotion<uintmax_t, int8_t>::type, uintmax_t>,
     "");
 static_assert(BigEnoughPromotion<int16_t, int8_t>::is_contained, "");
 static_assert(BigEnoughPromotion<int32_t, uint32_t>::is_contained, "");
@@ -1082,7 +1082,7 @@
     } else if (numeric_limits<Src>::is_signed) {
       // This block reverses the Src to Dst relationship so we don't have to
       // complicate the test macros.
-      if (!std::is_same<Src, Dst>::value) {
+      if (!std::is_same_v<Src, Dst>) {
         TEST_EXPECTED_SUCCESS(CheckDiv(SrcLimits::lowest(), Dst(-1)));
       }
       TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
@@ -1419,9 +1419,8 @@
   return 0;
 }
 
-static_assert(
-    std::is_same<decltype(TestOverload(StrictNumeric<int>())), int>::value,
-    "");
+static_assert(std::is_same_v<decltype(TestOverload(StrictNumeric<int>())), int>,
+              "");
 static_assert(std::is_same<decltype(TestOverload(StrictNumeric<size_t>())),
                            size_t>::value,
               "");
diff --git a/base/scoped_generic.h b/base/scoped_generic.h
index a347a954..4b034a1 100644
--- a/base/scoped_generic.h
+++ b/base/scoped_generic.h
@@ -262,7 +262,7 @@
 
   template <typename Void = void>
   typename std::enable_if_t<
-      std::is_base_of<ScopedGenericOwnershipTracking, Traits>::value,
+      std::is_base_of_v<ScopedGenericOwnershipTracking, Traits>,
       Void>
   TrackAcquire(const T& value) {
     if (value != traits_type::InvalidValue()) {
@@ -272,13 +272,13 @@
 
   template <typename Void = void>
   typename std::enable_if_t<
-      !std::is_base_of<ScopedGenericOwnershipTracking, Traits>::value,
+      !std::is_base_of_v<ScopedGenericOwnershipTracking, Traits>,
       Void>
   TrackAcquire(const T& value) {}
 
   template <typename Void = void>
   typename std::enable_if_t<
-      std::is_base_of<ScopedGenericOwnershipTracking, Traits>::value,
+      std::is_base_of_v<ScopedGenericOwnershipTracking, Traits>,
       Void>
   TrackRelease(const T& value) {
     if (value != traits_type::InvalidValue()) {
@@ -288,7 +288,7 @@
 
   template <typename Void = void>
   typename std::enable_if_t<
-      !std::is_base_of<ScopedGenericOwnershipTracking, Traits>::value,
+      !std::is_base_of_v<ScopedGenericOwnershipTracking, Traits>,
       Void>
   TrackRelease(const T& value) {}
 
diff --git a/base/template_util.h b/base/template_util.h
index 3ea6186..ff47ed49 100644
--- a/base/template_util.h
+++ b/base/template_util.h
@@ -45,11 +45,11 @@
 
 // The indirection with std::is_enum<T> is required, because instantiating
 // std::underlying_type_t<T> when T is not an enum is UB prior to C++20.
-template <typename T, bool = std::is_enum<T>::value>
+template <typename T, bool = std::is_enum_v<T>>
 struct IsScopedEnumImpl : std::false_type {};
 
 template <typename T>
-struct IsScopedEnumImpl<T, /*std::is_enum<T>::value=*/true>
+struct IsScopedEnumImpl<T, /*std::is_enum_v<T>=*/true>
     : std::negation<std::is_convertible<T, std::underlying_type_t<T>>> {};
 
 }  // namespace internal
diff --git a/base/template_util_unittest.cc b/base/template_util_unittest.cc
index 8857ef3..d1f93d4e 100644
--- a/base/template_util_unittest.cc
+++ b/base/template_util_unittest.cc
@@ -30,30 +30,26 @@
 }
 
 TEST(TemplateUtil, RemoveCvRefT) {
-  static_assert(std::is_same<int, remove_cvref_t<const int>>::value, "");
-  static_assert(std::is_same<int, remove_cvref_t<const volatile int>>::value,
-                "");
-  static_assert(std::is_same<int, remove_cvref_t<int&>>::value, "");
-  static_assert(std::is_same<int, remove_cvref_t<const int&>>::value, "");
-  static_assert(std::is_same<int, remove_cvref_t<const volatile int&>>::value,
-                "");
-  static_assert(std::is_same<int, remove_cvref_t<int&&>>::value, "");
+  static_assert(std::is_same_v<int, remove_cvref_t<const int>>, "");
+  static_assert(std::is_same_v<int, remove_cvref_t<const volatile int>>, "");
+  static_assert(std::is_same_v<int, remove_cvref_t<int&>>, "");
+  static_assert(std::is_same_v<int, remove_cvref_t<const int&>>, "");
+  static_assert(std::is_same_v<int, remove_cvref_t<const volatile int&>>, "");
+  static_assert(std::is_same_v<int, remove_cvref_t<int&&>>, "");
   static_assert(
-      std::is_same<SimpleStruct, remove_cvref_t<const SimpleStruct&>>::value,
-      "");
-  static_assert(std::is_same<int*, remove_cvref_t<int*>>::value, "");
+      std::is_same_v<SimpleStruct, remove_cvref_t<const SimpleStruct&>>, "");
+  static_assert(std::is_same_v<int*, remove_cvref_t<int*>>, "");
 
   // Test references and pointers to arrays.
-  static_assert(std::is_same<int[3], remove_cvref_t<int[3]>>::value, "");
-  static_assert(std::is_same<int[3], remove_cvref_t<int(&)[3]>>::value, "");
-  static_assert(std::is_same<int(*)[3], remove_cvref_t<int(*)[3]>>::value, "");
+  static_assert(std::is_same_v<int[3], remove_cvref_t<int[3]>>, "");
+  static_assert(std::is_same_v<int[3], remove_cvref_t<int(&)[3]>>, "");
+  static_assert(std::is_same_v<int(*)[3], remove_cvref_t<int(*)[3]>>, "");
 
   // Test references and pointers to functions.
-  static_assert(std::is_same<void(int), remove_cvref_t<void(int)>>::value, "");
-  static_assert(std::is_same<void(int), remove_cvref_t<void (&)(int)>>::value,
+  static_assert(std::is_same_v<void(int), remove_cvref_t<void(int)>>, "");
+  static_assert(std::is_same_v<void(int), remove_cvref_t<void (&)(int)>>, "");
+  static_assert(std::is_same_v<void (*)(int), remove_cvref_t<void (*)(int)>>,
                 "");
-  static_assert(
-      std::is_same<void (*)(int), remove_cvref_t<void (*)(int)>>::value, "");
 }
 
 }  // namespace
diff --git a/base/threading/platform_thread_win.cc b/base/threading/platform_thread_win.cc
index abb10032..9826508ef 100644
--- a/base/threading/platform_thread_win.cc
+++ b/base/threading/platform_thread_win.cc
@@ -45,6 +45,10 @@
              "AboveNormalCompositingBrowserWin",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+BASE_FEATURE(kBackgroundThreadNormalMemoryPriorityWin,
+             "BackgroundThreadNormalMemoryPriorityWin",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 namespace {
 
 // Flag used to set thread priority to |THREAD_PRIORITY_LOWEST| for
@@ -53,6 +57,9 @@
 // Flag used to map Compositing ThreadType |THREAD_PRIORITY_ABOVE_NORMAL| on the
 // UI thread for |kAboveNormalCompositingBrowserWin| Feature.
 std::atomic<bool> g_above_normal_compositing_browser{true};
+// Flag used to set thread memory priority to |MEMORY_PRIORITY_NORMAL| on
+// background threads for |kThreadNormalMemoryPriorityWin| Feature.
+std::atomic<bool> g_background_thread_normal_memory_priority_win{false};
 
 // These values are sometimes returned by ::GetThreadPriority().
 constexpr int kWinDisplayPriority1 = 5;
@@ -425,11 +432,23 @@
   }
   DCHECK_NE(desired_priority, THREAD_PRIORITY_ERROR_RETURN);
 
-  [[maybe_unused]] const BOOL success =
+  [[maybe_unused]] const BOOL cpu_priority_success =
       ::SetThreadPriority(thread_handle, desired_priority);
-  DPLOG_IF(ERROR, !success)
+  DPLOG_IF(ERROR, !cpu_priority_success)
       << "Failed to set thread priority to " << desired_priority;
 
+  if (g_background_thread_normal_memory_priority_win &&
+      desired_priority == THREAD_MODE_BACKGROUND_BEGIN) {
+    // Override the memory priority.
+    MEMORY_PRIORITY_INFORMATION memory_priority{.MemoryPriority =
+                                                    MEMORY_PRIORITY_NORMAL};
+    [[maybe_unused]] const BOOL memory_priority_success =
+        SetThreadInformation(thread_handle, ::ThreadMemoryPriority,
+                             &memory_priority, sizeof(memory_priority));
+    DPLOG_IF(ERROR, !memory_priority_success)
+        << "Set thread memory priority failed.";
+  }
+
   if (!g_use_thread_priority_lowest && thread_type == ThreadType::kBackground) {
     // In a background process, THREAD_MODE_BACKGROUND_BEGIN lowers the memory
     // and I/O priorities but not the CPU priority (kernel bug?). Use
@@ -564,6 +583,9 @@
   g_above_normal_compositing_browser.store(
       FeatureList::IsEnabled(kAboveNormalCompositingBrowserWin),
       std::memory_order_relaxed);
+  g_background_thread_normal_memory_priority_win.store(
+      FeatureList::IsEnabled(kBackgroundThreadNormalMemoryPriorityWin),
+      std::memory_order_relaxed);
 }
 
 // static
diff --git a/base/threading/platform_thread_win_unittest.cc b/base/threading/platform_thread_win_unittest.cc
index 009d66e9..c12ee17 100644
--- a/base/threading/platform_thread_win_unittest.cc
+++ b/base/threading/platform_thread_win_unittest.cc
@@ -9,6 +9,10 @@
 #include <array>
 
 #include "base/process/process.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/threading/platform_thread_win.h"
+#include "base/threading/simple_thread.h"
+#include "base/threading/threading_features.h"
 #include "base/win/windows_version.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -88,4 +92,53 @@
   internal::AssertMemoryPriority(thread_handle, MEMORY_PRIORITY_NORMAL);
 }
 
+namespace {
+class MemoryPriorityAssertingThreadDelegate
+    : public base::PlatformThread::Delegate {
+ public:
+  explicit MemoryPriorityAssertingThreadDelegate(LONG memory_priority)
+      : memory_priority_(memory_priority) {}
+
+  void ThreadMain() override {
+    PlatformThreadHandle::Handle thread_handle =
+        PlatformThread::CurrentHandle().platform_handle();
+    internal::AssertMemoryPriority(thread_handle, memory_priority_);
+  }
+
+  LONG memory_priority_;
+};
+}  // namespace
+
+// It has been observed (crbug.com/1489467) that memory priority is set to very
+// low on background threads, and a possible mitigation is running in the
+// kThreadNormalMemoryPriorityWin experiment which sets memory priority to
+// NORMAL on all threads at creation. If this test fails, the feature is broken
+// and investigation needs to be done into whether pages are being allocated at
+// pri-1 despite it as shown in the above linked bug.
+TEST(PlatformThreadWinTest, NormalPriorityFeatureForBackgroundThreads) {
+  base::test::ScopedFeatureList list;
+  list.InitAndEnableFeature(kBackgroundThreadNormalMemoryPriorityWin);
+  base::InitializePlatformThreadFeatures();
+
+  MemoryPriorityAssertingThreadDelegate delegate{MEMORY_PRIORITY_NORMAL};
+
+  PlatformThreadHandle handle;
+
+  CHECK(PlatformThread::CreateWithType(0, &delegate, &handle,
+                                       ThreadType::kBackground));
+  PlatformThread::Join(handle);
+}
+
+TEST(PlatformThreadWinTest, BackgroundThreadsSetLowMemoryPriority) {
+  base::InitializePlatformThreadFeatures();
+
+  MemoryPriorityAssertingThreadDelegate delegate{MEMORY_PRIORITY_VERY_LOW};
+
+  PlatformThreadHandle handle;
+
+  CHECK(PlatformThread::CreateWithType(0, &delegate, &handle,
+                                       ThreadType::kBackground));
+  PlatformThread::Join(handle);
+}
+
 }  // namespace base
diff --git a/base/threading/threading_features.h b/base/threading/threading_features.h
index 329a5c7..2b89b23 100644
--- a/base/threading/threading_features.h
+++ b/base/threading/threading_features.h
@@ -28,6 +28,7 @@
 
 #if BUILDFLAG(IS_WIN)
 BASE_EXPORT BASE_DECLARE_FEATURE(kAboveNormalCompositingBrowserWin);
+BASE_EXPORT BASE_DECLARE_FEATURE(kBackgroundThreadNormalMemoryPriorityWin);
 #endif
 
 BASE_EXPORT BASE_DECLARE_FEATURE(kEnableHangWatcher);
diff --git a/base/trace_event/category_registry.cc b/base/trace_event/category_registry.cc
index 66b640b..e9fc890 100644
--- a/base/trace_event/category_registry.cc
+++ b/base/trace_event/category_registry.cc
@@ -20,7 +20,7 @@
 namespace {
 
 // |categories_| might end up causing creating dynamic initializers if not POD.
-static_assert(std::is_pod<TraceCategory>::value, "TraceCategory must be POD");
+static_assert(std::is_pod_v<TraceCategory>, "TraceCategory must be POD");
 
 }  // namespace
 
diff --git a/base/trace_event/memory_usage_estimator.h b/base/trace_event/memory_usage_estimator.h
index 955839e..d9fad34 100644
--- a/base/trace_event/memory_usage_estimator.h
+++ b/base/trace_event/memory_usage_estimator.h
@@ -235,7 +235,7 @@
 struct EMUCaller {
   // std::is_same<> below makes static_assert depend on T, in order to
   // prevent it from asserting regardless instantiation.
-  static_assert(std::is_same<T, std::false_type>::value,
+  static_assert(std::is_same_v<T, std::false_type>,
                 "Neither global function 'size_t EstimateMemoryUsage(T)' "
                 "nor member function 'size_t T::EstimateMemoryUsage() const' "
                 "is defined for the type.");
@@ -255,7 +255,7 @@
 struct IsComplexIteratorForContainer<
     Container,
     I,
-    std::enable_if_t<!std::is_pointer<I>::value &&
+    std::enable_if_t<!std::is_pointer_v<I> &&
                      base::internal::is_iterator<I>::value>> {
   using value_type = typename std::iterator_traits<I>::value_type;
   using container_type = Container<value_type>;
@@ -265,11 +265,10 @@
   //
   // The downside is - value is not of type bool.
   enum : bool {
-    value =
-        std::is_same<typename container_type::iterator, I>::value ||
-        std::is_same<typename container_type::const_iterator, I>::value ||
-        std::is_same<typename container_type::reverse_iterator, I>::value ||
-        std::is_same<typename container_type::const_reverse_iterator, I>::value,
+    value = std::is_same_v<typename container_type::iterator, I> ||
+            std::is_same_v<typename container_type::const_iterator, I> ||
+            std::is_same_v<typename container_type::reverse_iterator, I> ||
+            std::is_same_v<typename container_type::const_reverse_iterator, I>,
   };
 };
 
@@ -304,7 +303,7 @@
 // However variable template does.
 template <typename T>
 constexpr bool IsKnownNonAllocatingType_v =
-    std::is_trivially_destructible<T>::value ||
+    std::is_trivially_destructible_v<T> ||
     IsStandardContainerComplexIterator<T>();
 
 template <class T>
@@ -336,9 +335,8 @@
 template <class T>
 auto EstimateMemoryUsage(const T& object)
     -> decltype(object.EstimateMemoryUsage()) {
-  static_assert(
-      std::is_same<decltype(object.EstimateMemoryUsage()), size_t>::value,
-      "'T::EstimateMemoryUsage() const' must return size_t.");
+  static_assert(std::is_same_v<decltype(object.EstimateMemoryUsage()), size_t>,
+                "'T::EstimateMemoryUsage() const' must return size_t.");
   return object.EstimateMemoryUsage();
 }
 
diff --git a/base/trace_event/trace_arguments.cc b/base/trace_event/trace_arguments.cc
index 01a6589..e0081df 100644
--- a/base/trace_event/trace_arguments.cc
+++ b/base/trace_event/trace_arguments.cc
@@ -165,7 +165,7 @@
 }
 
 static_assert(
-    std::is_pod<TraceValue>::value,
+    std::is_pod_v<TraceValue>,
     "TraceValue must be plain-old-data type for performance reasons!");
 
 void TraceValue::AppendAsJSON(unsigned char type, std::string* out) const {
diff --git a/base/trace_event/trace_arguments.h b/base/trace_event/trace_arguments.h
index fb614a8..d986bc4a 100644
--- a/base/trace_event/trace_arguments.h
+++ b/base/trace_event/trace_arguments.h
@@ -405,10 +405,9 @@
 template <typename T>
 struct TraceValue::Helper<
     T,
-    typename std::enable_if<std::is_integral<T>::value ||
-                            std::is_enum<T>::value>::type> {
+    typename std::enable_if<std::is_integral_v<T> || std::is_enum_v<T>>::type> {
   static constexpr unsigned char kType =
-      std::is_signed<T>::value ? TRACE_VALUE_TYPE_INT : TRACE_VALUE_TYPE_UINT;
+      std::is_signed_v<T> ? TRACE_VALUE_TYPE_INT : TRACE_VALUE_TYPE_UINT;
   static inline void SetValue(TraceValue* v, T value) {
     v->as_uint = static_cast<unsigned long long>(value);
   }
@@ -417,7 +416,7 @@
 // TraceValue::Helper for floating-point types
 template <typename T>
 struct TraceValue::
-    Helper<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
+    Helper<T, typename std::enable_if<std::is_floating_point_v<T>>::type> {
   static constexpr unsigned char kType = TRACE_VALUE_TYPE_DOUBLE;
   static inline void SetValue(TraceValue* v, T value) { v->as_double = value; }
 };
@@ -486,9 +485,9 @@
 template <typename T>
 struct TraceValue::Helper<
     T,
-    typename std::enable_if<std::is_same<T, base::Time>::value ||
-                            std::is_same<T, base::TimeTicks>::value ||
-                            std::is_same<T, base::ThreadTicks>::value>::type> {
+    typename std::enable_if<std::is_same_v<T, base::Time> ||
+                            std::is_same_v<T, base::TimeTicks> ||
+                            std::is_same_v<T, base::ThreadTicks>>::type> {
   static constexpr unsigned char kType = TRACE_VALUE_TYPE_INT;
   static inline void SetValue(TraceValue* v, const T& value) {
     v->as_int = value.ToInternalValue();
diff --git a/base/trace_event/trace_conversion_helper.h b/base/trace_event/trace_conversion_helper.h
index 9d9c0d1a..d2d8e14 100644
--- a/base/trace_event/trace_conversion_helper.h
+++ b/base/trace_event/trace_conversion_helper.h
@@ -103,23 +103,23 @@
 // is also |std::is_integral|, so we need to test |bool| before testing for
 // integral.
 template <typename T>
-typename std::enable_if<std::is_same<T, bool>::value>::type
-SetTracedValueArgHelper(base::internal::priority_tag<6>,
-                        TracedValue* traced_value,
-                        const char* name,
-                        const T& value) {
+typename std::enable_if<std::is_same_v<T, bool>>::type SetTracedValueArgHelper(
+    base::internal::priority_tag<6>,
+    TracedValue* traced_value,
+    const char* name,
+    const T& value) {
   traced_value->SetBoolean(name, value);
 }
 
-// std::is_integral<bool>::value == true
+// std::is_integral_v<bool> == true
 // This needs to be considered only when T is not bool (has higher
 // base::internal::priority_tag).
 template <typename T>
-typename std::enable_if<std::is_integral<T>::value>::type
-SetTracedValueArgHelper(base::internal::priority_tag<5>,
-                        TracedValue* traced_value,
-                        const char* name,
-                        const T& value) {
+typename std::enable_if<std::is_integral_v<T>>::type SetTracedValueArgHelper(
+    base::internal::priority_tag<5>,
+    TracedValue* traced_value,
+    const char* name,
+    const T& value) {
   // Avoid loss of precision.
   if (sizeof(int) < sizeof(value)) {
     // TODO(crbug.com/1111787): Add 64-bit support to TracedValue.
@@ -131,7 +131,7 @@
 
 // Any floating point type is converted to double.
 template <typename T>
-typename std::enable_if<std::is_floating_point<T>::value>::type
+typename std::enable_if<std::is_floating_point_v<T>>::type
 SetTracedValueArgHelper(base::internal::priority_tag<4>,
                         TracedValue* traced_value,
                         const char* name,
@@ -141,17 +141,17 @@
 
 // |void*| is traced natively.
 template <typename T>
-typename std::enable_if<std::is_same<T, void*>::value>::type
-SetTracedValueArgHelper(base::internal::priority_tag<3>,
-                        TracedValue* traced_value,
-                        const char* name,
-                        const T& value) {
+typename std::enable_if<std::is_same_v<T, void*>>::type SetTracedValueArgHelper(
+    base::internal::priority_tag<3>,
+    TracedValue* traced_value,
+    const char* name,
+    const T& value) {
   traced_value->SetPointer(name, value);
 }
 
 // |const char*| is traced natively.
 template <typename T>
-typename std::enable_if<std::is_same<T, const char*>::value>::type
+typename std::enable_if<std::is_same_v<T, const char*>>::type
 SetTracedValueArgHelper(base::internal::priority_tag<2>,
                         TracedValue* traced_value,
                         const char* name,
diff --git a/base/trace_event/typed_macros_internal.h b/base/trace_event/typed_macros_internal.h
index a208dd7d..f099a3e6 100644
--- a/base/trace_event/typed_macros_internal.h
+++ b/base/trace_event/typed_macros_internal.h
@@ -148,7 +148,7 @@
 template <typename TrackType,
           typename... Args,
           typename TrackTypeCheck = typename std::enable_if<
-              std::is_convertible<TrackType, perfetto::Track>::value>::type>
+              std::is_convertible_v<TrackType, perfetto::Track>>::type>
 inline void AddTypedTraceEvent(char phase,
                                const unsigned char* category_group_enabled,
                                perfetto::StaticString name,
@@ -163,7 +163,7 @@
 template <typename TrackType,
           typename... Args,
           typename TrackTypeCheck = typename std::enable_if<
-              std::is_convertible<TrackType, perfetto::Track>::value>::type>
+              std::is_convertible_v<TrackType, perfetto::Track>>::type>
 inline void AddTypedTraceEvent(char phase,
                                const unsigned char* category_group_enabled,
                                perfetto::StaticString name,
diff --git a/base/traits_bag.h b/base/traits_bag.h
index b8f9d9dd..cbf9d95 100644
--- a/base/traits_bag.h
+++ b/base/traits_bag.h
@@ -111,7 +111,7 @@
 template <class TraitFilterType,
           class ArgType,
           class CheckArgumentIsCompatible = std::enable_if_t<
-              std::is_constructible<TraitFilterType, ArgType>::value>>
+              std::is_constructible_v<TraitFilterType, ArgType>>>
 constexpr TraitFilterType GetTraitFromArg(CallFirstTag, ArgType arg) {
   return TraitFilterType(arg);
 }
@@ -127,8 +127,8 @@
 // disambiguation tag.
 template <class TraitFilterType,
           class... ArgTypes,
-          class TestCompatibleArgument = std::enable_if_t<any_of(
-              {std::is_constructible<TraitFilterType, ArgTypes>::value...})>>
+          class TestCompatibleArgument = std::enable_if_t<
+              any_of({std::is_constructible_v<TraitFilterType, ArgTypes>...})>>
 constexpr TraitFilterType GetTraitFromArgListImpl(CallFirstTag,
                                                   ArgTypes... args) {
   return std::get<TraitFilterType>(std::make_tuple(
@@ -138,7 +138,7 @@
 template <class TraitFilterType, class... ArgTypes>
 constexpr TraitFilterType GetTraitFromArgListImpl(CallSecondTag,
                                                   ArgTypes... args) {
-  static_assert(std::is_constructible<TraitFilterType>::value,
+  static_assert(std::is_constructible_v<TraitFilterType>,
                 "The traits bag is missing a required trait.");
   return TraitFilterType();
 }
@@ -151,8 +151,7 @@
 constexpr typename TraitFilterType::ValueType GetTraitFromArgList(
     ArgTypes... args) {
   static_assert(
-      count({std::is_constructible<TraitFilterType, ArgTypes>::value...},
-            true) <= 1,
+      count({std::is_constructible_v<TraitFilterType, ArgTypes>...}, true) <= 1,
       "The traits bag contains multiple traits of the same type.");
   return GetTraitFromArgListImpl<TraitFilterType>(CallFirstTag(), args...);
 }
@@ -239,9 +238,8 @@
 // Helper to make checking for the presence of a trait more readable.
 template <typename Trait, typename... Args>
 struct HasTrait : ParameterPack<Args...>::template HasType<Trait> {
-  static_assert(
-      count({std::is_constructible<Trait, Args>::value...}, true) <= 1,
-      "The traits bag contains multiple traits of the same type.");
+  static_assert(count({std::is_constructible_v<Trait, Args>...}, true) <= 1,
+                "The traits bag contains multiple traits of the same type.");
 };
 
 // If you need a template vararg constructor to delegate to a private
diff --git a/base/types/cxx23_to_underlying_unittest.cc b/base/types/cxx23_to_underlying_unittest.cc
index 1cb1970..0c03950 100644
--- a/base/types/cxx23_to_underlying_unittest.cc
+++ b/base/types/cxx23_to_underlying_unittest.cc
@@ -18,15 +18,15 @@
     kTwo = 2,
   };
 
-  static_assert(std::is_same<decltype(to_underlying(kOne)), int>::value, "");
-  static_assert(std::is_same<decltype(to_underlying(kTwo)), int>::value, "");
+  static_assert(std::is_same_v<decltype(to_underlying(kOne)), int>, "");
+  static_assert(std::is_same_v<decltype(to_underlying(kTwo)), int>, "");
   static_assert(to_underlying(kOne) == 1, "");
   static_assert(to_underlying(kTwo) == 2, "");
 
-  static_assert(
-      std::is_same<decltype(to_underlying(ScopedEnum::kOne)), char>::value, "");
-  static_assert(
-      std::is_same<decltype(to_underlying(ScopedEnum::kTwo)), char>::value, "");
+  static_assert(std::is_same_v<decltype(to_underlying(ScopedEnum::kOne)), char>,
+                "");
+  static_assert(std::is_same_v<decltype(to_underlying(ScopedEnum::kTwo)), char>,
+                "");
   static_assert(to_underlying(ScopedEnum::kOne) == 1, "");
   static_assert(to_underlying(ScopedEnum::kTwo) == 2, "");
 }
diff --git a/base/types/id_type.h b/base/types/id_type.h
index ca1dad14..63e7c6c 100644
--- a/base/types/id_type.h
+++ b/base/types/id_type.h
@@ -60,7 +60,7 @@
   static constexpr WrappedType kAllInvalidValues[] = {kInvalidValue,
                                                       kExtraInvalidValues...};
 
-  static_assert(std::is_unsigned<WrappedType>::value ||
+  static_assert(std::is_unsigned_v<WrappedType> ||
                     base::ranges::all_of(kAllInvalidValues,
                                          [](WrappedType v) { return v <= 0; }),
                 "If signed, invalid values should be negative or equal to zero "
@@ -72,7 +72,7 @@
                                      }),
                 "The first generated ID cannot be invalid.");
 
-  static_assert(std::is_unsigned<WrappedType>::value ||
+  static_assert(std::is_unsigned_v<WrappedType> ||
                     base::ranges::all_of(kAllInvalidValues,
                                          [](WrappedType v) {
                                            return kFirstGeneratedId > v;
diff --git a/base/types/optional_unittest.cc b/base/types/optional_unittest.cc
index a8ed26f9..3fbab45 100644
--- a/base/types/optional_unittest.cc
+++ b/base/types/optional_unittest.cc
@@ -204,7 +204,7 @@
 
 }  // anonymous namespace
 
-static_assert(std::is_trivially_destructible<std::optional<int>>::value,
+static_assert(std::is_trivially_destructible_v<std::optional<int>>,
               "OptionalIsTriviallyDestructible");
 
 static_assert(!std::is_trivially_destructible<
@@ -565,7 +565,7 @@
       Test(int a) {}  // NOLINT(runtime/explicit)
     };
     // If T is convertible from U, it is not marked as explicit.
-    static_assert(std::is_convertible<int, Test>::value,
+    static_assert(std::is_convertible_v<int, Test>,
                   "Int should be convertible to Test.");
     ([](std::optional<Test> param) {})(1);
   }
@@ -1179,7 +1179,7 @@
   {
     std::optional<std::vector<int>> a;
     auto& ref = a.emplace({2, 3});
-    static_assert(std::is_same<std::vector<int>&, decltype(ref)>::value, "");
+    static_assert(std::is_same_v<std::vector<int>&, decltype(ref)>, "");
     EXPECT_TRUE(a);
     EXPECT_THAT(*a, ElementsAre(2, 3));
     EXPECT_EQ(&ref, &*a);
@@ -1188,7 +1188,7 @@
   {
     std::optional<std::vector<int>> a;
     auto& ref = a.emplace({4, 5}, std::allocator<int>());
-    static_assert(std::is_same<std::vector<int>&, decltype(ref)>::value, "");
+    static_assert(std::is_same_v<std::vector<int>&, decltype(ref)>, "");
     EXPECT_TRUE(a);
     EXPECT_THAT(*a, ElementsAre(4, 5));
     EXPECT_EQ(&ref, &*a);
diff --git a/base/types/strong_alias_unittest.cc b/base/types/strong_alias_unittest.cc
index 328d3452..e69cf7b 100644
--- a/base/types/strong_alias_unittest.cc
+++ b/base/types/strong_alias_unittest.cc
@@ -103,7 +103,7 @@
 
   // Check that FooAlias is nothrow move constructible. This matters for
   // performance when used in std::vectors.
-  static_assert(std::is_nothrow_move_constructible<FooAlias>::value,
+  static_assert(std::is_nothrow_move_constructible_v<FooAlias>,
                 "Error: Alias is not nothow move constructible");
 }
 
@@ -186,35 +186,35 @@
 
 TYPED_TEST(StrongAliasTest, IsDefaultConstructible) {
   using FooAlias = StrongAlias<class FooTag, TypeParam>;
-  static_assert(std::is_default_constructible<FooAlias>::value,
+  static_assert(std::is_default_constructible_v<FooAlias>,
                 "Should be possible to default-construct a StrongAlias.");
   static_assert(
-      std::is_trivially_default_constructible<FooAlias>::value ==
-          std::is_trivially_default_constructible<TypeParam>::value,
+      std::is_trivially_default_constructible_v<FooAlias> ==
+          std::is_trivially_default_constructible_v<TypeParam>,
       "Should be possible to trivially default-construct a StrongAlias iff the "
       "underlying type is trivially default constructible.");
 }
 
 TEST(StrongAliasTest, TrivialTypeAliasIsStandardLayout) {
   using FooAlias = StrongAlias<class FooTag, int>;
-  static_assert(std::is_standard_layout<FooAlias>::value,
+  static_assert(std::is_standard_layout_v<FooAlias>,
                 "int-based alias should have standard layout. ");
-  static_assert(std::is_trivially_copyable<FooAlias>::value,
+  static_assert(std::is_trivially_copyable_v<FooAlias>,
                 "int-based alias should be trivially copyable. ");
 }
 
 TYPED_TEST(StrongAliasTest, CannotBeCreatedFromDifferentAlias) {
   using FooAlias = StrongAlias<class FooTag, TypeParam>;
   using BarAlias = StrongAlias<class BarTag, TypeParam>;
-  static_assert(!std::is_constructible<FooAlias, BarAlias>::value,
+  static_assert(!std::is_constructible_v<FooAlias, BarAlias>,
                 "Should be impossible to construct FooAlias from a BarAlias.");
-  static_assert(!std::is_convertible<BarAlias, FooAlias>::value,
+  static_assert(!std::is_convertible_v<BarAlias, FooAlias>,
                 "Should be impossible to convert a BarAlias into FooAlias.");
 }
 
 TYPED_TEST(StrongAliasTest, CannotBeImplicitlyConverterToUnderlyingValue) {
   using FooAlias = StrongAlias<class FooTag, TypeParam>;
-  static_assert(!std::is_convertible<FooAlias, TypeParam>::value,
+  static_assert(!std::is_convertible_v<FooAlias, TypeParam>,
                 "Should be impossible to implicitly convert a StrongAlias into "
                 "an underlying type.");
 }
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index 5d2aa329..af4c9c2 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -69,16 +69,15 @@
 #endif
 
 TEST(ValuesTest, TestNothrow) {
-  static_assert(std::is_nothrow_move_constructible<Value>::value,
+  static_assert(std::is_nothrow_move_constructible_v<Value>,
                 "IsNothrowMoveConstructible");
-  static_assert(std::is_nothrow_default_constructible<Value>::value,
+  static_assert(std::is_nothrow_default_constructible_v<Value>,
                 "IsNothrowDefaultConstructible");
-  static_assert(std::is_nothrow_constructible<Value, std::string&&>::value,
+  static_assert(std::is_nothrow_constructible_v<Value, std::string&&>,
                 "IsNothrowMoveConstructibleFromString");
-  static_assert(
-      std::is_nothrow_constructible<Value, Value::BlobStorage&&>::value,
-      "IsNothrowMoveConstructibleFromBlob");
-  static_assert(std::is_nothrow_move_assignable<Value>::value,
+  static_assert(std::is_nothrow_constructible_v<Value, Value::BlobStorage&&>,
+                "IsNothrowMoveConstructibleFromBlob");
+  static_assert(std::is_nothrow_move_assignable_v<Value>,
                 "IsNothrowMoveAssignable");
 }
 
@@ -106,15 +105,15 @@
 }
 
 TEST(ValuesTest, ConstructFromPtrs) {
-  static_assert(!std::is_constructible<Value, int*>::value, "");
-  static_assert(!std::is_constructible<Value, const int*>::value, "");
-  static_assert(!std::is_constructible<Value, wchar_t*>::value, "");
-  static_assert(!std::is_constructible<Value, const wchar_t*>::value, "");
+  static_assert(!std::is_constructible_v<Value, int*>, "");
+  static_assert(!std::is_constructible_v<Value, const int*>, "");
+  static_assert(!std::is_constructible_v<Value, wchar_t*>, "");
+  static_assert(!std::is_constructible_v<Value, const wchar_t*>, "");
 
-  static_assert(std::is_constructible<Value, char*>::value, "");
-  static_assert(std::is_constructible<Value, const char*>::value, "");
-  static_assert(std::is_constructible<Value, char16_t*>::value, "");
-  static_assert(std::is_constructible<Value, const char16_t*>::value, "");
+  static_assert(std::is_constructible_v<Value, char*>, "");
+  static_assert(std::is_constructible_v<Value, const char*>, "");
+  static_assert(std::is_constructible_v<Value, char16_t*>, "");
+  static_assert(std::is_constructible_v<Value, const char16_t*>, "");
 }
 
 TEST(ValuesTest, ConstructInt) {
diff --git a/build/android/chromium_annotations.flags b/build/android/chromium_annotations.flags
index c223f29b..c2c0d5b 100644
--- a/build/android/chromium_annotations.flags
+++ b/build/android/chromium_annotations.flags
@@ -15,15 +15,6 @@
 
 # Keeps for method level annotations.
 -keepclasseswithmembers,allowaccessmodification class ** {
-  @org.chromium.base.annotations.AccessedByNative <fields>;
-}
--keepclasseswithmembers,includedescriptorclasses,allowaccessmodification class ** {
-  @org.chromium.base.annotations.CalledByNative <methods>;
-}
--keepclasseswithmembers,includedescriptorclasses,allowaccessmodification class ** {
-  @org.chromium.base.annotations.CalledByNativeUnchecked <methods>;
-}
--keepclasseswithmembers,allowaccessmodification class ** {
   @org.chromium.build.annotations.UsedByReflection <methods>;
 }
 -keepclasseswithmembers,allowaccessmodification class ** {
diff --git a/build/android/pylib/local/device/local_device_instrumentation_test_run.py b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
index 193739e..a5483af 100644
--- a/build/android/pylib/local/device/local_device_instrumentation_test_run.py
+++ b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
@@ -1450,13 +1450,25 @@
   def _ProcessRenderTestResults(self, device, results):
     if not self._render_tests_device_output_dir:
       return
+    # TODO(b/295350872): Remove this and other timestamp logging in Gold-related
+    # code once the source of flaky slowness is tracked down.
+    logging.info('Starting render test result processing')
+    start_time = time.time()
     self._ProcessSkiaGoldRenderTestResults(device, results)
+    logging.info('Render test result processing took %fs',
+                 time.time() - start_time)
 
   def _ProcessSkiaGoldRenderTestResults(self, device, results):
     gold_dir = posixpath.join(self._render_tests_device_output_dir.name,
                               _DEVICE_GOLD_DIR)
-    if not device.FileExists(gold_dir):
-      return
+    logging.info('Starting Gold directory existence check')
+    start_time = time.time()
+    try:
+      if not device.FileExists(gold_dir):
+        return
+    finally:
+      logging.info('Gold directory existence check took %fs',
+                   time.time() - start_time)
 
     gold_properties = self._test_instance.skia_gold_properties
     with tempfile_ext.NamedTemporaryDirectory() as host_dir:
@@ -1467,7 +1479,12 @@
       # slightly faster since each command over adb has some overhead compared
       # to doing the same thing locally.
       host_dir = os.path.join(host_dir, _DEVICE_GOLD_DIR)
+
+      logging.info('Starting Gold directory pull')
+      start_time = time.time()
       device.PullFile(gold_dir, host_dir)
+      logging.info('Gold directory pull took %fs', time.time() - start_time)
+
       for image_name in os.listdir(host_dir):
         if not image_name.endswith('.png'):
           continue
@@ -1529,6 +1546,8 @@
         gold_session = self._skia_gold_session_manager.GetSkiaGoldSession(
             keys_input=json_path)
 
+        logging.info('Starting Gold comparison')
+        start_time = time.time()
         try:
           status, error = gold_session.RunComparison(
               name=render_name,
@@ -1541,6 +1560,8 @@
           _AppendToLog(results, full_test_name,
                        'Skia Gold comparison raised exception: %s' % e)
           continue
+        finally:
+          logging.info('Gold comparison took %fs', time.time() - start_time)
 
         if not status:
           continue
diff --git a/build/lacros/test_runner.py b/build/lacros/test_runner.py
index 32c1cad..013a487 100755
--- a/build/lacros/test_runner.py
+++ b/build/lacros/test_runner.py
@@ -117,7 +117,6 @@
     # serially.
     'interactive_ui_tests',
     'lacros_chrome_browsertests',
-    'lacros_chrome_browsertests_run_in_series'
 ]
 
 # Default test filter file for each target. These filter files will be
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni
index bd451f0..9bad22e 100644
--- a/buildtools/deps_revisions.gni
+++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@
 declare_args() {
   # Used to cause full rebuilds on libc++ rolls. This should be kept in sync
   # with the libcxx_revision vars in //DEPS.
-  libcxx_revision = "2f6750b44bbad5726de61f2b4e2021fedba63666"
+  libcxx_revision = "8d4b8a60c23515932186285479fe1e9c073cc513"
 }
diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc
index 2ef7a02..9ae6d4c 100644
--- a/cc/layers/video_layer_impl.cc
+++ b/cc/layers/video_layer_impl.cc
@@ -114,8 +114,7 @@
         layer_tree_impl()->layer_tree_frame_sink(),
         layer_tree_impl()->resource_provider(),
         settings.use_stream_video_draw_quad,
-        settings.resource_settings.use_gpu_memory_buffer_resources,
-        settings.resource_settings.use_r16_texture,
+        settings.use_gpu_memory_buffer_resources,
         layer_tree_impl()->max_texture_size());
   }
   updater_->ObtainFrameResources(frame_);
diff --git a/cc/trees/draw_properties_unittest.cc b/cc/trees/draw_properties_unittest.cc
index 34b94a42..cee9d59 100644
--- a/cc/trees/draw_properties_unittest.cc
+++ b/cc/trees/draw_properties_unittest.cc
@@ -3742,15 +3742,12 @@
 
   UpdateActiveTreeDrawProperties();
 
-  EXPECT_TRUE(draw_property_utils::IsLayerBackFaceVisible(
-      back_facing, back_facing->transform_tree_index(),
-      host_impl()->active_tree()->property_trees()));
-  EXPECT_TRUE(draw_property_utils::IsLayerBackFaceVisible(
-      back_facing, back_facing_double_sided->transform_tree_index(),
-      host_impl()->active_tree()->property_trees()));
-  EXPECT_FALSE(draw_property_utils::IsLayerBackFaceVisible(
-      front_facing, front_facing->transform_tree_index(),
-      host_impl()->active_tree()->property_trees()));
+  EXPECT_TRUE(draw_property_utils::IsLayerBackFaceVisibleForTesting(
+      back_facing, host_impl()->active_tree()->property_trees()));
+  EXPECT_TRUE(draw_property_utils::IsLayerBackFaceVisibleForTesting(
+      back_facing_double_sided, host_impl()->active_tree()->property_trees()));
+  EXPECT_FALSE(draw_property_utils::IsLayerBackFaceVisibleForTesting(
+      front_facing, host_impl()->active_tree()->property_trees()));
 
   EXPECT_TRUE(back_facing->raster_even_if_not_drawn());
   EXPECT_TRUE(
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
index 070d9c1..06a9aa9 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -419,61 +419,43 @@
 }
 
 template <typename LayerType>
-int TransformTreeIndexForBackfaceVisibility(LayerType* layer,
-                                            const TransformTree& tree) {
-  return layer->transform_tree_index();
+const TransformNode& TransformNodeForBackfaceVisibility(
+    LayerType* layer,
+    const TransformTree& tree) {
+  const TransformNode* node = tree.Node(layer->transform_tree_index());
+  while (node->delegates_to_parent_for_backface) {
+    const TransformNode* parent = tree.Node(node->parent_id);
+    CHECK(node);
+    // Backface visibility inheritance should not cross 3d sorting contexts.
+    DCHECK(!node->sorting_context_id ||
+           parent->sorting_context_id == node->sorting_context_id);
+    node = parent;
+  }
+  return *node;
 }
 
 bool IsTargetSpaceTransformBackFaceVisible(
-    Layer* layer,
-    int transform_tree_index,
+    const LayerImpl* layer,
     const PropertyTrees* property_trees) {
-  // We do not skip back face invisible layers on main thread as target space
-  // transform will not be available here.
-  return false;
-}
-
-bool IsTargetSpaceTransformBackFaceVisible(
-    LayerImpl* layer,
-    int transform_tree_index,
-    const PropertyTrees* property_trees) {
-  const TransformTree& transform_tree = property_trees->transform_tree();
-  const TransformNode& transform_node =
-      *transform_tree.Node(transform_tree_index);
-  if (transform_node.delegates_to_parent_for_backface)
-    transform_tree_index = transform_node.parent_id;
-
+  const TransformNode& transform_node = TransformNodeForBackfaceVisibility(
+      layer, property_trees->transform_tree());
   gfx::Transform to_target;
-  property_trees->GetToTarget(transform_tree_index,
-                              layer->render_target_effect_tree_index(),
-                              &to_target);
+  property_trees->GetToTarget(
+      transform_node.id, layer->render_target_effect_tree_index(), &to_target);
+
   return to_target.IsBackFaceVisible();
 }
 
 bool IsTransformToRootOf3DRenderingContextBackFaceVisible(
-    Layer* layer,
-    int transform_tree_index,
-    const PropertyTrees* property_trees) {
-  // We do not skip back face invisible layers on main thread as target space
-  // transform will not be available here.
-  return false;
-}
-
-bool IsTransformToRootOf3DRenderingContextBackFaceVisible(
-    LayerImpl* layer,
-    int transform_tree_index,
+    const LayerImpl* layer,
     const PropertyTrees* property_trees) {
   const TransformTree& transform_tree = property_trees->transform_tree();
 
   const TransformNode& transform_node =
-      *transform_tree.Node(transform_tree_index);
+      TransformNodeForBackfaceVisibility(layer, transform_tree);
   const TransformNode* root_node = &transform_node;
-  if (transform_node.delegates_to_parent_for_backface) {
-    transform_tree_index = transform_node.parent_id;
-    root_node = transform_tree.Node(transform_tree_index);
-  }
 
-  int root_id = transform_tree_index;
+  int root_id = transform_node.id;
   int sorting_context_id = transform_node.sorting_context_id;
 
   while (root_id > kRootPropertyNodeId) {
@@ -488,24 +470,35 @@
   // TODO(chrishtr): cache this on the transform trees if needed, similar to
   // |to_target| and |to_screen|.
   gfx::Transform to_3d_root;
-  if (transform_tree_index != root_id)
+  if (transform_node.id != root_id) {
     property_trees->transform_tree().CombineTransformsBetween(
-        transform_tree_index, root_id, &to_3d_root);
+        transform_node.id, root_id, &to_3d_root);
+  }
   to_3d_root.PreConcat(root_node->to_parent);
   return to_3d_root.IsBackFaceVisible();
 }
 
-inline bool TransformToScreenIsKnown(Layer* layer,
-                                     int transform_tree_index,
-                                     const TransformTree& tree) {
-  const TransformNode* node = tree.Node(transform_tree_index);
-  return !node->to_screen_is_potentially_animated;
+bool IsLayerBackFaceVisible(const Layer* layer,
+                            const PropertyTrees* property_trees) {
+  // We do not skip back face invisible layers on main thread as target space
+  // transform will not be available here.
+  return false;
 }
 
-inline bool TransformToScreenIsKnown(LayerImpl* layer,
-                                     int transform_tree_index,
-                                     const TransformTree& tree) {
-  return true;
+bool IsLayerBackFaceVisible(const LayerImpl* layer,
+                            const PropertyTrees* property_trees) {
+  // A layer with singular transform is not drawn. So, we can assume that its
+  // backface is not visible.
+  if (HasSingularTransform(layer->transform_tree_index(),
+                           property_trees->transform_tree())) {
+    return false;
+  }
+  if (layer->layer_tree_impl()->settings().enable_backface_visibility_interop) {
+    return IsTransformToRootOf3DRenderingContextBackFaceVisible(layer,
+                                                                property_trees);
+  } else {
+    return IsTargetSpaceTransformBackFaceVisible(layer, property_trees);
+  }
 }
 
 template <typename LayerType>
@@ -536,18 +529,9 @@
 
   // The layer should not be drawn if (1) it is not double-sided and (2) the
   // back of the layer is known to be facing the screen.
-  const TransformTree& tree = property_trees->transform_tree();
-  if (layer->should_check_backface_visibility()) {
-    int backface_transform_id =
-        TransformTreeIndexForBackfaceVisibility(layer, tree);
-    // A layer with singular transform is not drawn. So, we can assume that its
-    // backface is not visible.
-    if (TransformToScreenIsKnown(layer, backface_transform_id, tree) &&
-        !HasSingularTransform(backface_transform_id, tree) &&
-        draw_property_utils::IsLayerBackFaceVisible(
-            layer, backface_transform_id, property_trees)) {
-      return false;
-    }
+  if (layer->should_check_backface_visibility() &&
+      IsLayerBackFaceVisible(layer, property_trees)) {
+    return false;
   }
 
   return true;
@@ -1377,7 +1361,7 @@
 
 }  // namespace
 
-bool CC_EXPORT LayerShouldBeSkippedForDrawPropertiesComputation(
+bool LayerShouldBeSkippedForDrawPropertiesComputation(
     LayerImpl* layer,
     const PropertyTrees* property_trees) {
   const TransformTree& transform_tree = property_trees->transform_tree();
@@ -1403,37 +1387,15 @@
     return true;
   if (layer->layer_tree_impl()->settings().enable_backface_visibility_interop) {
     return layer->should_check_backface_visibility() &&
-           IsLayerBackFaceVisible(layer, layer->transform_tree_index(),
-                                  property_trees);
+           IsLayerBackFaceVisible(layer, property_trees);
   } else {
     return effect_node->hidden_by_backface_visibility;
   }
 }
 
-bool CC_EXPORT IsLayerBackFaceVisible(LayerImpl* layer,
-                                      int transform_tree_index,
+bool IsLayerBackFaceVisibleForTesting(const LayerImpl* layer,  // IN-TEST
                                       const PropertyTrees* property_trees) {
-  if (layer->layer_tree_impl()->settings().enable_backface_visibility_interop) {
-    return IsTransformToRootOf3DRenderingContextBackFaceVisible(
-        layer, transform_tree_index, property_trees);
-  } else {
-    return IsTargetSpaceTransformBackFaceVisible(layer, transform_tree_index,
-                                                 property_trees);
-  }
-}
-
-bool CC_EXPORT IsLayerBackFaceVisible(Layer* layer,
-                                      int transform_tree_index,
-                                      const PropertyTrees* property_trees) {
-  if (layer->layer_tree_host()
-          ->GetSettings()
-          .enable_backface_visibility_interop) {
-    return IsTransformToRootOf3DRenderingContextBackFaceVisible(
-        layer, transform_tree_index, property_trees);
-  } else {
-    return IsTargetSpaceTransformBackFaceVisible(layer, transform_tree_index,
-                                                 property_trees);
-  }
+  return IsLayerBackFaceVisible(layer, property_trees);
 }
 
 void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node,
diff --git a/cc/trees/draw_property_utils.h b/cc/trees/draw_property_utils.h
index a19209f..64f58a6 100644
--- a/cc/trees/draw_property_utils.h
+++ b/cc/trees/draw_property_utils.h
@@ -75,13 +75,9 @@
     LayerImpl* layer,
     const PropertyTrees* property_trees);
 
-bool CC_EXPORT IsLayerBackFaceVisible(LayerImpl* layer,
-                                      int transform_tree_index,
-                                      const PropertyTrees* property_trees);
-
-bool CC_EXPORT IsLayerBackFaceVisible(Layer* layer,
-                                      int transform_tree_index,
-                                      const PropertyTrees* property_trees);
+bool CC_EXPORT
+IsLayerBackFaceVisibleForTesting(const LayerImpl* layer,
+                                 const PropertyTrees* property_trees);
 
 #if DCHECK_IS_ON()
 // Checks and logs if double background blur exists in any layers. Returns
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 81de54a..78e581b 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -2882,7 +2882,7 @@
       viz::PlatformColor::BestSupportedTextureFormat(context_caps);
 
   raster_caps_.tile_overlay_candidate =
-      settings_.resource_settings.use_gpu_memory_buffer_resources &&
+      settings_.use_gpu_memory_buffer_resources &&
       shared_image_caps.supports_scanout_shared_images;
   raster_caps_.tile_texture_target = GL_TEXTURE_2D;
 
@@ -4608,7 +4608,7 @@
     const auto& shared_image_caps =
         context_provider->SharedImageInterface()->GetCapabilities();
     overlay_candidate =
-        settings_.resource_settings.use_gpu_memory_buffer_resources &&
+        settings_.use_gpu_memory_buffer_resources &&
         shared_image_caps.supports_scanout_shared_images &&
         viz::CanCreateGpuMemoryBufferForSinglePlaneSharedImageFormat(format);
     if (overlay_candidate) {
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index e0732eb..5b803de 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -16,7 +16,6 @@
 #include "cc/tiles/tile_manager_settings.h"
 #include "cc/trees/managed_memory_policy.h"
 #include "components/viz/common/display/renderer_settings.h"
-#include "components/viz/common/resources/resource_settings.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -31,7 +30,6 @@
   SchedulerSettings ToSchedulerSettings() const;
   TileManagerSettings ToTileManagerSettings() const;
 
-  viz::ResourceSettings resource_settings;
   bool single_thread_proxy_scheduler = true;
   bool main_frame_before_activation_enabled = false;
   bool using_synchronous_renderer_compositor = false;
@@ -45,6 +43,7 @@
   float gpu_rasterization_skewport_target_time_in_seconds = 0.2f;
   bool create_low_res_tiling = false;
   bool use_stream_video_draw_quad = false;
+  bool use_gpu_memory_buffer_resources = false;
 
   enum ScrollbarAnimator {
     NO_ANIMATOR,
diff --git a/chrome/VERSION b/chrome/VERSION
index f6942e48..9429763 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=120
 MINOR=0
-BUILD=6076
+BUILD=6077
 PATCH=0
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 57a6fe9..c17d19e 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -200,6 +200,7 @@
   "java/src/org/chromium/chrome/browser/bookmarks/BookmarkUiState.java",
   "java/src/org/chromium/chrome/browser/bookmarks/BookmarkUndoController.java",
   "java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java",
+  "java/src/org/chromium/chrome/browser/bookmarks/CancelableAnimator.java",
   "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderView.java",
   "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderViewBinder.java",
   "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderViewCoordinator.java",
diff --git a/chrome/android/expectations/monochrome_public_bundle.proguard_flags.expected b/chrome/android/expectations/monochrome_public_bundle.proguard_flags.expected
index 236d1c52..a4dacd4 100644
--- a/chrome/android/expectations/monochrome_public_bundle.proguard_flags.expected
+++ b/chrome/android/expectations/monochrome_public_bundle.proguard_flags.expected
@@ -92,15 +92,6 @@
 
 # Keeps for method level annotations.
 -keepclasseswithmembers,allowaccessmodification class ** {
-  @org.chromium.base.annotations.AccessedByNative <fields>;
-}
--keepclasseswithmembers,includedescriptorclasses,allowaccessmodification class ** {
-  @org.chromium.base.annotations.CalledByNative <methods>;
-}
--keepclasseswithmembers,includedescriptorclasses,allowaccessmodification class ** {
-  @org.chromium.base.annotations.CalledByNativeUnchecked <methods>;
-}
--keepclasseswithmembers,allowaccessmodification class ** {
   @org.chromium.build.annotations.UsedByReflection <methods>;
 }
 -keepclasseswithmembers,allowaccessmodification class ** {
diff --git a/chrome/android/features/tab_ui/public/android/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeUtil.java b/chrome/android/features/tab_ui/public/android/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeUtil.java
index 527de19..ebc4b0af 100644
--- a/chrome/android/features/tab_ui/public/android/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeUtil.java
+++ b/chrome/android/features/tab_ui/public/android/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeUtil.java
@@ -34,8 +34,12 @@
     public static @ColorInt int getTabStripBackgroundColor(Context context, boolean isIncognito) {
         if (TabManagementFieldTrial.isTabStripFolioEnabled()) {
             // Use black color for incognito and night mode for folio.
-            if (isIncognito || ColorUtils.inNightMode(context)) {
-                return Color.BLACK;
+            if (isIncognito) {
+                return context.getColor(R.color.default_bg_color_dark_elev_2_baseline);
+            }
+
+            if (ColorUtils.inNightMode(context)) {
+                return ChromeColors.getSurfaceColor(context, R.dimen.default_elevation_2);
             }
 
             return ChromeColors.getSurfaceColor(context, R.dimen.default_elevation_3);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java
index 29a21b9..fca76e9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java
@@ -73,6 +73,21 @@
         }
     };
 
+    private final class DragAndCancelAdapter extends DragReorderableRecyclerViewAdapter {
+        DragAndCancelAdapter(Context context, ModelList modelList) {
+            super(context, modelList);
+        }
+
+        @Override
+        public boolean onFailedToRecycleView(@NonNull ViewHolder holder) {
+            if (BookmarkFeatures.isAndroidImprovedBookmarksEnabled()
+                    && holder.itemView instanceof CancelableAnimator cancelable) {
+                cancelable.cancelAnimation();
+            }
+            return super.onFailedToRecycleView(holder);
+        }
+    }
+
     private final ObservableSupplierImpl<Boolean> mBackPressStateSupplier =
             new ObservableSupplierImpl<>();
     private final ViewGroup mMainView;
@@ -132,7 +147,7 @@
 
         ModelList modelList = new ModelList();
         DragReorderableRecyclerViewAdapter dragReorderableRecyclerViewAdapter =
-                new DragReorderableRecyclerViewAdapter(context, modelList);
+                new DragAndCancelAdapter(context, modelList);
         mRecyclerView =
                 mSelectableListLayout.initializeRecyclerView(dragReorderableRecyclerViewAdapter);
 
@@ -228,7 +243,7 @@
                 mMediator.getDraggabilityProvider());
         dragReorderableRecyclerViewAdapter.registerDraggableType(
                 ViewType.IMPROVED_BOOKMARK_COMPACT,
-                this::buildCompactImprovedBookmarkRow,
+                this::buildVisualImprovedBookmarkRow,
                 ImprovedBookmarkRowViewBinder::bind,
                 (viewHolder, itemTouchHelper) -> {},
                 mMediator.getDraggabilityProvider());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/CancelableAnimator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/CancelableAnimator.java
new file mode 100644
index 0000000..aa8c233
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/CancelableAnimator.java
@@ -0,0 +1,19 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.bookmarks;
+
+import android.view.View;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * Semi-tag interface that allows {@link RecyclerView.Adapter} to cast {@link View} to, and clear
+ * out in progress animations. This should hopefully clear the {@link View#hasTransientState()},
+ * allowing the {@link RecyclerView} to recycle the {@link View}. Implements are allowed to be a
+ * best effort, and if no in progress animation is running this call should no-op.
+ */
+interface CancelableAnimator {
+    void cancelAnimation();
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderViewBinder.java
index 21e10dbd..2decae4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderViewBinder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderViewBinder.java
@@ -4,15 +4,13 @@
 
 package org.chromium.chrome.browser.bookmarks;
 
-import android.view.View;
 
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
 
 /** Binds model properties to view methods for {@link ImprovedBookmarkFolderView}. */
 class ImprovedBookmarkFolderViewBinder {
-    static void bind(PropertyModel model, View view, PropertyKey key) {
-        ImprovedBookmarkFolderView folderView = (ImprovedBookmarkFolderView) view;
+    static void bind(PropertyModel model, ImprovedBookmarkFolderView folderView, PropertyKey key) {
         if (key == ImprovedBookmarkFolderViewProperties.START_AREA_BACKGROUND_COLOR) {
             folderView.setStartAreaBackgroundColor(
                     model.get(ImprovedBookmarkFolderViewProperties.START_AREA_BACKGROUND_COLOR));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderViewCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderViewCoordinator.java
index 5899ad0b..683ca25 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderViewCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderViewCoordinator.java
@@ -23,7 +23,7 @@
     private final BookmarkImageFetcher mBookmarkImageFetcher;
     private final BookmarkModel mBookmarkModel;
 
-    private View mView;
+    private ImprovedBookmarkFolderView mView;
     private BookmarkItem mBookmarkItem;
     private PropertyModelChangeProcessor mChangeProcessor;
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRow.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRow.java
index 9e397019..82b8e2d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRow.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRow.java
@@ -29,7 +29,8 @@
 import org.chromium.ui.widget.ViewLookupCachingFrameLayout;
 
 /** Common logic for improved bookmark and folder rows. */
-public class ImprovedBookmarkRow extends ViewLookupCachingFrameLayout {
+public class ImprovedBookmarkRow extends ViewLookupCachingFrameLayout
+        implements CancelableAnimator {
     /**
      * The base duration of the settling animation of the sheet. 218 ms is a spec for material
      * design (this is the minimum time a user is guaranteed to pay attention to something).
@@ -54,6 +55,7 @@
     // 3-dot menu which displays contextual actions.
     private ListMenuButton mMoreButton;
     private ImageView mEndImageView;
+    private @Nullable ViewPropertyAnimator mFadeAnimator;
 
     private boolean mDragEnabled;
     private boolean mBookmarkIdEditable;
@@ -87,6 +89,14 @@
         super(context, attrs);
     }
 
+    @Override
+    public void cancelAnimation() {
+        if (mFadeAnimator != null) {
+            mFadeAnimator.cancel();
+            mFadeAnimator = null;
+        }
+    }
+
     void setStartImageRoundedCornerOutlineProvider(boolean isVisual) {
         assert mStartImageView != null;
 
@@ -140,17 +150,16 @@
     }
 
     void setStartIconDrawable(@Nullable Drawable drawable) {
+        cancelAnimation();
+
         mStartImageView.setImageDrawable(drawable);
         // No need to fade-in a null drawable.
         if (drawable == null) return;
 
         mStartImageView.setAlpha(0f);
 
-        // Using a local variable to facilitate testing.
-        ViewPropertyAnimator anim = mStartImageView.animate();
-        anim.setDuration(BASE_ANIMATION_DURATION_MS);
-        anim.alpha(1f);
-        anim.start();
+        mFadeAnimator = mStartImageView.animate().setDuration(BASE_ANIMATION_DURATION_MS).alpha(1f);
+        mFadeAnimator.start();
     }
 
     void setStartIconTint(ColorStateList tint) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
index 3521731..7ff5a7d0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
@@ -74,6 +74,7 @@
 import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
 import org.chromium.chrome.features.start_surface.StartSurfaceUserData;
 import org.chromium.components.browser_ui.widget.TouchEventObserver;
+import org.chromium.components.browser_ui.widget.TouchEventProvider;
 import org.chromium.components.content_capture.OnscreenContentProvider;
 import org.chromium.components.embedder_support.view.ContentView;
 import org.chromium.components.prefs.PrefService;
@@ -99,14 +100,18 @@
 /**
  * This class holds a {@link CompositorView}. This level of indirection is needed to benefit from
  * the {@link android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent)} capability on
- * available on {@link android.view.ViewGroup}s.
- * This class also holds the {@link LayoutManagerImpl} responsible to describe the items to be
- * drawn by the UI compositor on the native side.
+ * available on {@link android.view.ViewGroup}s. This class also holds the {@link LayoutManagerImpl}
+ * responsible to describe the items to be drawn by the UI compositor on the native side.
  */
 public class CompositorViewHolder extends FrameLayout
-        implements LayoutManagerHost, LayoutRenderHost, Invalidator.Host,
-                   BrowserControlsStateProvider.Observer, ChromeAccessibilityUtil.Observer,
-                   TabObscuringHandler.Observer, ViewGroup.OnHierarchyChangeListener {
+        implements LayoutManagerHost,
+                LayoutRenderHost,
+                Invalidator.Host,
+                TouchEventProvider,
+                BrowserControlsStateProvider.Observer,
+                ChromeAccessibilityUtil.Observer,
+                TabObscuringHandler.Observer,
+                ViewGroup.OnHierarchyChangeListener {
     private static final long SYSTEM_UI_VIEWPORT_UPDATE_DELAY_MS = 500;
     private static final MutableFlagWithSafeDefault sDeferKeepScreenOnFlag =
             new MutableFlagWithSafeDefault(
@@ -655,18 +660,14 @@
         return mInvalidator;
     }
 
-    /**
-     * Add observer that needs to listen and process touch events.
-     * @param o {@link TouchEventObserver} object.
-     */
+    // TouchEventProvider implementation.
+
+    @Override
     public void addTouchEventObserver(TouchEventObserver o) {
         mTouchEventObservers.addObserver(o);
     }
 
-    /**
-     * Remove observer that needs to listen and process touch events.
-     * @param o {@link TouchEventObserver} object.
-     */
+    @Override
     public void removeTouchEventObserver(TouchEventObserver o) {
         mTouchEventObservers.removeObserver(o);
     }
@@ -675,7 +676,7 @@
     public boolean onInterceptTouchEvent(MotionEvent e) {
         super.onInterceptTouchEvent(e);
         for (TouchEventObserver o : mTouchEventObservers) {
-            if (o.shouldInterceptTouchEvent(e)) return true;
+            if (o.onInterceptTouchEvent(e)) return true;
         }
 
         if (mLayoutManager == null) return false;
@@ -687,6 +688,9 @@
     @Override
     public boolean onTouchEvent(MotionEvent e) {
         super.onTouchEvent(e);
+        for (TouchEventObserver o : mTouchEventObservers) {
+            if (o.onTouchEvent(e)) return true;
+        }
 
         boolean consumed = mLayoutManager != null && mLayoutManager.onTouchEvent(e);
         mEventOffsetHandler.onTouchEvent(e);
@@ -765,7 +769,9 @@
         assert e != null : "The motion event dispatched shouldn't be null!";
         updateLastActiveTouchEvent(e);
         updateIsInGesture(e);
-        for (TouchEventObserver o : mTouchEventObservers) o.handleTouchEvent(e);
+        for (TouchEventObserver o : mTouchEventObservers) {
+            if (o.dispatchTouchEvent(e)) return true;
+        }
 
         // This is where input events go from android through native to the web content. This
         // process is latency sensitive. Ideally observers that might be expensive, such as
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
index da72fce..0043c27f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -38,6 +38,7 @@
 import org.chromium.base.task.PostTask;
 import org.chromium.base.task.TaskTraits;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerHost;
 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl;
 import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost;
@@ -287,6 +288,7 @@
     private TabDropTarget mTabDropTarget;
 
     private StripTabHoverCardView mTabHoverCardView;
+    private BrowserControlsStateProvider mBrowserControlStateProvider;
 
     /**
      * Creates an instance of the {@link StripLayoutHelper}.
@@ -302,6 +304,8 @@
      *     for drag and drop.
      * @param dragDropDelegate The @{@link DragAndDropDelegate} passed to @{@link TabDragSource} to
      *     initiate drag and drop.
+     * @param browserControlsStateProvider The @BrowserControlsStateProvider passed for drag and
+     *     drop.
      * @param toolbarContainerView The @{link View} passed to @{link TabDragSource} for drag and
      *     drop.
      */
@@ -314,6 +318,7 @@
             CompositorButton modelSelectorButton,
             MultiInstanceManager multiInstanceManager,
             DragAndDropDelegate dragDropDelegate,
+            BrowserControlsStateProvider browserControlsStateProvider,
             View toolbarContainerView) {
         mTabOverlapWidth = ChromeFeatureList.sTabStripRedesign.isEnabled()
                 ? TAB_OVERLAP_WIDTH_LARGE_DP
@@ -327,6 +332,7 @@
         mMultiInstanceManager = multiInstanceManager;
         mToolbarContainerView = toolbarContainerView;
         mDragAndDropDelegate = dragDropDelegate;
+        mBrowserControlStateProvider = browserControlsStateProvider;
 
         if (ChromeFeatureList.sTabStripRedesign.isEnabled()) {
             // Use toolbar menu button padding to align NTB with menu button.
@@ -2236,7 +2242,9 @@
 
         for (int i = mStripTabsVisuallyOrdered.length - 1; i >= 0; i--) {
             final StripLayoutTab tab = mStripTabsVisuallyOrdered[i];
-            if (tab.isVisible() && tab.getDrawX() <= x && x <= (tab.getDrawX() + tab.getWidth())) {
+            if (tab.isVisible()
+                    && tab.getTouchTargetLeft() <= x
+                    && x <= tab.getTouchTargetRight()) {
                 return tab;
             }
         }
@@ -3330,7 +3338,8 @@
                         mToolbarContainerView,
                         mMultiInstanceManager,
                         mDragAndDropDelegate,
-                        mTabDropTarget);
+                        mTabDropTarget,
+                        mBrowserControlStateProvider);
     }
 
     @VisibleForTesting
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java
index f9f9bb2..f62b35e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java
@@ -423,6 +423,7 @@
                         mModelSelectorButton,
                         multiInstanceManager,
                         dragDropDelegate,
+                        managerHost.getBrowserControlsManager(),
                         toolbarContainerView);
         mIncognitoHelper =
                 new StripLayoutHelper(
@@ -434,6 +435,7 @@
                         mModelSelectorButton,
                         multiInstanceManager,
                         dragDropDelegate,
+                        managerHost.getBrowserControlsManager(),
                         toolbarContainerView);
 
         tabHoverCardViewStub.setOnInflateListener((viewStub, view) -> {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
index 1c55ae72..056c1977 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
@@ -175,12 +175,14 @@
     // Close Button Constants
     // Close button padding value comes from the built-in padding in the source png.
     private static final int CLOSE_BUTTON_PADDING_DP = 7;
+    private static final int CLOSE_BUTTON_OFFSET_X = 12;
     private static final int CLOSE_BUTTON_WIDTH_DP = 48;
 
     // Strip Tab Offset Constants
     private static final float TOP_MARGIN_DP = 2.f;
     private static final float FOLIO_CONTENT_OFFSET_Y = 8.f;
     private static final float DETACHED_CONTENT_OFFSET_Y = 10.f;
+    private static final float TOUCH_TARGET_INSET = 16.f;
 
     // Divider Constants
     private static final int DIVIDER_OFFSET_X = 13;
@@ -205,6 +207,8 @@
     private final boolean mIncognito;
     private float mBottomMargin;
     private float mContainerOpacity;
+    private float mLeftInset;
+    private float mRightInset;
     private String mAccessibilityDescription;
 
     // Ideal intermediate parameters
@@ -271,6 +275,15 @@
         mCloseButton.setIncognito(mIncognito);
         mCloseButton.setBounds(getCloseRect());
         mCloseButton.setClickSlop(0.f);
+        if (ChromeFeatureList.sTabStripRedesign.isEnabled()) {
+            if (LocalizationUtils.isLayoutRtl()) {
+                mLeftInset = getCloseButtonOffsetX();
+                mRightInset = TOUCH_TARGET_INSET;
+            } else {
+                mLeftInset = TOUCH_TARGET_INSET;
+                mRightInset = getCloseButtonOffsetX();
+            }
+        }
     }
 
     /** @param observer The observer to add. */
@@ -694,8 +707,8 @@
     public void setDrawX(float x) {
         mCloseButton.setX(mCloseButton.getX() + (x - mDrawX));
         mDrawX = x;
-        mTouchTarget.left = mDrawX;
-        mTouchTarget.right = mDrawX + mWidth;
+        mTouchTarget.left = mDrawX + mLeftInset;
+        mTouchTarget.right = mDrawX + mWidth - mRightInset;
     }
 
     /**
@@ -728,7 +741,7 @@
     public void setWidth(float width) {
         mWidth = width;
         resetCloseRect();
-        mTouchTarget.right = mDrawX + mWidth;
+        mTouchTarget.right = mDrawX + mWidth - mRightInset;
     }
 
     /**
@@ -881,6 +894,20 @@
         return mIsPlaceholder;
     }
 
+    /**
+     * @return The left-side of the tab's touch target.
+     */
+    public float getTouchTargetLeft() {
+        return mTouchTarget.left;
+    }
+
+    /**
+     * @return The right-side of the tab's touch target.
+     */
+    public float getTouchTargetRight() {
+        return mTouchTarget.right;
+    }
+
     private void resetCloseRect() {
         RectF closeRect = getCloseRect();
         mCloseButton.setWidth(closeRect.width());
@@ -891,12 +918,13 @@
 
     private RectF getCloseRect() {
         int closeButtonWidth = CLOSE_BUTTON_WIDTH_DP;
+        int closeButtonOffsetX = getCloseButtonOffsetX();
         if (!LocalizationUtils.isLayoutRtl()) {
-            mClosePlacement.left = getWidth() - closeButtonWidth;
+            mClosePlacement.left = getWidth() - closeButtonWidth - closeButtonOffsetX;
             mClosePlacement.right = mClosePlacement.left + closeButtonWidth;
         } else {
-            mClosePlacement.left = 0;
-            mClosePlacement.right = closeButtonWidth;
+            mClosePlacement.left = closeButtonOffsetX;
+            mClosePlacement.right = closeButtonWidth + closeButtonOffsetX;
         }
 
         mClosePlacement.top = 0;
@@ -910,6 +938,10 @@
         return ChromeFeatureList.sTabStripRedesign.isEnabled() ? CLOSE_BUTTON_PADDING_DP : 0;
     }
 
+    public int getCloseButtonOffsetX() {
+        return ChromeFeatureList.sTabStripRedesign.isEnabled() ? CLOSE_BUTTON_OFFSET_X : 0;
+    }
+
     // TODO(dtrainor): Don't animate this if we're selecting or deselecting this tab.
     private void checkCloseButtonVisibility(boolean animate) {
         boolean shouldShow = mCanShowCloseButton && !mIsPlaceholder;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java
index ff78b2ed..e5a4a3e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java
@@ -24,10 +24,10 @@
 
 import org.chromium.base.Log;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerImpl;
 import org.chromium.chrome.browser.dragdrop.ChromeDragAndDropBrowserDelegate;
 import org.chromium.chrome.browser.dragdrop.ChromeDropDataAndroid;
-import org.chromium.chrome.browser.fullscreen.BrowserControlsManagerSupplier;
 import org.chromium.chrome.browser.multiwindow.MultiInstanceManager;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabUtils;
@@ -60,6 +60,7 @@
     private float mTabsToolbarHeightInDp;
 
     private float mPxToDp;
+    private BrowserControlsStateProvider mBrowserControlStateProvider;
 
     private TabDragSource() {}
 
@@ -375,10 +376,7 @@
                     context.getResources().getDimensionPixelSize(R.dimen.tab_hover_card_width);
             shadowHeightPx =
                     TabUtils.deriveGridCardHeight(
-                            shadowWidthPx,
-                            context,
-                            BrowserControlsManagerSupplier.getValueOrNullFrom(
-                                    mTabBeingDragged.getWindowAndroid()));
+                            shadowWidthPx, context, mBrowserControlStateProvider);
         }
         if (show) {
             imageView.setBackgroundDrawable(new ColorDrawable(Color.LTGRAY));
@@ -423,7 +421,8 @@
             View tabsToolbarView,
             MultiInstanceManager multiInstanceManager,
             DragAndDropDelegate dragAndDropDelegate,
-            TabDropTarget tabDropTarget) {
+            TabDropTarget tabDropTarget,
+            BrowserControlsStateProvider browserControlsStateProvider) {
         if (!TabUiFeatureUtilities.isTabDragEnabled()) return;
 
         assert (tabsToolbarView != null);
@@ -433,6 +432,7 @@
         mPxToDp = 1.f / tabsToolbarView.getContext().getResources().getDisplayMetrics().density;
         mMultiInstanceManager = multiInstanceManager;
         mDragAndDropDelegate = dragAndDropDelegate;
+        mBrowserControlStateProvider = browserControlsStateProvider;
 
         // Setup a drop target and register the callback where the drag events
         // will be received.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTabHelper.java
index 6990a97..90b6cb68 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTabHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/display_cutout/DisplayCutoutTabHelper.java
@@ -14,6 +14,7 @@
 import org.chromium.base.UserDataHost;
 import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.chrome.browser.customtabs.BaseCustomTabActivity;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabObserver;
@@ -110,6 +111,11 @@
             return (baseCustomTabActivity.getIntentDataProvider().getTwaDisplayMode()
                             instanceof TrustedWebActivityDisplayMode.ImmersiveMode);
         }
+
+        @Override
+        public boolean isDrawEdgeToEdgeEnabled() {
+            return ChromeFeatureList.sDrawEdgeToEdge.isEnabled();
+        }
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationCoordinator.java
index 48fd4f6..a468056 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/HistoryNavigationCoordinator.java
@@ -10,9 +10,9 @@
 
 import androidx.annotation.Nullable;
 
-import org.chromium.base.Callback;
 import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.base.supplier.OneshotSupplier;
+import org.chromium.base.supplier.Supplier;
 import org.chromium.chrome.browser.layouts.LayoutManager;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
 import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver;
@@ -22,6 +22,7 @@
 import org.chromium.chrome.features.start_surface.StartSurface;
 import org.chromium.components.browser_ui.widget.InsetObserverView;
 import org.chromium.components.browser_ui.widget.TouchEventObserver;
+import org.chromium.components.browser_ui.widget.TouchEventProvider;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.ui.base.WindowAndroid;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -47,11 +48,11 @@
 
     private OverscrollGlowOverlay mOverscrollGlowOverlay;
 
-    private Callback<TouchEventObserver> mInitCallback;
-    private Callback<TouchEventObserver> mDestroyCallback;
+    private Supplier<TouchEventProvider> mTouchEventProvider;
 
     /**
      * Creates the coordinator for gesture navigation and initializes internal objects.
+     *
      * @param window Window object.
      * @param lifecycleDispatcher Lifecycle dispatcher for the associated activity.
      * @param parentView Parent view of the gesture navigation layout.
@@ -61,21 +62,33 @@
      *        capabilities of the device.
      * @param startSurfaceSupplier StartSurface supplier.
      * @param backActionDelegate Delegate handling actions for back gesture.
-     * @param initRunnable Runnable to run when Navigation Handler is initialized.
-     * @param destroyRunnable Runnable to run when Navigation Handler is destroyed.
+     * @param touchEventProvider {@link TouchEventProvider} object.
      * @param layoutManager LayoutManager for handling overscroll glow effect as scene layer.
      * @return HistoryNavigationCoordinator object or null if not enabled via feature flag.
      */
-    public static HistoryNavigationCoordinator create(WindowAndroid window,
-            ActivityLifecycleDispatcher lifecycleDispatcher, ViewGroup parentView,
-            Runnable requestRunnable, ObservableSupplier<Tab> tabSupplier,
-            InsetObserverView insetObserverView, OneshotSupplier<StartSurface> startSurfaceSupplier,
-            BackActionDelegate backActionDelegate, Callback<TouchEventObserver> initCallback,
-            Callback<TouchEventObserver> destroyCallback, LayoutManager layoutManager) {
+    public static HistoryNavigationCoordinator create(
+            WindowAndroid window,
+            ActivityLifecycleDispatcher lifecycleDispatcher,
+            ViewGroup parentView,
+            Runnable requestRunnable,
+            ObservableSupplier<Tab> tabSupplier,
+            InsetObserverView insetObserverView,
+            OneshotSupplier<StartSurface> startSurfaceSupplier,
+            BackActionDelegate backActionDelegate,
+            Supplier<TouchEventProvider> touchEventProvider,
+            LayoutManager layoutManager) {
         HistoryNavigationCoordinator coordinator = new HistoryNavigationCoordinator();
-        coordinator.init(window, lifecycleDispatcher, parentView, requestRunnable, tabSupplier,
-                insetObserverView, startSurfaceSupplier, backActionDelegate, initCallback,
-                destroyCallback, layoutManager);
+        coordinator.init(
+                window,
+                lifecycleDispatcher,
+                parentView,
+                requestRunnable,
+                tabSupplier,
+                insetObserverView,
+                startSurfaceSupplier,
+                backActionDelegate,
+                touchEventProvider,
+                layoutManager);
         return coordinator;
     }
 
@@ -84,14 +97,18 @@
         return OverscrollGlowOverlay.class;
     }
 
-    /**
-     * Initializes the navigation layout and internal objects.
-     */
-    private void init(WindowAndroid window, ActivityLifecycleDispatcher lifecycleDispatcher,
-            ViewGroup parentView, Runnable requestRunnable, ObservableSupplier<Tab> tabSupplier,
-            InsetObserverView insetObserverView, OneshotSupplier<StartSurface> startSurfaceSupplier,
-            BackActionDelegate backActionDelegate, Callback<TouchEventObserver> initCallback,
-            Callback<TouchEventObserver> destroyCallback, LayoutManager layoutManager) {
+    /** Initializes the navigation layout and internal objects. */
+    private void init(
+            WindowAndroid window,
+            ActivityLifecycleDispatcher lifecycleDispatcher,
+            ViewGroup parentView,
+            Runnable requestRunnable,
+            ObservableSupplier<Tab> tabSupplier,
+            InsetObserverView insetObserverView,
+            OneshotSupplier<StartSurface> startSurfaceSupplier,
+            BackActionDelegate backActionDelegate,
+            Supplier<TouchEventProvider> touchEventProvider,
+            LayoutManager layoutManager) {
         mOverscrollGlowOverlay = new OverscrollGlowOverlay(window, parentView, requestRunnable);
         mNavigationLayout = new HistoryNavigationLayout(parentView.getContext(), this::isNativePage,
                 mOverscrollGlowOverlay, (direction) -> mNavigationHandler.navigate(direction));
@@ -99,6 +116,7 @@
         mParentView = parentView;
         mActivityLifecycleDispatcher = lifecycleDispatcher;
         mBackActionDelegate = backActionDelegate;
+        mTouchEventProvider = touchEventProvider;
         lifecycleDispatcher.register(this);
 
         // TODO(crbug.com/1216949): Look into enforcing the z-order of the views.
@@ -126,9 +144,6 @@
         //     StartSurface becomes available. The former is the better signal for the update.
         startSurfaceSupplier.onAvailable(s -> updateNavigationHandler());
 
-        mInitCallback = initCallback;
-        mDestroyCallback = destroyCallback;
-
         // We wouldn't hear about the first tab until the content changed or we switched tabs
         // if tabProvider.get() != null. Do here what we do when tab switching happens.
         // Otherwise, just initialize |mEnabled| in preparation of the initialization of
@@ -218,7 +233,7 @@
                 model, mNavigationLayout, GestureNavigationViewBinder::bind);
         mNavigationHandler = new NavigationHandler(
                 model, mNavigationLayout, mBackActionDelegate, mNavigationLayout::willNavigate);
-        mInitCallback.onResult(mNavigationHandler);
+        mTouchEventProvider.get().addTouchEventObserver(mNavigationHandler);
     }
 
     @Override
@@ -302,7 +317,9 @@
         if (mNavigationHandler != null) {
             mNavigationHandler.setTab(null);
             mNavigationHandler.destroy();
-            mDestroyCallback.onResult(mNavigationHandler);
+            if (mTouchEventProvider.get() != null) {
+                mTouchEventProvider.get().removeTouchEventObserver(mNavigationHandler);
+            }
             mNavigationHandler = null;
         }
         if (mActivityLifecycleDispatcher != null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java
index 1d660b1..7d9efda 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/gesturenav/NavigationHandler.java
@@ -153,7 +153,7 @@
     }
 
     @Override
-    public boolean shouldInterceptTouchEvent(MotionEvent e) {
+    public boolean onInterceptTouchEvent(MotionEvent e) {
         // Forward gesture events only for native pages/start surface. Rendered pages receive events
         // from SwipeRefreshHandler.
         if (!shouldProcessTouchEvents()) return false;
@@ -161,11 +161,12 @@
     }
 
     @Override
-    public void handleTouchEvent(MotionEvent e) {
+    public boolean dispatchTouchEvent(MotionEvent e) {
         assert e != null : "The motion event in NavigationHandler shouldn't be null!";
-        if (e == null || !shouldProcessTouchEvents()) return;
+        if (e == null || !shouldProcessTouchEvents()) return false;
         mDetector.onTouchEvent(e);
         if (e.getAction() == MotionEvent.ACTION_UP) release(true);
+        return false;
     }
 
     private boolean shouldProcessTouchEvents() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/hub/HubLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/hub/HubLayout.java
index 302a5e3..5f6fdfd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/hub/HubLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/hub/HubLayout.java
@@ -44,7 +44,9 @@
  * capture and animations it may transiently host a {@link StaticTabSceneLayer}.
  */
 public class HubLayout extends Layout {
-    private static final long TIMEOUT_MS = 300L;
+    // Copied from TabSwitcherLayout.
+    private static final long FADE_DURATION_MS = 325L;
+    private static final long TIMEOUT_MS = 250L;
 
     private SceneLayer mCurrentSceneLayer;
     /** Scene layer to facilitate thumbnail capture prior to starting a transition animation. */
@@ -169,6 +171,8 @@
 
         mHubController.onHubLayoutShow();
 
+        HubContainerView containerView = mHubController.getContainerView();
+
         // TODO(crbug/1487209): Get the animations from a Pane or HubManager and forward some events
         // along so visibility and animation timing are synced.
         HubLayoutAnimatorProvider animatorProvider;
@@ -176,7 +180,9 @@
             animatorProvider =
                     new EmptyHubLayoutAnimatorProvider(HubLayoutAnimationType.TRANSLATE_UP);
         } else if (mPreviousLayoutType == LayoutType.START_SURFACE) {
-            animatorProvider = new EmptyHubLayoutAnimatorProvider(HubLayoutAnimationType.FADE_IN);
+            animatorProvider =
+                    FadeHubLayoutAnimationFactory.createFadeInAnimatorProvider(
+                            containerView, FADE_DURATION_MS);
         } else {
             animatorProvider =
                     new EmptyHubLayoutAnimatorProvider(HubLayoutAnimationType.SHRINK_TAB);
@@ -193,7 +199,6 @@
                     }
                 });
 
-        HubContainerView containerView = mHubController.getContainerView();
         containerView.setVisibility(View.INVISIBLE);
         mRootView.addView(
                 containerView,
@@ -229,6 +234,8 @@
         @LayoutType
         int nextLayoutType = mLayoutStateProvider.getNextLayoutType();
 
+        HubContainerView containerView = mHubController.getContainerView();
+
         // TODO(crbug/1487209): Get the animations from a Pane or HubManager and forward some events
         // along so visibility and animation timing are synced.
         HubLayoutAnimatorProvider animatorProvider;
@@ -236,7 +243,9 @@
             animatorProvider =
                     new EmptyHubLayoutAnimatorProvider(HubLayoutAnimationType.TRANSLATE_DOWN);
         } else if (nextLayoutType == LayoutType.START_SURFACE) {
-            animatorProvider = new EmptyHubLayoutAnimatorProvider(HubLayoutAnimationType.FADE_OUT);
+            animatorProvider =
+                    FadeHubLayoutAnimationFactory.createFadeOutAnimatorProvider(
+                            containerView, FADE_DURATION_MS);
         } else {
             animatorProvider =
                     new EmptyHubLayoutAnimatorProvider(HubLayoutAnimationType.EXPAND_TAB);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
index 71b72b9..592d4a7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
@@ -16,7 +16,6 @@
 import android.os.Build;
 import android.os.Build.VERSION;
 import android.os.Bundle;
-import android.util.Pair;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
@@ -245,9 +244,9 @@
                 getMainFragment() instanceof CustomDividerFragment
                         ? (CustomDividerFragment) getMainFragment()
                         : null;
-        mItemDecoration =
-                new PaddedItemDecorationWithDivider(
-                        getItemOffsets(mUiConfig.getCurrentDisplayStyle()));
+        Supplier<Integer> itemOffsetSupplier =
+                () -> getItemOffset(mUiConfig.getCurrentDisplayStyle());
+        mItemDecoration = new PaddedItemDecorationWithDivider(itemOffsetSupplier);
         Drawable dividerDrawable = getDividerDrawable();
         // Early return if (a)Fragment implements CustomDividerFragment and explicitly don't
         // want a divider OR (b) dividerDrawable not defined.
@@ -273,29 +272,11 @@
     }
 
     @NonNull
-    private Pair<Integer, Integer> getItemOffsets(DisplayStyle displayStyle) {
+    private Integer getItemOffset(DisplayStyle displayStyle) {
         if (displayStyle.isWide()) {
-            int widePadding =
-                    ViewResizerUtil.computePaddingForWideDisplay(this, mMinWidePaddingPixels);
-            return new Pair(widePadding, widePadding);
-        } else {
-            // Default to preference item paddings (if view does not define padding) for
-            // non-wide display.
-            TypedArray paddingArray =
-                    getTheme()
-                            .obtainStyledAttributes(
-                                    new int[] {
-                                        R.attr.listPreferredItemPaddingStart,
-                                        R.attr.listPreferredItemPaddingEnd
-                                    });
-            try {
-                return new Pair(
-                        (int) paddingArray.getDimension(0, 0f),
-                        (int) paddingArray.getDimension(1, 0f));
-            } finally {
-                paddingArray.recycle();
-            }
+            return ViewResizerUtil.computePaddingForWideDisplay(this, mMinWidePaddingPixels);
         }
+        return 0;
     }
 
     private boolean hasPreferenceRecyclerView(RecyclerView recyclerView) {
@@ -674,9 +655,6 @@
     public void onDisplayStyleChanged(DisplayStyle newDisplayStyle) {
         RecyclerView recyclerView = findViewById(R.id.recycler_view);
         if (hasPreferenceRecyclerView(recyclerView)) {
-            if (mItemDecoration != null) {
-                mItemDecoration.setItemOffsets(getItemOffsets(newDisplayStyle));
-            }
             // Invalidate decorations to reset.
             recyclerView.invalidateItemDecorations();
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
index 28f3a45..7e5bb71 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
@@ -493,8 +493,8 @@
                         return isShowingStartSurfaceHomepage();
                     }
                 },
-                mCompositorViewHolderSupplier.get()::addTouchEventObserver,
-                mCompositorViewHolderSupplier.get()::removeTouchEventObserver, mLayoutManager);
+                () -> mCompositorViewHolderSupplier.get(),
+                mLayoutManager);
         mRootUiTabObserver.swapToTab(mActivityTabProvider.get());
 
         if (!DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity)) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java
index 6944dbe..95590a55 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.browser.download;
 
+
 import android.app.Notification;
 import android.content.Intent;
 import android.graphics.Bitmap;
@@ -11,19 +12,22 @@
 import android.util.Pair;
 import android.view.View;
 
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.MediumTest;
+import androidx.test.filters.LargeTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.hamcrest.Matchers;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 
 import org.chromium.base.Callback;
+import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
@@ -31,12 +35,15 @@
 import org.chromium.base.test.util.UrlUtils;
 import org.chromium.chrome.browser.download.DownloadTestRule.CustomMainActivityStart;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
+import org.chromium.chrome.browser.omnibox.suggestions.AutocompleteController;
+import org.chromium.chrome.browser.omnibox.suggestions.AutocompleteControllerProvider;
 import org.chromium.chrome.browser.profiles.OTRProfileID;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabLaunchType;
 import org.chromium.chrome.browser.tabmodel.TabCreator;
 import org.chromium.chrome.browser.tabmodel.TabModel;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule;
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.components.download.DownloadState;
 import org.chromium.components.offline_items_collection.ContentId;
@@ -61,12 +68,27 @@
 /** Tests Chrome download feature by attempting to download some files. */
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-public class DownloadTest implements CustomMainActivityStart {
-    @Rule public DownloadTestRule mDownloadTestRule = new DownloadTestRule(this);
+@Batch(Batch.PER_CLASS)
+public class DownloadTest {
+    @ClassRule
+    public static DownloadTestRule sDownloadTestRule =
+            new DownloadTestRule(
+                    new CustomMainActivityStart() {
+                        @Override
+                        public void customMainActivityStart() throws InterruptedException {
+                            sDownloadTestRule.startMainActivityOnBlankPage();
+                        }
+                    });
+
+    @Rule
+    public BlankCTATabInitialStateRule mBlankCTATabInitialStateRule =
+            new BlankCTATabInitialStateRule(sDownloadTestRule, false);
 
     private static final String SUPERBO_CONTENTS = "plain text response from a POST";
 
-    private EmbeddedTestServer mTestServer;
+    private static EmbeddedTestServer sTestServer;
+
+    @Mock private static AutocompleteController sACController;
 
     private static final String TEST_DOWNLOAD_DIRECTORY = "/chrome/test/data/android/download/";
 
@@ -204,14 +226,17 @@
         void resumeDownload(Intent intent) {}
     }
 
+    @BeforeClass
+    public static void beforeClass() {
+        AutocompleteControllerProvider.setControllerForTesting(sACController);
+        Looper.prepare();
+        sTestServer = sDownloadTestRule.getTestServer();
+        DownloadNotificationService.setInstanceForTests(new MockNotificationService());
+    }
+
     @Before
     public void setUp() {
-        deleteTestFiles();
-        Looper.prepare();
-        mTestServer =
-                EmbeddedTestServer.createAndStartServer(
-                        ApplicationProvider.getApplicationContext());
-        DownloadNotificationService.setInstanceForTests(new MockNotificationService());
+        sDownloadTestRule.resetCallbackHelper();
     }
 
     @After
@@ -219,15 +244,10 @@
         deleteTestFiles();
     }
 
-    @Override
-    public void customMainActivityStart() throws InterruptedException {
-        mDownloadTestRule.startMainActivityOnBlankPage();
-    }
-
     void waitForLastDownloadToFinish() {
         CriteriaHelper.pollUiThread(
                 () -> {
-                    List<DownloadItem> downloads = mDownloadTestRule.getAllDownloads();
+                    List<DownloadItem> downloads = sDownloadTestRule.getAllDownloads();
                     Criteria.checkThat(downloads.size(), Matchers.greaterThanOrEqualTo(1));
                     Criteria.checkThat(
                             downloads.get(downloads.size() - 1).getDownloadInfo().state(),
@@ -238,7 +258,7 @@
     void waitForAnyDownloadToCancel() {
         CriteriaHelper.pollUiThread(
                 () -> {
-                    List<DownloadItem> downloads = mDownloadTestRule.getAllDownloads();
+                    List<DownloadItem> downloads = sDownloadTestRule.getAllDownloads();
                     Criteria.checkThat(downloads.size(), Matchers.greaterThanOrEqualTo(1));
                     boolean hasCanceled = false;
                     for (DownloadItem download : downloads) {
@@ -252,58 +272,58 @@
     }
 
     @Test
-    @MediumTest
+    @LargeTest
     @Feature({"Downloads"})
     public void testHttpGetDownload() throws Exception {
-        mDownloadTestRule.loadUrl(mTestServer.getURL(TEST_DOWNLOAD_DIRECTORY + "get.html"));
+        loadUrl(sTestServer.getURL(TEST_DOWNLOAD_DIRECTORY + "get.html"));
         waitForFocus();
-        View currentView = mDownloadTestRule.getActivity().getActivityTab().getView();
+        View currentView = sDownloadTestRule.getActivity().getActivityTab().getView();
 
-        int callCount = mDownloadTestRule.getChromeDownloadCallCount();
+        int callCount = sDownloadTestRule.getChromeDownloadCallCount();
         TouchCommon.singleClickView(currentView);
-        Assert.assertTrue(mDownloadTestRule.waitForChromeDownloadToFinish(callCount));
-        Assert.assertTrue(mDownloadTestRule.hasDownloaded(FILENAME_GZIP, null));
+        Assert.assertTrue(sDownloadTestRule.waitForChromeDownloadToFinish(callCount));
+        Assert.assertTrue(sDownloadTestRule.hasDownloaded(FILENAME_GZIP, null));
     }
 
     @Test
-    @MediumTest
+    @LargeTest
     @Feature({"Downloads"})
     public void testHttpPostDownload() throws Exception {
-        mDownloadTestRule.loadUrl(mTestServer.getURL(TEST_DOWNLOAD_DIRECTORY + "post.html"));
+        loadUrl(sTestServer.getURL(TEST_DOWNLOAD_DIRECTORY + "post.html"));
         waitForFocus();
-        View currentView = mDownloadTestRule.getActivity().getActivityTab().getView();
+        View currentView = sDownloadTestRule.getActivity().getActivityTab().getView();
 
-        int callCount = mDownloadTestRule.getChromeDownloadCallCount();
+        int callCount = sDownloadTestRule.getChromeDownloadCallCount();
         TouchCommon.singleClickView(currentView);
-        Assert.assertTrue(mDownloadTestRule.waitForChromeDownloadToFinish(callCount));
-        Assert.assertTrue(mDownloadTestRule.hasDownloaded(FILENAME_TEXT, SUPERBO_CONTENTS));
+        Assert.assertTrue(sDownloadTestRule.waitForChromeDownloadToFinish(callCount));
+        Assert.assertTrue(sDownloadTestRule.hasDownloaded(FILENAME_TEXT, SUPERBO_CONTENTS));
     }
 
     @Test
-    @MediumTest
+    @LargeTest
     @Feature({"Downloads"})
     @Policies.Add({@Policies.Item(key = "PromptForDownloadLocation", string = "false")})
     public void testCloseEmptyDownloadTab() throws Exception {
-        mDownloadTestRule.loadUrl(mTestServer.getURL(TEST_DOWNLOAD_DIRECTORY + "get.html"));
+        loadUrl(sTestServer.getURL(TEST_DOWNLOAD_DIRECTORY + "get.html"));
         waitForFocus();
-        final int initialTabCount = mDownloadTestRule.getActivity().getCurrentTabModel().getCount();
-        int currentCallCount = mDownloadTestRule.getChromeDownloadCallCount();
-        View currentView = mDownloadTestRule.getActivity().getActivityTab().getView();
+        final int initialTabCount = sDownloadTestRule.getActivity().getCurrentTabModel().getCount();
+        int currentCallCount = sDownloadTestRule.getChromeDownloadCallCount();
+        View currentView = sDownloadTestRule.getActivity().getActivityTab().getView();
         TouchCommon.singleClickView(currentView);
-        Assert.assertTrue(mDownloadTestRule.waitForChromeDownloadToFinish(currentCallCount));
+        Assert.assertTrue(sDownloadTestRule.waitForChromeDownloadToFinish(currentCallCount));
 
         CriteriaHelper.pollUiThread(
                 () -> {
                     Criteria.checkThat(
-                            mDownloadTestRule.getActivity().getCurrentTabModel().getCount(),
+                            sDownloadTestRule.getActivity().getCurrentTabModel().getCount(),
                             Matchers.is(initialTabCount));
                 });
     }
 
     private void openNewTab(String url) {
-        Tab oldTab = mDownloadTestRule.getActivity().getActivityTabProvider().get();
-        TabCreator tabCreator = mDownloadTestRule.getActivity().getTabCreator(false);
-        final TabModel model = mDownloadTestRule.getActivity().getCurrentTabModel();
+        Tab oldTab = sDownloadTestRule.getActivity().getActivityTabProvider().get();
+        TabCreator tabCreator = sDownloadTestRule.getActivity().getTabCreator(false);
+        final TabModel model = sDownloadTestRule.getActivity().getCurrentTabModel();
         final int count = model.getCount();
         final Tab newTab =
                 TestThreadUtils.runOnUiThreadBlockingNoException(
@@ -322,21 +342,30 @@
     }
 
     @Test
-    @MediumTest
+    @LargeTest
     @Feature({"Downloads"})
     public void testUrlEscaping() throws Exception {
-        mDownloadTestRule.loadUrl(mTestServer.getURL(TEST_DOWNLOAD_DIRECTORY + "urlescaping.html"));
+        loadUrl(sTestServer.getURL(TEST_DOWNLOAD_DIRECTORY + "urlescaping.html"));
         waitForFocus();
-        View currentView = mDownloadTestRule.getActivity().getActivityTab().getView();
+        View currentView = sDownloadTestRule.getActivity().getActivityTab().getView();
 
-        int callCount = mDownloadTestRule.getChromeDownloadCallCount();
+        int callCount = sDownloadTestRule.getChromeDownloadCallCount();
         TouchCommon.singleClickView(currentView);
-        Assert.assertTrue(mDownloadTestRule.waitForChromeDownloadToFinish(callCount));
-        Assert.assertTrue(mDownloadTestRule.hasDownloaded(FILENAME_WALLPAPER, null));
+        Assert.assertTrue(sDownloadTestRule.waitForChromeDownloadToFinish(callCount));
+        Assert.assertTrue(sDownloadTestRule.hasDownloaded(FILENAME_WALLPAPER, null));
+    }
+
+    private void loadUrl(String url) {
+        sDownloadTestRule.loadUrlInTab(
+                url,
+                PageTransition.TYPED | PageTransition.FROM_ADDRESS_BAR,
+                sDownloadTestRule.getActivity().getActivityTab(),
+                20L // 20 seconds timeout
+                );
     }
 
     @Test
-    @MediumTest
+    @LargeTest
     @Feature({"Navigation"})
     public void testOMADownloadInterception() throws Exception {
         TestWebServer webServer = TestWebServer.start();
@@ -347,10 +376,10 @@
                     () ->
                             DownloadManagerService.getDownloadManagerService()
                                     .setDownloadManagerRequestInterceptor(interceptor));
-            List<Pair<String, String>> headers = new ArrayList<Pair<String, String>>();
+            List<Pair<String, String>> headers = new ArrayList<>();
             headers.add(Pair.create("Content-Type", "application/vnd.oma.drm.message"));
             final String url = webServer.setResponse("/test.dm", "testdata", headers);
-            mDownloadTestRule.loadUrl(
+            sDownloadTestRule.loadUrl(
                     UrlUtils.encodeHtmlDataUri(
                             "<script>"
                                     + "  function download() {"
@@ -360,7 +389,7 @@
                                     + "  }"
                                     + "</script>"
                                     + "<body id='body' onclick='download()'></body>"));
-            DOMUtils.clickNode(mDownloadTestRule.getActivity().getCurrentWebContents(), "body");
+            DOMUtils.clickNode(sDownloadTestRule.getActivity().getCurrentWebContents(), "body");
             CriteriaHelper.pollUiThread(
                     () -> {
                         Criteria.checkThat(interceptor.mDownloadItem, Matchers.notNullValue());
@@ -374,7 +403,7 @@
     }
 
     private void waitForFocus() {
-        View currentView = mDownloadTestRule.getActivity().getActivityTab().getView();
+        View currentView = sDownloadTestRule.getActivity().getActivityTab().getView();
         if (!currentView.hasFocus()) {
             TouchCommon.singleClickView(currentView);
         }
@@ -386,6 +415,6 @@
      * downloads directory
      */
     private void deleteTestFiles() {
-        mDownloadTestRule.deleteFilesInDownloadDirectory(TEST_FILES);
+        sDownloadTestRule.deleteFilesInDownloadDirectory(TEST_FILES);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTestRule.java
index ce69e3fc..29484f3 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTestRule.java
@@ -173,17 +173,21 @@
     }
 
     private String mLastDownloadFilePath;
-    private final CallbackHelper mHttpDownloadFinished = new CallbackHelper();
+    private CallbackHelper mHttpDownloadFinished = new CallbackHelper();
     private TestDownloadManagerServiceObserver mDownloadManagerServiceObserver;
 
     public int getChromeDownloadCallCount() {
         return mHttpDownloadFinished.getCallCount();
     }
 
+    protected void resetCallbackHelper() {
+        mHttpDownloadFinished = new CallbackHelper();
+    }
+
     public boolean waitForChromeDownloadToFinish(int currentCallCount) {
         boolean eventReceived = true;
         try {
-            mHttpDownloadFinished.waitForCallback(currentCallCount, 1, 5, TimeUnit.SECONDS);
+            mHttpDownloadFinished.waitForCallback(currentCallCount, 1, 10, TimeUnit.SECONDS);
         } catch (TimeoutException e) {
             eventReceived = false;
         }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java
index fc22358..05b3ab6 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestMetricsTest.java
@@ -26,7 +26,6 @@
 import org.chromium.chrome.test.R;
 import org.chromium.chrome.test.util.ChromeTabUtils;
 import org.chromium.components.autofill.AutofillProfile;
-import org.chromium.components.payments.AbortReason;
 import org.chromium.components.payments.Event;
 import org.chromium.components.payments.NotShownReason;
 import org.chromium.components.payments.PaymentFeatureList;
@@ -157,8 +156,6 @@
         mPaymentRequestTestRule.expectResultContains(
                 new String[] {"User closed the Payment Request UI."});
 
-        mPaymentRequestTestRule.assertOnlySpecificAbortMetricLogged(AbortReason.ABORTED_BY_USER);
-
         // Make sure the events were logged correctly.
         int expectedSample =
                 Event.SHOWN
@@ -197,8 +194,6 @@
         mPaymentRequestTestRule.expectResultContains(
                 new String[] {"User closed the Payment Request UI."});
 
-        mPaymentRequestTestRule.assertOnlySpecificAbortMetricLogged(AbortReason.ABORTED_BY_USER);
-
         // Make sure the events were logged correctly.
         int expectedSample =
                 Event.SHOWN
@@ -243,8 +238,6 @@
         mPaymentRequestTestRule.expectResultContains(
                 new String[] {"User closed the Payment Request UI."});
 
-        mPaymentRequestTestRule.assertOnlySpecificAbortMetricLogged(AbortReason.ABORTED_BY_USER);
-
         // Make sure the events were logged correctly.
         int expectedSample =
                 Event.SHOWN
@@ -281,10 +274,6 @@
                 InstrumentationRegistry.getInstrumentation(),
                 mPaymentRequestTestRule.getActivity());
 
-        // Closing the tab will show Chrome's Tab Overview / Switcher UI, which triggers the "closed
-        // by user" event with "Tab overview mode dismissed Payment Request UI" error message.
-        mPaymentRequestTestRule.assertOnlySpecificAbortMetricLogged(AbortReason.ABORTED_BY_USER);
-
         // Make sure the events were logged correctly.
         int expectedSample =
                 Event.SHOWN
@@ -321,9 +310,6 @@
         mPaymentRequestTestRule.clickNodeAndWait("abort", mPaymentRequestTestRule.getDismissed());
         mPaymentRequestTestRule.expectResultContains(new String[] {"Abort"});
 
-        mPaymentRequestTestRule.assertOnlySpecificAbortMetricLogged(
-                AbortReason.ABORTED_BY_MERCHANT);
-
         // Make sure the events were logged correctly.
         int expectedSample =
                 Event.SHOWN
@@ -358,8 +344,6 @@
         mPaymentRequestTestRule.expectResultContains(
                 new String[] {"The payment method", "not supported"});
 
-        // Make sure that it is not logged as an abort.
-        mPaymentRequestTestRule.assertOnlySpecificAbortMetricLogged(-1 /* none */);
         // Make sure that it was logged as a reason why the Payment Request was not shown.
         Assert.assertEquals(
                 1,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowTwiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowTwiceTest.java
index 07019197..5b96d3d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowTwiceTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestShowTwiceTest.java
@@ -7,7 +7,6 @@
 import androidx.test.filters.MediumTest;
 
 import org.junit.Assert;
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -15,13 +14,11 @@
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Feature;
-import org.chromium.chrome.browser.autofill.AutofillTestHelper;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.payments.PaymentRequestTestRule.AppPresence;
 import org.chromium.chrome.browser.payments.PaymentRequestTestRule.FactorySpeed;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.R;
-import org.chromium.components.autofill.AutofillProfile;
 import org.chromium.components.payments.NotShownReason;
 
 import java.util.concurrent.TimeoutException;
@@ -34,24 +31,6 @@
     public PaymentRequestTestRule mPaymentRequestTestRule =
             new PaymentRequestTestRule("payment_request_show_twice_test.html");
 
-    @Before
-    public void setUp() throws TimeoutException {
-        AutofillTestHelper helper = new AutofillTestHelper();
-        String billingAddressId =
-                helper.setProfile(
-                        AutofillProfile.builder()
-                                .setFullName("Jon Doe")
-                                .setCompanyName("Google")
-                                .setStreetAddress("340 Main St")
-                                .setRegion("CA")
-                                .setLocality("Los Angeles")
-                                .setPostalCode("90291")
-                                .setCountryCode("US")
-                                .setPhoneNumber("555-555-5555")
-                                .setEmailAddress("en-US")
-                                .build());
-    }
-
     @Test
     @MediumTest
     @Feature({"Payments"})
@@ -69,9 +48,6 @@
                         + " different tab or window.\"",
                 mPaymentRequestTestRule.runJavaScriptAndWaitForPromise("showSecond()"));
 
-        // The web payments UI was not aborted.
-        mPaymentRequestTestRule.assertOnlySpecificAbortMetricLogged(-1 /* none */);
-
         // The second UI was never shown due to another web payments UI already showing.
         Assert.assertEquals(
                 1,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java
index de5570d9..ea28902 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestTestRule.java
@@ -20,7 +20,6 @@
 import org.junit.runners.model.Statement;
 
 import org.chromium.base.ThreadUtils;
-import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.task.PostTask;
 import org.chromium.base.task.TaskTraits;
 import org.chromium.base.test.util.CallbackHelper;
@@ -39,7 +38,6 @@
 import org.chromium.chrome.browser.payments.ui.PaymentRequestUI;
 import org.chromium.chrome.browser.payments.ui.PaymentRequestUI.PaymentRequestObserverForTest;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
-import org.chromium.components.payments.AbortReason;
 import org.chromium.components.payments.InputProtector;
 import org.chromium.components.payments.PayerData;
 import org.chromium.components.payments.PaymentApp;
@@ -64,7 +62,6 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
@@ -943,21 +940,6 @@
                 });
     }
 
-    /**
-     * Asserts that only the specified reason for abort is logged.
-     *
-     * @param abortReason The only bucket in the abort histogram that should have a record.
-     */
-    /* package */ void assertOnlySpecificAbortMetricLogged(int abortReason) {
-        for (int i = 0; i < AbortReason.MAX; ++i) {
-            Assert.assertEquals(
-                    String.format(Locale.getDefault(), "Found %d instead of %d", i, abortReason),
-                    (i == abortReason ? 1 : 0),
-                    RecordHistogram.getHistogramValueCountForTesting(
-                            "PaymentRequest.CheckoutFunnel.Aborted", i));
-        }
-    }
-
     /* package */ View getPaymentRequestView() {
         return ThreadUtils.runOnUiThreadBlockingNoException(
                 () -> mUI.getDialogForTest().findViewById(R.id.payment_request));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webid/DigitalCredentialProviderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webid/DigitalCredentialProviderTest.java
index 7d1af701..30477397 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/webid/DigitalCredentialProviderTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webid/DigitalCredentialProviderTest.java
@@ -67,7 +67,7 @@
 
     @Test
     @LargeTest
-    @EnableFeatures(ContentFeatureList.WEB_IDENTITY_MDOCS)
+    @EnableFeatures(ContentFeatureList.WEB_IDENTITY_DIGITAL_CREDENTIALS)
     public void testRequestMDoc() throws TimeoutException {
         when(mDelegate.get(any(), any(), any()))
                 .thenAnswer(input -> Promise.fulfilled(EXPECTED_MDOC.getBytes()));
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRowTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRowTest.java
index 3ca6a69b..c7d7397 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRowTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRowTest.java
@@ -4,9 +4,12 @@
 
 package org.chromium.chrome.browser.bookmarks;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -27,12 +30,17 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.Mock;
+import org.mockito.Spy;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowLooper;
 
+import org.chromium.base.Callback;
+import org.chromium.base.supplier.LazyOneshotSupplier;
 import org.chromium.base.supplier.LazyOneshotSupplierImpl;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Batch;
@@ -43,7 +51,7 @@
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
 
-/** Unit tests for {@link BookmarkToolbarMediator}. */
+/** Unit tests for {@link ImprovedBookmarkRow}. */
 @Batch(Batch.UNIT_TESTS)
 @RunWith(BaseRobolectricTestRunner.class)
 @Config(manifest = Config.NONE)
@@ -53,25 +61,21 @@
 
     @Rule
     public MockitoRule mMockitoRule = MockitoJUnit.rule();
-
     @Rule
     public ActivityScenarioRule<TestActivity> mActivityScenarioRule =
             new ActivityScenarioRule<>(TestActivity.class);
 
-    @Mock
-    View mView;
-    @Mock
-    ViewGroup mViewGroup;
-    @Mock
-    ListMenuButtonDelegate mListMenuButtonDelegate;
-    @Mock
-    Runnable mPopupListener;
-    @Mock
-    Runnable mOpenBookmarkCallback;
-    @Mock
-    ImageView mStartImageView;
-    @Mock
-    ViewPropertyAnimator mStartImageViewAnimator;
+    @Mock View mView;
+    @Mock ViewGroup mViewGroup;
+    @Mock ListMenuButtonDelegate mListMenuButtonDelegate;
+    @Mock Runnable mPopupListener;
+    @Mock Runnable mOpenBookmarkCallback;
+    @Mock LazyOneshotSupplier<Drawable> mMockDrawableSupplier;
+
+    @Spy ImageView mStartImageView;
+    @Spy ViewPropertyAnimator mStartImageViewAnimator;
+
+    @Captor ArgumentCaptor<Callback<Drawable>> mDrawableCallbackCaptor;
 
     Activity mActivity;
     ImprovedBookmarkRow mImprovedBookmarkRow;
@@ -100,6 +104,16 @@
                     }
                 };
 
+        mStartImageView =
+                spy(
+                        new ImageView(mActivity) {
+                            @Override
+                            public ViewPropertyAnimator animate() {
+                                ViewPropertyAnimator animator = super.animate();
+                                mStartImageViewAnimator = spy(animator);
+                                return mStartImageViewAnimator;
+                            }
+                        });
         mDrawable = new BitmapDrawable(
                 mActivity.getResources(), Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888));
         mImprovedBookmarkRow = ImprovedBookmarkRow.buildView(mActivity, /*isVisual=*/true);
@@ -173,8 +187,8 @@
     @Test
     public void testSelectionActive() {
         mModel.set(ImprovedBookmarkRowProperties.SELECTION_ACTIVE, true);
-        Assert.assertFalse(mImprovedBookmarkRow.findViewById(R.id.more).isClickable());
-        Assert.assertFalse(mImprovedBookmarkRow.findViewById(R.id.more).isEnabled());
+        assertFalse(mImprovedBookmarkRow.findViewById(R.id.more).isClickable());
+        assertFalse(mImprovedBookmarkRow.findViewById(R.id.more).isEnabled());
         Assert.assertEquals(View.IMPORTANT_FOR_ACCESSIBILITY_NO,
                 mImprovedBookmarkRow.findViewById(R.id.more).getImportantForAccessibility());
     }
@@ -182,8 +196,8 @@
     @Test
     public void testSelectionInactive() {
         mModel.set(ImprovedBookmarkRowProperties.SELECTION_ACTIVE, false);
-        Assert.assertTrue(mImprovedBookmarkRow.findViewById(R.id.more).isClickable());
-        Assert.assertTrue(mImprovedBookmarkRow.findViewById(R.id.more).isEnabled());
+        assertTrue(mImprovedBookmarkRow.findViewById(R.id.more).isClickable());
+        assertTrue(mImprovedBookmarkRow.findViewById(R.id.more).isEnabled());
         Assert.assertEquals(View.IMPORTANT_FOR_ACCESSIBILITY_YES,
                 mImprovedBookmarkRow.findViewById(R.id.more).getImportantForAccessibility());
     }
@@ -279,4 +293,18 @@
                 .setDuration(ImprovedBookmarkRow.BASE_ANIMATION_DURATION_MS);
         verify(mStartImageViewAnimator, never()).start();
     }
+
+    @Test
+    public void testCancelAnimation() {
+        // This is tricky because the supplier introduces a post by default. But if we wait, we risk
+        // letting the animation finish. So use a mock/captor to make it synchronous.
+        mModel.set(ImprovedBookmarkRowProperties.START_ICON_DRAWABLE, mMockDrawableSupplier);
+        verify(mMockDrawableSupplier).onAvailable(mDrawableCallbackCaptor.capture());
+        verify(mMockDrawableSupplier).get();
+        mDrawableCallbackCaptor.getValue().onResult(mDrawable);
+        assertTrue(mImprovedBookmarkRow.hasTransientState());
+
+        mImprovedBookmarkRow.cancelAnimation();
+        assertFalse(mImprovedBookmarkRow.hasTransientState());
+    }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/CompositorViewHolderUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/CompositorViewHolderUnitTest.java
index aea7e96..e846ceb7 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/CompositorViewHolderUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/CompositorViewHolderUnitTest.java
@@ -189,16 +189,19 @@
                 (inMotion) -> eventSequence.add(EventSource.IN_MOTION));
         // This touch observer is used as a proxy for when ViewGroup#dispatchTouchEvent is called,
         // which is when the touch is propagated to children.
-        mCompositorViewHolder.addTouchEventObserver(new TouchEventObserver() {
-            @Override
-            public boolean shouldInterceptTouchEvent(MotionEvent e) {
-                return false;
-            }
-            @Override
-            public void handleTouchEvent(MotionEvent e) {
-                eventSequence.add(EventSource.TOUCH_EVENT_OBSERVER);
-            }
-        });
+        mCompositorViewHolder.addTouchEventObserver(
+                new TouchEventObserver() {
+                    @Override
+                    public boolean onInterceptTouchEvent(MotionEvent e) {
+                        return false;
+                    }
+
+                    @Override
+                    public boolean dispatchTouchEvent(MotionEvent e) {
+                        eventSequence.add(EventSource.TOUCH_EVENT_OBSERVER);
+                        return false;
+                    }
+                });
         return eventSequence;
     }
 
@@ -569,7 +572,8 @@
         verify(mLayoutManager)
                 .onInterceptMotionEvent(MOTION_ACTION_HOVER_ENTER, false, EventType.HOVER);
         Assert.assertTrue(
-                "#onInterceptHoverEvent should return true if the LayoutManager intercepts the event.",
+                "#onInterceptHoverEvent should return true if the LayoutManager intercepts the"
+                        + " event.",
                 intercepted);
     }
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
index 6d98e5236..ca78556 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
@@ -60,6 +60,7 @@
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerHost;
 import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost;
 import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost;
@@ -119,6 +120,7 @@
     @Mock
     private View mToolbarContainerView;
     @Mock private DragAndDropDelegate mDragDropDelegate;
+    @Mock private BrowserControlsStateProvider mBrowserControlsStateProvider;
     @Mock private ActivityInfo mActivityInfo;
     @Mock
     private PackageManager mPackageManager;
@@ -2295,6 +2297,7 @@
                         mModelSelectorBtn,
                         mMultiInstanceManager,
                         mDragDropDelegate,
+                        mBrowserControlsStateProvider,
                         mToolbarContainerView);
         // Initialize StackScroller
         stripLayoutHelper.onContextChanged(mActivity);
@@ -2470,7 +2473,8 @@
                         eq(mToolbarContainerView),
                         eq(mMultiInstanceManager),
                         eq(mDragDropDelegate),
-                        any(TabDropTarget.class));
+                        any(TabDropTarget.class),
+                        eq(mBrowserControlsStateProvider));
 
         // Windup
         clearTabDragSourceMock();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java
index a05ddc6c0..5bf3273c 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java
@@ -46,6 +46,7 @@
 
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
 import org.chromium.chrome.browser.compositor.layouts.LayoutManagerHost;
 import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost;
 import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost;
@@ -66,26 +67,17 @@
 @RunWith(BaseRobolectricTestRunner.class)
 @EnableFeatures({ChromeFeatureList.TAB_DRAG_DROP_ANDROID})
 public class TabDragSourceTest {
-    @Rule
-    public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor();
-    @Mock
-    private MultiInstanceManager mMultiInstanceManager;
-    @Mock
-    private LayoutManagerHost mManagerHost;
-    @Mock
-    private LayoutUpdateHost mUpdateHost;
-    @Mock
-    private LayoutRenderHost mRenderHost;
-    @Mock
-    private CompositorButton mModelSelectorBtn;
-    @Mock
-    private TabGroupModelFilter mTabGroupModelFilter;
-    @Mock
-    private TabModelSelector mTabModelSelector;
-    @Mock
-    private View mToolbarContainerView;
-    @Mock
-    private TabDropTarget mTabDropTarget;
+    @Rule public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor();
+    @Mock private MultiInstanceManager mMultiInstanceManager;
+    @Mock private LayoutManagerHost mManagerHost;
+    @Mock private LayoutUpdateHost mUpdateHost;
+    @Mock private LayoutRenderHost mRenderHost;
+    @Mock private CompositorButton mModelSelectorBtn;
+    @Mock private TabGroupModelFilter mTabGroupModelFilter;
+    @Mock private TabModelSelector mTabModelSelector;
+    @Mock private View mToolbarContainerView;
+    @Mock private BrowserControlsStateProvider mBrowserControlsStateProvider;
+    @Mock private TabDropTarget mTabDropTarget;
     @Mock private DragAndDropDelegate mDragDropDelegate;
 
     private Activity mActivity;
@@ -183,6 +175,7 @@
                         mModelSelectorBtn,
                         mMultiInstanceManager,
                         mDragDropDelegate,
+                        mBrowserControlsStateProvider,
                         mTabsToolbarView);
         stripLayoutHelper.onContextChanged(mActivity);
         return stripLayoutHelper;
@@ -223,7 +216,11 @@
                 .thenReturn(true);
         // Act and verify.
         mTabDragSource.prepareForDragDrop(
-                mTabsToolbarView, mMultiInstanceManager, mDragDropDelegate, mTabDropTarget);
+                mTabsToolbarView,
+                mMultiInstanceManager,
+                mDragDropDelegate,
+                mTabDropTarget,
+                mBrowserControlsStateProvider);
         assertTrue(
                 "Failed to start the tag drag action.",
                 mTabDragSource.startTabDragAction(
@@ -253,7 +250,11 @@
                 .thenReturn(true);
         // Act and verify.
         mTabDragSource.prepareForDragDrop(
-                mTabsToolbarView, mMultiInstanceManager, mDragDropDelegate, mTabDropTarget);
+                mTabsToolbarView,
+                mMultiInstanceManager,
+                mDragDropDelegate,
+                mTabDropTarget,
+                mBrowserControlsStateProvider);
         assertTrue("Failed to start the tag drag action.",
                 mTabDragSource.startTabDragAction(
                         mTabsToolbarView, mStripLayoutHelper, tabBeingDragged, DRAG_START_POINT));
@@ -279,7 +280,11 @@
 
         // Act and verify.
         mTabDragSource.prepareForDragDrop(
-                mTabsToolbarView, mMultiInstanceManager, mDragDropDelegate, mTabDropTarget);
+                mTabsToolbarView,
+                mMultiInstanceManager,
+                mDragDropDelegate,
+                mTabDropTarget,
+                mBrowserControlsStateProvider);
         assertFalse(mTabDragSource.startTabDragAction(
                 mTabsToolbarView, mStripLayoutHelper, tabBeingDragged, DRAG_START_POINT));
         verify(mTabsToolbarView, never()).startDragAndDrop(any(), any(), any(), anyInt());
@@ -297,7 +302,11 @@
 
         // Act
         mTabDragSource.prepareForDragDrop(
-                mTabsToolbarView, mMultiInstanceManager, mDragDropDelegate, mTabDropTarget);
+                mTabsToolbarView,
+                mMultiInstanceManager,
+                mDragDropDelegate,
+                mTabDropTarget,
+                mBrowserControlsStateProvider);
 
         // Verify flow.
         assertTrue(mTabDropTarget.getDropContentReceiver() != null);
@@ -324,7 +333,11 @@
 
         // Act and verify.
         mTabDragSource.prepareForDragDrop(
-                mTabsToolbarView, mMultiInstanceManager, mDragDropDelegate, mTabDropTarget);
+                mTabsToolbarView,
+                mMultiInstanceManager,
+                mDragDropDelegate,
+                mTabDropTarget,
+                mBrowserControlsStateProvider);
         assertTrue(mTabDragSource.getDragSourceTabsToolbarHashCode() == 0);
         assertTrue(mTabDragSource.startTabDragAction(
                 mTabsToolbarView, mStripLayoutHelper, tabBeingDragged, DRAG_START_POINT));
@@ -342,7 +355,11 @@
         // Prepare
         initializeTest(false, false, 1, 5);
         mTabDragSource.prepareForDragDrop(
-                mTabsToolbarView, mMultiInstanceManager, mDragDropDelegate, mTabDropTarget);
+                mTabsToolbarView,
+                mMultiInstanceManager,
+                mDragDropDelegate,
+                mTabDropTarget,
+                mBrowserControlsStateProvider);
         mTabDragSource.setTabsToolbarHeightInDp(TAB_STRIP_HEIGHT);
         mTabDragSource.startTabDragAction(mTabsToolbarView, mStripLayoutHelper,
                 mStripLayoutHelper.getTabById(mClickedTab.getId()), DRAG_START_POINT);
@@ -369,7 +386,11 @@
         // Prepare
         initializeTest(false, false, 1, 5);
         mTabDragSource.prepareForDragDrop(
-                mTabsToolbarView, mMultiInstanceManager, mDragDropDelegate, mTabDropTarget);
+                mTabsToolbarView,
+                mMultiInstanceManager,
+                mDragDropDelegate,
+                mTabDropTarget,
+                mBrowserControlsStateProvider);
         mTabDragSource.setTabsToolbarHeightInDp(TAB_STRIP_HEIGHT);
         mTabDragSource.startTabDragAction(mTabsToolbarView, mStripLayoutHelper,
                 mStripLayoutHelper.getTabById(mClickedTab.getId()), DRAG_START_POINT);
@@ -397,7 +418,11 @@
         // Prepare
         initializeTest(false, false, 1, 5);
         mTabDragSource.prepareForDragDrop(
-                mTabsToolbarView, mMultiInstanceManager, mDragDropDelegate, mTabDropTarget);
+                mTabsToolbarView,
+                mMultiInstanceManager,
+                mDragDropDelegate,
+                mTabDropTarget,
+                mBrowserControlsStateProvider);
         mTabDragSource.setTabsToolbarHeightInDp(TAB_STRIP_HEIGHT);
         mTabDragSource.startTabDragAction(mTabsToolbarView, mStripLayoutHelper,
                 mStripLayoutHelper.getTabById(mClickedTab.getId()), DRAG_START_POINT);
@@ -421,7 +446,11 @@
         // Prepare
         initializeTest(false, false, 1, 5);
         mTabDragSource.prepareForDragDrop(
-                mTabsToolbarView, mMultiInstanceManager, mDragDropDelegate, mTabDropTarget);
+                mTabsToolbarView,
+                mMultiInstanceManager,
+                mDragDropDelegate,
+                mTabDropTarget,
+                mBrowserControlsStateProvider);
         mTabDragSource.setTabsToolbarHeightInDp(TAB_STRIP_HEIGHT);
         mTabDragSource.startTabDragAction(mTabsToolbarView, mStripLayoutHelper,
                 mStripLayoutHelper.getTabById(mClickedTab.getId()), DRAG_START_POINT);
@@ -445,7 +474,11 @@
         // Prepare
         initializeTest(false, false, 1, 5);
         mTabDragSource.prepareForDragDrop(
-                mTabsToolbarView, mMultiInstanceManager, mDragDropDelegate, mTabDropTarget);
+                mTabsToolbarView,
+                mMultiInstanceManager,
+                mDragDropDelegate,
+                mTabDropTarget,
+                mBrowserControlsStateProvider);
         mTabDragSource.setTabsToolbarHeightInDp(TAB_STRIP_HEIGHT);
         mTabDragSource.startTabDragAction(mTabsToolbarView, mStripLayoutHelper,
                 mStripLayoutHelper.getTabById(mClickedTab.getId()), DRAG_START_POINT);
@@ -565,7 +598,11 @@
         // Prepare
         initializeTest(false, false, 1, 5);
         mTabDragSource.prepareForDragDrop(
-                mTabsToolbarView, mMultiInstanceManager, mDragDropDelegate, mTabDropTarget);
+                mTabsToolbarView,
+                mMultiInstanceManager,
+                mDragDropDelegate,
+                mTabDropTarget,
+                mBrowserControlsStateProvider);
         mTabDragSource.setTabsToolbarHeightInDp(TAB_STRIP_HEIGHT);
         mTabDragSource.startTabDragAction(mTabsToolbarView, mStripLayoutHelper,
                 mStripLayoutHelper.getTabById(mClickedTab.getId()), DRAG_START_POINT);
@@ -619,7 +656,11 @@
         // Prepare
         initializeTest(false, false, 1, 5);
         mTabDragSource.prepareForDragDrop(
-                mTabsToolbarView, mMultiInstanceManager, mDragDropDelegate, mTabDropTarget);
+                mTabsToolbarView,
+                mMultiInstanceManager,
+                mDragDropDelegate,
+                mTabDropTarget,
+                mBrowserControlsStateProvider);
         mTabDragSource.setTabsToolbarHeightInDp(TAB_STRIP_HEIGHT);
         mTabDragSource.startTabDragAction(mTabsToolbarView, mStripLayoutHelper,
                 mStripLayoutHelper.getTabById(mClickedTab.getId()), DRAG_START_POINT);
@@ -647,7 +688,11 @@
         final float dragStartYPosition = 45f;
         initializeTest(false, false, 1, 5);
         mTabDragSource.prepareForDragDrop(
-                mTabsToolbarView, mMultiInstanceManager, mDragDropDelegate, mTabDropTarget);
+                mTabsToolbarView,
+                mMultiInstanceManager,
+                mDragDropDelegate,
+                mTabDropTarget,
+                mBrowserControlsStateProvider);
         mTabDragSource.setTabsToolbarHeightInDp(TAB_STRIP_HEIGHT);
         mTabDragSource.startTabDragAction(mTabsToolbarView, mStripLayoutHelper,
                 mStripLayoutHelper.getTabById(mClickedTab.getId()),
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/settings/SettingsActivityUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/settings/SettingsActivityUnitTest.java
index de25a9d7..b6cb8bd 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/settings/SettingsActivityUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/settings/SettingsActivityUnitTest.java
@@ -9,10 +9,8 @@
 import static org.junit.Assert.assertTrue;
 
 import android.content.Intent;
-import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Rect;
-import android.util.Pair;
 import android.view.View;
 
 import androidx.lifecycle.Lifecycle.State;
@@ -132,9 +130,8 @@
         assertNotNull("PaddedItemDecorationWithDivider should exists.", decoration);
         int parentPadding =
                 60; // (720 - UiConfig.WIDE_DISPLAY_STYLE_MIN_WIDTH_DP) / 2 = (720 - 600) / 2
-        Pair<Integer, Integer> itemOffsets = decoration.getItemOffsetsForTesting();
-        assertEquals("Item offset start is wrong.", parentPadding, itemOffsets.first.intValue());
-        assertEquals("Item offset end is wrong.", parentPadding, itemOffsets.second.intValue());
+        int itemOffset = decoration.getItemOffsetForTesting();
+        assertEquals("Item offset is wrong.", parentPadding, itemOffset);
         assertEquals("Divider start padding is wrong.", 0, decoration.getDividerPaddingStart());
         assertEquals("Divider end padding is wrong.", 0, decoration.getDividerPaddingEnd());
     }
@@ -150,23 +147,8 @@
         RecyclerView recyclerView = mSettingsActivity.findViewById(R.id.recycler_view);
         PaddedItemDecorationWithDivider decoration = getPaddedDecoration(recyclerView);
         assertNotNull("PaddedItemDecorationWithDivider should exists.", decoration);
-        TypedArray paddingArray =
-                mSettingsActivity
-                        .getTheme()
-                        .obtainStyledAttributes(
-                                new int[] {
-                                    R.attr.listPreferredItemPaddingStart,
-                                    R.attr.listPreferredItemPaddingEnd
-                                });
-        Pair<Integer, Integer> itemOffsets = decoration.getItemOffsetsForTesting();
-        assertEquals(
-                "Item offset start is wrong.",
-                (int) paddingArray.getDimension(0, 0f),
-                itemOffsets.first.intValue());
-        assertEquals(
-                "Item offset end is wrong.",
-                (int) paddingArray.getDimension(1, 0f),
-                itemOffsets.second.intValue());
+        int itemOffset = decoration.getItemOffsetForTesting();
+        assertEquals("Item offset is wrong.", 0, itemOffset);
         assertEquals("Divider start padding is wrong.", 0, decoration.getDividerPaddingStart());
         assertEquals("Divider end padding is wrong.", 0, decoration.getDividerPaddingEnd());
     }
@@ -186,9 +168,8 @@
         int parentPadding =
                 60; // (720 - UiConfig.WIDE_DISPLAY_STYLE_MIN_WIDTH_DP) / 2 = (720 - 600) / 2
 
-        Pair<Integer, Integer> itemOffsets = decoration.getItemOffsetsForTesting();
-        assertEquals("Item offset start is wrong.", parentPadding, itemOffsets.first.intValue());
-        assertEquals("Item offset end is wrong.", parentPadding, itemOffsets.second.intValue());
+        int itemOffset = decoration.getItemOffsetForTesting();
+        assertEquals("Item offset is wrong.", parentPadding, itemOffset);
         assertEquals(
                 "Divider start padding should not be set.", 0, decoration.getDividerPaddingStart());
         assertEquals(
@@ -211,9 +192,8 @@
         assertNotNull("PaddedItemDecorationWithDivider should exists.", decoration);
         int parentPadding =
                 60; // (720 - UiConfig.WIDE_DISPLAY_STYLE_MIN_WIDTH_DP) / 2 = (720 - 600) / 2
-        Pair<Integer, Integer> itemOffsets = decoration.getItemOffsetsForTesting();
-        assertEquals("Item offset start is wrong.", parentPadding, itemOffsets.first.intValue());
-        assertEquals("Item offset end is wrong.", parentPadding, itemOffsets.second.intValue());
+        int itemOffset = decoration.getItemOffsetForTesting();
+        assertEquals("Item offset is wrong.", parentPadding, itemOffset);
         assertEquals(
                 "Divider start padding is wrong.",
                 CustomDividerTestSettingsFragment.DIVIDER_START_PADDING,
diff --git a/chrome/android/profiles/arm.newest.txt b/chrome/android/profiles/arm.newest.txt
index b243e54..9d43ebe 100644
--- a/chrome/android/profiles/arm.newest.txt
+++ b/chrome/android/profiles/arm.newest.txt
@@ -1 +1 @@
-chromeos-chrome-arm-120.0.6073.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-arm-120.0.6074.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index d6164c3..b8cd034 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-120.0.6073.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-amd64-120.0.6074.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h
index cb25db2..9b9af4e 100644
--- a/chrome/app/chrome_command_ids.h
+++ b/chrome/app/chrome_command_ids.h
@@ -135,6 +135,7 @@
 #define IDC_SHOW_PASSWORD_MANAGER       35041
 #define IDC_SHOW_PAYMENT_METHODS        35042
 #define IDC_SHOW_ADDRESSES              35043
+#define IDC_ORGANIZE_TABS               35044
 
 // Page-manipulation commands that target a specified tab, which may not be the
 // active one.
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index b8e8a892..3533320 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -3900,6 +3900,9 @@
       <message name="IDS_COOKIE_CONTROLS_BUBBLE_COOKIES_BLOCKED_TITLE" desc="Title shown on the cookie controls bubble when third-party cookies are blocked.">
         Third-party cookies blocked
       </message>
+      <message name="IDS_TRACKING_PROTECTION_BUBBLE_TITLE" desc="Title shown for the Tracking Protection bubble.">
+        Tracking Protection
+      </message>
       <message name="IDS_COOKIE_CONTROLS_BUBBLE_COOKIES_ALLOWED_TITLE" desc="Title shown on the cookie controls bubble when third-party cookies are allowed.">
         Third-party cookies allowed
       </message>
@@ -3912,21 +3915,45 @@
       <message name="IDS_COOKIE_CONTROLS_BUBBLE_SITE_NOT_WORKING_DESCRIPTION_PERMANENT" desc="Descriptive text in the cookie controls bubble explaining the trade-off of allowing third-party cookies for this site, a change that will not automatically expire in the future.">
         Try allowing third-party cookies, which means less protection but site features are more likely to work
       </message>
+      <message name="IDS_TRACKING_PROTECTION_BUBBLE_SITE_NOT_WORKING_DESCRIPTION_PERMANENT" desc="Descriptive text in the trackings protection bubble mentioning the option to enable third-party cookies and mentions the trade off of doing so.">
+        Try temporarily allowing third-party cookies, which means less browsing protection but site features are more likely to work as expected.
+      </message>
       <message name="IDS_COOKIE_CONTROLS_BUBBLE_BLOCKING_RESTART_TITLE" desc="Subtitle shown on the cookie controls bubble when cookies are allowed temporarily, indicating how long until they are no longer allowed.">
         {COUNT, plural,
               =0 {Chrome will block cookies again today}
               =1 {Chrome will block cookies again tomorrow}
               other {# days until Chrome blocks cookies again}}
       </message>
+      <message name="IDS_TRACKING_PROTECTION_BUBBLE_LIMITING_RESTART_TITLE" desc="Subtitle shown on the tracking protection bubble indicating how long until cookies will be limited again.">
+        {COUNT, plural,
+              =0 {Chrome will limit cookies again today}
+              =1 {Chrome will limit cookies again tomorrow}
+              other {# days until Chrome limits cookies again}}
+      </message>
+      <message name="IDS_TRACKING_PROTECTION_BUBBLE_BLOCKING_RESTART_TITLE" desc="Subtitle shown on the tracking protection bubble indicating how long until cookies will be blocked again.">
+        {COUNT, plural,
+              =0 {Chrome will block cookies again today}
+              =1 {Chrome will block cookies again tomorrow}
+              other {# days until cookies are blocked again}}
+      </message>
       <message name="IDS_COOKIE_CONTROLS_BUBBLE_BLOCKING_RESTART_DESCRIPTION_TODAY" desc="Descriptive text in the cookie controls bubble after the user has allowed third-party cookies on a site explaining the trade-off of their decision.">
         You allowed this site to use third-party cookies. This means that most site features should work, but you have less protection.
       </message>
+      <message name="IDS_TRACKING_PROTECTION_BUBBLE_BLOCKING_RESTART_DESCRIPTION" desc="Descriptive text in the tracking protection bubble detailing the trade offs of temporarily allowing third-party cookies.">
+        You temporarily allowed this site to use third-party cookies, which means less browsing protection but site features are more likely to work as expected.
+      </message>
       <message name="IDS_COOKIE_CONTROLS_BUBBLE_PERMANENT_ALLOWED_TITLE" desc="A subtitle in the cookie controls bubble if cookies were allowed by the user and they won't be automatically blocked again the future.">
         You allowed third-party cookies for this site
       </message>
+      <message name="IDS_TRACKING_PROTECTION_BUBBLE_PERMANENT_ALLOWED_TITLE" desc="A subtitle in the tracking protection bubble stating that third-party cookies are allowed due to a permanent exception.">
+        You allowed third-party cookies on this site
+      </message>
       <message name="IDS_COOKIE_CONTROLS_BUBBLE_PERMANENT_ALLOWED_DESCRIPTION" desc="A description in the cookie controls bubble of the impact of current user settings for this site if cookies are allowed and they won't be automatically blocked again in the future.">
         This means that most site features should work, but you have less protection
       </message>
+      <message name="IDS_TRACKING_PROTECTION_BUBBLE_PERMANENT_ALLOWED_DESCRIPTION" desc="Descriptive text in the tracking protection bubble for permanent exceptions informing the user about having less browsing protection.">
+        This means site features should work as expected, but you may have less browsing protection.
+      </message>
       <message name="IDS_COOKIE_CONTROLS_BUBBLE_SEND_FEEDBACK_BUTTON_TITLE" desc="A subtitle for a portion of the cookie controls bubble soliciting feedback from users.">
         Send feedback
       </message>
@@ -3952,6 +3979,15 @@
               =1 {1 site allowed}
               other {# sites allowed}}
       </message>
+      <message name="IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_ALLOWED_LABEL" desc="A label for the third-party cookies toggle in the tracking protection bubble that tells the user third-party cookies are allowed.">
+        Allowed
+      </message>
+      <message name="IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_BLOCKED_LABEL" desc="A label for the third-party cookies toggle in the tracking protection bubble that tells the user third-party cookies are blocked.">
+        Blocked
+      </message>
+      <message name="IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_LIMITED_LABEL" desc="A label for the third-party cookies toggle in the tracking protection bubble that tells the user third-party cookies are limited.">
+        Limited
+      </message>
       <message name="IDS_COOKIE_CONTROLS_PAGE_ACTION_COOKIES_ALLOWED_LABEL" desc="Label in the Page Action (omnibox) icon indicating that cookies are allowed on the current site.">
         Third-party cookies allowed
       </message>
@@ -7769,6 +7805,9 @@
       <message name="IDS_NTP_MODULES_DISMISS_BUTTON_TEXT" desc="Text shown on the disable button of an NTP module.">
         Hide <ph name="MODULE_TITLE">$1<ex>Office Chairs</ex></ph>
       </message>
+      <message name="IDS_NTP_MODULES_DRIVE_MORE_ACTIONS_BUTTON_TEXT" desc="The tooltip and accessibility label for the 3 dot menu on a module.">
+        More actions for Google Drive Files
+      </message>
       <message name="IDS_NTP_MODULES_DISABLE_BUTTON_TEXT" desc="Text shown on the disable button of an NTP module.">
         Never show <ph name="MODULE_NAME">$1<ex>shopping suggestions</ex></ph>
       </message>
@@ -7871,21 +7910,24 @@
       <message name="IDS_NTP_MODULES_CART_ITEM_COUNT_MULTIPLE" desc="Item count displayed on chrome cart module when there are multiple items in a cart.">
         <ph name="ITEM_COUNT_MULTIPLE">$1<ex>2</ex></ph> items
       </message>
+      <message name="IDS_NTP_MODULES_DRIVE_DISABLE_BUTTON_TEXT" desc="Text shown on the disable button of a NTP Drive module v2.">
+       Never show Drive files
+      </message>
+      <message name="IDS_NTP_MODULES_DRIVE_DISABLE_BUTTON_TEXT_V2" desc="Text shown on the disable button of a NTP Drive module v2.">
+       Don't show Drive
+      </message>
+      <message name="IDS_NTP_MODULES_DRIVE_DISMISS_BUTTON_TEXT" desc="Text shown on the disable button of a NTP Drive module v2.">
+       Hide these files
+      </message>
       <message name="IDS_NTP_MODULES_DRIVE_SENTENCE" desc="Name of the Drive module in sentence case shown in various UIs.">
         Google Drive files
       </message>
-      <message name="IDS_NTP_MODULES_DRIVE_SENTENCE_V2" desc="Name of the Drive module v2 in sentence case shown in various UIs.">
-        Drive
-      </message>
       <message name="IDS_NTP_MODULES_DRIVE_SENTENCE2" desc="Variant of the name of the Drive module in sentence case shown in various UIs.">
         Drive files
       </message>
       <message name="IDS_NTP_MODULES_DRIVE_FILES_SENTENCE" desc="Name of the files in the Drive module in sentence case shown in various UIs.">
         Files
       </message>
-      <message name="IDS_NTP_MODULES_DRIVE_FILES_LOWER" desc="Name of the files in the Drive module in lowercase shown in various UIs.">
-        these files
-      </message>
       <message name="IDS_NTP_MODULES_DUMMY_LOWER" translateable="false" desc="Name of the dummy module in lowercase shown in various UIs.">
         this module
       </message>
@@ -8848,6 +8890,8 @@
       <message name="IDS_TOOLTIP_TAB_SEARCH" desc="The tooltip for the Tab Search bubble.">
         Search tabs
       </message>
+
+      <!-- Strings for tab organization -->
       <message name="IDS_TOOLTIP_TAB_ORGANIZE" desc="The tooltip for the Tab Organization button." translateable="false">
         Organize tabs
       </message>
@@ -8857,6 +8901,16 @@
       <message name="IDS_TOOLTIP_TAB_ORGANIZE_CLOSE" desc="The tooltip for the close button within the Tab Organization button." translateable="false">
         Close
       </message>
+      <if expr="use_titlecase">
+        <message name="IDS_TAB_ORGANIZE_MENU" desc="In Title Case: The text label for all tab organization menu items." translateable="false">
+          Organize Tabs
+        </message>
+      </if>
+      <if expr="not use_titlecase">
+        <message name="IDS_TAB_ORGANIZE_MENU" desc="The text label for all tab organization menu items." translateable="false">
+          Organize tabs
+        </message>
+      </if>
 
       <!-- Strings for intent picker -->
       <if expr="not is_android">
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_DISABLE_BUTTON_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_DISABLE_BUTTON_TEXT.png.sha1
new file mode 100644
index 0000000..fabc1c6
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_DISABLE_BUTTON_TEXT.png.sha1
@@ -0,0 +1 @@
+dd664118b0100b67c3b5cf8158909e49677178b7
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_DISABLE_BUTTON_TEXT_V2.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_DISABLE_BUTTON_TEXT_V2.png.sha1
new file mode 100644
index 0000000..9369e55
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_DISABLE_BUTTON_TEXT_V2.png.sha1
@@ -0,0 +1 @@
+5ea9aad9b7d86a0b83782e5473ae876906111288
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_DISMISS_BUTTON_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_DISMISS_BUTTON_TEXT.png.sha1
new file mode 100644
index 0000000..fabc1c6
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_DISMISS_BUTTON_TEXT.png.sha1
@@ -0,0 +1 @@
+dd664118b0100b67c3b5cf8158909e49677178b7
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_FILES_LOWER.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_FILES_LOWER.png.sha1
deleted file mode 100644
index c8b5b587..0000000
--- a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_FILES_LOWER.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-6b3cfb1f6f6448e8db2bd7017c908c7c439dc319
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_MORE_ACTIONS_BUTTON_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_MORE_ACTIONS_BUTTON_TEXT.png.sha1
new file mode 100644
index 0000000..c346c0d
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_MORE_ACTIONS_BUTTON_TEXT.png.sha1
@@ -0,0 +1 @@
+d16ff0f1a05a395bed8f941c600095ebdc62b3af
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_SENTENCE_V2.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_SENTENCE_V2.png.sha1
deleted file mode 100644
index 527eab9e..0000000
--- a/chrome/app/generated_resources_grd/IDS_NTP_MODULES_DRIVE_SENTENCE_V2.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-95b54bb9a228b9b606e4824787789105905b1b03
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_BLOCKING_RESTART_DESCRIPTION.png.sha1 b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_BLOCKING_RESTART_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..42f1516
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_BLOCKING_RESTART_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+a1123fe130a731941b91ce59e66d8b2612f4f8e5
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_BLOCKING_RESTART_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_BLOCKING_RESTART_TITLE.png.sha1
new file mode 100644
index 0000000..71d96d7
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_BLOCKING_RESTART_TITLE.png.sha1
@@ -0,0 +1 @@
+58781d2114cb09edb3e3a1f321cfdcfd8e8a8482
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_ALLOWED_LABEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_ALLOWED_LABEL.png.sha1
new file mode 100644
index 0000000..06d138d2
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_ALLOWED_LABEL.png.sha1
@@ -0,0 +1 @@
+6722baba2651fa1ecf5882ff6935f5216dd48527
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_BLOCKED_LABEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_BLOCKED_LABEL.png.sha1
new file mode 100644
index 0000000..5bc8953
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_BLOCKED_LABEL.png.sha1
@@ -0,0 +1 @@
+ff0ca926ea5a923939e4d7b91192623ef0bf6e84
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_LIMITED_LABEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_LIMITED_LABEL.png.sha1
new file mode 100644
index 0000000..bda35cb
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_LIMITED_LABEL.png.sha1
@@ -0,0 +1 @@
+edb8fad0b2a0ba00fa65f092c53621ca17901a4a
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_LIMITING_RESTART_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_LIMITING_RESTART_TITLE.png.sha1
new file mode 100644
index 0000000..37476b8
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_LIMITING_RESTART_TITLE.png.sha1
@@ -0,0 +1 @@
+b4054894a64ab22a544917612239801f38ac86ba
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_PERMANENT_ALLOWED_DESCRIPTION.png.sha1 b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_PERMANENT_ALLOWED_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..bfbce22
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_PERMANENT_ALLOWED_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+79fbf7812d5587ce2e4537b3021631a3c7220bef
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_PERMANENT_ALLOWED_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_PERMANENT_ALLOWED_TITLE.png.sha1
new file mode 100644
index 0000000..7e9dae08
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_PERMANENT_ALLOWED_TITLE.png.sha1
@@ -0,0 +1 @@
+5c72f5e52f1a03314f97110b8e07e79c34681ca2
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_SITE_NOT_WORKING_DESCRIPTION_PERMANENT.png.sha1 b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_SITE_NOT_WORKING_DESCRIPTION_PERMANENT.png.sha1
new file mode 100644
index 0000000..3c465d7f
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_SITE_NOT_WORKING_DESCRIPTION_PERMANENT.png.sha1
@@ -0,0 +1 @@
+1f5033a9cbc78209e2761b8329b941801649d0a6
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_TITLE.png.sha1
new file mode 100644
index 0000000..4195d30
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TRACKING_PROTECTION_BUBBLE_TITLE.png.sha1
@@ -0,0 +1 @@
+528c93b962e8e56a72977d4d0a025d0f6736523b
\ No newline at end of file
diff --git a/chrome/app/os_settings_search_tag_strings.grdp b/chrome/app/os_settings_search_tag_strings.grdp
index c0eda70..0d34e08 100644
--- a/chrome/app/os_settings_search_tag_strings.grdp
+++ b/chrome/app/os_settings_search_tag_strings.grdp
@@ -120,7 +120,7 @@
     Mobile networks
   </message>
   <message name="IDS_OS_SETTINGS_TAG_INSTANT_MOBILE_NETWORKS_ALT1" desc="Text for search result item which, when clicked, navigates the user to Instant Tethering settings (allows Chromebook to use mobile connection from phone). Alternate phrase for: 'Mobile networks'">
-    Hotspot
+    Instant hotspot
   </message>
   <message name="IDS_OS_SETTINGS_TAG_INSTANT_TETHERING_TURN_OFF" desc="Text for search result item which, when clicked, navigates the user to Instant Tethering settings (allows Chromebook to use mobile connection from phone), with a toggle to turn off the feature. Alternate phrase for: 'Disable Instant Tethering'">
     Turn off Instant Tethering
diff --git a/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_INSTANT_MOBILE_NETWORKS_ALT1.png.sha1 b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_INSTANT_MOBILE_NETWORKS_ALT1.png.sha1
index d766190a..3b2f96d1 100644
--- a/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_INSTANT_MOBILE_NETWORKS_ALT1.png.sha1
+++ b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_INSTANT_MOBILE_NETWORKS_ALT1.png.sha1
@@ -1 +1 @@
-c05a803cfbeec956685740cc60a9b5a5eda51489
\ No newline at end of file
+0f34e15fd3137c594a7c8cdf8cc73c303e5bdd41
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp
index 49a8dd25..08006ba 100644
--- a/chrome/app/os_settings_strings.grdp
+++ b/chrome/app/os_settings_strings.grdp
@@ -904,19 +904,19 @@
   <message name="IDS_OS_SETTINGS_DEVICE_MENU_ITEM_DESCRIPTION_3_WORDS" desc="Description for the Device menu item in the left menu which lists relevant settings in this page. This includes 3 words from a predefined set of words.">
     <ph name="DESCRIPTION_ITEM_1">$1<ex>Keyboard</ex></ph>, <ph name="DESCRIPTION_ITEM_2">$2<ex>mouse</ex></ph>, <ph name="DESCRIPTION_ITEM_3">$3<ex>print</ex></ph>
   </message>
-  <message name="IDS_OS_SETTINGS_DEVICE_MENU_ITEM_DESCRIPTION_KEYBOARD" desc="Label for keyboard settings in the Device menu item description in the left menu.">
+  <message name="IDS_OS_SETTINGS_DEVICE_MENU_ITEM_DESCRIPTION_KEYBOARD" desc="Description for keyboard settings in the Device menu item description in the left menu.">
     keyboard
   </message>
-  <message name="IDS_OS_SETTINGS_DEVICE_MENU_ITEM_DESCRIPTION_MOUSE" desc="Label for mouse settings in the Device menu item description in the left menu.">
+  <message name="IDS_OS_SETTINGS_DEVICE_MENU_ITEM_DESCRIPTION_MOUSE" desc="Description for mouse settings in the Device menu item description in the left menu.">
     mouse
   </message>
-  <message name="IDS_OS_SETTINGS_DEVICE_MENU_ITEM_DESCRIPTION_TOUCHPAD" desc="Label for touchpad settings in the Device menu item description in the left menu.">
+  <message name="IDS_OS_SETTINGS_DEVICE_MENU_ITEM_DESCRIPTION_TOUCHPAD" desc="Description for touchpad settings in the Device menu item description in the left menu.">
     touchpad
   </message>
-  <message name="IDS_OS_SETTINGS_DEVICE_MENU_ITEM_DESCRIPTION_PRINT" desc="Label for print settings in the Device menu item description in the left menu.">
+  <message name="IDS_OS_SETTINGS_DEVICE_MENU_ITEM_DESCRIPTION_PRINT" desc="Description for print settings in the Device menu item description in the left menu.">
     print
   </message>
-  <message name="IDS_OS_SETTINGS_DEVICE_MENU_ITEM_DESCRIPTION_DISPLAY" desc="Label for display settings in the Device menu item description in the left menu.">
+  <message name="IDS_OS_SETTINGS_DEVICE_MENU_ITEM_DESCRIPTION_DISPLAY" desc="Description for display settings in the Device menu item description in the left menu.">
     display
   </message>
 
@@ -2816,6 +2816,9 @@
   <message name="IDS_SETTINGS_CUSTOMIZE_BUTTONS_SUBPAGE_DESCRIPTION" desc="In customize buttons subpage, the description label above customize buttons to describe the actions user can perform.">
     Click additional buttons on your <ph name="DEVICE_NAME">$1<ex>MX Anywhere 2S</ex></ph> to add or locate buttons.
   </message>
+  <message name="IDS_SETTINGS_CUSTOMIZE_BUTTONS_RENAMING_DIALOG_INPUT_CHARACTER_COUNT" desc="Character count of the button renaming dialog input that shows up the current and maximum character count.">
+    <ph name="CURRENT_CHARACTER_COUNT">$1<ex>15</ex></ph>/<ph name="MAX_CHARACTER_COUNT">$2<ex>64</ex></ph>
+  </message>
 
   <!-- Bluetooth page (OS settings) -->
   <message name="IDS_SETTINGS_BLUETOOTH_CONNECTED" desc="In Bluetooth device list, this label is shown below a device which is already connected.">
@@ -6024,6 +6027,15 @@
       Help improve ChromeOS features and performance. Data is aggregated and highly protected.
     </message>
   </if>
+  <message name="IDS_OS_SETTINGS_PRIVACY_TITLE" desc="Name of the privacy settings page.">
+    Security and Privacy
+  </message>
+  <message name="IDS_OS_SETTINGS_REVAMP_PRIVACY_TITLE" desc="Name of the privacy settings page.">
+    Privacy and security
+  </message>
+  <message name="IDS_OS_SETTINGS_PRIVACY_MENU_ITEM_DESCRIPTION" desc="Description for the Privacy menu item in the left menu.">
+    Lock screen, controls
+  </message>
   <message name="IDS_SETTINGS_ENABLE_LOGGING_TOGGLE_DESC" desc="The description of the checkbox to enable/disable crash and user metrics logging in ChromeOS for user of the device.">
     Automatically sends crash reports as well as diagnostic and usage data to Google
   </message>
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_PRIVACY_MENU_ITEM_DESCRIPTION.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_PRIVACY_MENU_ITEM_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..1dc4acb
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_PRIVACY_MENU_ITEM_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+a7abce7f7f67466b3c42a1558fcd5b6a88f33267
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_PRIVACY_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_PRIVACY_TITLE.png.sha1
new file mode 100644
index 0000000..2db2adf
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_PRIVACY_TITLE.png.sha1
@@ -0,0 +1 @@
+c7c953571fc3f43a825ad96d9e7cd35126f62c1c
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_REVAMP_PRIVACY_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_REVAMP_PRIVACY_TITLE.png.sha1
new file mode 100644
index 0000000..cf27767
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_REVAMP_PRIVACY_TITLE.png.sha1
@@ -0,0 +1 @@
+8a93390f68ebe2c04a0c19fd1dd8e8824d5ace77
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CUSTOMIZE_BUTTONS_RENAMING_DIALOG_INPUT_CHARACTER_COUNT.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CUSTOMIZE_BUTTONS_RENAMING_DIALOG_INPUT_CHARACTER_COUNT.png.sha1
new file mode 100644
index 0000000..04191f9
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_CUSTOMIZE_BUTTONS_RENAMING_DIALOG_INPUT_CHARACTER_COUNT.png.sha1
@@ -0,0 +1 @@
+1d44eb1235ad3b1b0be85c9fdd9d5881f5a63d0b
\ No newline at end of file
diff --git a/chrome/app_shim/app_shim_controller.mm b/chrome/app_shim/app_shim_controller.mm
index 39e0daab..cab0339 100644
--- a/chrome/app_shim/app_shim_controller.mm
+++ b/chrome/app_shim/app_shim_controller.mm
@@ -134,8 +134,6 @@
       application_dock_menu_target_(
           [[ApplicationDockMenuTarget alloc] initWithController:this]) {
   screen_ = std::make_unique<display::ScopedNativeScreen>();
-  // Since AppShimController is created before the main message loop starts,
-  // NSApp will not be set, so use sharedApplication.
   NSApp.delegate = delegate_;
 }
 
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index c9f86d10..3c70e7b 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1217,6 +1217,8 @@
     "policy/javascript_policy_handler.h",
     "policy/messaging_layer/public/report_client.cc",
     "policy/messaging_layer/public/report_client.h",
+    "policy/messaging_layer/upload/configuration_file_controller.cc",
+    "policy/messaging_layer/upload/configuration_file_controller.h",
     "policy/messaging_layer/upload/dm_server_uploader.cc",
     "policy/messaging_layer/upload/dm_server_uploader.h",
     "policy/messaging_layer/upload/encrypted_reporting_client.cc",
@@ -1834,6 +1836,8 @@
     "tpcd/heuristics/opener_heuristic_tab_helper.h",
     "tpcd/heuristics/opener_heuristic_utils.cc",
     "tpcd/heuristics/opener_heuristic_utils.h",
+    "tpcd/metadata/devtools_observer.cc",
+    "tpcd/metadata/devtools_observer.h",
     "tpcd/metadata/updater_service.cc",
     "tpcd/metadata/updater_service.h",
     "tpcd/metadata/updater_service_factory.cc",
@@ -2298,6 +2302,7 @@
     "//components/optimization_guide/optimization_guide_internals/webui",
     "//components/origin_trials:browser",
     "//components/origin_trials:common",
+    "//components/os_crypt/async/browser",
     "//components/os_crypt/sync",
     "//components/page_image_service",
     "//components/page_info/core:proto",
@@ -2351,6 +2356,7 @@
     "//components/reporting/client:report_queue_provider",
     "//components/reporting/encryption:encryption_module",
     "//components/reporting/encryption:encryption_module_interface",
+    "//components/reporting/encryption:primitives",
     "//components/reporting/encryption:verification",
     "//components/reporting/proto:configuration_file_proto",
     "//components/reporting/proto:record_constants",
@@ -8120,8 +8126,6 @@
       "//chrome/browser/resources/chromeos/arc_account_picker:web_components",
       "//chrome/browser/resources/chromeos/crostini_installer:html_wrapper_files",
       "//chrome/browser/resources/chromeos/crostini_upgrader:html_wrapper_files",
-      "//chrome/browser/resources/chromeos/edu_coexistence:edu_coexistence_controller",
-      "//chrome/browser/resources/chromeos/edu_coexistence:web_components",
       "//chrome/browser/resources/chromeos/emulator:web_components",
       "//chrome/browser/resources/chromeos/gaia_action_buttons:web_components",
       "//chrome/browser/resources/chromeos/password_change:html_wrapper_files",
@@ -8291,6 +8295,7 @@
     "//components/policy/core/browser:test_support",
     "//components/prefs:test_support",
     "//components/reporting/client:test_support",
+    "//components/reporting/proto:configuration_file_proto",
     "//components/reporting/proto:record_constants",
     "//components/reporting/proto:record_proto",
     "//components/reporting/proto:status_proto",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 1e50bfa..1759236 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -237,6 +237,7 @@
   "+components/optimization_guide",
   "+components/optimization_guide/optimization_guide_internals",
   "+components/origin_trials",
+  "+components/os_crypt/async",
   "+components/os_crypt/sync",
   "+components/ownership",
   "+components/page_image_service",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index c719717..b796f7a 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -7684,6 +7684,11 @@
      flag_descriptions::kEnablePeripheralCustomizationDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kPeripheralCustomization)},
 
+    {"enable-peripheral-notification",
+     flag_descriptions::kEnablePeripheralNotificationName,
+     flag_descriptions::kEnablePeripheralNotificationDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(ash::features::kPeripheralNotification)},
+
     {"enable-accessibility-accelerators-notifications-timeout",
      flag_descriptions::kAccessibilityAcceleratorNotificationsTimeoutName,
      flag_descriptions::
@@ -8933,9 +8938,10 @@
      flag_descriptions::kFedCmWithoutWellKnownEnforcementDescription, kOsAll,
      FEATURE_VALUE_TYPE(features::kFedCmWithoutWellKnownEnforcement)},
 
-    {"web-identity-mdocs", flag_descriptions::kWebIdentityMDocsName,
-     flag_descriptions::kWebIdentityMDocsDescription, kOsAndroid,
-     FEATURE_VALUE_TYPE(features::kWebIdentityMDocs)},
+    {"web-identity-digital-credentials",
+     flag_descriptions::kWebIdentityDigitalCredentialsName,
+     flag_descriptions::kWebIdentityDigitalCredentialsDescription, kOsAndroid,
+     FEATURE_VALUE_TYPE(features::kWebIdentityDigitalCredentials)},
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     {"bluetooth-sessionized-metrics",
@@ -9088,11 +9094,6 @@
      FEATURE_VALUE_TYPE(features::kDefaultPassthroughCommandDecoder)},
 #endif  // BUILDFLAG(ENABLE_VALIDATING_COMMAND_DECODER)
 
-    {"disable-slow-msaa-in-graphite",
-     flag_descriptions::kDisableSlowMSAAInGraphiteName,
-     flag_descriptions::kDisableSlowMSAAInGraphiteDescription, kOsAll,
-     FEATURE_VALUE_TYPE(features::kDisableSlowMSAAInGraphite)},
-
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     {"focus-follows-cursor", flag_descriptions::kFocusFollowsCursorName,
      flag_descriptions::kFocusFollowsCursorDescription, kOsCrOS,
diff --git a/chrome/browser/about_flags_browsertest.cc b/chrome/browser/about_flags_browsertest.cc
index 97c2023..ec29e4b7 100644
--- a/chrome/browser/about_flags_browsertest.cc
+++ b/chrome/browser/about_flags_browsertest.cc
@@ -132,7 +132,9 @@
 
 void WaitForExperimentalFeatures(content::WebContents* contents) {
   ASSERT_TRUE(content::ExecJs(
-      contents, "experimentalFeaturesReadyForTest.then(() => true);"));
+      contents,
+      "var k = document.querySelector('flags-app');"
+      "k.experimentalFeaturesReadyForTesting().then(() => true);"));
 }
 
 const std::vector<flags_ui::FeatureEntry> GetFeatureEntries(
diff --git a/chrome/browser/apps/app_deduplication_service/app_deduplication_service.cc b/chrome/browser/apps/app_deduplication_service/app_deduplication_service.cc
index 672754a..47141ce5 100644
--- a/chrome/browser/apps/app_deduplication_service/app_deduplication_service.cc
+++ b/chrome/browser/apps/app_deduplication_service/app_deduplication_service.cc
@@ -16,12 +16,12 @@
 #include "chrome/browser/apps/app_deduplication_service/app_deduplication_service.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_features.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
 #include "components/services/app_service/public/cpp/app_types.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "components/services/app_service/public/cpp/types_util.h"
 
 namespace {
diff --git a/chrome/browser/apps/app_preload_service/preload_app_definition.cc b/chrome/browser/apps/app_preload_service/preload_app_definition.cc
index 54b958ae..8bcf4483 100644
--- a/chrome/browser/apps/app_preload_service/preload_app_definition.cc
+++ b/chrome/browser/apps/app_preload_service/preload_app_definition.cc
@@ -6,7 +6,7 @@
 
 #include "base/strings/string_util.h"
 #include "chrome/browser/apps/app_preload_service/proto/app_preload.pb.h"
-#include "chrome/browser/apps/app_service/package_id.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "url/gurl.h"
 
 namespace apps {
diff --git a/chrome/browser/apps/app_preload_service/preload_app_definition.h b/chrome/browser/apps/app_preload_service/preload_app_definition.h
index 9c8378d..26c7582 100644
--- a/chrome/browser/apps/app_preload_service/preload_app_definition.h
+++ b/chrome/browser/apps/app_preload_service/preload_app_definition.h
@@ -9,8 +9,8 @@
 #include <string>
 
 #include "chrome/browser/apps/app_preload_service/proto/app_preload.pb.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "components/services/app_service/public/cpp/app_types.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 
 class GURL;
 
diff --git a/chrome/browser/apps/app_service/BUILD.gn b/chrome/browser/apps/app_service/BUILD.gn
index c9e09e1c..61a9910 100644
--- a/chrome/browser/apps/app_service/BUILD.gn
+++ b/chrome/browser/apps/app_service/BUILD.gn
@@ -18,7 +18,6 @@
     "app_icon/app_icon_util.h",
     "app_icon/dip_px_util.cc",
     "app_icon/dip_px_util.h",
-    "app_icon/icon_effects.h",
     "app_icon/icon_key_util.cc",
     "app_icon/icon_key_util.h",
     "app_service_proxy.h",
@@ -35,8 +34,6 @@
     "launch_utils.h",
     "metrics/app_service_metrics.cc",
     "metrics/app_service_metrics.h",
-    "package_id.cc",
-    "package_id.h",
     "package_id_util.cc",
     "package_id_util.h",
     "paused_apps.cc",
@@ -343,7 +340,6 @@
     "app_service_proxy_unittest.cc",
     "intent_util_unittest.cc",
     "launch_utils_unittest.cc",
-    "package_id_unittest.cc",
     "publishers/publisher_unittest.cc",
   ]
 
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_factory.cc b/chrome/browser/apps/app_service/app_icon/app_icon_factory.cc
index 797bbc3..0a6d503 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_factory.cc
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_factory.cc
@@ -25,11 +25,11 @@
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_loader.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_util.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/grit/app_icon_resources.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "content/public/browser/browser_thread.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/constants.h"
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_factory.h b/chrome/browser/apps/app_service/app_icon/app_icon_factory.h
index cc6186c..a02113da 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_factory.h
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_factory.h
@@ -13,8 +13,8 @@
 #include "base/files/file_path.h"
 #include "base/functional/callback_forward.h"
 #include "build/chromeos_buildflags.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
 #include "ui/gfx/image/image_skia.h"
 
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_reader.h b/chrome/browser/apps/app_service/app_icon/app_icon_reader.h
index c921ff0..06d36c0 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_reader.h
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_reader.h
@@ -11,7 +11,7 @@
 
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
 
 class Profile;
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_util.cc b/chrome/browser/apps/app_service/app_icon/app_icon_util.cc
index 8c785a2..c144573 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_util.cc
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_util.cc
@@ -11,7 +11,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/task/thread_pool.h"
 #include "chrome/browser/apps/app_service/app_icon/dip_px_util.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "services/data_decoder/public/cpp/data_decoder.h"
 #include "ui/base/resource/resource_scale_factor.h"
 #include "ui/gfx/geometry/size.h"
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_util.h b/chrome/browser/apps/app_service/app_icon/app_icon_util.h
index 6b5943a..6a8a678d 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_util.h
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_util.h
@@ -10,7 +10,7 @@
 
 #include "ash/public/cpp/shelf_types.h"
 #include "base/files/file_path.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
 #include "services/data_decoder/public/cpp/data_decoder.h"
 #include "ui/base/resource/resource_scale_factor.h"
diff --git a/chrome/browser/apps/app_service/app_icon/web_app_icon_unittest.cc b/chrome/browser/apps/app_service/app_icon/web_app_icon_unittest.cc
index d4a89606..d4aab352 100644
--- a/chrome/browser/apps/app_service/app_icon/web_app_icon_unittest.cc
+++ b/chrome/browser/apps/app_service/app_icon/web_app_icon_unittest.cc
@@ -22,7 +22,6 @@
 #include "cc/test/pixel_test_utils.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_test_util.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/app_icon/web_app_icon_test_helper.h"
 #include "chrome/browser/web_applications/test/test_file_utils.h"
 #include "chrome/browser/web_applications/test/web_app_icon_test_utils.h"
@@ -38,6 +37,7 @@
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/services/app_service/public/cpp/features.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
 #include "content/public/test/browser_task_environment.h"
 #include "extensions/grit/extensions_browser_resources.h"
diff --git a/chrome/browser/apps/app_service/app_service_proxy_ash.cc b/chrome/browser/apps/app_service/app_service_proxy_ash.cc
index 1dab250f..8add2d9 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_ash.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_ash.cc
@@ -13,14 +13,12 @@
 #include "base/task/single_thread_task_runner.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_util.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/browser_app_instance_registry.h"
 #include "chrome/browser/apps/app_service/browser_app_instance_tracker.h"
 #include "chrome/browser/apps/app_service/instance_registry_updater.h"
 #include "chrome/browser/apps/app_service/metrics/app_platform_metrics.h"
 #include "chrome/browser/apps/app_service/metrics/app_platform_metrics_service.h"
 #include "chrome/browser/apps/app_service/metrics/app_service_metrics.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_service.h"
@@ -49,6 +47,8 @@
 #include "components/services/app_service/public/cpp/app_capability_access_cache_wrapper.h"
 #include "components/services/app_service/public/cpp/app_registry_cache_wrapper.h"
 #include "components/services/app_service/public/cpp/features.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "components/services/app_service/public/cpp/preferred_apps_impl.h"
 #include "components/services/app_service/public/cpp/preferred_apps_list.h"
 #include "components/services/app_service/public/cpp/shortcut/shortcut_registry_cache.h"
diff --git a/chrome/browser/apps/app_service/app_service_proxy_ash.h b/chrome/browser/apps/app_service/app_service_proxy_ash.h
index 41ea7eb6..4e250fd 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_ash.h
+++ b/chrome/browser/apps/app_service/app_service_proxy_ash.h
@@ -22,7 +22,6 @@
 #include "chrome/browser/apps/app_service/app_icon/app_icon_writer.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_base.h"
 #include "chrome/browser/apps/app_service/launch_result_type.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/paused_apps.h"
 #include "chrome/browser/apps/app_service/publisher_host.h"
 #include "chrome/browser/apps/app_service/subscriber_crosapi.h"
@@ -33,6 +32,7 @@
 #include "components/services/app_service/public/cpp/app_types.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
 #include "components/services/app_service/public/cpp/instance_registry.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "components/services/app_service/public/cpp/preferred_app.h"
 #include "components/services/app_service/public/cpp/shortcut/shortcut.h"
 #include "ui/gfx/native_widget_types.h"
diff --git a/chrome/browser/apps/app_service/app_service_proxy_base.cc b/chrome/browser/apps/app_service/app_service_proxy_base.cc
index 2982759..ebca286 100644
--- a/chrome/browser/apps/app_service/app_service_proxy_base.cc
+++ b/chrome/browser/apps/app_service/app_service_proxy_base.cc
@@ -16,7 +16,6 @@
 #include "base/functional/bind.h"
 #include "base/logging.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_source.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/app_launch_params.h"
 #include "chrome/browser/apps/app_service/browser_app_launcher.h"
 #include "chrome/browser/apps/app_service/metrics/app_service_metrics.h"
@@ -26,6 +25,7 @@
 #include "components/services/app_service/public/cpp/app_types.h"
 #include "components/services/app_service/public/cpp/app_update.h"
 #include "components/services/app_service/public/cpp/features.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "components/services/app_service/public/cpp/intent.h"
 #include "components/services/app_service/public/cpp/intent_filter.h"
 #include "components/services/app_service/public/cpp/intent_filter_util.h"
diff --git a/chrome/browser/apps/app_service/metrics/app_discovery_metrics.cc b/chrome/browser/apps/app_service/metrics/app_discovery_metrics.cc
index 053d9e3..f509a40 100644
--- a/chrome/browser/apps/app_service/metrics/app_discovery_metrics.cc
+++ b/chrome/browser/apps/app_service/metrics/app_discovery_metrics.cc
@@ -8,13 +8,13 @@
 #include "chrome/browser/apps/app_service/app_service_proxy_ash.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/app_service/extension_apps_utils.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/ash/borealis/borealis_util.h"
 #include "chrome/browser/ash/guest_os/guest_os_registry_service.h"
 #include "chrome/browser/ash/guest_os/guest_os_registry_service_factory.h"
 #include "chrome/browser/sync/sync_service_factory.h"
 #include "components/metrics/structured/structured_events.h"
 #include "components/services/app_service/public/cpp/instance.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "components/sync/base/model_type.h"
 #include "components/sync/service/sync_service.h"
 
diff --git a/chrome/browser/apps/app_service/package_id_util.cc b/chrome/browser/apps/app_service/package_id_util.cc
index 8606c152..da0fb249 100644
--- a/chrome/browser/apps/app_service/package_id_util.cc
+++ b/chrome/browser/apps/app_service/package_id_util.cc
@@ -6,10 +6,10 @@
 
 #include <string>
 
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/profiles/profile.h"
 #include "components/services/app_service/public/cpp/app_types.h"
 #include "components/services/app_service/public/cpp/app_update.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app.h b/chrome/browser/apps/app_service/promise_apps/promise_app.h
index 0da07eda..2f3948f 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app.h
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app.h
@@ -7,7 +7,7 @@
 
 #include <ostream>
 
-#include "chrome/browser/apps/app_service/package_id.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector.cc
index 09851e19..e4e1959 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector.cc
@@ -7,10 +7,10 @@
 #include "base/functional/callback.h"
 #include "chrome/browser/apps/almanac_api_client/almanac_api_util.h"
 #include "chrome/browser/apps/almanac_api_client/device_info_manager.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_wrapper.h"
 #include "chrome/browser/apps/app_service/promise_apps/proto/promise_app.pb.h"
 #include "chrome/browser/profiles/profile.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "net/base/net_errors.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/cpp/simple_url_loader.h"
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector.h b/chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector.h
index d90b3a7..f64c481 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector.h
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector.h
@@ -12,7 +12,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/apps/almanac_api_client/device_info_manager.h"
-#include "chrome/browser/apps/app_service/package_id.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector_unittest.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector_unittest.cc
index 0152f1cdd..6e3b7b7 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector_unittest.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector_unittest.cc
@@ -8,12 +8,12 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/test/bind.h"
 #include "base/test/test_future.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_wrapper.h"
 #include "chrome/browser/apps/app_service/promise_apps/proto/promise_app.pb.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/system/fake_statistics_provider.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "content/public/test/browser_task_environment.h"
 #include "net/http/http_request_headers.h"
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.cc
index 11c5cc58..8a79575 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.cc
@@ -10,9 +10,9 @@
 #include "base/logging.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
 #include "chrome/browser/apps/app_service/app_icon/dip_px_util.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/grit/app_icon_resources.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "skia/ext/image_operations.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/resource/resource_scale_factor.h"
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.h b/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.h
index 44b10103..b8c609a 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.h
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.h
@@ -7,8 +7,8 @@
 
 #include <map>
 
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
-#include "chrome/browser/apps/app_service/package_id.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/image/image_skia.h"
 
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache_unittest.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache_unittest.cc
index 47ac53c..93d97b5 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache_unittest.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache_unittest.cc
@@ -7,10 +7,10 @@
 #include "base/test/test_future.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_loader.h"
 #include "chrome/browser/apps/app_service/app_icon/dip_px_util.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/grit/app_icon_resources.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkColor.h"
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.cc
index c692bba1..6295be03 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.cc
@@ -4,11 +4,11 @@
 
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
 
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_update.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_utils.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_wrapper.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 
 namespace apps {
 
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h
index 09be264..db27c8d 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h
@@ -10,7 +10,7 @@
 #include "base/observer_list.h"
 #include "base/observer_list_types.h"
 #include "base/sequence_checker.h"
-#include "chrome/browser/apps/app_service/package_id.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 
 namespace apps {
 
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache_unittest.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache_unittest.cc
index 3f0e404..1b529d6 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache_unittest.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache_unittest.cc
@@ -5,10 +5,10 @@
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
 
 #include "base/scoped_observation.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_update.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_utils.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_service.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_service.cc
index 1a7f2e2..ad864f3 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_service.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_service.cc
@@ -12,7 +12,6 @@
 #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/package_id_util.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector.h"
@@ -25,6 +24,7 @@
 #include "components/services/app_service/public/cpp/app_registry_cache.h"
 #include "components/services/app_service/public/cpp/app_types.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "components/services/app_service/public/cpp/types_util.h"
 #include "google_apis/google_api_keys.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_service.h b/chrome/browser/apps/app_service/promise_apps/promise_app_service.h
index f1a7f6a3..045d1de 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_service.h
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_service.h
@@ -10,9 +10,9 @@
 #include "base/functional/callback_forward.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_icon_cache.h"
 #include "components/services/app_service/public/cpp/app_registry_cache.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 class Profile;
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_service_unittest.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_service_unittest.cc
index 8dbcb04a..bdbb923 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_service_unittest.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_service_unittest.cc
@@ -10,7 +10,6 @@
 #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
@@ -21,6 +20,7 @@
 #include "chromeos/ash/components/system/fake_statistics_provider.h"
 #include "components/services/app_service/public/cpp/app_types.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "content/public/test/browser_task_environment.h"
 #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_unittest.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_unittest.cc
index eb26029..481b29c 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_unittest.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 
-#include "chrome/browser/apps/app_service/package_id.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace apps {
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_update.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_update.cc
index a56faa09..efefdbd 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_update.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_update.cc
@@ -6,9 +6,9 @@
 
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "components/services/app_service/public/cpp/macros.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 
 namespace apps {
 
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_update_unittest.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_update_unittest.cc
index 538be35..c229097 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_update_unittest.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_update_unittest.cc
@@ -4,8 +4,8 @@
 
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_update.h"
 
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace apps {
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_wrapper.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_wrapper.cc
index 09baaa0..9af76ec 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_wrapper.cc
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_wrapper.cc
@@ -7,7 +7,7 @@
 #include <vector>
 
 #include "base/strings/string_util.h"
-#include "chrome/browser/apps/app_service/package_id.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_wrapper.h b/chrome/browser/apps/app_service/promise_apps/promise_app_wrapper.h
index 17f0d245..8c1d43a 100644
--- a/chrome/browser/apps/app_service/promise_apps/promise_app_wrapper.h
+++ b/chrome/browser/apps/app_service/promise_apps/promise_app_wrapper.h
@@ -9,9 +9,9 @@
 #include <string>
 #include <vector>
 
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/proto/promise_app.pb.h"
 #include "components/services/app_service/public/cpp/app_types.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
diff --git a/chrome/browser/apps/app_service/publishers/app_publisher.cc b/chrome/browser/apps/app_service/publishers/app_publisher.cc
index 5ad1f29..f16b469 100644
--- a/chrome/browser/apps/app_service/publishers/app_publisher.cc
+++ b/chrome/browser/apps/app_service/publishers/app_publisher.cc
@@ -7,8 +7,8 @@
 #include "base/logging.h"
 #include "base/notreached.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "components/services/app_service/public/cpp/capability_access.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.cc b/chrome/browser/apps/app_service/publishers/arc_apps.cc
index 17ab057..bad9765 100644
--- a/chrome/browser/apps/app_service/publishers/arc_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/arc_apps.cc
@@ -33,7 +33,6 @@
 #include "chrome/browser/apps/app_service/intent_util.h"
 #include "chrome/browser/apps/app_service/launch_utils.h"
 #include "chrome/browser/apps/app_service/menu_util.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
 #include "chrome/browser/apps/app_service/publishers/arc_apps_factory.h"
@@ -61,6 +60,7 @@
 #include "components/services/app_service/public/cpp/intent.h"
 #include "components/services/app_service/public/cpp/intent_filter.h"
 #include "components/services/app_service/public/cpp/intent_util.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "components/services/app_service/public/cpp/permission.h"
 #include "components/services/app_service/public/cpp/types_util.h"
 #include "extensions/grit/extensions_browser_resources.h"
diff --git a/chrome/browser/apps/intent_helper/intent_picker_helpers.cc b/chrome/browser/apps/intent_helper/intent_picker_helpers.cc
index 8648a8618..b36f4a5b 100644
--- a/chrome/browser/apps/intent_helper/intent_picker_helpers.cc
+++ b/chrome/browser/apps/intent_helper/intent_picker_helpers.cc
@@ -12,15 +12,13 @@
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/intent_helper/intent_chip_display_prefs.h"
-#include "chrome/browser/apps/link_capturing/enable_link_capturing_infobar_delegate.h"
 #include "chrome/browser/apps/link_capturing/intent_picker_info.h"
 #include "chrome/browser/apps/link_capturing/link_capturing_features.h"
-#include "chrome/browser/infobars/confirm_infobar_creator.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/share/share_attempt.h"
 #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
-#include "components/infobars/content/content_infobar_manager.h"
-#include "components/infobars/core/infobar.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/browser/web_applications/web_app_ui_manager.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/gfx/favicon_size.h"
 #include "url/gurl.h"
@@ -62,13 +60,11 @@
     case apps::PickerEntryType::kWeb:
       web_app::ReparentWebContentsIntoAppBrowser(web_contents, launch_name);
       if (base::FeatureList::IsEnabled(features::kDesktopPWAsLinkCapturing)) {
-        std::unique_ptr<EnableLinkCapturingInfoBarDelegate> delegate =
-            EnableLinkCapturingInfoBarDelegate::MaybeCreate(web_contents,
-                                                            launch_name);
-        if (delegate) {
-          infobars::ContentInfoBarManager::FromWebContents(web_contents)
-              ->AddInfoBar(CreateConfirmInfoBar(std::move(delegate)));
-        }
+        web_app::WebAppProvider* web_app_provider =
+            web_app::WebAppProvider::GetForWebApps(profile);
+        CHECK(web_app_provider);
+        web_app_provider->ui_manager().MaybeCreateEnableSupportedLinksInfobar(
+            web_contents, launch_name);
       }
       break;
     case apps::PickerEntryType::kMacOs:
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index 16dd53b..9cb3e0ef 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -414,8 +414,6 @@
     "arc/input_overlay/ui/action_view_list_item.h",
     "arc/input_overlay/ui/arrow_container.cc",
     "arc/input_overlay/ui/arrow_container.h",
-    "arc/input_overlay/ui/button_label_list.cc",
-    "arc/input_overlay/ui/button_label_list.h",
     "arc/input_overlay/ui/button_options_menu.cc",
     "arc/input_overlay/ui/button_options_menu.h",
     "arc/input_overlay/ui/delete_edit_shortcut.cc",
@@ -4941,6 +4939,7 @@
     "../ui/webui/ash/settings/pages/main/send_search_feedback_handler_unittest.cc",
     "../ui/webui/ash/settings/pages/multidevice/multidevice_handler_unittest.cc",
     "../ui/webui/ash/settings/pages/multidevice/multidevice_section_unittest.cc",
+    "../ui/webui/ash/settings/pages/os_settings_section_unittest.cc",
     "../ui/webui/ash/settings/pages/privacy/metrics_consent_handler_unittest.cc",
     "../ui/webui/ash/settings/pages/privacy/privacy_hub_handler_unittest.cc",
     "../ui/webui/ash/settings/pages/search/search_engines_handler_unittest.cc",
@@ -4952,7 +4951,6 @@
     "../ui/webui/settings/ash/display_settings/display_settings_provider_unittest.cc",
     "../ui/webui/settings/ash/os_settings_features_util_unittest.cc",
     "../ui/webui/settings/ash/os_settings_manager_unittest.cc",
-    "../ui/webui/settings/ash/os_settings_section_unittest.cc",
     "../ui/webui/settings/ash/per_session_settings_user_action_tracker_unittest.cc",
     "../ui/webui/settings/ash/settings_user_action_tracker_unittest.cc",
     "accessibility/pumpkin_installer_unittest.cc",
diff --git a/chrome/browser/ash/accessibility/autoclick_browsertest.cc b/chrome/browser/ash/accessibility/autoclick_browsertest.cc
index 3bc284bd..a066f8c 100644
--- a/chrome/browser/ash/accessibility/autoclick_browsertest.cc
+++ b/chrome/browser/ash/accessibility/autoclick_browsertest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "ash/accessibility/autoclick/autoclick_controller.h"
 #include "ash/accessibility/ui/accessibility_focus_ring_controller_impl.h"
 #include "ash/accessibility/ui/accessibility_focus_ring_layer.h"
 #include "ash/constants/ash_pref_names.h"
@@ -13,10 +14,7 @@
 #include "chrome/browser/ash/accessibility/accessibility_manager.h"
 #include "chrome/browser/ash/accessibility/accessibility_test_utils.h"
 #include "chrome/browser/ash/accessibility/autoclick_test_utils.h"
-#include "chrome/browser/ash/accessibility/caret_bounds_changed_waiter.h"
-#include "chrome/browser/ash/accessibility/html_test_utils.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/common/extensions/extension_constants.h"
@@ -26,8 +24,6 @@
 #include "content/public/test/accessibility_notification_waiter.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
-#include "content/public/test/test_utils.h"
-#include "extensions/browser/browsertest_util.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/events/test/event_generator.h"
 #include "url/url_constants.h"
@@ -156,9 +152,23 @@
 
   LoadURLAndAutoclick(
       "data:text/html;charset=utf-8,"
-      "<textarea id='test_textarea' rows='2'' cols='20'>" +
+      "<textarea id='test_textarea' class='scrollableField' rows='2'' "
+      "cols='20'>" +
       kQuoteText + "</textarea>");
 
+  gfx::Rect bounds =
+      utils()->GetBoundsForNodeInRootByClassName("scrollableField");
+  gfx::Rect found_bounds;
+  base::RunLoop waiter;
+  Shell::Get()->autoclick_controller()->SetScrollableBoundsCallbackForTesting(
+      base::BindLambdaForTesting([&waiter, &bounds, &found_bounds](
+                                     const gfx::Rect& scrollable_bounds) {
+        found_bounds = scrollable_bounds;
+        if (scrollable_bounds == bounds && waiter.running()) {
+          waiter.Quit();
+        }
+      }));
+
   AccessibilityFocusRingControllerImpl* controller =
       Shell::Get()->accessibility_focus_ring_controller();
   std::string focus_ring_id = AccessibilityManager::Get()->GetFocusRingId(
@@ -179,6 +189,11 @@
   std::vector<std::unique_ptr<AccessibilityFocusRingLayer>> const& focus_rings =
       focus_ring_group->focus_layers_for_testing();
   ASSERT_EQ(focus_rings.size(), 1u);
+
+  if (found_bounds != bounds) {
+    // Wait for bounds changed.
+    waiter.Run();
+  }
 }
 
 IN_PROC_BROWSER_TEST_F(AutoclickBrowserTest, LongDelay) {
diff --git a/chrome/browser/ash/accessibility/autoclick_test_utils.cc b/chrome/browser/ash/accessibility/autoclick_test_utils.cc
index fc358fc..798f5615 100644
--- a/chrome/browser/ash/accessibility/autoclick_test_utils.cc
+++ b/chrome/browser/ash/accessibility/autoclick_test_utils.cc
@@ -163,6 +163,11 @@
   return automation_utils_->GetNodeBoundsInRoot(name, role);
 }
 
+gfx::Rect AutoclickTestUtils::GetBoundsForNodeInRootByClassName(
+    const std::string& class_name) {
+  return automation_utils_->GetBoundsForNodeInRootByClassName(class_name);
+}
+
 void AutoclickTestUtils::WaitForAutoclickReady() {
   base::ScopedAllowBlockingForTesting allow_blocking;
   std::string script = base::StringPrintf(R"JS(
diff --git a/chrome/browser/ash/accessibility/autoclick_test_utils.h b/chrome/browser/ash/accessibility/autoclick_test_utils.h
index 218dccc..cba9f33 100644
--- a/chrome/browser/ash/accessibility/autoclick_test_utils.h
+++ b/chrome/browser/ash/accessibility/autoclick_test_utils.h
@@ -53,6 +53,7 @@
   // Waits for the given node to exist, then returns its bounds.
   gfx::Rect GetNodeBoundsInRoot(const std::string& name,
                                 const std::string& role);
+  gfx::Rect GetBoundsForNodeInRootByClassName(const std::string& class_name);
 
  private:
   void WaitForAutoclickReady();
diff --git a/chrome/browser/ash/accessibility/service/accessibility_service_client_browsertest.cc b/chrome/browser/ash/accessibility/service/accessibility_service_client_browsertest.cc
index 800aa31..90cc42f6 100644
--- a/chrome/browser/ash/accessibility/service/accessibility_service_client_browsertest.cc
+++ b/chrome/browser/ash/accessibility/service/accessibility_service_client_browsertest.cc
@@ -5,6 +5,8 @@
 #include "ash/accessibility/accessibility_controller_impl.h"
 #include "ash/accessibility/ui/accessibility_focus_ring_controller_impl.h"
 #include "ash/accessibility/ui/accessibility_highlight_layer.h"
+#include "ash/keyboard/keyboard_controller_impl.h"
+#include "ash/keyboard/ui/keyboard_util.h"
 #include "ash/public/cpp/accessibility_focus_ring_info.h"
 #include "ash/shell.h"
 #include "base/command_line.h"
@@ -18,6 +20,7 @@
 #include "chrome/browser/ash/accessibility/service/fake_accessibility_service.h"
 #include "chrome/browser/ash/accessibility/speech_monitor.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -35,6 +38,33 @@
 
 using ax::mojom::AssistiveTechnologyType;
 
+class KeyboardVisibleWaiter : public ChromeKeyboardControllerClient::Observer {
+ public:
+  explicit KeyboardVisibleWaiter(bool visible) : visible_(visible) {
+    ChromeKeyboardControllerClient::Get()->AddObserver(this);
+  }
+
+  KeyboardVisibleWaiter(const KeyboardVisibleWaiter&) = delete;
+  KeyboardVisibleWaiter& operator=(const KeyboardVisibleWaiter&) = delete;
+
+  ~KeyboardVisibleWaiter() override {
+    ChromeKeyboardControllerClient::Get()->RemoveObserver(this);
+  }
+
+  void Wait() { run_loop_.Run(); }
+
+  // ChromeKeyboardControllerClient::Observer
+  void OnKeyboardVisibilityChanged(bool visible) override {
+    if (visible == visible_) {
+      run_loop_.QuitWhenIdle();
+    }
+  }
+
+ private:
+  base::RunLoop run_loop_;
+  const bool visible_;
+};  // namespace
+
 namespace ash {
 
 namespace {
@@ -1020,4 +1050,29 @@
   waiter.Run();
 }
 
+IN_PROC_BROWSER_TEST_F(AccessibilityServiceClientTest,
+                       RequestSetVirtualKeyboardVisible) {
+  // Initialize ATP.
+  auto client = TurnOnAccessibilityService(AssistiveTechnologyType::kChromeVox);
+  fake_service_->BindAnotherUserInterface();
+
+  // Enable virtual keyboard.
+  keyboard::SetAccessibilityKeyboardEnabled(true);
+
+  // Verify keyboard is hidden.
+  KeyboardControllerImpl* keyboard_controller_ =
+      Shell::Get()->keyboard_controller();
+  EXPECT_FALSE(keyboard_controller_->IsKeyboardVisible());
+
+  // Show keyboard, and verify visible.
+  fake_service_->RequestSetVirtualKeyboardVisible(true);
+  KeyboardVisibleWaiter(true).Wait();
+  EXPECT_TRUE(keyboard_controller_->IsKeyboardVisible());
+
+  // Hide keyboard, and verify invisible.
+  fake_service_->RequestSetVirtualKeyboardVisible(false);
+  KeyboardVisibleWaiter(false).Wait();
+  EXPECT_FALSE(keyboard_controller_->IsKeyboardVisible());
+}
+
 }  // namespace ash
diff --git a/chrome/browser/ash/accessibility/service/fake_accessibility_service.cc b/chrome/browser/ash/accessibility/service/fake_accessibility_service.cc
index a3d7207..df17199e 100644
--- a/chrome/browser/ash/accessibility/service/fake_accessibility_service.cc
+++ b/chrome/browser/ash/accessibility/service/fake_accessibility_service.cc
@@ -229,4 +229,11 @@
   }
 }
 
+void FakeAccessibilityService::RequestSetVirtualKeyboardVisible(
+    bool is_visible) {
+  for (auto& ux_client : ux_remotes_) {
+    ux_client->SetVirtualKeyboardVisible(is_visible);
+  }
+}
+
 }  // namespace ash
diff --git a/chrome/browser/ash/accessibility/service/fake_accessibility_service.h b/chrome/browser/ash/accessibility/service/fake_accessibility_service.h
index aee8c4a..e30b8448 100644
--- a/chrome/browser/ash/accessibility/service/fake_accessibility_service.h
+++ b/chrome/browser/ash/accessibility/service/fake_accessibility_service.h
@@ -148,6 +148,8 @@
 
   void RequestSetHighlights(const std::vector<gfx::Rect>& rects, SkColor color);
 
+  void RequestSetVirtualKeyboardVisible(bool is_visible);
+
   // Getters for automation events.
   std::vector<ui::AXTreeID> tree_destroyed_events() const {
     return tree_destroyed_events_;
diff --git a/chrome/browser/ash/accessibility/service/user_interface_impl.cc b/chrome/browser/ash/accessibility/service/user_interface_impl.cc
index fe02231..640fb1e 100644
--- a/chrome/browser/ash/accessibility/service/user_interface_impl.cc
+++ b/chrome/browser/ash/accessibility/service/user_interface_impl.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ash/accessibility/service/user_interface_impl.h"
 
+#include "ash/public/cpp/accessibility_controller.h"
 #include "ash/public/cpp/accessibility_focus_ring_info.h"
 #include "chrome/browser/ash/accessibility/accessibility_manager.h"
 #include "content/public/common/color_parser.h"
@@ -94,4 +95,8 @@
   AccessibilityManager::Get()->SetHighlights(rects, color);
 }
 
+void UserInterfaceImpl::SetVirtualKeyboardVisible(bool is_visible) {
+  AccessibilityController::Get()->SetVirtualKeyboardVisible(is_visible);
+}
+
 }  // namespace ash
diff --git a/chrome/browser/ash/accessibility/service/user_interface_impl.h b/chrome/browser/ash/accessibility/service/user_interface_impl.h
index 995c026..cdd3aae9 100644
--- a/chrome/browser/ash/accessibility/service/user_interface_impl.h
+++ b/chrome/browser/ash/accessibility/service/user_interface_impl.h
@@ -31,6 +31,7 @@
                      ax::mojom::AssistiveTechnologyType at_type) override;
   void SetHighlights(const std::vector<gfx::Rect>& rects,
                      SkColor color) override;
+  void SetVirtualKeyboardVisible(bool is_visible) override;
 
  private:
   mojo::ReceiverSet<ax::mojom::UserInterface> ui_receivers_;
diff --git a/chrome/browser/ash/app_list/app_list_client_impl_browsertest.cc b/chrome/browser/ash/app_list/app_list_client_impl_browsertest.cc
index 99182e2f..9aa31d7 100644
--- a/chrome/browser/ash/app_list/app_list_client_impl_browsertest.cc
+++ b/chrome/browser/ash/app_list/app_list_client_impl_browsertest.cc
@@ -30,7 +30,6 @@
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/app_service/launch_utils.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
 #include "chrome/browser/apps/platform_apps/app_browsertest_util.h"
@@ -77,6 +76,7 @@
 #include "components/app_constants/constants.h"
 #include "components/browser_sync/browser_sync_switches.h"
 #include "components/prefs/pref_service.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "components/user_manager/user_names.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/test_utils.h"
diff --git a/chrome/browser/ash/app_list/app_service/app_service_promise_app_context_menu.cc b/chrome/browser/ash/app_list/app_service/app_service_promise_app_context_menu.cc
index 09ea664..dc8f909 100644
--- a/chrome/browser/ash/app_list/app_service/app_service_promise_app_context_menu.cc
+++ b/chrome/browser/ash/app_list/app_service/app_service_promise_app_context_menu.cc
@@ -9,7 +9,6 @@
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/app_service/menu_util.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
 #include "chrome/browser/ash/app_list/app_context_menu.h"
 #include "chrome/browser/ash/app_list/app_context_menu_delegate.h"
@@ -17,6 +16,7 @@
 #include "chrome/browser/ash/app_list/chrome_app_list_model_updater.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/grit/generated_resources.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/vector_icon_types.h"
 
diff --git a/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.cc b/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.cc
index 435c11ec..3783340 100644
--- a/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.cc
+++ b/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.cc
@@ -10,10 +10,8 @@
 #include "ash/public/cpp/shelf_types.h"
 #include "base/functional/callback_helpers.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_util.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_service.h"
@@ -22,6 +20,8 @@
 #include "chrome/browser/ash/app_list/app_service/app_service_app_icon_loader.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/ash/shelf/shelf_controller_helper.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 
 AppServicePromiseAppIconLoader::AppServicePromiseAppIconLoader(
     Profile* profile,
diff --git a/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.h b/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.h
index b8a52f40..8f7c092 100644
--- a/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.h
+++ b/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.h
@@ -10,10 +10,10 @@
 
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observation.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
 #include "chrome/browser/ui/app_icon_loader.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 
 class Profile;
 
diff --git a/chrome/browser/ash/app_list/app_service/app_service_promise_app_item_browsertest.cc b/chrome/browser/ash/app_list/app_service/app_service_promise_app_item_browsertest.cc
index 4240362..b5e4ab7 100644
--- a/chrome/browser/ash/app_list/app_service/app_service_promise_app_item_browsertest.cc
+++ b/chrome/browser/ash/app_list/app_service/app_service_promise_app_item_browsertest.cc
@@ -25,7 +25,6 @@
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_ash.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
 #include "chrome/browser/apps/platform_apps/app_browsertest_util.h"
@@ -45,6 +44,7 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/services/app_service/public/cpp/app_types.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "components/sync/model/string_ordinal.h"
 #include "components/sync/protocol/entity_specifics.pb.h"
 #include "components/sync/test/fake_sync_change_processor.h"
diff --git a/chrome/browser/ash/app_list/app_service/app_service_promise_app_model_builder_unittest.cc b/chrome/browser/ash/app_list/app_service/app_service_promise_app_model_builder_unittest.cc
index 9893bbb..fe25bb41 100644
--- a/chrome/browser/ash/app_list/app_service/app_service_promise_app_model_builder_unittest.cc
+++ b/chrome/browser/ash/app_list/app_service/app_service_promise_app_model_builder_unittest.cc
@@ -10,7 +10,6 @@
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/app_service/app_service_test.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
 #include "chrome/browser/ash/app_list/app_list_test_util.h"
@@ -21,6 +20,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/services/app_service/public/cpp/app_types.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "content/public/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/display/test/test_screen.h"
diff --git a/chrome/browser/ash/app_list/arc/arc_app_unittest.cc b/chrome/browser/ash/app_list/arc/arc_app_unittest.cc
index 64c6df9..e21e8d9 100644
--- a/chrome/browser/ash/app_list/arc/arc_app_unittest.cc
+++ b/chrome/browser/ash/app_list/arc/arc_app_unittest.cc
@@ -40,7 +40,6 @@
 #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_util.h"
 #include "chrome/browser/apps/app_service/app_icon/dip_px_util.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/app_service/publishers/arc_apps.h"
@@ -85,6 +84,7 @@
 #include "components/services/app_service/public/cpp/app_types.h"
 #include "components/services/app_service/public/cpp/app_update.h"
 #include "components/services/app_service/public/cpp/features.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
 #include "components/services/app_service/public/cpp/intent.h"
 #include "components/services/app_service/public/cpp/intent_util.h"
diff --git a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc
index 9631c272..f527908 100644
--- a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc
+++ b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/ash/arc/input_overlay/touch_injector.h"
 #include "chrome/browser/ash/arc/input_overlay/ui/action_view.h"
 #include "chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.h"
-#include "chrome/browser/ash/arc/input_overlay/ui/button_label_list.h"
 #include "chrome/browser/ash/arc/input_overlay/ui/button_options_menu.h"
 #include "chrome/browser/ash/arc/input_overlay/ui/delete_edit_shortcut.h"
 #include "chrome/browser/ash/arc/input_overlay/ui/edit_finish_view.h"
@@ -49,7 +48,6 @@
 constexpr int kMenuEntrySideMargin = 24;
 constexpr int kNudgeVerticalAlign = 8;
 
-constexpr char kButtonLabelList[] = "GameControlsButtonLabelList";
 constexpr char kButtonOptionsMenu[] = "GameControlsButtonOptionsMenu";
 constexpr char kEditingList[] = "GameControlsEditingList";
 constexpr char kInputMapping[] = "GameControlsInputMapping";
@@ -714,18 +712,9 @@
 
     button_options_widget_->Close();
     button_options_widget_.reset();
-
-    RemoveButtonLabelListWidget();
   }
 }
 
-void DisplayOverlayController::OnButtonOptionsMenuButtonLabelPressed(
-    Action* action) {
-  DCHECK(button_options_widget_);
-  button_options_widget_->Hide();
-  AddButtonLabelListWidget(action);
-}
-
 void DisplayOverlayController::SetButtonOptionsMenuWidgetVisibility(
     bool is_visible) {
   if (!button_options_widget_) {
@@ -742,41 +731,6 @@
   }
 }
 
-void DisplayOverlayController::AddButtonLabelListWidget(Action* action) {
-  if (button_label_list_widget_) {
-    return;
-  }
-
-  button_label_list_widget_ = CreateTransientWidget(
-      touch_injector_->window(), /*widget_name=*/kButtonLabelList,
-      /*accept_events=*/true, /*is_floating=*/true);
-  auto* view = button_label_list_widget_->SetContentsView(
-      std::make_unique<ButtonLabelList>(this, action));
-  auto* window = button_label_list_widget_->GetNativeWindow();
-  window->parent()->StackChildAtTop(window);
-  UpdateWidgetBoundsInRootWindow(
-      button_label_list_widget_.get(),
-      gfx::Rect(action->action_view()->CalculateAttachViewPositionInRootWindow(
-                    CalculateAvailableBounds(
-                        touch_injector_->window()->GetRootWindow()),
-                    touch_injector_->content_bounds().origin(), view),
-                view->GetPreferredSize()));
-  button_label_list_widget_->ShowInactive();
-}
-
-void DisplayOverlayController::RemoveButtonLabelListWidget() {
-  if (!button_label_list_widget_) {
-    return;
-  }
-  button_label_list_widget_->Close();
-  button_label_list_widget_.reset();
-}
-
-void DisplayOverlayController::OnButtonLabelListBackButtonPressed() {
-  RemoveButtonLabelListWidget();
-  button_options_widget_->ShowInactive();
-}
-
 void DisplayOverlayController::AddNudgeWidget(views::View* anchor_view,
                                               const std::u16string& text) {
   auto* anchor_widget = anchor_view->GetWidget();
@@ -1122,7 +1076,6 @@
     UpdateEditingListWidgetBounds();
 
     // Remove the floating window attached the ActionView.
-    RemoveButtonLabelListWidget();
     RemoveButtonOptionsMenuWidget();
     RemoveDeleteEditShortcutWidget();
   } else {
diff --git a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h
index fcf15b3..77f71477 100644
--- a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h
+++ b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h
@@ -31,7 +31,6 @@
 class ActionEditMenu;
 class ActionViewListItem;
 class ButtonOptionsMenu;
-class ButtonLabelList;
 class EditFinishView;
 class EditingList;
 class EducationalView;
@@ -108,13 +107,8 @@
 
   void AddButtonOptionsMenuWidget(Action* action);
   void RemoveButtonOptionsMenuWidget();
-  void OnButtonOptionsMenuButtonLabelPressed(Action* action);
   void SetButtonOptionsMenuWidgetVisibility(bool is_visible);
 
-  void AddButtonLabelListWidget(Action* action);
-  void RemoveButtonLabelListWidget();
-  void OnButtonLabelListBackButtonPressed();
-
   void AddNudgeWidget(views::View* anchor_view, const std::u16string& text);
   void RemoveNudgeWidget(views::Widget* widget);
 
@@ -146,14 +140,9 @@
 
   const TouchInjector* touch_injector() const { return touch_injector_; }
 
-  const std::vector<std::u16string> action_name_list() const {
-    return action_name_list_;
-  }
-
  private:
   friend class ActionView;
   friend class ArcInputOverlayManagerTest;
-  friend class ButtonLabelList;
   friend class ButtonOptionsMenu;
   friend class DisplayOverlayControllerTest;
   friend class DisplayOverlayControllerAlphaTest;
@@ -266,13 +255,6 @@
   InputMenuView* GetInputMenuView() { return input_menu_view_; }
   MenuEntryView* GetMenuEntryView() { return menu_entry_; }
 
-  // `action_name_list_` is a vector that holds the list of action name labels
-  // that can be selected.
-  // TODO(b/274690042): Replace placeholder text with localized strings.
-  const std::vector<std::u16string> action_name_list_ = {
-      u"Move",  u"Jump",  u"Attack", u"Special ability", u"Crouch", u"Run",
-      u"Shoot", u"Magic", u"Reload", u"Dodge", u"Menu", u"Other"};
-
   const raw_ptr<TouchInjector> touch_injector_;
 
   // References to UI elements owned by the overlay widget.
@@ -290,7 +272,6 @@
   std::unique_ptr<views::Widget> input_mapping_widget_;
   std::unique_ptr<views::Widget> editing_list_widget_;
   std::unique_ptr<views::Widget> button_options_widget_;
-  std::unique_ptr<views::Widget> button_label_list_widget_;
   std::unique_ptr<views::Widget> delete_edit_shortcut_widget_;
 
   // Each widget can associate with one education nudge widget.
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_edit_view.cc b/chrome/browser/ash/arc/input_overlay/ui/action_edit_view.cc
index 5aa57ea..eb533d8 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/action_edit_view.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/action_edit_view.cc
@@ -54,9 +54,8 @@
                  /*fixed_width=*/0, /*min_width=*/0)
       .AddRows(1, /*vertical_resize=*/views::TableLayout::kFixedSize);
 
-  auto title_string = GetActionNameAtIndex(controller_->action_name_list(),
-                                           action_->name_label_index());
-  name_tag_ = AddChildView(NameTag::CreateNameTag(title_string));
+  // TODO(b/274690042): Replace placeholder text with localized strings.
+  name_tag_ = AddChildView(NameTag::CreateNameTag(u"Unassigned"));
   labels_view_ = AddChildView(EditLabels::CreateEditLabels(
       controller_, action_, name_tag_, /*should_update_title=*/true));
 }
diff --git a/chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.cc b/chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.cc
index a107e03..b6243f7 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/action_view_list_item.cc
@@ -22,9 +22,7 @@
 ActionViewListItem::~ActionViewListItem() = default;
 
 void ActionViewListItem::OnActionNameUpdated() {
-  auto action_name = GetActionNameAtIndex(controller_->action_name_list(),
-                                          action_->name_label_index());
-  name_tag_->SetTitle(action_name);
+  NOTIMPLEMENTED();
 }
 
 void ActionViewListItem::ClickCallback() {
diff --git a/chrome/browser/ash/arc/input_overlay/ui/button_label_list.cc b/chrome/browser/ash/arc/input_overlay/ui/button_label_list.cc
deleted file mode 100644
index 34d78130..0000000
--- a/chrome/browser/ash/arc/input_overlay/ui/button_label_list.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ash/arc/input_overlay/ui/button_label_list.h"
-
-#include "ash/bubble/bubble_utils.h"
-#include "ash/strings/grit/ash_strings.h"
-#include "ash/style/icon_button.h"
-#include "ash/style/radio_button_group.h"
-#include "ash/style/rounded_container.h"
-#include "chrome/app/vector_icons/vector_icons.h"
-#include "chrome/browser/ash/arc/input_overlay/actions/action.h"
-#include "chrome/browser/ash/arc/input_overlay/display_overlay_controller.h"
-#include "chrome/browser/ash/arc/input_overlay/ui/action_view.h"
-#include "chrome/browser/ash/arc/input_overlay/ui/ui_utils.h"
-#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
-#include "ui/views/layout/box_layout.h"
-#include "ui/views/layout/table_layout.h"
-#include "ui/views/view_class_properties.h"
-
-namespace arc::input_overlay {
-
-namespace {
-
-constexpr int kMenuWidth = 316;
-
-}  // namespace
-
-ButtonLabelList::ButtonLabelList(
-    DisplayOverlayController* display_overlay_controller,
-    Action* action)
-    : display_overlay_controller_(display_overlay_controller), action_(action) {
-  Init();
-}
-
-ButtonLabelList::~ButtonLabelList() = default;
-
-void ButtonLabelList::Init() {
-  SetLayoutManager(std::make_unique<views::BoxLayout>(
-      views::BoxLayout::Orientation::kVertical));
-  AddHeader();
-  AddActionLabels();
-}
-
-void ButtonLabelList::AddHeader() {
-  auto* container = AddChildView(std::make_unique<views::View>());
-  container->SetLayoutManager(std::make_unique<views::TableLayout>())
-      ->AddColumn(views::LayoutAlignment::kStart,
-                  views::LayoutAlignment::kCenter,
-                  /*horizontal_resize=*/1.0f,
-                  views::TableLayout::ColumnSize::kUsePreferred,
-                  /*fixed_width=*/0, /*min_width=*/0)
-      .AddColumn(views::LayoutAlignment::kCenter,
-                 views::LayoutAlignment::kCenter,
-                 /*horizontal_resize=*/2.0f,
-                 views::TableLayout::ColumnSize::kUsePreferred,
-                 /*fixed_width=*/0, /*min_width=*/0)
-      .AddColumn(views::LayoutAlignment::kEnd, views::LayoutAlignment::kCenter,
-                 /*horizontal_resize=*/1.0f,
-                 views::TableLayout::ColumnSize::kUsePreferred,
-                 /*fixed_width=*/0, /*min_width=*/0)
-      .AddRows(1, views::TableLayout::kFixedSize, 0);
-  container->SetProperty(views::kMarginsKey, gfx::Insets::TLBR(0, 0, 16, 0));
-
-  container->AddChildView(std::make_unique<ash::IconButton>(
-      base::BindRepeating(&ButtonLabelList::OnBackButtonPressed,
-                          base::Unretained(this)),
-      ash::IconButton::Type::kMedium, &kBackArrowTouchIcon,
-      IDS_APP_LIST_FOLDER_NAME_PLACEHOLDER));
-
-  container->AddChildView(ash::bubble_utils::CreateLabel(
-      // TODO(b/274690042): Replace placeholder text with localized strings.
-      ash::TypographyToken::kCrosTitle1, u"Action list",
-      cros_tokens::kCrosSysOnSurface));
-}
-
-void ButtonLabelList::AddActionLabels() {
-  // "container" uses the default background color of "ash::RoundedContainer".
-  auto* container = AddChildView(std::make_unique<ash::RoundedContainer>());
-  container->SetLayoutManager(std::make_unique<views::BoxLayout>(
-      views::BoxLayout::Orientation::kVertical));
-
-  button_group_ =
-      container->AddChildView(std::make_unique<ash::RadioButtonGroup>(
-          /*group_width=*/kMenuWidth - 32,
-          /*insider_border_insets=*/gfx::Insets::VH(8, 8),
-          /*between_child_spacing=*/0,
-          /*icon_direction=*/ash::RadioButton::IconDirection::kFollowing,
-          /*icon_type=*/ash::RadioButton::IconType::kCheck,
-          /*radio_button_padding=*/gfx::Insets::VH(10, 10),
-          /*radio_button_image_label_padding=*/
-          ash::RadioButton::kImageLabelSpacingDP));
-
-  const auto& action_name_list =
-      display_overlay_controller_->action_name_list();
-  for (size_t index = 0; index < action_name_list.size(); index++) {
-    const auto& action_name = action_name_list[index];
-    auto* button = button_group_->AddButton(
-        base::BindRepeating(&ButtonLabelList::OnActionLabelPressed,
-                            base::Unretained(this)),
-        action_name);
-
-    if (action_->name_label_index() == static_cast<int>(index)) {
-      button->SetSelected(true);
-    }
-  }
-}
-
-void ButtonLabelList::OnActionLabelPressed() {
-  auto* selected_button = button_group_->GetSelectedButtons()[0];
-  auto action_name = selected_button->GetText();
-  int index = GetIndexOfActionName(
-      display_overlay_controller_->action_name_list(), action_name);
-  DCHECK(index >= 0);
-  display_overlay_controller_->ChangeActionName(action_, index);
-  OnBackButtonPressed();
-}
-
-void ButtonLabelList::OnBackButtonPressed() {
-  display_overlay_controller_->OnButtonLabelListBackButtonPressed();
-}
-
-}  // namespace arc::input_overlay
diff --git a/chrome/browser/ash/arc/input_overlay/ui/button_label_list.h b/chrome/browser/ash/arc/input_overlay/ui/button_label_list.h
deleted file mode 100644
index 583ce76..0000000
--- a/chrome/browser/ash/arc/input_overlay/ui/button_label_list.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_UI_BUTTON_LABEL_LIST_H_
-#define CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_UI_BUTTON_LABEL_LIST_H_
-
-#include "base/memory/raw_ptr.h"
-#include "chrome/browser/ash/arc/input_overlay/ui/arrow_container.h"
-
-namespace ash {
-class RadioButtonGroup;
-}  // namespace ash
-
-namespace arc::input_overlay {
-
-class Action;
-class DisplayOverlayController;
-
-// ButtonLabelList displays a list of action names that can be assigned to the
-// current action.
-//
-// View looks like this:
-// +----------------------------------+
-// ||icon|  |"Action List"|           |
-// |----------------------------------|
-// ||<Action string>|                 |
-// |----------------------------------|
-// ||<Action string>|                 |
-// |----------------------------------|
-// | ...                              |
-// |----------------------------------|
-// ||<Action string>|                 |
-// +----------------------------------+
-class ButtonLabelList : public ArrowContainer {
- public:
-  ButtonLabelList(DisplayOverlayController* display_overlay_controller,
-                  Action* action);
-  ButtonLabelList(const ButtonLabelList&) = delete;
-  ButtonLabelList& operator=(const ButtonLabelList&) = delete;
-  ~ButtonLabelList() override;
-
- private:
-  // Build related views.
-  void Init();
-  void AddHeader();
-  void AddActionLabels();
-
-  // Handle button functions.
-  void OnActionLabelPressed();
-  void OnBackButtonPressed();
-
-  // DisplayOverlayController owns this class, no need to deallocate.
-  const raw_ptr<DisplayOverlayController> display_overlay_controller_ = nullptr;
-  raw_ptr<Action> action_ = nullptr;
-  raw_ptr<ash::RadioButtonGroup> button_group_ = nullptr;
-};
-
-}  // namespace arc::input_overlay
-
-#endif  // CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_UI_BUTTON_LABEL_LIST_H_
diff --git a/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.cc b/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.cc
index bfc50844..1533e681 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.cc
@@ -34,72 +34,6 @@
 
 namespace arc::input_overlay {
 
-// `ActionLabelButton` is the entry point to `ButtonActionLabel`.
-// ------------------------------
-// ||"Button label"           > |
-// ||"Unassigned"               |
-//  -----------------------------
-class ButtonOptionsMenu::ActionLabelButton : public views::Button {
- public:
-  ActionLabelButton(DisplayOverlayController* controller, Action* action)
-      : Button(base::BindRepeating(
-            &ActionLabelButton::OnButtonLabelAssignmentPressed,
-            base::Unretained(this))),
-        controller_(controller),
-        action_(action) {
-    Init();
-  }
-
-  void SetSubtitle(std::u16string subtitle) {
-    label_name_tag_->SetSubtitle(subtitle);
-  }
-
-  void set_action(Action* action) { action_ = action; }
-
- private:
-  void Init() {
-    // TODO(b/279117180): Replace with proper accessible name.
-    SetAccessibleName(
-        l10n_util::GetStringUTF16(IDS_APP_LIST_FOLDER_NAME_PLACEHOLDER));
-    SetUseDefaultFillLayout(true);
-    auto* container = AddChildView(std::make_unique<ash::RoundedContainer>());
-    container->SetBorderInsets(gfx::Insets::VH(14, 16));
-    container->SetBackground(
-        views::CreateThemedSolidBackground(cros_tokens::kCrosSysSystemOnBase));
-    container->SetLayoutManager(std::make_unique<views::TableLayout>())
-        ->AddColumn(/*h_align=*/views::LayoutAlignment::kStart,
-                    /*v_align=*/views::LayoutAlignment::kCenter,
-                    /*horizontal_resize=*/1.0f,
-                    /*size_type=*/views::TableLayout::ColumnSize::kUsePreferred,
-                    /*fixed_width=*/0, /*min_width=*/0)
-        .AddColumn(/*h_align=*/views::LayoutAlignment::kEnd,
-                   /*v_align=*/views::LayoutAlignment::kCenter,
-                   /*horizontal_resize=*/1.0f,
-                   /*size_type=*/views::TableLayout::ColumnSize::kUsePreferred,
-                   /*fixed_width=*/0, /*min_width=*/0)
-        .AddRows(1, /*vertical_resize=*/views::TableLayout::kFixedSize);
-
-    // TODO(b/274690042): Replace placeholder text with localized strings.
-    label_name_tag_ =
-        container->AddChildView(NameTag::CreateNameTag(u"Button label"));
-    label_name_tag_->SetSubtitle(GetActionNameAtIndex(
-        controller_->action_name_list(), action_->name_label_index()));
-    label_name_tag_->SetState(/*is_error=*/false, u"");
-    container->AddChildView(std::make_unique<views::ImageView>(
-        ui::ImageModel::FromVectorIcon(ash::kQuickSettingsRightArrowIcon,
-                                       cros_tokens::kCrosSysOnSurface)));
-  }
-
-  void OnButtonLabelAssignmentPressed() {
-    controller_->OnButtonOptionsMenuButtonLabelPressed(action_);
-  }
-
-  raw_ptr<DisplayOverlayController> controller_ = nullptr;
-  raw_ptr<Action, DanglingUntriaged> action_ = nullptr;
-
-  raw_ptr<NameTag> label_name_tag_ = nullptr;
-};
-
 // ButtonOptionsActionEdit shows in ButtonOptions and is associated with each
 // of Action.
 // ----------------------------
@@ -155,10 +89,6 @@
   AddEditTitle();
   AddActionSelection();
   AddActionEdit();
-  action_label_button_ =
-      AddChildView(std::make_unique<ActionLabelButton>(controller_, action_));
-  action_label_button_->SetProperty(views::kMarginsKey,
-                                    gfx::Insets::TLBR(8, 0, 0, 0));
 }
 
 void ButtonOptionsMenu::AddHeader() {
@@ -255,10 +185,6 @@
   controller_->RemoveButtonOptionsMenuWidget();
 }
 
-void ButtonOptionsMenu::OnButtonLabelAssignmentPressed() {
-  controller_->OnButtonOptionsMenuButtonLabelPressed(action_);
-}
-
 void ButtonOptionsMenu::OnActionRemoved(const Action& action) {
   if (action_ != &action) {
     return;
@@ -271,7 +197,6 @@
   DCHECK_EQ(action_, action);
   action_ = new_action;
   button_group_->set_action(new_action);
-  action_label_button_->set_action(new_action);
   auto index = GetIndexOf(action_edit_);
   RemoveChildViewT(action_edit_);
   action_edit_ = AddChildViewAt(
@@ -286,10 +211,7 @@
 }
 
 void ButtonOptionsMenu::OnActionNameUpdated(const Action& action) {
-  if (action_ == &action) {
-    action_label_button_->SetSubtitle(GetActionNameAtIndex(
-        controller_->action_name_list(), action_->name_label_index()));
-  }
+  NOTIMPLEMENTED();
 }
 
 void ButtonOptionsMenu::OnActionNewStateRemoved(const Action& action) {
diff --git a/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.h b/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.h
index 83549f36..069d9ce 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.h
+++ b/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.h
@@ -57,8 +57,6 @@
   friend class EditLabelTest;
   friend class EditingListTest;
 
-  class ActionLabelButton;
-
   void Init();
 
   // Add UI components.
@@ -86,7 +84,6 @@
   raw_ptr<ash::IconButton> done_button_ = nullptr;
   raw_ptr<ActionTypeButtonGroup> button_group_ = nullptr;
   raw_ptr<ActionEditView, DisableDanglingPtrDetection> action_edit_ = nullptr;
-  raw_ptr<ActionLabelButton> action_label_button_ = nullptr;
 };
 
 }  // namespace arc::input_overlay
diff --git a/chrome/browser/ash/arc/input_overlay/ui/edit_labels.cc b/chrome/browser/ash/arc/input_overlay/ui/edit_labels.cc
index 81541b5..76480a6 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/edit_labels.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/edit_labels.cc
@@ -66,8 +66,7 @@
 }
 
 void EditLabels::UpdateNameTagTitle() {
-  name_tag_->SetTitle(GetActionNameAtIndex(controller_->action_name_list(),
-                                           action_->name_label_index()));
+  NOTIMPLEMENTED();
 }
 
 void EditLabels::SetNameTagState(bool is_error,
diff --git a/chrome/browser/ash/arc/input_overlay/ui/ui_utils.cc b/chrome/browser/ash/arc/input_overlay/ui/ui_utils.cc
index addefaf..4f4201c 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/ui_utils.cc
+++ b/chrome/browser/ash/arc/input_overlay/ui/ui_utils.cc
@@ -133,22 +133,6 @@
   }
 }
 
-int GetIndexOfActionName(const std::vector<std::u16string>& action_names,
-                         const std::u16string& action_name) {
-  auto it = std::find(action_names.begin(), action_names.end(), action_name);
-  return it == action_names.end() ? -1 : it - action_names.begin();
-}
-
-std::u16string GetActionNameAtIndex(
-    const std::vector<std::u16string>& action_names,
-    int index) {
-  if (index < 0 || index >= static_cast<int>(action_names.size())) {
-    // TODO(b/274690042): Replace placeholder text with localized strings.
-    return u"Unassigned";
-  }
-  return action_names[index];
-}
-
 gfx::Rect CalculateAvailableBounds(aura::Window* root_window) {
   DCHECK(root_window->IsRootWindow());
 
diff --git a/chrome/browser/ash/arc/input_overlay/ui/ui_utils.h b/chrome/browser/ash/arc/input_overlay/ui/ui_utils.h
index 54a910c9..01aac729 100644
--- a/chrome/browser/ash/arc/input_overlay/ui/ui_utils.h
+++ b/chrome/browser/ash/arc/input_overlay/ui/ui_utils.h
@@ -26,17 +26,6 @@
 // Sometimes, `text` is a symbol.
 std::u16string GetDisplayTextAccessibleName(const std::u16string& text);
 
-// Returns the index of `action_name` within `action_names`, and returns the
-// length of the array on failure.
-int GetIndexOfActionName(const std::vector<std::u16string>& action_names,
-                         const std::u16string& action_name);
-
-// Returns the action name at the `index` of `action_names`, and "Unassigned" on
-// failure.
-std::u16string GetActionNameAtIndex(
-    const std::vector<std::u16string>& action_names,
-    int index);
-
 // Returns bounds of `root_window` excluding the shelf if the shelf is visible.
 gfx::Rect CalculateAvailableBounds(aura::Window* root_window);
 
diff --git a/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper.cc b/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper.cc
index a0d0e24..e923ba1 100644
--- a/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper.cc
+++ b/chrome/browser/ash/child_accounts/time_limits/app_service_wrapper.cc
@@ -11,7 +11,6 @@
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/unguessable_token.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/app_service/launch_utils.h"
@@ -21,6 +20,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/app_update.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "components/services/app_service/public/cpp/instance_update.h"
 #include "components/services/app_service/public/cpp/types_util.h"
 #include "extensions/browser/extension_registry.h"
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc
index 018fefe..80820c4d 100644
--- a/chrome/browser/ash/crosapi/browser_util.cc
+++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -54,6 +54,7 @@
 namespace {
 
 bool g_profile_migration_completed_for_test = false;
+absl::optional<bool> g_cpu_override_for_test = absl::nullopt;
 
 // At session start the value for LacrosAvailability logic is applied and the
 // result is stored in this variable which is used after that as a cache.
@@ -186,11 +187,27 @@
          !cmdline->HasSwitch(ash::switches::kDisableDisallowLacros);
 }
 
+// Return true if the CPU of this system is capable to run Lacros.
+bool IsCPUSupported() {
+  if (g_cpu_override_for_test.has_value()) {
+    return g_cpu_override_for_test.value();
+  }
+#ifdef ARCH_CPU_X86_64
+  // Some very old Flex devices are not capable to support the -v2 instruction
+  // set. Those CPU's should not use Lacros as Lacros has only one binary
+  // for all intel platforms. As 'x86-64-v2' does not work on the build server,
+  // we check against SSE4.2 here which should be as as good.
+  return __builtin_cpu_supports("sse4.2");
+#else
+  return true;
+#endif
+}
+
 // Returns whether or not lacros is allowed for the Primary user,
 // with given LacrosAvailability policy.
 bool IsLacrosAllowedInternal(const User* user,
                              LacrosAvailability lacros_availability) {
-  if (IsLacrosDisallowedByCommand()) {
+  if (IsLacrosDisallowedByCommand() || !IsCPUSupported()) {
     // This happens when Ash is restarted in multi-user session, meaning there
     // are more than two users logged in to the device. This will not cause an
     // accidental removal of Lacros data because for the primary user, the fact
@@ -1092,4 +1109,8 @@
          base::FeatureList::IsEnabled(ash::features::kAllowDevtoolsInSystemUI);
 }
 
+void SetCpuAvailabilityForTesting(absl::optional<bool> value) {
+  g_cpu_override_for_test = value;
+}
+
 }  // namespace crosapi::browser_util
diff --git a/chrome/browser/ash/crosapi/browser_util.h b/chrome/browser/ash/crosapi/browser_util.h
index 7c9aa1b..7f630908 100644
--- a/chrome/browser/ash/crosapi/browser_util.h
+++ b/chrome/browser/ash/crosapi/browser_util.h
@@ -344,6 +344,10 @@
 void SetCachedLacrosAvailabilityForTesting(
     ash::standalone_browser::LacrosAvailability lacros_availability);
 
+// Exposed for testing. When |value| is given, the CPU availability gets
+// overridden with the value.
+void SetCpuAvailabilityForTesting(absl::optional<bool> value);
+
 // Exposed for testing. Returns the lacros integration suggested by the policy
 // lacros-availability, modified by Finch flags and user flags as appropriate.
 ash::standalone_browser::LacrosAvailability
diff --git a/chrome/browser/ash/crosapi/browser_util_unittest.cc b/chrome/browser/ash/crosapi/browser_util_unittest.cc
index 4ecc1bb8..f91135a7 100644
--- a/chrome/browser/ash/crosapi/browser_util_unittest.cc
+++ b/chrome/browser/ash/crosapi/browser_util_unittest.cc
@@ -118,6 +118,7 @@
   void TearDown() override {
     ash::system::StatisticsProvider::SetTestProvider(nullptr);
     fake_user_manager_.Reset();
+    browser_util::SetCpuAvailabilityForTesting(absl::nullopt);
   }
 
   void AddRegularUser(const std::string& email) {
@@ -391,6 +392,19 @@
   EXPECT_EQ(browser_util::LacrosMode::kOnly, browser_util::GetLacrosMode());
 }
 
+TEST_F(BrowserUtilTest, LacrosDisabledForOldHardware) {
+  AddRegularUser("user@test.com");
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures({ash::features::kLacrosOnly}, {});
+  EXPECT_TRUE(browser_util::IsLacrosEnabled());
+  EXPECT_EQ(browser_util::LacrosMode::kOnly, browser_util::GetLacrosMode());
+
+  browser_util::SetCpuAvailabilityForTesting(false);
+  EXPECT_EQ(browser_util::LacrosMode::kDisabled, browser_util::GetLacrosMode());
+  browser_util::SetCpuAvailabilityForTesting(true);
+  EXPECT_EQ(browser_util::LacrosMode::kOnly, browser_util::GetLacrosMode());
+}
+
 TEST_F(BrowserUtilTest, LacrosOnlyBrowserAllowed) {
   AddRegularUser("user@test.com");
   EXPECT_TRUE(browser_util::IsLacrosOnlyBrowserAllowed());
diff --git a/chrome/browser/ash/crosapi/crosapi_util.cc b/chrome/browser/ash/crosapi/crosapi_util.cc
index 4f70f12..ccfba40 100644
--- a/chrome/browser/ash/crosapi/crosapi_util.cc
+++ b/chrome/browser/ash/crosapi/crosapi_util.cc
@@ -677,6 +677,9 @@
 
   params->is_app_install_service_uri_enabled =
       chromeos::features::IsAppInstallServiceUriEnabled();
+
+  params->is_desk_profiles_enabled =
+      chromeos::features::IsDeskProfilesEnabled();
 }
 
 template <typename BrowserParams>
diff --git a/chrome/browser/ash/display/refresh_rate_controller_unittest.cc b/chrome/browser/ash/display/refresh_rate_controller_unittest.cc
index 2a1d9b9..c17d51b 100644
--- a/chrome/browser/ash/display/refresh_rate_controller_unittest.cc
+++ b/chrome/browser/ash/display/refresh_rate_controller_unittest.cc
@@ -92,8 +92,8 @@
   }
 
   void TearDown() override {
-    game_mode_controller_.reset();
     controller_.reset();
+    game_mode_controller_.reset();
     AshTestBase::TearDown();
   }
 
diff --git a/chrome/browser/ash/eol_notification.cc b/chrome/browser/ash/eol_notification.cc
index 866911c..9b9029e 100644
--- a/chrome/browser/ash/eol_notification.cc
+++ b/chrome/browser/ash/eol_notification.cc
@@ -272,9 +272,9 @@
   } else {
     switch (*button_index) {
       case BUTTON_MORE_INFO: {
-        const GURL url = dismiss_pref_ == prefs::kEolNotificationDismissed
-                             ? GURL(chrome::kEolNotificationURL)
-                             : GURL(chrome::kAutoUpdatePolicyURL);
+        const GURL url(dismiss_pref_ == prefs::kEolNotificationDismissed
+                           ? chrome::kEolNotificationURL
+                           : chrome::kAutoUpdatePolicyURL);
         // Show eol link.
         NewWindowDelegate::GetPrimary()->OpenUrl(
             url, NewWindowDelegate::OpenUrlFrom::kUserInteraction,
diff --git a/chrome/browser/ash/events/event_rewriter_unittest.cc b/chrome/browser/ash/events/event_rewriter_unittest.cc
index 8f463ef..dfeb629 100644
--- a/chrome/browser/ash/events/event_rewriter_unittest.cc
+++ b/chrome/browser/ash/events/event_rewriter_unittest.cc
@@ -221,6 +221,9 @@
     input_device_settings_controller_mock_ =
         std::make_unique<MockInputDeviceSettingsController>();
     keyboard_settings = mojom::KeyboardSettings::New();
+    // Disable F11/F12 settings by default.
+    keyboard_settings->f11 = ui::mojom::ExtendedFkeysModifier::kDisabled;
+    keyboard_settings->f12 = ui::mojom::ExtendedFkeysModifier::kDisabled;
     EXPECT_CALL(*input_device_settings_controller_mock_,
                 GetKeyboardSettings(testing::_))
         .WillRepeatedly(testing::Return(keyboard_settings.get()));
@@ -2578,7 +2581,6 @@
 
 TEST_F(EventRewriterTest, TestRewriteFunctionKeysCustomLayoutsFKeyUnchanged) {
   Preferences::RegisterProfilePrefs(prefs()->registry());
-
   // On devices with custom layouts, the F-Keys are never remapped.
   TestChromeCustomLayoutKeyboardVariants({
       // F1-> F1
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest.cc b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
index 1b9f9532..b2266d7 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
@@ -792,8 +792,7 @@
         TestCase("dirCreateWithKeyboard").NewDirectoryTree(),
         TestCase("dirCreateWithoutChangingCurrent").NewDirectoryTree(),
         TestCase("dirContextMenuZip").NewDirectoryTree(),
-        // TODO(b/305121828): support eject button for zip archive mount.
-        // TestCase("dirContextMenuZipEject").NewDirectoryTree(),
+        TestCase("dirContextMenuZipEject").NewDirectoryTree(),
         TestCase("dirContextMenuRecent").NewDirectoryTree(),
         TestCase("dirContextMenuMyFiles").NewDirectoryTree(),
         TestCase("dirContextMenuMyFilesWithPaste").NewDirectoryTree(),
@@ -1564,6 +1563,7 @@
         TestCase("searchImageByContent")
             .EnableLocalImageSearch()
             .EnableSearchV2(),
+        TestCase("changingDirectoryClosesSearch").EnableSearchV2(),
         TestCase("searchQueryLaunchParam")));
 
 WRAPPED_INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/ash/login/oobe_metrics_helper.cc b/chrome/browser/ash/login/oobe_metrics_helper.cc
index 0547b567..ad876b2 100644
--- a/chrome/browser/ash/login/oobe_metrics_helper.cc
+++ b/chrome/browser/ash/login/oobe_metrics_helper.cc
@@ -129,9 +129,13 @@
 
 OobeMetricsHelper::~OobeMetricsHelper() = default;
 
-void OobeMetricsHelper::OnScreenShownStatusDetermined(
-    OobeScreenId screen,
-    ScreenShownStatus status) {
+void OobeMetricsHelper::RecordScreenShownStatus(OobeScreenId screen,
+                                                ScreenShownStatus status) {
+  // Notify registered observers.
+  for (auto& observer : observers_) {
+    observer.OnScreenShownStatusChanged(screen, status);
+  }
+
   if (status == ScreenShownStatus::kShown) {
     screen_show_times_[screen] = base::TimeTicks::Now();
   }
@@ -155,8 +159,13 @@
   base::UmaHistogramEnumeration(histogram_name, status);
 }
 
-void OobeMetricsHelper::OnScreenExited(OobeScreenId screen,
-                                       const std::string& exit_reason) {
+void OobeMetricsHelper::RecordScreenExit(OobeScreenId screen,
+                                         const std::string& exit_reason) {
+  // Notify registered observers.
+  for (auto& observer : observers_) {
+    observer.OnScreenExited(screen, exit_reason);
+  }
+
   // Legacy histogram, requires old screen names.
   std::string legacy_screen_name = GetUmaLegacyScreenName(screen);
   std::string histogram_name =
@@ -190,13 +199,23 @@
                                 base::Milliseconds(10), base::Minutes(10), 100);
 }
 
-void OobeMetricsHelper::OnPreLoginOobeFirstStart() {
+void OobeMetricsHelper::RecordPreLoginOobeFirstStart() {
+  // Notify registered observers.
+  for (auto& observer : observers_) {
+    observer.OnPreLoginOobeFirstStarted();
+  }
+
   // Record `False` to report the `Started` bucket.
   base::UmaHistogramBoolean(kUmaOobeFlowStatus, false);
 }
 
-void OobeMetricsHelper::OnPreLoginOobeCompleted(
+void OobeMetricsHelper::RecordPreLoginOobeComplete(
     CompletedPreLoginOobeFlowType flow_type) {
+  // Notify registered observers.
+  for (auto& observer : observers_) {
+    observer.OnPreLoginOobeCompleted(flow_type);
+  }
+
   base::TimeTicks startup_time =
       startup_metric_utils::GetCommon().MainEntryPointTicks();
   if (startup_time.is_null()) {
@@ -221,8 +240,12 @@
                                 base::Minutes(10), 100);
 }
 
-void OobeMetricsHelper::OnOnboardingFlowStarted(base::Time oobe_start_time) {
-  std::string onboarding_type;
+void OobeMetricsHelper::RecordOnboardingStart(base::Time oobe_start_time) {
+  // Notify registered observers.
+  for (auto& observer : observers_) {
+    observer.OnOnboardingStarted();
+  }
+
   if (!oobe_start_time.is_null()) {
     base::UmaHistogramCustomTimes(
         kUmaOobeStartToOnboardingStart, base::Time::Now() - oobe_start_time,
@@ -234,9 +257,13 @@
       kUmaOnboardingFlowStatus + GetOnboardingTypeSuffix(), false);
 }
 
-void OobeMetricsHelper::OnOnboadingFlowCompleted(
+void OobeMetricsHelper::RecordOnboadingComplete(
     base::Time oobe_start_time,
     base::Time onboarding_start_time) {
+  for (auto& observer : observers_) {
+    observer.OnOnboadingCompleted();
+  }
+
   if (!oobe_start_time.is_null()) {
     // Record `True` to report the `Completed` bucket.
     base::UmaHistogramBoolean(kUmaOobeFlowStatus, true);
@@ -256,7 +283,7 @@
   }
 }
 
-void OobeMetricsHelper::OnEnrollmentScreenShown() {
+void OobeMetricsHelper::RecordEnrollingUserType() {
   bool is_consumer = g_browser_process->local_state()->GetBoolean(
       prefs::kOobeIsConsumerSegment);
   base::UmaHistogramBoolean("OOBE.Enrollment.IsUserEnrollingAConsumer",
@@ -268,4 +295,12 @@
                            version_info::GetMajorVersionNumberAsInt());
 }
 
+void OobeMetricsHelper::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void OobeMetricsHelper::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
 }  // namespace ash
diff --git a/chrome/browser/ash/login/oobe_metrics_helper.h b/chrome/browser/ash/login/oobe_metrics_helper.h
index 9e8917d..ce6ee79 100644
--- a/chrome/browser/ash/login/oobe_metrics_helper.h
+++ b/chrome/browser/ash/login/oobe_metrics_helper.h
@@ -7,6 +7,8 @@
 
 #include <map>
 
+#include "base/observer_list.h"
+#include "base/observer_list_types.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/login/oobe_screen.h"
 
@@ -28,6 +30,36 @@
     kRegular = 2
   };
 
+  // Observer that is notified on certain OOBE recording events.
+  class Observer : public base::CheckedObserver {
+   public:
+    Observer() = default;
+    Observer(const Observer&) = delete;
+    Observer& operator=(const Observer&) = delete;
+    ~Observer() override = default;
+
+    // Invoked when `screen shown status` metrics are being reported.
+    virtual void OnScreenShownStatusChanged(OobeScreenId screen,
+                                            ScreenShownStatus status) {}
+
+    // Invoked when `screen exit` metrics are being reported.
+    virtual void OnScreenExited(OobeScreenId screen,
+                                const std::string& exit_reason) {}
+
+    // Invoked when `pre login OOBE flow start` metrics are being reported.
+    virtual void OnPreLoginOobeFirstStarted() {}
+
+    // Invoked when `pre login OOBE flow complete` metrics are being reported.
+    virtual void OnPreLoginOobeCompleted(
+        CompletedPreLoginOobeFlowType flow_type) {}
+
+    // Invoked when `onboarding flow start` metrics are being reported.
+    virtual void OnOnboardingStarted() {}
+
+    // Invoked when `onboarding complete` metrics are being reported.
+    virtual void OnOnboadingCompleted() {}
+  };
+
   OobeMetricsHelper();
   ~OobeMetricsHelper();
   OobeMetricsHelper(const OobeMetricsHelper& other) = delete;
@@ -35,38 +67,41 @@
 
   // Called when the status of a screen during the flow is determined,
   // shown/skipped.
-  void OnScreenShownStatusDetermined(OobeScreenId screen,
-                                     ScreenShownStatus status);
+  void RecordScreenShownStatus(OobeScreenId screen, ScreenShownStatus status);
 
   // Called when the screen is exited, this should be preceded by a call to
   // `OnScreenShownStatusDetermined()`.
-  void OnScreenExited(OobeScreenId screen, const std::string& exit_reason);
+  void RecordScreenExit(OobeScreenId screen, const std::string& exit_reason);
 
   // Called the first time pre-login OOBE has started. This method will not be
   // called again if the device restarts into the pre-login flow.
-  void OnPreLoginOobeFirstStart();
+  void RecordPreLoginOobeFirstStart();
 
   // Called upon marking pre-login OOBE as completed.
-  void OnPreLoginOobeCompleted(CompletedPreLoginOobeFlowType screen);
+  void RecordPreLoginOobeComplete(CompletedPreLoginOobeFlowType screen);
 
   // Called after the log-in of a new user is completed and before the showing
   // of the first onboarding screen. If this is the first onboarding after OOBE
   // completion, the start time of OOBE should be passed to the method,
   // otherwise, the NULL time should be passed.
-  void OnOnboardingFlowStarted(base::Time oobe_start_time);
+  void RecordOnboardingStart(base::Time oobe_start_time);
 
   // Called after the last screen of the onboarding flow is exited and before
   // the session starts.
   // A NULL time in either `oobe_start_time` or `onboarding_start_time` means
   // that the start time is not available.
-  void OnOnboadingFlowCompleted(base::Time oobe_start_time,
-                                base::Time onboarding_start_time);
+  void RecordOnboadingComplete(base::Time oobe_start_time,
+                               base::Time onboarding_start_time);
 
   // Called when `ShowEnrollmentScreen()` is called.
-  void OnEnrollmentScreenShown();
+  void RecordEnrollingUserType();
 
   void RecordChromeVersion();
 
+  void AddObserver(Observer* observer);
+
+  void RemoveObserver(Observer* observer);
+
  private:
   void RecordUpdatedStepShownStatus(OobeScreenId screen,
                                     ScreenShownStatus status);
@@ -75,6 +110,8 @@
 
   // Maps screen names to last time of their shows.
   std::map<OobeScreenId, base::TimeTicks> screen_show_times_;
+
+  base::ObserverList<Observer> observers_;
 };
 
 }  // namespace ash
diff --git a/chrome/browser/ash/login/ui/login_display_host_common.cc b/chrome/browser/ash/login/ui/login_display_host_common.cc
index 664dd3b..962142f 100644
--- a/chrome/browser/ash/login/ui/login_display_host_common.cc
+++ b/chrome/browser/ash/login/ui/login_display_host_common.cc
@@ -539,7 +539,7 @@
 }
 
 void LoginDisplayHostCommon::StartUserOnboarding() {
-  oobe_metrics_helper_->OnOnboardingFlowStarted(
+  oobe_metrics_helper_->RecordOnboardingStart(
       g_browser_process->local_state()->GetTime(prefs::kOobeStartTime));
   StartWizard(LocaleSwitchView::kScreenId);
 }
diff --git a/chrome/browser/ash/login/ui/login_display_host_webui.cc b/chrome/browser/ash/login/ui/login_display_host_webui.cc
index 0efa69d0..daff0246 100644
--- a/chrome/browser/ash/login/ui/login_display_host_webui.cc
+++ b/chrome/browser/ash/login/ui/login_display_host_webui.cc
@@ -536,7 +536,7 @@
     if (GetLocalState() &&
         GetLocalState()->GetTime(prefs::kOobeStartTime).is_null()) {
       GetLocalState()->SetTime(prefs::kOobeStartTime, base::Time::Now());
-      GetOobeMetricsHelper()->OnPreLoginOobeFirstStart();
+      GetOobeMetricsHelper()->RecordPreLoginOobeFirstStart();
     }
 
     CHECK(OobeConfiguration::Get());
diff --git a/chrome/browser/ash/login/wizard_controller.cc b/chrome/browser/ash/login/wizard_controller.cc
index 982c619..56467ff 100644
--- a/chrome/browser/ash/login/wizard_controller.cc
+++ b/chrome/browser/ash/login/wizard_controller.cc
@@ -1016,7 +1016,7 @@
 
 void WizardController::ShowEnrollmentScreen() {
   // Update the enrollment configuration and start the screen.
-  GetLoginDisplayHost()->GetOobeMetricsHelper()->OnEnrollmentScreenShown();
+  GetLoginDisplayHost()->GetOobeMetricsHelper()->RecordEnrollingUserType();
   prescribed_enrollment_config_ =
       policy::EnrollmentConfig::GetPrescribedEnrollmentConfig();
   StartEnrollmentScreen(false);
@@ -1777,8 +1777,8 @@
   }
   DCHECK(current_screen_->screen_id() == screen);
 
-  GetLoginDisplayHost()->GetOobeMetricsHelper()->OnScreenExited(screen,
-                                                                exit_reason);
+  GetLoginDisplayHost()->GetOobeMetricsHelper()->RecordScreenExit(screen,
+                                                                  exit_reason);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -2376,7 +2376,7 @@
     active_user_prefs->ClearPref(prefs::kChoobeCompletedScreens);
   }
 
-  GetLoginDisplayHost()->GetOobeMetricsHelper()->OnOnboadingFlowCompleted(
+  GetLoginDisplayHost()->GetOobeMetricsHelper()->RecordOnboadingComplete(
       GetLocalState()->GetTime(prefs::kOobeStartTime),
       active_user_prefs->GetTime(prefs::kOobeOnboardingTime));
 
@@ -2488,7 +2488,7 @@
   }
 
   StartupUtils::MarkOobeCompleted();
-  GetLoginDisplayHost()->GetOobeMetricsHelper()->OnPreLoginOobeCompleted(
+  GetLoginDisplayHost()->GetOobeMetricsHelper()->RecordPreLoginOobeComplete(
       flow_type);
 
   // Triggers DLC installation once OOBE is complete.
@@ -2510,11 +2510,9 @@
       }
     }
 
-    GetLoginDisplayHost()
-        ->GetOobeMetricsHelper()
-        ->OnScreenShownStatusDetermined(
-            new_current->screen_id(),
-            OobeMetricsHelper::ScreenShownStatus::kSkipped);
+    GetLoginDisplayHost()->GetOobeMetricsHelper()->RecordScreenShownStatus(
+        new_current->screen_id(),
+        OobeMetricsHelper::ScreenShownStatus::kSkipped);
     return;
   }
 
@@ -2560,7 +2558,7 @@
   }
 
   UpdateStatusAreaVisibilityForScreen(current_screen_->screen_id());
-  GetLoginDisplayHost()->GetOobeMetricsHelper()->OnScreenShownStatusDetermined(
+  GetLoginDisplayHost()->GetOobeMetricsHelper()->RecordScreenShownStatus(
       current_screen_->screen_id(),
       OobeMetricsHelper::ScreenShownStatus::kShown);
   current_screen_->Show(wizard_context_);
diff --git a/chrome/browser/ash/nearby/presence/credential_storage/nearby_presence_credential_storage.cc b/chrome/browser/ash/nearby/presence/credential_storage/nearby_presence_credential_storage.cc
index c272c5d..d678bb8d 100644
--- a/chrome/browser/ash/nearby/presence/credential_storage/nearby_presence_credential_storage.cc
+++ b/chrome/browser/ash/nearby/presence/credential_storage/nearby_presence_credential_storage.cc
@@ -164,6 +164,41 @@
   }
 }
 
+void NearbyPresenceCredentialStorage::GetPrivateCredentials(
+    GetPrivateCredentialsCallback callback) {
+  CHECK(callback);
+  private_db_->LoadEntries(base::BindOnce(
+      &NearbyPresenceCredentialStorage::OnPrivateCredentialsRetrieved,
+      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+}
+
+void NearbyPresenceCredentialStorage::OnPrivateCredentialsRetrieved(
+    GetPrivateCredentialsCallback callback,
+    bool success,
+    std::unique_ptr<std::vector<::nearby::internal::LocalCredential>> entries) {
+  CHECK(callback);
+
+  if (!success) {
+    // TODO(b/287334363): Emit a failure metric.
+    LOG(ERROR) << __func__ << ": failed to retrieve private credentials";
+    std::move(callback).Run(mojo_base::mojom::AbslStatusCode::kAborted,
+                            absl::nullopt);
+    return;
+  }
+
+  CHECK(entries);
+
+  std::vector<ash::nearby::presence::mojom::LocalCredentialPtr>
+      local_credentials_mojom;
+  for (const auto& entry : *entries) {
+    local_credentials_mojom.emplace_back(
+        ash::nearby::presence::proto::LocalCredentialToMojom(entry));
+  }
+
+  std::move(callback).Run(mojo_base::mojom::AbslStatusCode::kOk,
+                          std::move(local_credentials_mojom));
+}
+
 void NearbyPresenceCredentialStorage::OnPublicCredentialsRetrieved(
     GetPublicCredentialsCallback callback,
     bool success,
diff --git a/chrome/browser/ash/nearby/presence/credential_storage/nearby_presence_credential_storage.h b/chrome/browser/ash/nearby/presence/credential_storage/nearby_presence_credential_storage.h
index 8c0b393..ab509ff 100644
--- a/chrome/browser/ash/nearby/presence/credential_storage/nearby_presence_credential_storage.h
+++ b/chrome/browser/ash/nearby/presence/credential_storage/nearby_presence_credential_storage.h
@@ -42,7 +42,7 @@
   // credentials.
   void Initialize(base::OnceCallback<void(bool)> on_initialized);
 
-  // NearbyPresenceCredentialStorage:
+  // mojom::NearbyPresenceCredentialStorage:
   void SaveCredentials(
       std::vector<mojom::LocalCredentialPtr> local_credentials,
       std::vector<mojom::SharedCredentialPtr> shared_credentials,
@@ -50,6 +50,7 @@
       SaveCredentialsCallback on_credentials_fully_saved_callback) override;
   void GetPublicCredentials(mojom::PublicCredentialType public_credential_type,
                             GetPublicCredentialsCallback callback) override;
+  void GetPrivateCredentials(GetPrivateCredentialsCallback callback) override;
 
  protected:
   NearbyPresenceCredentialStorage(
@@ -63,6 +64,11 @@
           remote_public_db);
 
  private:
+  void OnPrivateCredentialsRetrieved(
+      GetPrivateCredentialsCallback callback,
+      bool success,
+      std::unique_ptr<std::vector<::nearby::internal::LocalCredential>>
+          entries);
   void OnPublicCredentialsRetrieved(
       GetPublicCredentialsCallback callback,
       bool success,
diff --git a/chrome/browser/ash/nearby/presence/credential_storage/nearby_presence_credential_storage_unittest.cc b/chrome/browser/ash/nearby/presence/credential_storage/nearby_presence_credential_storage_unittest.cc
index 09bf8b85..757d179 100644
--- a/chrome/browser/ash/nearby/presence/credential_storage/nearby_presence_credential_storage_unittest.cc
+++ b/chrome/browser/ash/nearby/presence/credential_storage/nearby_presence_credential_storage_unittest.cc
@@ -817,11 +817,77 @@
               EXPECT_FALSE(credentials.has_value());
               run_loop.Quit();
             }));
-
     remote_public_db_->LoadCallback(false);
 
     run_loop.Run();
   }
 }
 
+TEST_F(NearbyPresenceCredentialStorageTest, GetPrivateCredentials_Success) {
+  {
+    base::RunLoop run_loop;
+    FullyInitializeDatabases(run_loop);
+  }
+
+  {
+    base::RunLoop run_loop;
+    PrepopulateCredentials(run_loop,
+                           ash::nearby::presence::mojom::PublicCredentialType::
+                               kLocalPublicCredential);
+    run_loop.Run();
+  }
+
+  ASSERT_EQ(private_db_entries_.size(), 3u);
+
+  {
+    base::RunLoop run_loop;
+    credential_storage_->GetPrivateCredentials(base::BindLambdaForTesting(
+        [&run_loop](mojo_base::mojom::AbslStatusCode status,
+                    absl::optional<std::vector<mojom::LocalCredentialPtr>>
+                        credentials) {
+          EXPECT_EQ(status, mojo_base::mojom::AbslStatusCode::kOk);
+          EXPECT_TRUE(credentials.has_value());
+          EXPECT_EQ(credentials->size(), 3u);
+          run_loop.Quit();
+        }));
+    private_db_->LoadCallback(true);
+
+    run_loop.Run();
+  }
+}
+
+TEST_F(NearbyPresenceCredentialStorageTest, GetPrivateCredentials_Fail) {
+  {
+    base::RunLoop run_loop;
+    FullyInitializeDatabases(run_loop);
+    run_loop.Run();
+  }
+
+  {
+    base::RunLoop run_loop;
+    PrepopulateCredentials(run_loop,
+                           ash::nearby::presence::mojom::PublicCredentialType::
+                               kLocalPublicCredential);
+    run_loop.Run();
+  }
+
+  ASSERT_EQ(private_db_entries_.size(), 3u);
+
+  {
+    base::RunLoop run_loop;
+    credential_storage_->GetPrivateCredentials(base::BindLambdaForTesting(
+        [&run_loop](mojo_base::mojom::AbslStatusCode status,
+                    absl::optional<std::vector<mojom::LocalCredentialPtr>>
+                        credentials) {
+          EXPECT_EQ(status, mojo_base::mojom::AbslStatusCode::kAborted);
+          EXPECT_FALSE(credentials.has_value());
+          run_loop.Quit();
+        }));
+
+    private_db_->LoadCallback(false);
+
+    run_loop.Run();
+  }
+}
+
 }  // namespace ash::nearby::presence
diff --git a/chrome/browser/ash/night_light/night_light_client_impl_unittest.cc b/chrome/browser/ash/night_light/night_light_client_impl_unittest.cc
index 37de85b..5e9ecc4 100644
--- a/chrome/browser/ash/night_light/night_light_client_impl_unittest.cc
+++ b/chrome/browser/ash/night_light/night_light_client_impl_unittest.cc
@@ -54,7 +54,7 @@
     ++position_pushes_num_;
   }
 
-  bool GetEnabled() const override { return false; }
+  bool IsNightLightEnabled() const override { return false; }
 
   void NotifyScheduleTypeChanged(ScheduleType type) {
     for (auto& observer : observers_) {
diff --git a/chrome/browser/ash/policy/core/device_policy_decoder.cc b/chrome/browser/ash/policy/core/device_policy_decoder.cc
index 5ce14530..8543516 100644
--- a/chrome/browser/ash/policy/core/device_policy_decoder.cc
+++ b/chrome/browser/ash/policy/core/device_policy_decoder.cc
@@ -2335,17 +2335,6 @@
                     nullptr);
     }
   }
-
-  if (policy.has_device_flex_hw_data_for_product_improvement_enabled()) {
-    const em::DeviceFlexHwDataForProductImprovementEnabledProto& container(
-        policy.device_flex_hw_data_for_product_improvement_enabled());
-    if (container.has_enabled()) {
-      policies->Set(key::kDeviceFlexHwDataForProductImprovementEnabled,
-                    POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
-                    POLICY_SOURCE_CLOUD, base::Value(container.enabled()),
-                    nullptr);
-    }
-  }
 }
 
 }  // namespace
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/apps/app_usage_telemetry_sampler_browsertest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/apps/app_usage_telemetry_sampler_browsertest.cc
index c879012b..7c231a1b 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/apps/app_usage_telemetry_sampler_browsertest.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/apps/app_usage_telemetry_sampler_browsertest.cc
@@ -10,7 +10,6 @@
 
 #include "base/check.h"
 #include "base/functional/bind.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/time/time.h"
 #include "base/time/time_override.h"
 #include "chrome/browser/apps/app_service/metrics/app_platform_metrics.h"
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer_browsertest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer_browsertest.cc
index 801f4b3..80c6b50 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer_browsertest.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_events_observer_browsertest.cc
@@ -8,7 +8,6 @@
 
 #include "base/functional/bind.h"
 #include "base/run_loop.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/values.h"
 #include "chrome/browser/ash/login/test/cryptohome_mixin.h"
 #include "chrome/browser/ash/policy/affiliation/affiliation_mixin.h"
@@ -130,7 +129,6 @@
   ::policy::AffiliationMixin affiliation_mixin_{&mixin_host_, &test_helper_};
   ash::CryptohomeMixin crypto_home_mixin_{&mixin_host_};
   ash::ScopedTestingCrosSettings scoped_testing_cros_settings_;
-  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 IN_PROC_BROWSER_TEST_F(NetworkEventsBrowserTest,
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_unittest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_unittest.cc
index 00076928..6e0498e 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_unittest.cc
@@ -11,7 +11,6 @@
 #include "base/run_loop.h"
 #include "base/strings/strcat.h"
 #include "base/test/bind.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/values.h"
 #include "chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_manager.h"
@@ -180,8 +179,6 @@
   std::unique_ptr<user_manager::ScopedUserManager> scoped_user_manager_;
 
   ::ash::NetworkHandlerTestHelper network_handler_test_helper_;
-
-  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 TEST_F(NetworkTelemetrySamplerTest, CellularConnected) {
diff --git a/chrome/browser/ash/printing/cups_printers_manager.cc b/chrome/browser/ash/printing/cups_printers_manager.cc
index 7362181..39cd992 100644
--- a/chrome/browser/ash/printing/cups_printers_manager.cc
+++ b/chrome/browser/ash/printing/cups_printers_manager.cc
@@ -41,6 +41,7 @@
 #include "chrome/browser/ash/printing/zeroconf_printer_detector.h"
 #include "chrome/browser/ash/scanning/zeroconf_scanner_detector.h"
 #include "chrome/browser/ash/settings/cros_settings.h"
+#include "chrome/browser/printing/print_preview_sticky_settings.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
@@ -425,13 +426,25 @@
     OnPrinterStatusTimerElapsed();
   }
 
-  // Starts printer status requests for all Saved printers then queues the next
-  // round of requests if the overall timer hasn't elapsed.
+  // Starts printer status requests for all Saved and recently used printers
+  // then queues the next round of requests if the overall timer hasn't elapsed.
   void OnPrinterStatusTimerElapsed() {
-    const auto printers = printers_.Get(chromeos::PrinterClass::kSaved);
+    std::vector<std::string> recently_used_printers;
+    ::printing::PrintPreviewStickySettings* sticky_settings =
+        ::printing::PrintPreviewStickySettings::GetInstance();
+    if (sticky_settings) {
+      recently_used_printers = sticky_settings->GetRecentlyUsedPrinters();
+    }
+
+    const auto printers = printers_.Get();
     for (const auto& printer : printers) {
-      FetchPrinterStatus(printer.id(),
-                         /*PrinterStatusCallback=*/base::DoNothing());
+      // Query every printer that is either saved or recently used.
+      if (printers_.IsPrinterInClass(chromeos::PrinterClass::kSaved,
+                                     printer.id()) ||
+          base::Contains(recently_used_printers, printer.id())) {
+        FetchPrinterStatus(printer.id(),
+                           /*PrinterStatusCallback=*/base::DoNothing());
+      }
     }
 
     // Only restart requests when the 5 minute timer hasn't elapsed.
diff --git a/chrome/browser/ash/printing/cups_printers_manager_unittest.cc b/chrome/browser/ash/printing/cups_printers_manager_unittest.cc
index 8310fd4..6348844 100644
--- a/chrome/browser/ash/printing/cups_printers_manager_unittest.cc
+++ b/chrome/browser/ash/printing/cups_printers_manager_unittest.cc
@@ -33,6 +33,7 @@
 #include "chrome/browser/ash/printing/synced_printers_manager.h"
 #include "chrome/browser/ash/printing/usb_printer_detector.h"
 #include "chrome/browser/ash/printing/usb_printer_notification_controller.h"
+#include "chrome/browser/printing/print_preview_sticky_settings.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/testing_browser_process.h"
@@ -1248,17 +1249,32 @@
   feature_list_.InitAndEnableFeature(::features::kLocalPrinterObserving);
 
   // Add a saved printer to be queried for status.
-  synced_printers_manager_.AddSavedPrinters({Printer("Printer1")});
+  synced_printers_manager_.AddSavedPrinters({Printer("SavedPrinter")});
+  zeroconf_detector_->AddDetections({MakeDiscoveredPrinter("RecentPrinter"),
+                                     MakeDiscoveredPrinter("OldPrinter")});
   task_environment_.RunUntilIdle();
 
+  // Add `RecentPrinter` to the Print Preview sticky settings so it'll get
+  // polled for status. `OldPrinter` will not get queried.
+  ::printing::PrintPreviewStickySettings* sticky_settings =
+      ::printing::PrintPreviewStickySettings::GetInstance();
+  sticky_settings->StoreAppState(R"({
+    "recentDestinations": [
+      {
+        "id": "RecentPrinter"
+      }
+    ]
+  })");
+
   // Add the observer to capture the triggers from printer status queries.
   FakeLocalPrintersObserver observer;
   manager_->AddLocalPrintersObserver(&observer);
   task_environment_.FastForwardUntilNoTasksRemain();
 
-  // 1 call when observer added + 1 call from initial printer status query +
-  // 30 calls from polling (every 10 seconds for 5 minutes).
-  const size_t expected_obsever_calls = 32;
+  // 1 call when observer added + 2 calls for initial printer status queries to
+  // the Saved and Recent printer + 60 calls from polling both the Saved and
+  // Recent printer 30 times each (every 10 seconds for 5 minutes).
+  const size_t expected_obsever_calls = 63;
   EXPECT_EQ(expected_obsever_calls, observer.num_observer_calls());
 }
 
diff --git a/chrome/browser/ash/screenshot_integration_test.cc b/chrome/browser/ash/screenshot_integration_test.cc
index 62b6fab8..0b649a3 100644
--- a/chrome/browser/ash/screenshot_integration_test.cc
+++ b/chrome/browser/ash/screenshot_integration_test.cc
@@ -3,11 +3,14 @@
 // found in the LICENSE file.
 
 #include <string>
+#include <vector>
 
 #include "ash/shell.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/run_loop.h"
+#include "base/strings/string_split.h"
+#include "base/system/sys_info.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
@@ -28,26 +31,60 @@
 
 namespace {
 
+// Returns true if the board is known to support Vulkan compositing.
+bool BoardSupportsVulkanComposite() {
+  // The full board name may have the form "glimmer-signed-mp-v4keys" and we
+  // just want "glimmer".
+  std::vector<std::string> board =
+      base::SplitString(base::SysInfo::GetLsbReleaseBoard(), "-",
+                        base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+  if (board.empty()) {
+    LOG(ERROR) << "Unable to determine LSB release board";
+    return false;
+  }
+  // Vulkan compositing is only supported on a few boards, so use an allow
+  // list.
+  return board[0] == "brya" || board[0] == "volteer" || board[0] == "dedede";
+}
+
 class ScreenshotIntegrationTest : public MixinBasedInProcessBrowserTest,
                                   public testing::WithParamInterface<bool> {
  public:
   ScreenshotIntegrationTest() {
-    if (GetParam()) {
-      feature_list_.InitAndEnableFeature(features::kVulkan);
+    if (UseVulkan()) {
+      // Check for board support because enabling the ScopedFeatureList,
+      // otherwise GPU process initialization will crash before the test body.
+      if (BoardSupportsVulkanComposite()) {
+        feature_list_.InitAndEnableFeature(features::kVulkan);
+      } else {
+        skip_test_ = true;
+      }
     } else {
       feature_list_.InitAndDisableFeature(features::kVulkan);
     }
   }
 
- private:
+  bool UseVulkan() { return GetParam(); }
+
+  // MixinBasedInProcessBrowserTest:
+  void TearDownOnMainThread() override {
+    // Clean up even if the test was skipped.
+    browser()->window()->Close();
+  }
+
+ protected:
   base::test::ScopedFeatureList feature_list_;
+  bool skip_test_ = false;
   ChromeOSIntegrationTestMixin chromeos_integration_test_mixin_{&mixin_host_};
 };
 
 INSTANTIATE_TEST_SUITE_P(Vulkan, ScreenshotIntegrationTest, testing::Bool());
 
-// Flaky on chromeos-amd64-generic-rel, https://crbug.com/1492672
-IN_PROC_BROWSER_TEST_P(ScreenshotIntegrationTest, DISABLED_AverageColor) {
+IN_PROC_BROWSER_TEST_P(ScreenshotIntegrationTest, AverageColor) {
+  if (skip_test_) {
+    GTEST_SKIP();
+  }
+
   // Ensure the display is powered on, otherwise the screenshot will fail.
   base::RunLoop run_loop;
   ash::Shell::Get()->display_configurator()->SetDisplayPower(
@@ -71,7 +108,7 @@
   // screenshots in a loop until we get a valid one.
   SkColor dominant_color;
   bool success = false;
-  for (int i = 0; i < 5; ++i) {
+  for (int i = 0; i < 10; ++i) {
     // Sleep for 1 second.
     base::RunLoop run_loop2;
     base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
@@ -104,9 +141,6 @@
   }
   EXPECT_TRUE(success) << "Final screenshot had invalid dominant color "
                        << std::hex << dominant_color;
-
-  // Clean up.
-  browser()->window()->Close();
 }
 
 }  // namespace
diff --git a/chrome/browser/ash/settings/token_encryptor.cc b/chrome/browser/ash/settings/token_encryptor.cc
index d57da57..8348cb2 100644
--- a/chrome/browser/ash/settings/token_encryptor.cc
+++ b/chrome/browser/ash/settings/token_encryptor.cc
@@ -10,6 +10,7 @@
 #include <array>
 #include <vector>
 
+#include "base/check_is_test.h"
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
@@ -119,6 +120,9 @@
 
 std::string CryptohomeTokenEncryptor::WeakEncryptWithSystemSalt(
     const std::string& token) {
+  // Only tests should ever use this.
+  CHECK_IS_TEST();
+
   // Don't care about token encryption while debugging.
   if (!base::SysInfo::IsRunningOnChromeOS()) {
     return token;
diff --git a/chrome/browser/ash/settings/token_encryptor.h b/chrome/browser/ash/settings/token_encryptor.h
index 98ac562..0543f9f 100644
--- a/chrome/browser/ash/settings/token_encryptor.h
+++ b/chrome/browser/ash/settings/token_encryptor.h
@@ -31,9 +31,12 @@
   virtual std::string DecryptWithSystemSalt(
       std::string_view encrypted_token_hex) = 0;
 
-  // Old deprecated versions of the Encrypt and Decrypt functions. These
-  // functions are weaker because they do not use a proper counter with the
-  // encryptor and should not be used in any new code.
+  // Old deprecated versions of Encrypt and Decrypt. These functions are weak
+  // because they do not use a proper counter with the encryptor.
+  //
+  // The WeakEncrypt function will CHECK-fail if called in non-test code. No new
+  // code should ever use it, the function is only kept to enable testing of
+  // WeakDecrypt. The WeakDecrypt is available to allow code to read old tokens.
   virtual std::string WeakEncryptWithSystemSalt(const std::string& token) = 0;
   virtual std::string WeakDecryptWithSystemSalt(
       const std::string& encrypted_token_hex) = 0;
diff --git a/chrome/browser/autofill/autofill_captured_sites_interactive_uitest.cc b/chrome/browser/autofill/autofill_captured_sites_interactive_uitest.cc
index b1dc2c3..32f93bf4 100644
--- a/chrome/browser/autofill/autofill_captured_sites_interactive_uitest.cc
+++ b/chrome/browser/autofill/autofill_captured_sites_interactive_uitest.cc
@@ -57,6 +57,7 @@
 #include "net/dns/mock_host_resolver.h"
 #include "services/network/public/cpp/data_element.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
 
 using captured_sites_test_utils::CapturedSiteParams;
 using captured_sites_test_utils::GetCapturedSites;
@@ -333,7 +334,11 @@
     // prediction. Test will check this attribute on all the relevant input
     // elements in a form to determine if the form is ready for interaction.
     feature_list_.InitWithFeaturesAndParameters(
-        /*enabled_features=*/{{features::test::kAutofillServerCommunication,
+        /*enabled_features=*/{{blink::features::
+                                   kAutofillUseDomNodeIdForRendererId,
+                               {}},
+                              {features::kAutofillContentEditables, {}},
+                              {features::test::kAutofillServerCommunication,
                                {}},
                               {features::test::kAutofillShowTypePredictions,
                                {}},
diff --git a/chrome/browser/browser_encoding_browsertest.cc b/chrome/browser/browser_encoding_browsertest.cc
index a254730..48eb027 100644
--- a/chrome/browser/browser_encoding_browsertest.cc
+++ b/chrome/browser/browser_encoding_browsertest.cc
@@ -238,6 +238,7 @@
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   for (size_t i = 0; i < std::size(kTestDatas); ++i) {
+    SCOPED_TRACE(i);
     base::FilePath test_file_path(test_dir_path);
     test_file_path = test_file_path.AppendASCII(kTestDatas[i].test_file_name);
     GURL url =
diff --git a/chrome/browser/browser_keyevents_browsertest.cc b/chrome/browser/browser_keyevents_browsertest.cc
index a8df170..92dd5da 100644
--- a/chrome/browser/browser_keyevents_browsertest.cc
+++ b/chrome/browser/browser_keyevents_browsertest.cc
@@ -30,14 +30,14 @@
 namespace {
 
 constexpr char kTestingPage[] = "/keyevents_test.html";
-constexpr char kSuppressEventJS[] = "setDefaultAction('%ls', %ls);";
+constexpr char kSuppressEventJS[] = "setDefaultAction('%s', %s);";
 constexpr char kGetResultJS[] = "keyEventResult[%d];";
 constexpr char kGetResultLengthJS[] = "keyEventResult.length;";
 constexpr char kGetFocusedElementJS[] = "focusedElement;";
-constexpr char kSetFocusedElementJS[] = "setFocusedElement('%ls');";
-constexpr char kGetTextBoxValueJS[] = "document.getElementById('%ls').value;";
+constexpr char kSetFocusedElementJS[] = "setFocusedElement('%s');";
+constexpr char kGetTextBoxValueJS[] = "document.getElementById('%s').value;";
 constexpr char kSetTextBoxValueJS[] =
-    "document.getElementById('%ls').value = '%ls';";
+    "document.getElementById('%s').value = '%s';";
 constexpr char kStartTestJS[] = "startTest(%d);";
 
 // Maximum length of the result array in KeyEventTestData structure.
@@ -70,10 +70,6 @@
   const char* const result[kMaxResultLength];
 };
 
-const wchar_t* GetBoolString(bool value) {
-  return value ? L"true" : L"false";
-}
-
 // A class to help wait for the finish of a key event test.
 class TestFinishObserver : public content::WebContentsObserver {
  public:
@@ -131,25 +127,23 @@
   // Set the suppress flag of an event specified by |type|. If |suppress| is
   // true then the web page will suppress all events with |type|. Following
   // event types are supported: keydown, keypress, keyup and textInput.
-  void SuppressEventByType(int tab_index, const wchar_t* type, bool suppress) {
+  void SuppressEventByType(int tab_index, const char* type, bool suppress) {
     ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
     ASSERT_EQ(!suppress,
               content::EvalJs(
                   browser()->tab_strip_model()->GetWebContentsAt(tab_index),
                   base::StringPrintf(kSuppressEventJS, type,
-                                     GetBoolString(!suppress))));
+                                     suppress ? "false" : "true")));
   }
 
   void SuppressEvents(int tab_index, bool keydown, bool keypress,
                       bool keyup, bool textinput) {
+    ASSERT_NO_FATAL_FAILURE(SuppressEventByType(tab_index, "keydown", keydown));
     ASSERT_NO_FATAL_FAILURE(
-        SuppressEventByType(tab_index, L"keydown", keydown));
+        SuppressEventByType(tab_index, "keypress", keypress));
+    ASSERT_NO_FATAL_FAILURE(SuppressEventByType(tab_index, "keyup", keyup));
     ASSERT_NO_FATAL_FAILURE(
-        SuppressEventByType(tab_index, L"keypress", keypress));
-    ASSERT_NO_FATAL_FAILURE(
-        SuppressEventByType(tab_index, L"keyup", keyup));
-    ASSERT_NO_FATAL_FAILURE(
-        SuppressEventByType(tab_index, L"textInput", textinput));
+        SuppressEventByType(tab_index, "textInput", textinput));
   }
 
   void SuppressAllEvents(int tab_index, bool suppress) {
@@ -184,15 +178,15 @@
     }
   }
 
-  void CheckFocusedElement(int tab_index, const wchar_t* focused) {
+  void CheckFocusedElement(int tab_index, const char* focused) {
     ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
-    ASSERT_EQ(base::WideToUTF8(focused),
+    ASSERT_EQ(focused,
               content::EvalJs(
                   browser()->tab_strip_model()->GetWebContentsAt(tab_index),
                   kGetFocusedElementJS));
   }
 
-  void SetFocusedElement(int tab_index, const wchar_t* focused) {
+  void SetFocusedElement(int tab_index, const char* focused) {
     ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
     ASSERT_EQ(true,
               content::EvalJs(
@@ -200,19 +194,17 @@
                   base::StringPrintf(kSetFocusedElementJS, focused)));
   }
 
-  void CheckTextBoxValue(int tab_index, const wchar_t* id,
-                         const wchar_t* value) {
+  void CheckTextBoxValue(int tab_index, const char* id, const char* value) {
     ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
-    ASSERT_EQ(base::WideToUTF8(value),
+    ASSERT_EQ(value,
               content::EvalJs(
                   browser()->tab_strip_model()->GetWebContentsAt(tab_index),
                   base::StringPrintf(kGetTextBoxValueJS, id)));
   }
 
-  void SetTextBoxValue(int tab_index, const wchar_t* id,
-                       const wchar_t* value) {
+  void SetTextBoxValue(int tab_index, const char* id, const char* value) {
     ASSERT_LT(tab_index, browser()->tab_strip_model()->count());
-    ASSERT_EQ(base::WideToUTF8(value),
+    ASSERT_EQ(value,
               content::EvalJs(
                   browser()->tab_strip_model()->GetWebContentsAt(tab_index),
                   base::StringPrintf(kSetTextBoxValueJS, id, value)));
@@ -345,22 +337,22 @@
   }
 
   // Input in normal text box.
-  ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L"A"));
+  ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, "A"));
   for (size_t i = 0; i < std::size(kTestWithInput); ++i) {
     EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestWithInput[i]))
         << "kTestWithInput[" << i << "] in text box failed:\n"
         << GetTestDataDescription(kTestWithInput[i]);
   }
-  EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, L"A", L"aA"));
+  EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, "A", "aA"));
 
   // Input in password box.
-  ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L"B"));
+  ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, "B"));
   for (size_t i = 0; i < std::size(kTestWithInput); ++i) {
     EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestWithInput[i]))
         << "kTestWithInput[" << i << "] in password box failed:\n"
         << GetTestDataDescription(kTestWithInput[i]);
   }
-  EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, L"B", L"aA"));
+  EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, "B", "aA"));
 }
 
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
@@ -559,15 +551,15 @@
 
   int tab_index = browser()->tab_strip_model()->active_index();
   // Make sure no element is focused.
-  EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
+  EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, ""));
   // Alt+A should focus the element with accesskey = "A".
   EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestAccessA));
-  EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L"A"));
+  EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, "A"));
 
   // Blur the focused element.
-  EXPECT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L""));
+  EXPECT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, ""));
   // Make sure no element is focused.
-  EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
+  EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, ""));
 
 #if !BUILDFLAG(IS_MAC)
   // Alt+D should move the focus to the location entry.
@@ -578,14 +570,14 @@
   content::RunAllPendingInMessageLoop();
   EXPECT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX));
   // No element should be focused, as Alt+D was handled by the browser.
-  EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
+  EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, ""));
 
   // Move the focus back to the web page.
   ASSERT_NO_FATAL_FAILURE(ClickOnView(VIEW_ID_TAB_CONTAINER));
   ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
 
   // Make sure no element is focused.
-  EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
+  EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, ""));
 #endif
 
   // If the keydown event is suppressed, then Alt+D should be handled as an
@@ -594,12 +586,12 @@
   // suppressed at all.
   EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestAccessDSuppress));
   ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
-  EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L"D"));
+  EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, "D"));
 
   // Blur the focused element.
-  EXPECT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L""));
+  EXPECT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, ""));
   // Make sure no element is focused.
-  EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, L""));
+  EXPECT_NO_FATAL_FAILURE(CheckFocusedElement(tab_index, ""));
 }
 
 IN_PROC_BROWSER_TEST_F(BrowserKeyEventsTest, ReservedAccelerators) {
@@ -713,15 +705,15 @@
   ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
 
   int tab_index = browser()->tab_strip_model()->active_index();
-  ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L"A"));
-  ASSERT_NO_FATAL_FAILURE(SetTextBoxValue(tab_index, L"A", L"Hello"));
+  ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, "A"));
+  ASSERT_NO_FATAL_FAILURE(SetTextBoxValue(tab_index, "A", "Hello"));
   // Move the caret to the beginning of the line.
   EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlA));
   // Forward one character
   EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlF));
   // Delete to the end of the line.
   EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestCtrlK));
-  EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, L"A", L"H"));
+  EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, "A", "H"));
 }
 #endif
 
@@ -750,10 +742,10 @@
   ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER));
 
   int tab_index = browser()->tab_strip_model()->active_index();
-  ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, L"A"));
+  ASSERT_NO_FATAL_FAILURE(SetFocusedElement(tab_index, "A"));
   EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestPageUp));
   EXPECT_NO_FATAL_FAILURE(TestKeyEvent(tab_index, kTestPageDown));
-  EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, L"A", L""));
+  EXPECT_NO_FATAL_FAILURE(CheckTextBoxValue(tab_index, "A", ""));
 }
 
 // AltKey is enabled only on Windows. See crbug.com/114537.
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h
index 25a82353..e50822a 100644
--- a/chrome/browser/browser_process.h
+++ b/chrome/browser/browser_process.h
@@ -91,6 +91,10 @@
 class NetworkTimeTracker;
 }
 
+namespace os_crypt_async {
+class OSCryptAsync;
+}
+
 namespace policy {
 class ChromeBrowserPolicyConnector;
 class PolicyService;
@@ -275,6 +279,10 @@
   virtual UsbSystemTrayIcon* usb_system_tray_icon() = 0;
 #endif
 
+  // Obtain the browser instance of OSCryptAsync, which should be used for data
+  // encryption.
+  virtual os_crypt_async::OSCryptAsync* os_crypt_async() = 0;
+
   virtual BuildState* GetBuildState() = 0;
 };
 
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index ff24d8c..228c377 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -105,6 +105,7 @@
 #include "components/metrics_services_manager/metrics_services_manager.h"
 #include "components/metrics_services_manager/metrics_services_manager_client.h"
 #include "components/network_time/network_time_tracker.h"
+#include "components/os_crypt/async/browser/os_crypt_async.h"
 #include "components/permissions/permissions_client.h"
 #include "components/policy/core/common/policy_service.h"
 #include "components/prefs/json_pref_store.h"
@@ -1011,6 +1012,11 @@
 }
 #endif
 
+os_crypt_async::OSCryptAsync* BrowserProcessImpl::os_crypt_async() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return os_crypt_async_.get();
+}
+
 BuildState* BrowserProcessImpl::GetBuildState() {
 #if !BUILDFLAG(IS_ANDROID)
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -1261,6 +1267,17 @@
   } else {
     breadcrumbs::DeleteBreadcrumbFiles(user_data_dir);
   }
+
+  // For now, initialize OSCryptAsync with no providers. This delegates all
+  // encryption operations to OSCrypt.
+  // TODO(crbug.com/1373092): Add providers behind features, as support for them
+  // is added.
+  os_crypt_async_ = std::make_unique<os_crypt_async::OSCryptAsync>(
+      std::vector<
+          std::pair<size_t, std::unique_ptr<os_crypt_async::KeyProvider>>>());
+
+  // Trigger async initialization of OSCrypt key providers.
+  std::ignore = os_crypt_async_->GetInstance(base::DoNothing());
 }
 
 void BrowserProcessImpl::CreateIconManager() {
diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h
index 7cc361a..906ec958 100644
--- a/chrome/browser/browser_process_impl.h
+++ b/chrome/browser/browser_process_impl.h
@@ -71,6 +71,10 @@
 class GCMDriver;
 }
 
+namespace os_crypt_async {
+class OSCryptAsync;
+}
+
 namespace policy {
 class ChromeBrowserPolicyConnector;
 class PolicyService;
@@ -220,6 +224,8 @@
   UsbSystemTrayIcon* usb_system_tray_icon() override;
 #endif
 
+  os_crypt_async::OSCryptAsync* os_crypt_async() override;
+
   BuildState* GetBuildState() override;
 
   static void RegisterPrefs(PrefRegistrySimple* registry);
@@ -459,6 +465,8 @@
   std::unique_ptr<breadcrumbs::ApplicationBreadcrumbsLogger>
       application_breadcrumbs_logger_;
 
+  std::unique_ptr<os_crypt_async::OSCryptAsync> os_crypt_async_;
+
   SEQUENCE_CHECKER(sequence_checker_);
 };
 
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 5411fa46..5d67549e 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -38,18 +38,6 @@
         <include name="IDR_CHROME_APP_MANIFEST" file="resources\chrome_app\manifest.json" type="BINDATA" />
         <include name="IDR_URL_MOJOM_LITE_JS" file="${root_gen_dir}\url\mojom\url.mojom-lite.js" use_base_dir="false" type="BINDATA" />
 
-        <!-- Edu Coexistence account login resources -->
-        <include name="IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_HTML" file="resources\chromeos\edu_coexistence\edu_coexistence.html" type="BINDATA" />
-        <include name="IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_APP_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_coexistence\edu_coexistence_app.js" use_base_dir="false" type="BINDATA" />
-        <include name="IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_UI_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_coexistence\edu_coexistence_ui.js" use_base_dir="false" type="BINDATA" />
-        <include name="IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_CONTROLLER_JS" file="resources\chromeos\edu_coexistence\edu_coexistence_controller.js" type="BINDATA" />
-        <include name="IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_BROWSER_PROXY_JS" file="resources\chromeos\edu_coexistence\edu_coexistence_browser_proxy.js" type="BINDATA" />
-        <include name="IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_BUTTON_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_coexistence\edu_coexistence_button.js" use_base_dir="false" type="BINDATA" />
-        <include name="IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_OFFLINE_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_coexistence\edu_coexistence_offline.js" use_base_dir="false" type="BINDATA" />
-        <include name="IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_ERROR_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_coexistence\edu_coexistence_error.js" use_base_dir="false" type="BINDATA" />
-        <include name="IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_TEMPLATE_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_coexistence\edu_coexistence_template.js" use_base_dir="false" type="BINDATA" />
-        <include name="IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_CSS_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\edu_coexistence\edu_coexistence_css.js" use_base_dir="false" type="BINDATA" />
-
         <!-- ChromeOS Account Manager resources -->
         <include name="IDR_ACCOUNT_MANAGER_COMPONENTS_ERROR_SCREEN_JS" file="resources\chromeos\account_manager\components\error_screen.js" type ="BINDATA"/>
         <include name="IDR_ACCOUNT_MANAGER_COMPONENTS_ERROR_SCREEN_HTML_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\account_manager\components\error_screen.html.js" use_base_dir="false" type ="BINDATA"/>
diff --git a/chrome/browser/chrome_browser_main_linux.cc b/chrome/browser/chrome_browser_main_linux.cc
index f8fc06d0..0d3bc8c 100644
--- a/chrome/browser/chrome_browser_main_linux.cc
+++ b/chrome/browser/chrome_browser_main_linux.cc
@@ -8,6 +8,7 @@
 #include <string>
 #include <utility>
 
+#include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
 #include "base/functional/bind.h"
@@ -24,6 +25,7 @@
 #include "ui/base/l10n/l10n_util.h"
 
 #if BUILDFLAG(IS_CHROMEOS)
+#include "chrome/browser/chromeos/tast_support/stack_sampling_recorder.h"
 #include "chrome/installer/util/google_update_settings.h"
 #endif
 
@@ -36,7 +38,6 @@
 #endif
 
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
-#include "base/command_line.h"
 #include "base/linux_util.h"
 #include "chrome/common/chrome_paths_internal.h"
 #include "chrome/common/chrome_switches.h"
@@ -53,9 +54,16 @@
 }
 
 void ChromeBrowserMainPartsLinux::PostCreateMainMessageLoop() {
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
 #if BUILDFLAG(IS_CHROMEOS)
-  // No-op: Ash and Lacros Bluetooth DBusManager initialization depend on
-  // FeatureList, and is done elsewhere.
+  if (command_line->HasSwitch(
+          chromeos::tast_support::kRecordStackSamplingDataSwitch)) {
+    stack_sampling_recorder_ =
+        base::MakeRefCounted<chromeos::tast_support::StackSamplingRecorder>();
+    stack_sampling_recorder_->Start();
+  }
+  // Don't initialize DBus here. Ash and Lacros Bluetooth DBusManager
+  // initialization depend on FeatureList, and is done elsewhere.
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
 #if !BUILDFLAG(IS_CHROMEOS)
@@ -70,8 +78,7 @@
   std::unique_ptr<os_crypt::Config> config =
       std::make_unique<os_crypt::Config>();
   // Forward to os_crypt the flag to use a specific password store.
-  config->store = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-      switches::kPasswordStore);
+  config->store = command_line->GetSwitchValueASCII(switches::kPasswordStore);
   // Forward the product name
   config->product_name = l10n_util::GetStringUTF8(IDS_PRODUCT_NAME);
   // OSCrypt can be disabled in a special settings file.
diff --git a/chrome/browser/chrome_browser_main_linux.h b/chrome/browser/chrome_browser_main_linux.h
index 640e87c..968e56d 100644
--- a/chrome/browser/chrome_browser_main_linux.h
+++ b/chrome/browser/chrome_browser_main_linux.h
@@ -7,9 +7,16 @@
 #ifndef CHROME_BROWSER_CHROME_BROWSER_MAIN_LINUX_H_
 #define CHROME_BROWSER_CHROME_BROWSER_MAIN_LINUX_H_
 
+#include "base/memory/scoped_refptr.h"
 #include "build/build_config.h"
 #include "chrome/browser/chrome_browser_main_posix.h"
 
+#if BUILDFLAG(IS_CHROMEOS)
+namespace chromeos::tast_support {
+class StackSamplingRecorder;
+}
+#endif
+
 class ChromeBrowserMainPartsLinux : public ChromeBrowserMainPartsPosix {
  public:
   ChromeBrowserMainPartsLinux(bool is_integration_test,
@@ -30,6 +37,16 @@
   void PostBrowserStart() override;
 #endif
   void PostDestroyThreads() override;
+
+ private:
+#if BUILDFLAG(IS_CHROMEOS)
+  // Used by ChromeOS tast tests. This is used by both Lacros and Ash, which
+  // is why it's in ChromeBrowserMainPartsLinux, even though it's not used in
+  // Linux. ChromeBrowserMainPartsLinux is the base class of both
+  // ChromeBrowserMainPartsAsh and ChromeBrowserMainPartsLacros.
+  scoped_refptr<chromeos::tast_support::StackSamplingRecorder>
+      stack_sampling_recorder_;
+#endif
 };
 
 #endif  // CHROME_BROWSER_CHROME_BROWSER_MAIN_LINUX_H_
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 259e651..9fe1c85 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -185,6 +185,8 @@
     "tablet_mode/chrome_content_browser_client_tablet_mode_part.h",
     "tablet_mode/tablet_mode_page_behavior.cc",
     "tablet_mode/tablet_mode_page_behavior.h",
+    "tast_support/stack_sampling_recorder.cc",
+    "tast_support/stack_sampling_recorder.h",
     "upload_office_to_cloud/upload_office_to_cloud.cc",
     "upload_office_to_cloud/upload_office_to_cloud.h",
     "video_conference/video_conference_manager_client.cc",
@@ -261,6 +263,7 @@
     "//url",
   ]
   deps = [
+    ":system_stack_sampled_metrics_status_proto",
     "//chrome/app:command_ids",
     "//chrome/app:generated_resources",
     "//chrome/app/vector_icons",
@@ -525,6 +528,7 @@
     "reporting/websites/website_events_observer_unittest.cc",
     "reporting/websites/website_usage_observer_unittest.cc",
     "reporting/websites/website_usage_telemetry_sampler_unittest.cc",
+    "tast_support/stack_sampling_recorder_unittest.cc",
     "video_conference/video_conference_ukm_helper_unittest.cc",
 
     # TODO(zturner): Enable this on Windows. See
@@ -535,6 +539,7 @@
   ]
   deps = [
     ":chromeos",
+    ":system_stack_sampled_metrics_status_proto",
     ":test_support",
     "//base",
     "//base/test:test_support",
@@ -680,3 +685,10 @@
     ]
   }
 }
+
+proto_library("system_stack_sampled_metrics_status_proto") {
+  sources = [ "//third_party/cros_system_api/proto/stack_sampled_metrics_status//stack_sampled_metrics_status.proto" ]
+
+  proto_out_dir =
+      "third_party/cros_system_api/proto/stack_sampled_metrics_status"
+}
diff --git a/chrome/browser/chromeos/tast_support/stack_sampling_recorder.cc b/chrome/browser/chromeos/tast_support/stack_sampling_recorder.cc
new file mode 100644
index 0000000..57c3e0c
--- /dev/null
+++ b/chrome/browser/chromeos/tast_support/stack_sampling_recorder.cc
@@ -0,0 +1,117 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/tast_support/stack_sampling_recorder.h"
+
+#include <sys/file.h>
+
+#include <string>
+#include <utility>
+
+#include "base/containers/span.h"
+#include "base/files/file.h"
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+#include "base/task/task_traits.h"
+#include "base/task/thread_pool.h"
+#include "base/time/time.h"
+#include "build/chromeos_buildflags.h"
+#include "components/metrics/call_stack_profile_metrics_provider.h"
+#include "third_party/cros_system_api/proto/stack_sampled_metrics_status/stack_sampled_metrics_status.pb.h"
+
+namespace chromeos::tast_support {
+
+namespace {
+// The path to write to. Deliberately not using base::GetTempDir() here;
+// the tast test needs to known the complete, exact path.
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+constexpr char kDefaultFilePath[] = "/tmp/stack-sampling-data-lacros";
+#else
+constexpr char kDefaultFilePath[] = "/tmp/stack-sampling-data";
+#endif
+
+// Time between writes. This is very short because we are only using this as
+// part of an integration test and the test doesn't want to have a large
+// timeout.
+constexpr base::TimeDelta kTimeBetweenWrites = base::Seconds(1);
+}  // namespace
+
+StackSamplingRecorder::StackSamplingRecorder()
+    : file_path_(base::FilePath(kDefaultFilePath)) {}
+
+StackSamplingRecorder::StackSamplingRecorder(base::FilePath file_path)
+    : file_path_(std::move(file_path)) {}
+
+void StackSamplingRecorder::Start() {
+  base::ThreadPool::PostDelayedTask(
+      FROM_HERE, {base::TaskPriority::BEST_EFFORT, base::MayBlock()},
+      base::BindOnce(&StackSamplingRecorder::WriteFile, this),
+      kTimeBetweenWrites);
+}
+
+StackSamplingRecorder::~StackSamplingRecorder() = default;
+
+metrics::CallStackProfileMetricsProvider::ProcessThreadCount
+StackSamplingRecorder::GetSuccessfullyCollectedCounts() const {
+  return metrics::CallStackProfileMetricsProvider::
+      GetSuccessfullyCollectedCounts();
+}
+
+void StackSamplingRecorder::WriteFile() {
+  // Do most work in a helper function so that we can return early if there's
+  // an error, but we still always post a retry task.
+  WriteFileHelper();
+
+  base::ThreadPool::PostDelayedTask(
+      FROM_HERE, {base::TaskPriority::BEST_EFFORT, base::MayBlock()},
+      base::BindOnce(&StackSamplingRecorder::WriteFile, this),
+      kTimeBetweenWrites);
+}
+
+void StackSamplingRecorder::WriteFileHelper() {
+  // Build up the protobuf we want to write before locking the file, to
+  // minimize the time spent holding the lock.
+  auto process_thread_count_map = GetSuccessfullyCollectedCounts();
+  stack_sampled_metrics_status::StackSampledMetricsStatus status;
+
+  for (const auto& [process, thread_count_map] : process_thread_count_map) {
+    auto& thread_count_map_proto =
+        (*status.mutable_process_type_to_thread_count_map())[process];
+    thread_count_map_proto.mutable_thread_type_to_success_count()->insert(
+        thread_count_map.begin(), thread_count_map.end());
+  }
+
+  // Don't use the open flags that truncate the file; we can't truncate until
+  // the lock succeeds.
+  base::File file(file_path_,
+                  base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE);
+
+  if (!file.IsValid()) {
+    LOG(ERROR) << "Failed to open " << file_path_ << ": "
+               << base::File::ErrorToString(file.error_details());
+    return;
+  }
+
+  // Use flock instead of File::Lock; File::Lock doesn't allow
+  // block-until-locked.
+  if (HANDLE_EINTR(flock(file.GetPlatformFile(), LOCK_EX)) != 0) {
+    PLOG(ERROR) << "Unable to lock " << file_path_ << ": ";
+    return;
+  }
+
+  // We don't need to unlock the file explicitly; it will always unlock when
+  // we destruct |file|.
+  if (!file.SetLength(0)) {
+    LOG(ERROR) << "Unable to truncate " << file_path_;
+    return;
+  }
+
+  if (!status.SerializeToFileDescriptor(file.GetPlatformFile())) {
+    LOG(ERROR) << "Unable to write to " << file_path_;
+    return;
+  }
+}
+
+}  // namespace chromeos::tast_support
diff --git a/chrome/browser/chromeos/tast_support/stack_sampling_recorder.h b/chrome/browser/chromeos/tast_support/stack_sampling_recorder.h
new file mode 100644
index 0000000..5078b16
--- /dev/null
+++ b/chrome/browser/chromeos/tast_support/stack_sampling_recorder.h
@@ -0,0 +1,64 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_TAST_SUPPORT_STACK_SAMPLING_RECORDER_H_
+#define CHROME_BROWSER_CHROMEOS_TAST_SUPPORT_STACK_SAMPLING_RECORDER_H_
+
+#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
+#include "components/metrics/call_stack_profile_metrics_provider.h"
+
+namespace chromeos::tast_support {
+
+// Instructs Chrome to record /tmp/stack-sampling-data (or
+// /tmp/stack-sampling-data-lacros) with details of which threads and processes
+// are being successfully stack-sampled.
+inline constexpr char kRecordStackSamplingDataSwitch[] =
+    "record-stack-sampling-data";
+
+// Regularly writes a file (default: /tmp/stack-sampling-data or
+// /tmp/stack-sampling-data-lacros) listing which threads and processes have
+// been successfully stack sampled.
+//
+// Used by a few ChromeOS tast tests (for both ash and Lacros). Not created
+// during normal operations. Creation is controlled by
+// kRecordStackSamplingDataSwitch.
+class StackSamplingRecorder
+    : public base::RefCountedThreadSafe<StackSamplingRecorder> {
+ public:
+  StackSamplingRecorder();
+  StackSamplingRecorder(const StackSamplingRecorder&) = delete;
+  StackSamplingRecorder& operator=(const StackSamplingRecorder&) = delete;
+
+  void Start();
+
+ private:
+  friend class base::RefCountedThreadSafe<StackSamplingRecorder>;
+  // Friends to access some test-only functions
+  friend class TestingStackSamplingRecorder;
+
+  // Constructor for testing.
+  explicit StackSamplingRecorder(base::FilePath file_path);
+  virtual ~StackSamplingRecorder();
+
+  // Calls
+  // metrics::CallStackProfileMetricsProvider::GetSuccessfullyCollectedCounts()
+  // Virtual so we can override in tests.
+  virtual metrics::CallStackProfileMetricsProvider::ProcessThreadCount
+  GetSuccessfullyCollectedCounts() const;
+
+  // File writing callback.
+  void WriteFile();
+
+  // Helper for WriteFile(). A separate function so that we can return early on
+  // error, but always post a retry task inside WriteFile().
+  void WriteFileHelper();
+
+  // The path that the stack sampling data is written to.
+  const base::FilePath file_path_;
+};
+
+}  // namespace chromeos::tast_support
+
+#endif  // CHROME_BROWSER_CHROMEOS_TAST_SUPPORT_STACK_SAMPLING_RECORDER_H_
diff --git a/chrome/browser/chromeos/tast_support/stack_sampling_recorder_unittest.cc b/chrome/browser/chromeos/tast_support/stack_sampling_recorder_unittest.cc
new file mode 100644
index 0000000..d80544b0
--- /dev/null
+++ b/chrome/browser/chromeos/tast_support/stack_sampling_recorder_unittest.cc
@@ -0,0 +1,337 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/tast_support/stack_sampling_recorder.h"
+
+#include <sys/file.h>
+
+#include <memory>
+#include <utility>
+
+#include "base/check.h"
+#include "base/containers/span.h"
+#include "base/files/file.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/platform_thread.h"
+#include "base/threading/thread.h"
+#include "base/time/time.h"
+#include "components/metrics/call_stack_profile_metrics_provider.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/cros_system_api/proto/stack_sampled_metrics_status/stack_sampled_metrics_status.pb.h"
+#include "third_party/metrics_proto/execution_context.pb.h"
+
+namespace chromeos::tast_support {
+
+using ::stack_sampled_metrics_status::StackSampledMetricsStatus;
+
+// A version of StackSamplingRecorder that overrides
+// GetSuccessfullyCollectedCounts() to return a test-provided list of
+// process/thread/counts.
+class TestingStackSamplingRecorder : public StackSamplingRecorder {
+ public:
+  explicit TestingStackSamplingRecorder(base::FilePath file_path)
+      : StackSamplingRecorder(std::move(file_path)) {}
+
+  void SetSuccessfullyCollectedCounts(
+      const metrics::CallStackProfileMetricsProvider::ProcessThreadCount&
+          counts) {
+    counts_ = counts;
+  }
+
+  // Allow tests to access the private function WriteFileHelper().
+  void WriteFileHelper() { StackSamplingRecorder::WriteFileHelper(); }
+
+ private:
+  ~TestingStackSamplingRecorder() override = default;
+
+  metrics::CallStackProfileMetricsProvider::ProcessThreadCount
+  GetSuccessfullyCollectedCounts() const override {
+    return counts_;
+  }
+
+  metrics::CallStackProfileMetricsProvider::ProcessThreadCount counts_;
+};
+
+class StackSamplingRecorderTest : public testing::Test {
+ protected:
+  void SetUp() override {
+    CHECK(tmp_dir_.CreateUniqueTempDir());
+
+    output_path_ = tmp_dir_.GetPath().Append("stack-sampling-data");
+    recorder_ =
+        base::MakeRefCounted<TestingStackSamplingRecorder>(output_path_);
+  }
+
+  base::ScopedTempDir tmp_dir_;
+  base::FilePath output_path_;
+  scoped_refptr<TestingStackSamplingRecorder> recorder_;
+};
+
+TEST_F(StackSamplingRecorderTest, ProducesValidFile) {
+  metrics::CallStackProfileMetricsProvider::ProcessThreadCount counts;
+  counts[metrics::BROWSER_PROCESS][metrics::MAIN_THREAD] = 5;
+  counts[metrics::BROWSER_PROCESS][metrics::FILE_THREAD] = 7;
+  counts[metrics::BROWSER_PROCESS][metrics::IO_THREAD] = 9;
+  counts[metrics::RENDERER_PROCESS][metrics::MAIN_THREAD] = 11;
+  counts[metrics::UTILITY_PROCESS][metrics::IO_THREAD] = 13;
+  recorder_->SetSuccessfullyCollectedCounts(counts);
+
+  recorder_->WriteFileHelper();
+
+  base::File result_file(output_path_,
+                         base::File::FLAG_OPEN | base::File::FLAG_READ);
+  ASSERT_TRUE(result_file.IsValid());
+
+  StackSampledMetricsStatus result;
+  EXPECT_TRUE(result.ParseFromFileDescriptor(result_file.GetPlatformFile()));
+
+  // base::EqualsProto doesn't work well on MessageLite's. Validate |result|
+  // manually.
+  EXPECT_EQ(result.process_type_to_thread_count_map().size(), 3UL);
+
+  ASSERT_TRUE(result.process_type_to_thread_count_map().contains(
+      metrics::BROWSER_PROCESS));
+  const StackSampledMetricsStatus::ThreadCountMap& browser_thread_count =
+      result.process_type_to_thread_count_map().at(metrics::BROWSER_PROCESS);
+  EXPECT_EQ(browser_thread_count.thread_type_to_success_count().size(), 3UL);
+  ASSERT_TRUE(browser_thread_count.thread_type_to_success_count().contains(
+      metrics::MAIN_THREAD));
+  EXPECT_EQ(browser_thread_count.thread_type_to_success_count().at(
+                metrics::MAIN_THREAD),
+            5);
+  ASSERT_TRUE(browser_thread_count.thread_type_to_success_count().contains(
+      metrics::FILE_THREAD));
+  EXPECT_EQ(browser_thread_count.thread_type_to_success_count().at(
+                metrics::FILE_THREAD),
+            7);
+  ASSERT_TRUE(browser_thread_count.thread_type_to_success_count().contains(
+      metrics::IO_THREAD));
+  EXPECT_EQ(browser_thread_count.thread_type_to_success_count().at(
+                metrics::IO_THREAD),
+            9);
+
+  ASSERT_TRUE(result.process_type_to_thread_count_map().contains(
+      metrics::RENDERER_PROCESS));
+  const StackSampledMetricsStatus::ThreadCountMap& renderer_thread_count =
+      result.process_type_to_thread_count_map().at(metrics::RENDERER_PROCESS);
+  EXPECT_EQ(renderer_thread_count.thread_type_to_success_count().size(), 1UL);
+  ASSERT_TRUE(renderer_thread_count.thread_type_to_success_count().contains(
+      metrics::MAIN_THREAD));
+  EXPECT_EQ(renderer_thread_count.thread_type_to_success_count().at(
+                metrics::MAIN_THREAD),
+            11);
+
+  ASSERT_TRUE(result.process_type_to_thread_count_map().contains(
+      metrics::UTILITY_PROCESS));
+  const StackSampledMetricsStatus::ThreadCountMap& utility_thread_count =
+      result.process_type_to_thread_count_map().at(metrics::UTILITY_PROCESS);
+  EXPECT_EQ(utility_thread_count.thread_type_to_success_count().size(), 1UL);
+  ASSERT_TRUE(utility_thread_count.thread_type_to_success_count().contains(
+      metrics::IO_THREAD));
+  EXPECT_EQ(utility_thread_count.thread_type_to_success_count().at(
+                metrics::IO_THREAD),
+            13);
+}
+
+TEST_F(StackSamplingRecorderTest, ProducesValidEmptyFileIfNoCounts) {
+  recorder_->WriteFileHelper();
+
+  base::File result_file(output_path_,
+                         base::File::FLAG_OPEN | base::File::FLAG_READ);
+  ASSERT_TRUE(result_file.IsValid());
+
+  StackSampledMetricsStatus result;
+  EXPECT_TRUE(result.ParseFromFileDescriptor(result_file.GetPlatformFile()));
+  EXPECT_EQ(result.process_type_to_thread_count_map().size(), 0UL);
+}
+
+TEST_F(StackSamplingRecorderTest, TruncatesExistingFileToEmpty) {
+  // Add some existing data.
+  metrics::CallStackProfileMetricsProvider::ProcessThreadCount counts;
+  counts[metrics::BROWSER_PROCESS][metrics::MAIN_THREAD] = 5;
+  counts[metrics::BROWSER_PROCESS][metrics::FILE_THREAD] = 7;
+  counts[metrics::BROWSER_PROCESS][metrics::IO_THREAD] = 9;
+  counts[metrics::RENDERER_PROCESS][metrics::MAIN_THREAD] = 11;
+  counts[metrics::UTILITY_PROCESS][metrics::IO_THREAD] = 13;
+  recorder_->SetSuccessfullyCollectedCounts(counts);
+
+  recorder_->WriteFileHelper();
+
+  // Rewrite with no count.
+  recorder_->SetSuccessfullyCollectedCounts({});
+  recorder_->WriteFileHelper();
+
+  int64_t file_size = -1;
+  EXPECT_TRUE(base::GetFileSize(output_path_, &file_size));
+  EXPECT_EQ(file_size, 0L);
+}
+
+TEST_F(StackSamplingRecorderTest, TruncatesExistingFileWithLessData) {
+  // Add some existing data.
+  metrics::CallStackProfileMetricsProvider::ProcessThreadCount counts;
+  counts[metrics::BROWSER_PROCESS][metrics::MAIN_THREAD] = 5;
+  counts[metrics::BROWSER_PROCESS][metrics::FILE_THREAD] = 7;
+  counts[metrics::BROWSER_PROCESS][metrics::IO_THREAD] = 9;
+  counts[metrics::RENDERER_PROCESS][metrics::MAIN_THREAD] = 11;
+  counts[metrics::UTILITY_PROCESS][metrics::IO_THREAD] = 13;
+  recorder_->SetSuccessfullyCollectedCounts(counts);
+
+  recorder_->WriteFileHelper();
+
+  // Rewrite with a different, smaller set of counts.
+  counts.clear();
+  counts[metrics::GPU_PROCESS][metrics::FILE_THREAD] = 15;
+  counts[metrics::UTILITY_PROCESS][metrics::MAIN_THREAD] = 17;
+
+  recorder_->SetSuccessfullyCollectedCounts(counts);
+  recorder_->WriteFileHelper();
+
+  base::File result_file(output_path_,
+                         base::File::FLAG_OPEN | base::File::FLAG_READ);
+  ASSERT_TRUE(result_file.IsValid());
+
+  // Confirm that result only contains the new counts, not the old counts.
+  StackSampledMetricsStatus result;
+  EXPECT_TRUE(result.ParseFromFileDescriptor(result_file.GetPlatformFile()));
+
+  // base::EqualsProto doesn't work well on MessageLite's. Validate |result|
+  // manually.
+  EXPECT_EQ(result.process_type_to_thread_count_map().size(), 2UL);
+
+  ASSERT_TRUE(
+      result.process_type_to_thread_count_map().contains(metrics::GPU_PROCESS));
+  const StackSampledMetricsStatus::ThreadCountMap& gpu_thread_count =
+      result.process_type_to_thread_count_map().at(metrics::GPU_PROCESS);
+  EXPECT_EQ(gpu_thread_count.thread_type_to_success_count().size(), 1UL);
+  ASSERT_TRUE(gpu_thread_count.thread_type_to_success_count().contains(
+      metrics::FILE_THREAD));
+  EXPECT_EQ(
+      gpu_thread_count.thread_type_to_success_count().at(metrics::FILE_THREAD),
+      15);
+
+  ASSERT_TRUE(result.process_type_to_thread_count_map().contains(
+      metrics::UTILITY_PROCESS));
+  const StackSampledMetricsStatus::ThreadCountMap& utility_thread_count =
+      result.process_type_to_thread_count_map().at(metrics::UTILITY_PROCESS);
+  EXPECT_EQ(utility_thread_count.thread_type_to_success_count().size(), 1UL);
+  ASSERT_TRUE(utility_thread_count.thread_type_to_success_count().contains(
+      metrics::MAIN_THREAD));
+  EXPECT_EQ(utility_thread_count.thread_type_to_success_count().at(
+                metrics::MAIN_THREAD),
+            17);
+}
+
+TEST_F(StackSamplingRecorderTest, DoesNotCrashOnUnwritableFile) {
+  // Will prevent normal file opens from working:
+  ASSERT_TRUE(base::CreateDirectory(output_path_));
+
+  metrics::CallStackProfileMetricsProvider::ProcessThreadCount counts;
+  counts[metrics::GPU_PROCESS][metrics::FILE_THREAD] = 15;
+  counts[metrics::UTILITY_PROCESS][metrics::MAIN_THREAD] = 17;
+  recorder_->SetSuccessfullyCollectedCounts(counts);
+
+  recorder_->WriteFileHelper();
+}
+
+// Called on a second thread to make sure the file doesn't change while locked.
+// Specifically:
+// 1. Writes a known pattern into the file
+// 2. Locks the file
+// 3. Signals that it has locked the file
+// 4. Waits for the other thread to try & write to the file
+// 5. CHECKs that the file still contains the original pattern
+static void LockFileAndPreventChange(base::FilePath path,
+                                     base::WaitableEvent* waitable) {
+  // 1. Write a known pattern into the file
+  base::File file(path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_READ |
+                            base::File::FLAG_WRITE);
+  CHECK(file.IsValid());
+  constexpr char kPattern[] = "Not a valid proto";
+  CHECK_EQ(file.Write(0, kPattern, sizeof(kPattern)),
+           static_cast<int>(sizeof(kPattern)));
+
+  // 2. Lock the file
+  CHECK_EQ(HANDLE_EINTR(flock(file.GetPlatformFile(), LOCK_EX)), 0);
+
+  // 3. Signal that it has locked the file
+  waitable->Signal();
+
+  // 4. Wait for the other thread to try & write to the file.
+  //
+  // Note: Yes, using Sleep here. There's no way for the other thread to signal
+  // to this thread "I've started trying to lock the file and I am now blocked
+  // waiting for the file to be unlocked." This can lead to anti-flakes (cases
+  // where the test passes even thought the code-under-test is wrong -- if the
+  // other thread doesn't start the write until the sleep is done) but shouldn't
+  // lead to flakes.
+  base::PlatformThreadBase::Sleep(base::Seconds(5));
+
+  // 5. CHECK that the file still contains the original pattern.
+  char buffer[sizeof(kPattern) + 1];
+  CHECK_EQ(file.Read(0, buffer, sizeof(buffer)),
+           static_cast<int>(sizeof(kPattern)));
+  CHECK_EQ(std::string(buffer), std::string(kPattern));
+}
+
+TEST_F(StackSamplingRecorderTest, DoesNotWriteToLockedFile) {
+  metrics::CallStackProfileMetricsProvider::ProcessThreadCount counts;
+  counts[metrics::GPU_PROCESS][metrics::FILE_THREAD] = 15;
+  counts[metrics::UTILITY_PROCESS][metrics::MAIN_THREAD] = 17;
+  recorder_->SetSuccessfullyCollectedCounts(counts);
+
+  base::WaitableEvent waitable;
+  base::Thread thread("locker_thread");
+  ASSERT_TRUE(thread.StartAndWaitForTesting());
+
+  ASSERT_TRUE(thread.task_runner()->PostTask(
+      FROM_HERE,
+      base::BindOnce(&LockFileAndPreventChange, output_path_, &waitable)));
+
+  // Wait for the locker to have locked the file.
+  waitable.Wait();
+
+  // Try to write. This should only return once the locker thread has released
+  // the file lock.
+  recorder_->WriteFileHelper();
+
+  // The write should still have been successful once the lock is released.
+  base::File result_file(output_path_,
+                         base::File::FLAG_OPEN | base::File::FLAG_READ);
+  ASSERT_TRUE(result_file.IsValid());
+
+  // Confirm that result only contains the new counts, not the old counts.
+  StackSampledMetricsStatus result;
+  EXPECT_TRUE(result.ParseFromFileDescriptor(result_file.GetPlatformFile()));
+
+  // base::EqualsProto doesn't work well on MessageLite's. Validate |result|
+  // manually.
+  EXPECT_EQ(result.process_type_to_thread_count_map().size(), 2UL);
+
+  ASSERT_TRUE(
+      result.process_type_to_thread_count_map().contains(metrics::GPU_PROCESS));
+  const StackSampledMetricsStatus::ThreadCountMap& gpu_thread_count =
+      result.process_type_to_thread_count_map().at(metrics::GPU_PROCESS);
+  EXPECT_EQ(gpu_thread_count.thread_type_to_success_count().size(), 1UL);
+  ASSERT_TRUE(gpu_thread_count.thread_type_to_success_count().contains(
+      metrics::FILE_THREAD));
+  EXPECT_EQ(
+      gpu_thread_count.thread_type_to_success_count().at(metrics::FILE_THREAD),
+      15);
+
+  ASSERT_TRUE(result.process_type_to_thread_count_map().contains(
+      metrics::UTILITY_PROCESS));
+  const StackSampledMetricsStatus::ThreadCountMap& utility_thread_count =
+      result.process_type_to_thread_count_map().at(metrics::UTILITY_PROCESS);
+  EXPECT_EQ(utility_thread_count.thread_type_to_success_count().size(), 1UL);
+  ASSERT_TRUE(utility_thread_count.thread_type_to_success_count().contains(
+      metrics::MAIN_THREAD));
+  EXPECT_EQ(utility_thread_count.thread_type_to_success_count().at(
+                metrics::MAIN_THREAD),
+            17);
+}
+
+}  // namespace chromeos::tast_support
diff --git a/chrome/browser/devtools/devtools_browsertest.cc b/chrome/browser/devtools/devtools_browsertest.cc
index 60593c26..fc6f80d 100644
--- a/chrome/browser/devtools/devtools_browsertest.cc
+++ b/chrome/browser/devtools/devtools_browsertest.cc
@@ -2368,8 +2368,9 @@
   }
 };
 
+// TODO(crbug.com/1493771): Reenable after fixing consistent Windows failure.
 IN_PROC_BROWSER_TEST_F(DevToolsReattachAfterCrashTest,
-                       TestReattachAfterCrashOnTimeline) {
+                       DISABLED_TestReattachAfterCrashOnTimeline) {
   RunTestWithPanel("timeline");
 }
 
diff --git a/chrome/browser/download/bubble/download_bubble_ui_controller.cc b/chrome/browser/download/bubble/download_bubble_ui_controller.cc
index a87491b..040d67f 100644
--- a/chrome/browser/download/bubble/download_bubble_ui_controller.cc
+++ b/chrome/browser/download/bubble/download_bubble_ui_controller.cc
@@ -256,8 +256,7 @@
     return;
   }
   DownloadCommands commands(model);
-  base::UmaHistogramExactLinear("Download.Bubble.ProcessedCommand", command,
-                                DownloadCommands::MAX + 1);
+  base::UmaHistogramEnumeration("Download.Bubble.ProcessedCommand2", command);
   DownloadItemWarningData::WarningSurface warning_surface =
       is_main_view ? DownloadItemWarningData::WarningSurface::BUBBLE_MAINPAGE
                    : DownloadItemWarningData::WarningSurface::BUBBLE_SUBPAGE;
diff --git a/chrome/browser/download/download_commands.h b/chrome/browser/download/download_commands.h
index 96cf84e..51923e80 100644
--- a/chrome/browser/download/download_commands.h
+++ b/chrome/browser/download/download_commands.h
@@ -9,8 +9,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/task/sequenced_task_runner.h"
 #include "build/build_config.h"
-#include "content/public/browser/page_navigator.h"
-#include "ui/gfx/image/image.h"
+#include "url/gurl.h"
 
 #if !BUILDFLAG(IS_ANDROID)
 class Browser;
@@ -20,29 +19,31 @@
 
 class DownloadCommands {
  public:
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
   enum Command {
-    SHOW_IN_FOLDER = 1,   // Open a folder view window with the item selected.
-    OPEN_WHEN_COMPLETE,   // Open the download when it's finished.
-    ALWAYS_OPEN_TYPE,     // Default this file extension to always open.
-    PLATFORM_OPEN,        // Open using platform handler.
-    CANCEL,               // Cancel the download.
-    PAUSE,                // Pause a download.
-    RESUME,               // Resume a download.
-    DISCARD,              // Discard the malicious download.
-    KEEP,                 // Keep the malicious download.
-    LEARN_MORE_SCANNING,  // Show information about download scanning.
-    LEARN_MORE_INTERRUPTED,  // Show information about interrupted downloads.
-    LEARN_MORE_INSECURE_DOWNLOAD,  // Show info about insecure downloads.
-    LEARN_MORE_DOWNLOAD_BLOCKED,   // Show info about blocked downloads.
-    OPEN_SAFE_BROWSING_SETTING,    // Open the settings page for Safe Browsing.
-    COPY_TO_CLIPBOARD,             // Copy the contents to the clipboard.
-    DEEP_SCAN,             // Send file to Safe Browsing for deep scanning.
-    BYPASS_DEEP_SCANNING,  // Bypass the prompt to deep scan.
-    REVIEW,                // Show enterprise download review dialog.
-    RETRY,                 // Retry the download.
-    CANCEL_DEEP_SCAN,      // Cancel the deep scan, returning to a prompt for
-                           // scanning.
-    MAX
+    SHOW_IN_FOLDER = 0,  // Open a folder view window with the item selected.
+    OPEN_WHEN_COMPLETE = 1,       // Open the download when it's finished.
+    ALWAYS_OPEN_TYPE = 2,         // Default this file extension to always open.
+    PLATFORM_OPEN = 3,            // Open using platform handler.
+    CANCEL = 4,                   // Cancel the download.
+    PAUSE = 5,                    // Pause a download.
+    RESUME = 6,                   // Resume a download.
+    DISCARD = 7,                  // Discard the malicious download.
+    KEEP = 8,                     // Keep the malicious download.
+    LEARN_MORE_SCANNING = 9,      // Show info about download scanning.
+    LEARN_MORE_INTERRUPTED = 10,  // Show info about interrupted downloads.
+    LEARN_MORE_INSECURE_DOWNLOAD = 11,  // Show info about insecure downloads.
+    LEARN_MORE_DOWNLOAD_BLOCKED = 12,   // Show info about blocked downloads.
+    OPEN_SAFE_BROWSING_SETTING = 13,    // Open settings page for Safe Browsing.
+    COPY_TO_CLIPBOARD = 14,             // Copy the contents to the clipboard.
+    DEEP_SCAN = 15,             // Send file to Safe Browsing for deep scanning.
+    BYPASS_DEEP_SCANNING = 16,  // Bypass the prompt to deep scan.
+    REVIEW = 17,                // Show enterprise download review dialog.
+    RETRY = 18,                 // Retry the download.
+    CANCEL_DEEP_SCAN = 19,  // Cancel deep scan and return to scanning prompt.
+
+    kMaxValue = CANCEL_DEEP_SCAN,  // Keep last.
   };
 
   // |model| must outlive DownloadCommands.
diff --git a/chrome/browser/download/download_item_model.cc b/chrome/browser/download/download_item_model.cc
index 22212b4..c9f8467 100644
--- a/chrome/browser/download/download_item_model.cc
+++ b/chrome/browser/download/download_item_model.cc
@@ -701,9 +701,6 @@
     const DownloadCommands* download_commands,
     DownloadCommands::Command command) const {
   switch (command) {
-    case DownloadCommands::MAX:
-      NOTREACHED();
-      break;
     case DownloadCommands::SHOW_IN_FOLDER:
       return download_->CanShowInFolder();
     case DownloadCommands::OPEN_WHEN_COMPLETE:
@@ -749,9 +746,6 @@
     const DownloadCommands* download_commands,
     DownloadCommands::Command command) const {
   switch (command) {
-    case DownloadCommands::MAX:
-      NOTREACHED();
-      break;
     case DownloadCommands::OPEN_WHEN_COMPLETE:
       return download_->GetOpenWhenComplete() ||
              download_crx_util::IsExtensionDownload(*download_);
@@ -877,9 +871,6 @@
 #endif
       break;
     }
-    case DownloadCommands::MAX:
-      NOTREACHED();
-      break;
     case DownloadCommands::PLATFORM_OPEN:
     case DownloadCommands::CANCEL:
     case DownloadCommands::LEARN_MORE_INTERRUPTED:
diff --git a/chrome/browser/download/download_item_model_unittest.cc b/chrome/browser/download/download_item_model_unittest.cc
index 4791025..58b59b85 100644
--- a/chrome/browser/download/download_item_model_unittest.cc
+++ b/chrome/browser/download/download_item_model_unittest.cc
@@ -264,14 +264,9 @@
 
     // Expected bubble status string. This will include the progress as well.
     // If empty, use the expected_status_msg.
-    // \xE2\x80\xA2 refers to the UTF8 encoding for the unicode symbol
-    // 0x2022 "•" bullet, used as the separator in Download Bubble
-    // \xE2\x80\xA6 refers to the UTF8 encoding for the unicode symbol
-    // 0x2026 "…" HORIZONTAL ELLIPSIS
     std::string expected_bubble_status_msg;
   } kTestCases[] = {
-      {download::DOWNLOAD_INTERRUPT_REASON_NONE, "1/2 B",
-       "1/2 B \xE2\x80\xA2 Resuming\xE2\x80\xA6"},
+      {download::DOWNLOAD_INTERRUPT_REASON_NONE, "1/2 B", "1/2 B • Resuming…"},
       {download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, "%s - Download error",
        "Something went wrong"},
       {download::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
@@ -293,7 +288,7 @@
       {download::DOWNLOAD_INTERRUPT_REASON_FILE_SAME_AS_SOURCE,
        "%s - Already downloaded", "Already downloaded"},
       {download::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR,
-       "%s - System busy", "Couldn\xE2\x80\x99t finish download"},
+       "%s - System busy", "Couldn’t finish download"},
       {download::DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH,
        "%s - Download error", "Something went wrong"},
       {download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, "%s - Network error",
@@ -303,33 +298,33 @@
       {download::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
        "%s - Network disconnected", "Check internet connection"},
       {download::DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN,
-       "%s - Server unavailable", "Site wasn\xE2\x80\x99t available"},
+       "%s - Server unavailable", "Site wasn’t available"},
       {download::DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST,
        "%s - Network error", "Check internet connection"},
       {download::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED, "%s - Server problem",
-       "Site wasn\xE2\x80\x99t available"},
+       "Site wasn’t available"},
       {download::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE,
        "%s - Download error", "Something went wrong"},
       {download::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT, "%s - No file",
-       "File wasn\xE2\x80\x99t available on site"},
+       "File wasn’t available on site"},
       {download::DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED,
-       "%s - Needs authorization", "File wasn\xE2\x80\x99t available on site"},
+       "%s - Needs authorization", "File wasn’t available on site"},
       {download::DOWNLOAD_INTERRUPT_REASON_SERVER_CERT_PROBLEM,
-       "%s - Bad certificate", "Site wasn\xE2\x80\x99t available"},
+       "%s - Bad certificate", "Site wasn’t available"},
       {download::DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN, "%s - Forbidden",
-       "File wasn\xE2\x80\x99t available on site"},
+       "File wasn’t available on site"},
       {download::DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE,
-       "%s - Server unreachable", "Site wasn\xE2\x80\x99t available"},
+       "%s - Server unreachable", "Site wasn’t available"},
       {download::DOWNLOAD_INTERRUPT_REASON_SERVER_CONTENT_LENGTH_MISMATCH,
-       "%s - File incomplete", "Couldn\xE2\x80\x99t finish download"},
+       "%s - File incomplete", "Couldn’t finish download"},
       {download::DOWNLOAD_INTERRUPT_REASON_SERVER_CROSS_ORIGIN_REDIRECT,
        "%s - Download error", "Something went wrong"},
       {download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED, "Canceled",
        "Canceled"},
       {download::DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN, "%s - Shutdown",
-       "Couldn\xE2\x80\x99t finish download"},
+       "Couldn’t finish download"},
       {download::DOWNLOAD_INTERRUPT_REASON_CRASH, "%s - Crash",
-       "Couldn\xE2\x80\x99t finish download"},
+       "Couldn’t finish download"},
   };
   static_assert(kInterruptReasonCount == std::size(kTestCases),
                 "interrupt reason mismatch");
diff --git a/chrome/browser/download/download_shelf_context_menu.cc b/chrome/browser/download/download_shelf_context_menu.cc
index 4e66dd5..c717bb2 100644
--- a/chrome/browser/download/download_shelf_context_menu.cc
+++ b/chrome/browser/download/download_shelf_context_menu.cc
@@ -50,7 +50,7 @@
     return;
   }
 
-  for (int command_int = 1; command_int < DownloadCommands::Command::MAX;
+  for (int command_int = 0; command_int <= DownloadCommands::Command::kMaxValue;
        command_int++) {
     if (model->GetIndexOfCommandId(command_int).has_value() &&
         IsCommandIdEnabled(command_int)) {
@@ -210,7 +210,6 @@
     case DownloadCommands::CANCEL_DEEP_SCAN:
     case DownloadCommands::LEARN_MORE_DOWNLOAD_BLOCKED:
     case DownloadCommands::OPEN_SAFE_BROWSING_SETTING:
-    case DownloadCommands::MAX:
       NOTREACHED();
       break;
   }
diff --git a/chrome/browser/download/download_stats.cc b/chrome/browser/download/download_stats.cc
index 7f9bcca..1ee5844 100644
--- a/chrome/browser/download/download_stats.cc
+++ b/chrome/browser/download/download_stats.cc
@@ -95,9 +95,6 @@
     DownloadCommands::Command download_command,
     bool clicked) {
   switch (download_command) {
-    case DownloadCommands::Command::MAX:
-      NOTREACHED();
-      return DownloadShelfContextMenuAction::kMaxValue;
     case DownloadCommands::Command::SHOW_IN_FOLDER:
       return clicked ? DownloadShelfContextMenuAction::kShowInFolderClicked
                      : DownloadShelfContextMenuAction::kShowInFolderEnabled;
diff --git a/chrome/browser/download/download_ui_model.cc b/chrome/browser/download/download_ui_model.cc
index 662d692..c89179a 100644
--- a/chrome/browser/download/download_ui_model.cc
+++ b/chrome/browser/download/download_ui_model.cc
@@ -623,7 +623,6 @@
     case DownloadCommands::OPEN_WHEN_COMPLETE:
     case DownloadCommands::PLATFORM_OPEN:
     case DownloadCommands::ALWAYS_OPEN_TYPE:
-    case DownloadCommands::MAX:
       NOTREACHED();
       return false;
     case DownloadCommands::CANCEL:
@@ -661,7 +660,6 @@
   switch (command) {
     case DownloadCommands::OPEN_WHEN_COMPLETE:
     case DownloadCommands::ALWAYS_OPEN_TYPE:
-    case DownloadCommands::MAX:
       NOTREACHED();
       return false;
     case DownloadCommands::PAUSE:
@@ -694,7 +692,6 @@
     case DownloadCommands::SHOW_IN_FOLDER:
     case DownloadCommands::OPEN_WHEN_COMPLETE:
     case DownloadCommands::ALWAYS_OPEN_TYPE:
-    case DownloadCommands::MAX:
       NOTREACHED();
       break;
     case DownloadCommands::PLATFORM_OPEN:
diff --git a/chrome/browser/download/download_ui_model.h b/chrome/browser/download/download_ui_model.h
index 880f290..7071449 100644
--- a/chrome/browser/download/download_ui_model.h
+++ b/chrome/browser/download/download_ui_model.h
@@ -143,7 +143,7 @@
         // Link text length.
         size_t length = 0;
         // Action to perform when the link is clicked.
-        DownloadCommands::Command command = DownloadCommands::Command::MAX;
+        DownloadCommands::Command command;
       };
 
       // The entire label string with link, i.e. "Learn why Chrome blocks some
diff --git a/chrome/browser/download/notification/download_item_notification.cc b/chrome/browser/download/notification/download_item_notification.cc
index 9bcc8c4..89fbfefe 100644
--- a/chrome/browser/download/notification/download_item_notification.cc
+++ b/chrome/browser/download/notification/download_item_notification.cc
@@ -208,7 +208,6 @@
     case DownloadCommands::BYPASS_DEEP_SCANNING:
     case DownloadCommands::CANCEL_DEEP_SCAN:
     case DownloadCommands::RETRY:
-    case DownloadCommands::MAX:
       NOTREACHED();
       break;
   }
@@ -961,7 +960,6 @@
     case DownloadCommands::BYPASS_DEEP_SCANNING:
     case DownloadCommands::CANCEL_DEEP_SCAN:
     case DownloadCommands::RETRY:
-    case DownloadCommands::MAX:
       // Only for menu.
       NOTREACHED();
       return std::u16string();
diff --git a/chrome/browser/download/offline_item_model.cc b/chrome/browser/download/offline_item_model.cc
index a069747..d0d36a2 100644
--- a/chrome/browser/download/offline_item_model.cc
+++ b/chrome/browser/download/offline_item_model.cc
@@ -295,9 +295,6 @@
     const DownloadCommands* download_commands,
     DownloadCommands::Command command) const {
   switch (command) {
-    case DownloadCommands::MAX:
-      NOTREACHED();
-      return false;
     case DownloadCommands::SHOW_IN_FOLDER:
     case DownloadCommands::OPEN_WHEN_COMPLETE:
     case DownloadCommands::PLATFORM_OPEN:
@@ -330,9 +327,6 @@
     const DownloadCommands* download_commands,
     DownloadCommands::Command command) const {
   switch (command) {
-    case DownloadCommands::MAX:
-      NOTREACHED();
-      return false;
     case DownloadCommands::OPEN_WHEN_COMPLETE:
     case DownloadCommands::ALWAYS_OPEN_TYPE:
       NOTIMPLEMENTED();
@@ -364,9 +358,6 @@
 void OfflineItemModel::ExecuteCommand(DownloadCommands* download_commands,
                                       DownloadCommands::Command command) {
   switch (command) {
-    case DownloadCommands::MAX:
-      NOTREACHED();
-      break;
     case DownloadCommands::SHOW_IN_FOLDER:
     case DownloadCommands::OPEN_WHEN_COMPLETE:
     case DownloadCommands::ALWAYS_OPEN_TYPE:
diff --git a/chrome/browser/enterprise/reporting/prefs.cc b/chrome/browser/enterprise/reporting/prefs.cc
index ca091e1b..d2f0b75c 100644
--- a/chrome/browser/enterprise/reporting/prefs.cc
+++ b/chrome/browser/enterprise/reporting/prefs.cc
@@ -21,7 +21,7 @@
     "enterprise_reporting.extension_request.pending.ids";
 
 const char kCloudLegacyTechReportAllowlist[] =
-    "enterprise_reporting.legachy_tech.urls";
+    "enterprise_reporting.legacy_tech.urls";
 
 const base::TimeDelta kDefaultReportFrequency = base::Hours(24);
 
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index fef3530..f9ba5ed 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -596,8 +596,6 @@
     "external_component_loader.h",
     "external_install_error.cc",
     "external_install_error.h",
-    "external_install_error_constants.cc",
-    "external_install_error_constants.h",
     "external_install_manager.cc",
     "external_install_manager.h",
     "external_loader.cc",
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc b/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc
index 4097a52..6940a10 100644
--- a/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc
+++ b/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc
@@ -37,51 +37,6 @@
 using browsing_data::ClearBrowsingDataTab;
 using content::BrowserThread;
 
-namespace extension_browsing_data_api_constants {
-// Parameter name keys.
-const char kDataRemovalPermittedKey[] = "dataRemovalPermitted";
-const char kDataToRemoveKey[] = "dataToRemove";
-const char kOptionsKey[] = "options";
-
-// Type keys.
-const char kCacheKey[] = "cache";
-const char kCookiesKey[] = "cookies";
-const char kDownloadsKey[] = "downloads";
-const char kFileSystemsKey[] = "fileSystems";
-const char kFormDataKey[] = "formData";
-const char kHistoryKey[] = "history";
-const char kIndexedDBKey[] = "indexedDB";
-const char kLocalStorageKey[] = "localStorage";
-const char kPasswordsKey[] = "passwords";
-const char kPluginDataKeyDeprecated[] = "pluginData";
-const char kServiceWorkersKey[] = "serviceWorkers";
-const char kCacheStorageKey[] = "cacheStorage";
-const char kWebSQLKey[] = "webSQL";
-
-// Option keys.
-const char kExtensionsKey[] = "extension";
-const char kOriginTypesKey[] = "originTypes";
-const char kProtectedWebKey[] = "protectedWeb";
-const char kSinceKey[] = "since";
-const char kOriginsKey[] = "origins";
-const char kExcludeOriginsKey[] = "excludeOrigins";
-const char kUnprotectedWebKey[] = "unprotectedWeb";
-
-// Errors!
-// The placeholder will be filled by the name of the affected data type (e.g.,
-// "history").
-const char kBadDataTypeDetails[] = "Invalid value for data type '%s'.";
-const char kDeleteProhibitedError[] =
-    "Browsing history and downloads are not "
-    "permitted to be removed.";
-const char kNonFilterableError[] =
-    "At least one data type doesn't support filtering by origin.";
-const char kIncompatibleFilterError[] =
-    "Don't set both 'origins' and 'excludeOrigins' at the same time.";
-const char kInvalidOriginError[] = "'%s' is not a valid origin.";
-
-}  // namespace extension_browsing_data_api_constants
-
 namespace {
 
 const int64_t kFilterableDataTypes =
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_api.h b/chrome/browser/extensions/api/browsing_data/browsing_data_api.h
index d3531e1d..0a284ba 100644
--- a/chrome/browser/extensions/api/browsing_data/browsing_data_api.h
+++ b/chrome/browser/extensions/api/browsing_data/browsing_data_api.h
@@ -27,38 +27,47 @@
 namespace extension_browsing_data_api_constants {
 
 // Parameter name keys.
-extern const char kDataRemovalPermittedKey[];
-extern const char kDataToRemoveKey[];
-extern const char kOptionsKey[];
+inline constexpr char kDataRemovalPermittedKey[] = "dataRemovalPermitted";
+inline constexpr char kDataToRemoveKey[] = "dataToRemove";
+inline constexpr char kOptionsKey[] = "options";
 
 // Type keys.
-extern const char kCacheKey[];
-extern const char kCookiesKey[];
-extern const char kDownloadsKey[];
-extern const char kFileSystemsKey[];
-extern const char kFormDataKey[];
-extern const char kHistoryKey[];
-extern const char kIndexedDBKey[];
-extern const char kPluginDataKey[];
-extern const char kLocalStorageKey[];
-extern const char kPasswordsKey[];
-extern const char kServiceWorkersKey[];
-extern const char kCacheStorageKey[];
-extern const char kWebSQLKey[];
+inline constexpr char kCacheKey[] = "cache";
+inline constexpr char kCookiesKey[] = "cookies";
+inline constexpr char kDownloadsKey[] = "downloads";
+inline constexpr char kFileSystemsKey[] = "fileSystems";
+inline constexpr char kFormDataKey[] = "formData";
+inline constexpr char kHistoryKey[] = "history";
+inline constexpr char kIndexedDBKey[] = "indexedDB";
+inline constexpr char kLocalStorageKey[] = "localStorage";
+inline constexpr char kPasswordsKey[] = "passwords";
+inline constexpr char kPluginDataKeyDeprecated[] = "pluginData";
+inline constexpr char kServiceWorkersKey[] = "serviceWorkers";
+inline constexpr char kCacheStorageKey[] = "cacheStorage";
+inline constexpr char kWebSQLKey[] = "webSQL";
 
 // Option keys.
-extern const char kExtensionsKey[];
-extern const char kOriginTypesKey[];
-extern const char kProtectedWebKey[];
-extern const char kSinceKey[];
-extern const char kUnprotectedWebKey[];
+inline constexpr char kExtensionsKey[] = "extension";
+inline constexpr char kOriginTypesKey[] = "originTypes";
+inline constexpr char kProtectedWebKey[] = "protectedWeb";
+inline constexpr char kSinceKey[] = "since";
+inline constexpr char kOriginsKey[] = "origins";
+inline constexpr char kExcludeOriginsKey[] = "excludeOrigins";
+inline constexpr char kUnprotectedWebKey[] = "unprotectedWeb";
 
 // Errors!
-extern const char kBadDataTypeDetails[];
-extern const char kDeleteProhibitedError[];
-extern const char kNonFilterableError[];
-extern const char kIncompatibleFilterError[];
-extern const char kInvalidOriginError[];
+// The placeholder will be filled by the name of the affected data type (e.g.,
+// "history").
+inline constexpr char kBadDataTypeDetails[] =
+    "Invalid value for data type '%s'.";
+inline constexpr char kDeleteProhibitedError[] =
+    "Browsing history and downloads are not "
+    "permitted to be removed.";
+inline constexpr char kNonFilterableError[] =
+    "At least one data type doesn't support filtering by origin.";
+inline constexpr char kIncompatibleFilterError[] =
+    "Don't set both 'origins' and 'excludeOrigins' at the same time.";
+inline constexpr char kInvalidOriginError[] = "'%s' is not a valid origin.";
 
 }  // namespace extension_browsing_data_api_constants
 
diff --git a/chrome/browser/extensions/api/web_accessible_resources_apitest.cc b/chrome/browser/extensions/api/web_accessible_resources_apitest.cc
index c488521..e29aede 100644
--- a/chrome/browser/extensions/api/web_accessible_resources_apitest.cc
+++ b/chrome/browser/extensions/api/web_accessible_resources_apitest.cc
@@ -189,16 +189,13 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), gurl));
   auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
   const int tab_id = ExtensionTabUtil::GetTabId(web_contents);
-  std::string script = base::StringPrintf(
-      R"(
-      (async () => {
+  static constexpr char kScript[] =
+      R"((async () => {
         await chrome.scripting.executeScript(
           {target: {tabId: %d}, files: ['test.js']})
-      })();
-    )",
-      tab_id);
+      })();)";
   BackgroundScriptExecutor::ExecuteScriptAsync(
-      profile(), extension->id(), base::StringPrintf(script.c_str(), tab_id));
+      profile(), extension->id(), base::StringPrintf(kScript, tab_id));
   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
 }
 
@@ -218,7 +215,7 @@
  protected:
   const Extension* GetExtension(const char* manifest_piece) {
     // manifest.json.
-    const char* kManifestStub = R"({
+    static constexpr char kManifestStub[] = R"({
       "name": "Test",
       "version": "1.0",
       "manifest_version": 3,
@@ -240,7 +237,7 @@
     test_dir_.WriteManifest(kManifest);
 
     // content.js
-    const char* kTestScript = R"(
+    static constexpr char kTestScript[] = R"(
       // Verify that web accessible resource can be fetched.
       async function run(expectOk, filename, identifier) {
         return new Promise(async resolve => {
@@ -303,7 +300,7 @@
 
 // Load dynamic web accessible resource from a content script.
 IN_PROC_BROWSER_TEST_F(WebAccessibleResourcesDynamicUrlApiTest, ContentScript) {
-  const char* kManifest = R"(
+  static constexpr char kManifest[] = R"(
     "content_scripts": [
       {
         "matches": ["<all_urls>"],
@@ -325,7 +322,7 @@
 IN_PROC_BROWSER_TEST_F(WebAccessibleResourcesDynamicUrlApiTest, ExecuteScript) {
   // Load extension.
   WriteFile(FILE_PATH_LITERAL("worker.js"), "// Intentionally blank.");
-  const char* kManifest = R"(
+  static constexpr char kManifest[] = R"(
     "permissions": ["scripting"],
     "background": {"service_worker": "worker.js"}
   )";
@@ -338,16 +335,13 @@
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), gurl));
   auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
   const int tab_id = ExtensionTabUtil::GetTabId(web_contents);
-  std::string script = base::StringPrintf(
-      R"(
-      (async () => {
+  static constexpr char kScript[] =
+      R"((async () => {
         await chrome.scripting.executeScript(
           {target: {tabId: %d}, files: ['content.js']})
-      })();
-    )",
-      tab_id);
+      })();)";
   BackgroundScriptExecutor::ExecuteScriptAsync(
-      profile(), extension->id(), base::StringPrintf(script.c_str(), tab_id));
+      profile(), extension->id(), base::StringPrintf(kScript, tab_id));
   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
 }
 
diff --git a/chrome/browser/extensions/back_forward_cache_browsertest.cc b/chrome/browser/extensions/back_forward_cache_browsertest.cc
index 23feeb7..d6628389 100644
--- a/chrome/browser/extensions/back_forward_cache_browsertest.cc
+++ b/chrome/browser/extensions/back_forward_cache_browsertest.cc
@@ -502,14 +502,13 @@
   content::TitleWatcher title_watcher(
       browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
 
-  std::string action =
+  static constexpr char kAction[] =
       R"HTML(
         chrome.runtime.sendMessage('%s', 'some message',
           () => { document.title = 'sent'});
       )HTML";
-  EXPECT_TRUE(
-      ExecJs(render_frame_host_a.get(),
-             base::StringPrintf(action.c_str(), extension->id().c_str())));
+  EXPECT_TRUE(ExecJs(render_frame_host_a.get(),
+                     base::StringPrintf(kAction, extension->id().c_str())));
 
   // 2) Wait until the sendMessage has completed.
   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
diff --git a/chrome/browser/extensions/cross_origin_isolation_browsertest.cc b/chrome/browser/extensions/cross_origin_isolation_browsertest.cc
index b88bfb31e..d62d037 100644
--- a/chrome/browser/extensions/cross_origin_isolation_browsertest.cc
+++ b/chrome/browser/extensions/cross_origin_isolation_browsertest.cc
@@ -348,7 +348,7 @@
   // contexts inherit extension's cross-origin privileges.
   {
     auto execute_fetch = [](content::RenderFrameHost* host, const GURL& url) {
-      const char* kScript = R"(
+      static constexpr char kScript[] = R"(
         fetch('%s')
           .then(response => response.text())
           .catch(err => "Fetch error: " + err);
diff --git a/chrome/browser/extensions/error_console/error_console.cc b/chrome/browser/extensions/error_console/error_console.cc
index 4b0f763..97dbc30c 100644
--- a/chrome/browser/extensions/error_console/error_console.cc
+++ b/chrome/browser/extensions/error_console/error_console.cc
@@ -254,10 +254,10 @@
 void ErrorConsole::AddManifestErrorsForExtension(const Extension* extension) {
   const std::vector<InstallWarning>& warnings =
       extension->install_warnings();
-  for (auto iter = warnings.begin(); iter != warnings.end(); ++iter) {
-    ReportError(std::unique_ptr<ExtensionError>(
-        new ManifestError(extension->id(), base::UTF8ToUTF16(iter->message),
-                          iter->key, base::UTF8ToUTF16(iter->specific))));
+  for (const auto& warning : warnings) {
+    ReportError(std::make_unique<ManifestError>(
+        extension->id(), base::UTF8ToUTF16(warning.message), warning.key,
+        base::UTF8ToUTF16(warning.specific)));
   }
 }
 
diff --git a/chrome/browser/extensions/external_install_error.cc b/chrome/browser/extensions/external_install_error.cc
index cd434f3..ed29bb6 100644
--- a/chrome/browser/extensions/external_install_error.cc
+++ b/chrome/browser/extensions/external_install_error.cc
@@ -13,7 +13,6 @@
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
-#include "base/metrics/field_trial_params.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
 #include "base/strings/utf_string_conversions.h"
@@ -22,7 +21,6 @@
 #include "chrome/browser/extensions/extension_install_error_menu_item_id_provider.h"
 #include "chrome/browser/extensions/extension_install_prompt_show_params.h"
 #include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/external_install_error_constants.h"
 #include "chrome/browser/extensions/external_install_manager.h"
 #include "chrome/browser/extensions/webstore_data_fetcher.h"
 #include "chrome/browser/profiles/profile.h"
@@ -32,7 +30,6 @@
 #include "chrome/browser/ui/global_error/global_error_service.h"
 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/common/chrome_features.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "content/public/browser/storage_partition.h"
@@ -66,19 +63,6 @@
   return l10n_util::GetStringFUTF16(id, base::UTF8ToUTF16(extension->name()));
 }
 
-ExternalInstallError::DefaultDialogButtonSetting
-MapDefaultButtonStringToSetting(const std::string& button_setting_string) {
-  if (button_setting_string == kDefaultDialogButtonSettingOk)
-    return ExternalInstallError::DIALOG_BUTTON_OK;
-  if (button_setting_string == kDefaultDialogButtonSettingCancel)
-    return ExternalInstallError::DIALOG_BUTTON_CANCEL;
-  if (button_setting_string == kDefaultDialogButtonSettingNoDefault)
-    return ExternalInstallError::NO_DEFAULT_DIALOG_BUTTON;
-
-  NOTREACHED() << "Unexpected default button string: " << button_setting_string;
-  return ExternalInstallError::NOT_SPECIFIED;
-}
-
 // A global error that spawns a dialog when the menu item is clicked.
 class ExternalInstallMenuAlert : public GlobalError {
  public:
@@ -133,7 +117,6 @@
   std::vector<std::u16string> GetBubbleViewMessages() override;
   std::u16string GetBubbleViewAcceptButtonLabel() override;
   std::u16string GetBubbleViewCancelButtonLabel() override;
-  int GetDefaultDialogButton() const override;
   void OnBubbleViewDidClose(Browser* browser) override;
   void BubbleViewAcceptButtonPressed(Browser* browser) override;
   void BubbleViewCancelButtonPressed(Browser* browser) override;
@@ -259,20 +242,6 @@
   return messages;
 }
 
-int ExternalInstallBubbleAlert::GetDefaultDialogButton() const {
-  switch (error_->default_dialog_button_setting()) {
-    case ExternalInstallError::DIALOG_BUTTON_OK:
-      return ui::DIALOG_BUTTON_OK;
-    case ExternalInstallError::DIALOG_BUTTON_CANCEL:
-      return ui::DIALOG_BUTTON_CANCEL;
-    case ExternalInstallError::NO_DEFAULT_DIALOG_BUTTON:
-      return ui::DIALOG_BUTTON_NONE;
-    case ExternalInstallError::NOT_SPECIFIED:
-      break;
-  }
-  return GlobalErrorWithStandardBubble::GetDefaultDialogButton();
-}
-
 std::u16string ExternalInstallBubbleAlert::GetBubbleViewAcceptButtonLabel() {
   return prompt_->GetAcceptButtonLabel();
 }
@@ -302,29 +271,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 // ExternalInstallError
 
-// static
-ExternalInstallError::DefaultDialogButtonSetting
-ExternalInstallError::GetDefaultDialogButton(
-    const base::Value::Dict& webstore_response) {
-  const std::string* value_str =
-      webstore_response.FindString(kExternalInstallDefaultButtonKey);
-  if (value_str) {
-    return MapDefaultButtonStringToSetting(*value_str);
-  }
-
-  if (base::FeatureList::IsEnabled(
-          ::features::kExternalExtensionDefaultButtonControl)) {
-    std::string default_button = base::GetFieldTrialParamValueByFeature(
-        ::features::kExternalExtensionDefaultButtonControl,
-        kExternalInstallDefaultButtonKey);
-    if (!default_button.empty()) {
-      return MapDefaultButtonStringToSetting(default_button);
-    }
-  }
-
-  return NOT_SPECIFIED;
-}
-
 ExternalInstallError::ExternalInstallError(
     content::BrowserContext* browser_context,
     const std::string& extension_id,
@@ -443,8 +389,6 @@
     return;
   }
 
-  default_dialog_button_setting_ = GetDefaultDialogButton(webstore_data);
-
   absl::optional<bool> show_user_count =
       webstore_data.FindBool(kShowUserCountKey);
 
diff --git a/chrome/browser/extensions/external_install_error.h b/chrome/browser/extensions/external_install_error.h
index 3fa8984..c5761884 100644
--- a/chrome/browser/extensions/external_install_error.h
+++ b/chrome/browser/extensions/external_install_error.h
@@ -45,14 +45,6 @@
     MENU_ALERT
   };
 
-  // The possible dialog button configurations to use in the error bubble.
-  enum DefaultDialogButtonSetting {
-    NOT_SPECIFIED,
-    DIALOG_BUTTON_OK,
-    DIALOG_BUTTON_CANCEL,
-    NO_DEFAULT_DIALOG_BUTTON
-  };
-
   ExternalInstallError(content::BrowserContext* browser_context,
                        const std::string& extension_id,
                        AlertType error_type,
@@ -78,19 +70,6 @@
   const ExtensionId& extension_id() const { return extension_id_; }
   AlertType alert_type() const { return alert_type_; }
 
-  // Returns the setting specified by the following optional sources, by order
-  // of priority:
-  // 1. The webstore response's |kExternalInstallDefaultButtonKey| parameter.
-  // 2. The |kExternalExtensionDefaultButtonControl| field trial parameter's
-  //    |kExternalInstallDefaultButtonKey| value.
-  // If not specified by either optional source, returns |NOT_SPECIFIED|.
-  static DefaultDialogButtonSetting GetDefaultDialogButton(
-      const base::Value::Dict& webstore_response);
-
-  DefaultDialogButtonSetting default_dialog_button_setting() const {
-    return default_dialog_button_setting_;
-  }
-
  private:
   // WebstoreDataFetcherDelegate implementation.
   void OnWebstoreRequestFailure(const std::string& extension_id) override;
@@ -122,9 +101,6 @@
   // The type of alert to show the user.
   AlertType alert_type_;
 
-  // The dialog button configuration to use in the error bubble.
-  DefaultDialogButtonSetting default_dialog_button_setting_ = NOT_SPECIFIED;
-
   // The owning ExternalInstallManager.
   raw_ptr<ExternalInstallManager> manager_;
 
diff --git a/chrome/browser/extensions/external_install_error_constants.cc b/chrome/browser/extensions/external_install_error_constants.cc
deleted file mode 100644
index b7fc7a3..0000000
--- a/chrome/browser/extensions/external_install_error_constants.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/external_install_error_constants.h"
-
-namespace extensions {
-
-const char kDefaultDialogButtonSettingOk[] = "button_ok";
-const char kDefaultDialogButtonSettingCancel[] = "button_cancel";
-const char kDefaultDialogButtonSettingNoDefault[] = "no_default_button";
-
-}  // namespace extensions
diff --git a/chrome/browser/extensions/external_install_error_constants.h b/chrome/browser/extensions/external_install_error_constants.h
deleted file mode 100644
index 38ab843c..0000000
--- a/chrome/browser/extensions/external_install_error_constants.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_EXTERNAL_INSTALL_ERROR_CONSTANTS_H_
-#define CHROME_BROWSER_EXTENSIONS_EXTERNAL_INSTALL_ERROR_CONSTANTS_H_
-
-namespace extensions {
-
-// Expected |kExternalInstallDefaultButtonKey| parameter values from Feature
-// parameters or from the Webstore response.
-
-// The confirmation button (enable the extension) is the default.
-extern const char kDefaultDialogButtonSettingOk[];
-// The cancel button (remove the extension) is the default.
-extern const char kDefaultDialogButtonSettingCancel[];
-// Neither button is the default.
-extern const char kDefaultDialogButtonSettingNoDefault[];
-
-}  // namespace extensions
-
-#endif  // CHROME_BROWSER_EXTENSIONS_EXTERNAL_INSTALL_ERROR_CONSTANTS_H_
diff --git a/chrome/browser/extensions/external_install_error_unittest.cc b/chrome/browser/extensions/external_install_error_unittest.cc
deleted file mode 100644
index 7f0f56f..0000000
--- a/chrome/browser/extensions/external_install_error_unittest.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/extensions/external_install_error.h"
-
-#include "base/test/scoped_feature_list.h"
-#include "base/values.h"
-#include "chrome/browser/extensions/external_install_error_constants.h"
-#include "chrome/common/chrome_features.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace extensions {
-
-TEST(ExternalInstallErrorTest, DefaultButtonFromFeature) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      features::kExternalExtensionDefaultButtonControl,
-      {{WebstoreDataFetcherDelegate::kExternalInstallDefaultButtonKey,
-        kDefaultDialogButtonSettingOk}});
-
-  EXPECT_EQ(ExternalInstallError::DIALOG_BUTTON_OK,
-            ExternalInstallError::GetDefaultDialogButton({}));
-}
-
-TEST(ExternalInstallErrorTest, DefaultButtonFromWebstoreResponse) {
-  // Set the default button from the feature as well. The webstore response,
-  // when present, should have priority.
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeatureWithParameters(
-      features::kExternalExtensionDefaultButtonControl,
-      {{WebstoreDataFetcherDelegate::kExternalInstallDefaultButtonKey,
-        kDefaultDialogButtonSettingOk}});
-
-  base::Value::Dict webstore_data;
-  webstore_data.Set(
-      WebstoreDataFetcherDelegate::kExternalInstallDefaultButtonKey,
-      kDefaultDialogButtonSettingCancel);
-
-  EXPECT_EQ(ExternalInstallError::DIALOG_BUTTON_CANCEL,
-            ExternalInstallError::GetDefaultDialogButton(webstore_data));
-}
-
-TEST(ExternalInstallErrorTest, DefaultButtonFallback) {
-  EXPECT_EQ(ExternalInstallError::NOT_SPECIFIED,
-            ExternalInstallError::GetDefaultDialogButton({}));
-}
-
-}  // namespace extensions
diff --git a/chrome/browser/extensions/fetch_apitest.cc b/chrome/browser/extensions/fetch_apitest.cc
index d761e2e..69687b7d 100644
--- a/chrome/browser/extensions/fetch_apitest.cc
+++ b/chrome/browser/extensions/fetch_apitest.cc
@@ -47,7 +47,7 @@
 // JavaScript snippet which performs a fetch given a URL expression to be
 // substituted as %s, then sends back the fetched content using
 // chrome.test.sendScriptResult.
-const char* kFetchScript = R"(
+constexpr char kFetchScript[] = R"(
   fetch(%s).then(function(result) {
     return result.text();
   }).then(function(text) {
@@ -59,7 +59,7 @@
 
 // JavaScript snippet which performs a fetch given a URL expression to be
 // substituted as %s.
-const char* kDOMFetchScript = R"(
+constexpr char kDOMFetchScript[] = R"(
   fetch(%s).then(function(result) {
     return result.text();
   }).catch(function(err) {
diff --git a/chrome/browser/extensions/policy_handlers_unittest.cc b/chrome/browser/extensions/policy_handlers_unittest.cc
index 2955b1b..0b4413e 100644
--- a/chrome/browser/extensions/policy_handlers_unittest.cc
+++ b/chrome/browser/extensions/policy_handlers_unittest.cc
@@ -71,14 +71,14 @@
     "  },"
     "}";
 
-const char kTestManagementPolicy3[] =
+constexpr char kTestManagementPolicy3[] =
     "{"
     "  \"*\": {"
     "    \"runtime_blocked_hosts\": [\"%s\"]"
     "  }"
     "}";
 
-const char kTestManagementPolicy4[] =
+constexpr char kTestManagementPolicy4[] =
     "{"
     "  \"*\": {"
     "    \"runtime_allowed_hosts\": [\"%s\"]"
diff --git a/chrome/browser/extensions/wake_event_page_apitest.cc b/chrome/browser/extensions/wake_event_page_apitest.cc
index 227add1d..f22ff0a 100644
--- a/chrome/browser/extensions/wake_event_page_apitest.cc
+++ b/chrome/browser/extensions/wake_event_page_apitest.cc
@@ -33,7 +33,7 @@
 //
 // Expects a single string replacement of the "background" property, including
 // trailing comma, or nothing if there is no background page.
-const char* kManifestJson =
+constexpr char kManifestJson[] =
     "{\n"
     "  %s\n"
     "  'content_scripts': [{\n"
diff --git a/chrome/browser/extensions/webstore_data_fetcher_delegate.cc b/chrome/browser/extensions/webstore_data_fetcher_delegate.cc
index afd385f3..ee481e3 100644
--- a/chrome/browser/extensions/webstore_data_fetcher_delegate.cc
+++ b/chrome/browser/extensions/webstore_data_fetcher_delegate.cc
@@ -7,8 +7,6 @@
 namespace extensions {
 
 const char WebstoreDataFetcherDelegate::kAverageRatingKey[] = "average_rating";
-const char WebstoreDataFetcherDelegate::kExternalInstallDefaultButtonKey[] =
-    "external_install_default_button";
 const char WebstoreDataFetcherDelegate::kIconUrlKey[] = "icon_url";
 const char WebstoreDataFetcherDelegate::kIdKey[] = "id";
 const char WebstoreDataFetcherDelegate::kLocalizedDescriptionKey[] =
diff --git a/chrome/browser/extensions/webstore_data_fetcher_delegate.h b/chrome/browser/extensions/webstore_data_fetcher_delegate.h
index bc6021d..d56e922a 100644
--- a/chrome/browser/extensions/webstore_data_fetcher_delegate.h
+++ b/chrome/browser/extensions/webstore_data_fetcher_delegate.h
@@ -27,7 +27,6 @@
 
   // Keys for indexing the returned webstore data.
   static const char kAverageRatingKey[];
-  static const char kExternalInstallDefaultButtonKey[];
   static const char kIconUrlKey[];
   static const char kIdKey[];
   static const char kLocalizedDescriptionKey[];
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
index 5b4723b..5d8fdb3d 100644
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.cc
@@ -1025,6 +1025,10 @@
 
   PersistedGrantStatus persisted_grant_status = PersistedGrantStatus::kLoaded;
 
+  // Cached data about whether this origin has an actively installed web app.
+  // This is used to determine the origin's extended permission eligibility.
+  WebAppInstallStatus web_app_install_status = WebAppInstallStatus::kUnknown;
+
   // Timer that is triggered whenever the user navigates away from this origin.
   // This is used to give a website a little bit of time for background work
   // before revoking all permissions for the origin.
@@ -1993,6 +1997,11 @@
 
 void ChromeFileSystemAccessPermissionContext::OnWebAppInstalled(
     const webapps::AppId& app_id) {
+  if (!base::FeatureList::IsEnabled(
+          features::kFileSystemAccessPersistentPermissions)) {
+    return;
+  }
+
   auto* provider = web_app::WebAppProvider::GetForWebApps(
       Profile::FromBrowserContext(profile()));
   const auto& registrar = provider->registrar_unsafe();
@@ -2007,6 +2016,17 @@
     return;
   }
   const auto origin = url::Origin::Create(gurl);
+  auto origin_it = active_permissions_map_.find(origin);
+  if (origin_it == active_permissions_map_.end()) {
+    // Ignore the origin if it does not have any active permission.
+    return;
+  }
+
+  // Update the cache value for web app state.
+  OriginState& origin_state = origin_it->second;
+  origin_state.web_app_install_status = WebAppInstallStatus::kInstalled;
+
+  // Update the persisted grants, if needed.
   auto content_setting_value = content_settings_->GetContentSetting(
       origin.GetURL(), origin.GetURL(),
       ContentSettingsType::FILE_SYSTEM_ACCESS_EXTENDED_PERMISSION);
@@ -2017,8 +2037,7 @@
     // change the extended permission state.
     return;
   }
-  if (active_permissions_map_[origin].persisted_grant_status ==
-      PersistedGrantStatus::kCurrent) {
+  if (origin_state.persisted_grant_status == PersistedGrantStatus::kCurrent) {
     // Previously, the given origin's persisted grants were shadow grants, and
     // installing a WebApp promotes these grants to extended grants. The
     // persisted grants are not affected, given that they are now considered
@@ -2030,12 +2049,16 @@
   // are cleared so that they cannot be considered extended grants.
   RevokeObjectPermissions(origin);
   ScheduleUsageIconUpdate();
-  active_permissions_map_[origin].persisted_grant_status =
-      PersistedGrantStatus::kCurrent;
+  origin_state.persisted_grant_status = PersistedGrantStatus::kCurrent;
 }
 
 void ChromeFileSystemAccessPermissionContext::OnWebAppWillBeUninstalled(
     const webapps::AppId& app_id) {
+  if (!base::FeatureList::IsEnabled(
+          features::kFileSystemAccessPersistentPermissions)) {
+    return;
+  }
+
   auto* provider = web_app::WebAppProvider::GetForWebApps(
       Profile::FromBrowserContext(profile()));
   const auto& registrar = provider->registrar_unsafe();
@@ -2044,6 +2067,17 @@
     return;
   }
   const auto origin = url::Origin::Create(gurl);
+  auto origin_it = active_permissions_map_.find(origin);
+  if (origin_it == active_permissions_map_.end()) {
+    // Ignore the origin if it does not have any active permission.
+    return;
+  }
+
+  // Update the cache value for web app state.
+  OriginState& origin_state = origin_it->second;
+  origin_state.web_app_install_status = WebAppInstallStatus::kUninstalled;
+
+  // Update the persisted grants, if needed.
   auto content_setting_value = content_settings_->GetContentSetting(
       origin.GetURL(), origin.GetURL(),
       ContentSettingsType::FILE_SYSTEM_ACCESS_EXTENDED_PERMISSION);
@@ -2058,8 +2092,7 @@
   RevokeObjectPermissions(origin);
   CreatePersistedGrantsFromActiveGrants(origin);
   ScheduleUsageIconUpdate();
-  active_permissions_map_[origin].persisted_grant_status =
-      PersistedGrantStatus::kCurrent;
+  origin_state.persisted_grant_status = PersistedGrantStatus::kCurrent;
 }
 
 void ChromeFileSystemAccessPermissionContext::
@@ -2472,7 +2505,7 @@
 }
 
 bool ChromeFileSystemAccessPermissionContext::OriginHasExtendedPermission(
-    const url::Origin& origin) const {
+    const url::Origin& origin) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
 #if BUILDFLAG(IS_ANDROID)
@@ -2497,26 +2530,36 @@
   }
 
   // If user has not set the extended permission preference, the extended
-  // permission state depends on whether the origin has webapp actively
-  // installed.
+  // permission state depends on whether the origin has an web app actively
+  // installed. First, check the cached value.
+  auto& origin_state = active_permissions_map_[origin];
+  if (origin_state.web_app_install_status != WebAppInstallStatus::kUnknown) {
+    return origin_state.web_app_install_status ==
+           WebAppInstallStatus::kInstalled;
+  }
+  // No cached value for web app install status. Retrieve the install status.
   DCHECK(profile());
   auto* web_app_provider = web_app::WebAppProvider::GetForWebApps(
       Profile::FromBrowserContext(profile()));
   if (!web_app_provider) {
     return false;
   }
-
   auto app_id = web_app_provider->registrar_unsafe().FindAppWithUrlInScope(
       origin.GetURL());
-  return app_id.has_value() &&
-         web_app_provider->registrar_unsafe().IsActivelyInstalled(
-             app_id.value());
+  auto has_actively_installed_app =
+      app_id.has_value() &&
+      web_app_provider->registrar_unsafe().IsActivelyInstalled(app_id.value());
+  // Update the cached value.
+  origin_state.web_app_install_status = has_actively_installed_app
+                                            ? WebAppInstallStatus::kInstalled
+                                            : WebAppInstallStatus::kUninstalled;
+  return has_actively_installed_app;
 #endif  // BUILDFLAG(IS_ANDROID)
 }
 
 ChromeFileSystemAccessPermissionContext::PersistedGrantType
 ChromeFileSystemAccessPermissionContext::GetPersistedGrantType(
-    const url::Origin& origin) const {
+    const url::Origin& origin) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (OriginHasExtendedPermission(origin)) {
diff --git a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h
index b375ab42..56463e4 100644
--- a/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h
+++ b/chrome/browser/file_system_access/chrome_file_system_access_permission_context.h
@@ -292,6 +292,12 @@
     kUpdatePersistedPermission,
   };
 
+  enum class WebAppInstallStatus {
+    kUnknown = 0,
+    kInstalled,
+    kUninstalled,
+  };
+
   void PermissionGrantDestroyed(PermissionGrantImpl* grant);
 
   // Checks whether the file or directory at `path` corresponds to a directory
@@ -412,10 +418,10 @@
 
   // Returns whether the origin has extended permission enabled via user
   // opt-in or by having an actively installed PWA.
-  bool OriginHasExtendedPermission(const url::Origin& origin) const;
+  bool OriginHasExtendedPermission(const url::Origin& origin);
 
   // Retrieve the persisted grant type for a given origin.
-  PersistedGrantType GetPersistedGrantType(const url::Origin& origin) const;
+  PersistedGrantType GetPersistedGrantType(const url::Origin& origin);
 
   PersistedGrantStatus GetPersistedGrantStatus(const url::Origin& origin) const;
   void SetPersistedGrantStatus(const url::Origin& origin,
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index dae869d..360b4f4 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -388,16 +388,6 @@
     "expiry_milestone": 122
   },
   {
-    "name": "arc-use-high-memory-dalvik-profile",
-    "owners": [ "khmel" ],
-    "expiry_milestone": 92
-  },
-  {
-    "name": "arc-use-limit-cache-balloon-policy",
-    "owners": [ "cwd" ],
-    "expiry_milestone": 110
-  },
-  {
     "name": "arc-vmm-swap-keyboard-shortcut",
     "owners": [ "sstan"],
     "expiry_milestone": 120
@@ -507,11 +497,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "autofill-account-profiles-union-view",
-    "owners": [ "vidhanj", "koerber" ],
-    "expiry_milestone": 120
-  },
-  {
     "name": "autofill-address-verification-in-save-prompt",
     "owners": [ "mamir", "koerber" ],
     "expiry_milestone": 120
@@ -652,11 +637,6 @@
     "expiry_milestone": 116
   },
   {
-    "name": "autofill-enable-support-for-landmark",
-    "owners": [ "vizcay","koerber" ],
-    "expiry_milestone": 120
-  },
-  {
     "name": "autofill-enable-update-virtual-card-enrollment",
     "owners": [ "siyua", "jsaul@google.com" ],
     "expiry_milestone": 120
@@ -743,15 +723,6 @@
     "expiry_milestone": 124
   },
   {
-    "name": "autofill-upstream-authenticate-preflight-call",
-    "owners": [
-      "jsaul@google.com",
-      "koulvipul@google.com",
-      "payments-autofill-team@google.com"
-    ],
-    "expiry_milestone": 124
-  },
-  {
     "name": "autofill-use-improved-label-disambiguation",
     "owners": [ "autofill-squad-muc@google.com" ],
     "expiry_milestone": 106
@@ -883,11 +854,6 @@
     "expiry_milestone": 95
   },
   {
-    "name": "bookmark-bottom-sheet",
-    "owners": [ "wylieb" ],
-    "expiry_milestone": 115
-  },
-  {
     "name": "bookmarks-improved-save-flow",
     "owners": ["wylieb", "fgorski", "mdjones"],
     "expiry_milestone": 115
@@ -979,11 +945,6 @@
     "expiry_milestone": 119
   },
   {
-    "name": "calendar-view-debug-mode",
-    "owners": [ "rtinkoff" ],
-    "expiry_milestone": 113
-  },
-  {
     "name": "camera-app-time-lapse",
     "owners": [ "kamchonlathorn", "chromeos-camera-app-eng@google.com" ],
     "expiry_milestone": 120
@@ -1093,16 +1054,6 @@
     "expiry_milestone": 110
   },
   {
-    "name": "cct-resizable-allow-resize-by-user-gesture",
-    "owners": ["jinsukkim", "twellington"],
-    "expiry_milestone": 110
-  },
-  {
-    "name": "cct-resizable-for-first-parties",
-    "owners": ["jinsukkim", "twellington"],
-    "expiry_milestone": 110
-  },
-  {
     "name": "cct-resizable-for-third-parties",
     "owners": ["jinsukkim", "twellington"],
     "expiry_milestone": 110
@@ -1175,11 +1126,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "chrome-whats-new-ui",
-    "owners": [ "rbpotter" ],
-    "expiry_milestone": 116
-  },
-  {
     "name": "chrome-wide-echo-cancellation",
     "owners": [ "olka", "saza", "fhernqvist" ],
     // TODO(http://crubg.com/1372451): remove when we have a proper solution.
@@ -1261,14 +1207,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "consistency-new-account-interface",
-    "owners": [
-      "kalettuce",
-      "chrome-with-friends@google.com"
-    ],
-    "expiry_milestone": 122
-  },
-  {
     "name": "consumer-auto-update-toggle-allowed",
     "owners": [
       "kimjae",
@@ -1366,11 +1304,6 @@
     "expiry_milestone": 119
   },
   {
-    "name": "cpu-affinity-restrict-to-little-cores",
-    "owners": [ "eseckler", "skyostil" ],
-    "expiry_milestone": 107
-  },
-  {
     "name": "cras-split-alsa-usb-internal",
     "owners": [ "whalechang@google.com", "chromeos-audio-sw@google.com" ],
     "expiry_milestone": 125
@@ -1411,11 +1344,6 @@
     "expiry_milestone": 122
   },
   {
-    "name": "cros-labs-overview-scroll-layout-for-clamshell",
-    "owners": [ "sammiequon", "chromeos-wm-corexp@google.com" ],
-    "expiry_milestone": 130
-  },
-  {
     "name": "cros-labs-window-cycle-shortcut",
     "owners": [ "andp", "benbecker", "nupurjain" ],
     "expiry_milestone": 120
@@ -1446,11 +1374,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "cros-privacy-hub-v2",
-    "owners": [ "chromeos-privacyhub@google.com" ],
-    "expiry_milestone": 120
-  },
-  {
     "name": "cros-shortstand",
     "owners": [ "mxcai", "chromeos-apps-foundation-team@google.com" ],
     "expiry_milestone": 130
@@ -1590,11 +1513,6 @@
     "expiry_milestone": 116
   },
   {
-    "name": "default-browser-fullscreen-promo-experiment",
-    "owners": [ "thegreenfrog", "bling-flags@google.com" ],
-    "expiry_milestone": 93
-  },
-  {
     "name": "default-browser-intents-show-settings",
     "owners": [ "olivierrobin", "bling-flags@google.com" ],
     "expiry_milestone": 120
@@ -1788,11 +1706,6 @@
     "expiry_milestone": 100
   },
   {
-    "name": "disable-slow-msaa-in-graphite",
-    "owners": [ "blundell" ],
-    "expiry_milestone": 127
-  },
-  {
     "name": "disable-virtual-keyboard",
     "owners": [ "dvallet", "essential-inputs-team@google.com" ],
     "expiry_milestone": 116
@@ -1838,12 +1751,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "display-sync-errors-refactor",
-    "owners": [ "pakzhygitov", "bling-flags@google.com" ],
-    // This is a temp flag and should be removed within this milestone.
-    "expiry_milestone": 104
-  },
-  {
     "name": "disruptive-notification-permission-revocation",
     "owners": [ "engedy", "ravjit", "andypaicu", "hkamila", "elklm" ],
     "expiry_milestone": 125
@@ -1869,21 +1776,6 @@
     "expiry_milestone": 85
   },
   {
-    "name": "download-auto-resumption-native",
-    "owners": [ "shaktisahu", "qinmin" ],
-    "expiry_milestone": 96
-  },
-  {
-    "name": "download-later",
-    "owners": [ "xingliu", "dtrainor" ],
-    "expiry_milestone": 102
-  },
-  {
-    "name": "download-later-debug-on-wifi",
-    "owners": [ "xingliu", "dtrainor" ],
-    "expiry_milestone": 102
-  },
-  {
     "name": "download-notification-service-unified-api",
     "owners": ["shaktisahu", "qinmin"],
     "expiry_milestone": 125
@@ -2056,7 +1948,7 @@
   {
     "name": "enable-accessibility-live-caption",
     "owners": [ "abigailbklein@google.com", "evliu@google.com", "//ui/accessibility/OWNERS" ],
-    "expiry_milestone": 120
+    "expiry_milestone": 130
   },
   {
     "name": "enable-accessibility-page-zoom",
@@ -2126,7 +2018,7 @@
   {
     "name": "enable-auto-disable-accessibility",
     "owners": [ "abigailbklein@google.com", "//ui/accessibility/OWNERS" ],
-    "expiry_milestone": 120
+    "expiry_milestone": 130
   },
   {
     "name": "enable-auto-disable-accessibility-v2",
@@ -2159,11 +2051,6 @@
     "expiry_milestone": 123
   },
   {
-    "name": "enable-automatic-snooze",
-    "owners": [ "shaktisahu", "haileywang" ],
-    "expiry_milestone": 101
-  },
-  {
     "name": "enable-background-blur",
     "owners": [ "newcomer" ],
     "expiry_milestone": 86
@@ -2181,11 +2068,6 @@
     "expiry_milestone": -1
   },
   {
-    "name": "enable-bluetooth-spp-in-serial-api",
-    "owners": [ "mattreynolds", "//content/browser/serial/OWNERS" ],
-    "expiry_milestone": 120
-  },
-  {
     "name": "enable-bookmarks-account-storage",
     "owners": [ "jlebel", "bsazonov", "chrome-signin-team" ],
     "expiry_milestone": 118
@@ -2338,11 +2220,6 @@
     "expiry_milestone": 116
   },
   {
-    "name": "enable-cros-diacritics-on-physical-keyboard-longpress-on-by-default",
-    "owners": ["jopalmer", "essential-inputs-team@google.com" ],
-    "expiry_milestone": 120
-  },
-  {
     "name": "enable-cros-diacritics-use-replace-surrounding-text",
     "owners": ["jopalmer", "essential-inputs-team@google.com" ],
     "expiry_milestone": 120
@@ -2373,11 +2250,6 @@
     "expiry_milestone": 110
   },
   {
-    "name": "enable-cros-ime-assist-personal-info",
-    "owners": [ "jiwan", "essential-inputs-team@google.com" ],
-    "expiry_milestone": 111
-  },
-  {
     "name": "enable-cros-ime-fst-decoder-params-update",
     "owners": [ "hdchuong", "essential-inputs-team@google.com" ],
     "expiry_milestone": 120
@@ -2388,11 +2260,6 @@
     "expiry_milestone": 122
   },
   {
-    "name": "enable-cros-ime-mozc-proto",
-    "owners": [ "essential-inputs-team@google.com" ],
-    "expiry_milestone": 95
-  },
-  {
     "name": "enable-cros-ime-stylus-handwriting",
     "owners": ["jopalmer", "essential-inputs-team@google.com"],
     "expiry_milestone" : 116
@@ -2463,11 +2330,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "enable-cros-virtual-keyboard-api",
-    "owners": [ "keithlee", "essential-inputs-team@google.com" ],
-    "expiry_milestone": 97
-  },
-  {
     "name": "enable-cros-virtual-keyboard-new-header",
     "owners": ["jopalmer", "essential-inputs-team@google.com"],
     "expiry_milestone" : 116
@@ -2525,16 +2387,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "enable-desktop-pwas-default-offline-page",
-    "owners": [ "catherinecheng@google.com", "anosua@google.com", "ericwilligers@google.com", "alexbn@google.com", "desktop-pwas-team@google.com" ],
-    "expiry_milestone": 118
-  },
-  {
-    "name": "enable-desktop-pwas-detailed-install-dialog",
-    "owners": [ "phillis@chromium.org", "desktop-pwas-team@google.com" ],
-    "expiry_milestone": 116
-  },
-  {
     "name": "enable-desktop-pwas-elided-extensions-menu",
     "owners": [ "cmp@chromium.org", "desktop-pwas-team@google.com" ],
     "expiry_milestone": 130
@@ -2590,11 +2442,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "enable-discover-multi-column",
-    "owners": [ "skavuluru", "clank-app-team@google.com" ],
-    "expiry_milestone": 118
-  },
-  {
     "name": "enable-download-service-foreground-session",
     "owners": [ "rajendrant", "mcrouse", "chrome-intelligence-core@google.com" ],
     "expiry_milestone": 116
@@ -2605,11 +2452,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "enable-drdc-vulkan",
-    "owners": [ "vikassoni", "sunnyps" ],
-    "expiry_milestone": 130
-  },
-  {
     "name": "enable-edge-detection",
     "owners": ["cgzhang","robsc"],
     "expiry_milestone": 120
@@ -2617,7 +2459,7 @@
   {
     "name": "enable-edid-based-display-ids",
     "owners": [ "gildekel", "//ui/display/OWNERS", "chromeos-gfx-display@chromium.org" ],
-    "expiry_milestone": 120
+    "expiry_milestone": 130
   },
   {
     "name": "enable-empty-states",
@@ -2699,11 +2541,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "enable-expkit-calendar-text-classifier",
-    "owners": [ "chrome-intelligence-core@google.com" ],
-    "expiry_milestone": 116
-  },
-  {
     "name": "enable-expkit-text-classifier",
     "owners": [ "chrome-intelligence-core@google.com" ],
     "expiry_milestone": 116
@@ -3184,11 +3021,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "enable-new-download-api",
-    "owners": [ "sdefresne", "bling-flags@google.com" ],
-    "expiry_milestone": 130
-  },
-  {
     "name": "enable-new-download-backend",
     "owners": [ "shaktisahu", "dtrainor" ],
     "expiry_milestone": 97
@@ -3209,11 +3041,6 @@
     "expiry_milestone": 122
   },
   {
-    "name": "enable-notifications-revamp",
-    "owners": [ "amehfooz", "newcomer" ],
-    "expiry_milestone": 106
-  },
-  {
     "name": "enable-notifier-collision",
     "owners": ["leandre"],
     "expiry_milestone": 124
@@ -3267,11 +3094,6 @@
     "expiry_milestone": 121
   },
   {
-    "name": "enable-penetrating-image-selection",
-    "owners": [ "benwgold@google.com", "flackr" ],
-    "expiry_milestone": 95
-  },
-  {
     "name": "enable-per-desk-z-order",
     "owners": [ "dandersson", "janetmac" ],
     "expiry_milestone": 130
@@ -3288,6 +3110,11 @@
     "expiry_milestone": 130
   },
   {
+    "name": "enable-peripheral-notification",
+    "owners": ["dpad", "zentaro", "cros-peripherals@google.com"],
+    "expiry_milestone": 130
+  },
+  {
     "name": "enable-phone-hub-call-notification",
     "owners": [ "jonmann", "nayebi" ],
     "expiry_milestone": 125
@@ -3360,11 +3187,6 @@
     "expiry_milestone": 108
   },
   {
-    "name": "enable-projector-local-playback",
-    "owners": [ "tobyhuang", "cros-projector@google.com" ],
-    "expiry_milestone": 108
-  },
-  {
     "name": "enable-projector-server-side-speech-recognition",
     "owners": ["yilkal", "cros-projector@google.com"],
     "expiry_milestone": 115
@@ -3546,16 +3368,6 @@
     "expiry_milestone": -1
   },
   {
-    "name": "enable-skip-service-worker-check-install-for-promotion",
-    "owners": [ "camdenking@google.com", "desktop-pwas-team@google.com" ],
-    "expiry_milestone": 122
-  },
-  {
-    "name": "enable-skip-service-worker-check-install-only",
-    "owners": [ "camdenking@google.com", "desktop-pwas-team@google.com" ],
-    "expiry_milestone": 122
-  },
-  {
     "name": "enable-smart-card-web-api",
     "owners": ["dandrader@google.com", "vkovalova@google.com"],
     "expiry_milestone": 130
@@ -3665,11 +3477,6 @@
     "expiry_milestone": 90
   },
   {
-    "name": "enable-tab-groups-for-tablets",
-    "owners": [ "skavuluru", "clank-app-team@google.com" ],
-    "expiry_milestone": 114
-  },
-  {
     "name": "enable-tab-strip-redesign",
     "owners": [ "zheliooo@google.com", "skavuluru@google.com", "nemco@google.com", "clank-app-team@google.com" ],
     "expiry_milestone": 125
@@ -3680,11 +3487,6 @@
     "expiry_milestone": 125
   },
   {
-    "name": "enable-tab-switcher-on-return",
-    "owners": [ "memex-team@google.com" ],
-    "expiry_milestone": 108
-  },
-  {
     "name": "enable-tablet-toolbar-reordering",
     "owners": [ "zheliooo@google.com", "twellington@google.com", "nemco@google.com", "clank-app-team@google.com" ],
     "expiry_milestone": 125
@@ -3781,11 +3583,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "enable-vaapi-av1-decode-acceleration",
-    "owners": [ "andrescj", "chromeos-gfx-video@google.com" ],
-    "expiry_milestone": 100
-  },
-  {
     "name": "enable-vaapi-vp9-kSVC-encode-acceleration",
     "owners": [ "mcasas", "chromeos-gfx-video@google.com" ],
     "expiry_milestone": 100
@@ -3842,11 +3639,6 @@
     "expiry_milestone": 92
   },
   {
-    "name": "enable-web-authentication-passkeys-ui-experiment",
-    "owners": [ "agl" ],
-    "expiry_milestone": 118
-  },
-  {
     "name": "enable-web-bluetooth",
     "owners": [ "web-bluetooth@google.com" ],
     "expiry_milestone": 120
@@ -3946,31 +3738,16 @@
     "expiry_milestone": 123
   },
   {
-    "name": "enable-webrtc-analog-agc-clipping-control",
-    "owners": [ "alessiob", "silen", "minyue" ],
-    "expiry_milestone": 103
-  },
-  {
     "name": "enable-webrtc-apm-downmix-capture-audio-method",
     "owners": [ "alessiob", "silen" ],
     "expiry_milestone": 123
   },
   {
-    "name": "enable-webrtc-capture-multi-channel-audio-processing",
-    "owners": [ "saza" ],
-    "expiry_milestone": 123
-  },
-  {
     "name": "enable-webrtc-hide-local-ips-with-mdns",
     "owners": [ "hta" ],
     "expiry_milestone": 120
   },
   {
-    "name": "enable-webrtc-hybrid-agc",
-    "owners": [ "alessiob" ],
-    "expiry_milestone": 103
-  },
-  {
     "name": "enable-webrtc-pipewire-capturer",
     "owners": [ "tomas.popela@gmail.com", "grulja@gmail.com", "mfoltz@google.com", "alcooper@chromium.org" ],
     "expiry_milestone": 120
@@ -4117,11 +3894,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "explore-sites",
-    "owners": [ "chili", "dewittj" ],
-    "expiry_milestone": 102
-  },
-  {
     "name": "expose-out-of-process-video-decoding-to-lacros",
     "owners": [ "pmolinalopez", "andrescj" ],
     "expiry_milestone": 128
@@ -4180,14 +3952,6 @@
     "expiry_milestone": 125
   },
   {
-    "name": "fast-pair-handshake-refactor",
-    "owners": [
-      "//ash/quick_pair/OWNERS",
-      "jackshira"
-    ],
-    "expiry_milestone": 116
-  },
-  {
     "name": "fast-pair-hid",
     "owners": [
       "//ash/quick_pair/OWNERS",
@@ -4363,11 +4127,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "feed-share",
-    "owners": ["//chrome/android/feed/OWNERS", "chili@chromium.org"],
-    "expiry_milestone": 95
-  },
-  {
     "name": "feed-signed-out-view-demotion",
     "owners": ["//components/feed/OWNERS", "harringtond@chromium.org"],
     "expiry_milestone": 122
@@ -4383,16 +4142,6 @@
     "expiry_milestone": 115
   },
   {
-    "name": "feed-video-inline-playback",
-    "owners": [ "//chrome/android/feed/OWNERS", "jianli@chromium.org" ],
-    "expiry_milestone": 115
-  },
-  {
-    "name": "file-handling-api",
-    "owners": [ "dmurph", "mgiuca", "cmp" ],
-    "expiry_milestone": 110
-  },
-  {
     "name": "file-handling-icons",
     "owners": [ "dmurph", "mgiuca", "cmp" ],
     "expiry_milestone": 110
@@ -4607,11 +4356,6 @@
     "expiry_milestone": 81
   },
   {
-    "name": "frame-sink-desktop-capturer-in-crd",
-    "owners" : ["chromeos-commercial-crd@google.com", "macinashutosh@google.com"],
-    "expiry_milestone": 120
-  },
-  {
     "name": "frame-throttle-fps",
     "owners":[ "yjliu", "chromeos-perf@google.com"],
     "expiry_milestone": 95
@@ -4680,11 +4424,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "global-media-controls-for-cast",
-    "owners": [ "takumif", "openscreen-eng@google.com" ],
-    "expiry_milestone": 130
-  },
-  {
     "name": "google-one-offer-files-banner",
     "owners": ["yawano@google.com","assistive-eng@google.com"],
     "expiry_milestone": 116
@@ -4881,11 +4620,6 @@
     "expiry_milestone": -1
   },
   {
-    "name": "in-product-help-snooze",
-    "owners": [ "shaktisahu", "haileywang" ],
-    "expiry_milestone": 101
-  },
-  {
     "name": "in-product-help-use-client-config",
     "owners": [ "shaktisahu", "haileywang" ],
     // This flag is used by teams as they develop in-product help integrations,
@@ -4973,16 +4707,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "interest-feed-v1-clicks-and-views-cond-upload",
-    "owners": [ "//chrome/android/feed/OWNERS", "feed@chromium.org" ],
-    "expiry_milestone": 90
-  },
-  {
-    "name": "interest-feed-v2",
-    "owners": [ "//chrome/android/feed/OWNERS", "feed@chromium.org" ],
-    "expiry_milestone": 95
-  },
-  {
     "name": "ios-breadcrumbs",
     "owners": [ "michaeldo", "bling-flags@google.com" ],
     // Breadcrumbs is not a launching feature, but rather a tool used on
@@ -5105,11 +4829,6 @@
     "expiry_milestone": 109
   },
   {
-    "name": "ios-webpage-intent-annotations",
-    "owners": [ "djean", "bling-flags@google.com" ],
-    "expiry_milestone": 120
-  },
-  {
       "name": "ip-protection-proxy-opt-out",
       "owners": [ "awillia", "//chrome/browser/ip_protection/OWNERS" ],
       "expiry_milestone": 128
@@ -5144,11 +4863,6 @@
       "expiry_milestone": 125
   },
   {
-    "name": "is-name-enabled",
-    "owners": ["brandosocarras@google.com", "jackshira@google.com", "chromeos-cross-device-eng@google.com"],
-    "expiry_milestone": 128
-  },
-  {
     "name": "isolate-origins",
     "owners": [ "site-isolation-dev", "alexmos", "creis", "lukasza" ],
     // This is useful for isolating additional origins beyond the normal site
@@ -5204,14 +4918,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "lacros-move-profile-migration",
-    "owners": ["ythjkt", "hidehiko", "lacros-team@google.com"],
-    // Once Lacros is launched, this flag can be removed. Until then, this
-    // absolutely must not expire. We do not yet have a launch milestone.
-    // TODO(https://crbug.com/1148474).
-    "expiry_milestone": 130
-  },
-  {
     "name": "lacros-only",
     "owners": [ "hidehiko", "erikchen", "lacros-team@google.com" ],
     // Once Lacros is launched, this flag can be removed. Until then, this
@@ -5220,14 +4926,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "lacros-profile-migration-for-any-user",
-    "owners": ["ythjkt", "hidehiko", "lacros-team@google.com"],
-    // Once Lacros is launched, this flag can be removed. Until then, this
-    // absolutely must not expire. We do not yet have a launch milestone.
-    // TODO(https://crbug.com/1148474).
-    "expiry_milestone": 130
-  },
-  {
     "name": "lacros-profile-migration-force-off",
     "owners": ["ythjkt", "hidehiko", "lacros-team@google.com"],
     // Once Lacros is launched, this flag can be removed. Until then, this
@@ -5236,14 +4934,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "lacros-resources-file-sharing",
-    "owners": ["elkurin", "hidehiko", "lacros-team@google.com" ],
-    // Once Lacros is launched, this flag can be removed. Until then, this
-    // absolutely must not expire. We do not yet have a launch milestone.
-    // TODO(https://crbug.com/1148474).
-    "expiry_milestone": 130
-  },
-  {
     "name": "lacros-selection",
     "owners": [ "kimjae", "erikchen", "lacros-team@google.com" ],
     "expiry_milestone": 130
@@ -5365,11 +5055,6 @@
     "expiry_milestone": 122
   },
   {
-    "name": "legacy-tls-interstitial",
-    "owners": [ "cthomp" ],
-    "expiry_milestone": 92
-  },
-  {
     "name": "lens-camera-assisted-search",
     "owners": [ "yusuyoutube@google.com", "benwgold@google.com", "fgorski", "wylieb", "lens-chrome@google.com" ],
     "expiry_milestone": 114
@@ -5399,11 +5084,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "location-bar-model-optimizations",
-    "owners": [ "pnoland@google.com"],
-    "expiry_milestone": 105
-  },
-  {
     "name": "mac-address-randomization",
     "owners": [ "chadduffin", "cros-connectivity@google.com"],
     "expiry_milestone": 125
@@ -5661,16 +5341,6 @@
     "expiry_milestone": 115
   },
   {
-    "name": "new-overflow-menu-alternate-iph",
-    "owners": [ "rkgibson@google.com", "bling-flags@google.com" ],
-    "expiry_milestone": 115
-  },
-  {
-    "name": "new-window-app-menu",
-    "owners": [ "jinsukkim" ],
-    "expiry_milestone": 100
-  },
-  {
     "name": "notification-interaction-history",
     "owners": [
       "sideyilmaz",
@@ -5850,11 +5520,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "ntp-realbox-rounded-corners",
-    "owners": [ "mahmadi", "mfacey" ],
-    "expiry_milestone": 120
-  },
-  {
     "name": "ntp-realbox-use-google-g-icon",
     "owners": [ "mahmadi", "mfacey" ],
     "expiry_milestone": 120
@@ -5937,16 +5602,6 @@
     "expiry_milestone": 130
   },
   {
-    "name": "omnibox-bookmark-paths",
-    "owners": [ "manukh", "chrome-omnibox-team@google.com" ],
-    "expiry_milestone": 115
-  },
-  {
-    "name": "omnibox-bubble-url-suggestions",
-    "owners": [ "manukh", "chrome-omnibox-team@google.com" ],
-    "expiry_milestone": 95
-  },
-  {
     "name": "omnibox-cache-suggestion-resources",
     "owners": ["pnoland", "chrome-omnibox-team@google.com"],
     "expiry_milestone": 120
@@ -5962,11 +5617,6 @@
     "expiry_milestone": 125
   },
   {
-    "name": "omnibox-consumes-ime-insets",
-    "owners": ["pnoland", "chrome-omnibox-team@google.com"],
-    "expiry_milestone": 120
-  },
-  {
     "name": "omnibox-cr23-action-chips",
     "owners": [
       "manukh", "chrome-omnibox-team@google.com"
@@ -6016,11 +5666,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "omnibox-cr23-umbrella",
-    "owners": [ "manukh", "khalid", "chrome-omnibox-team@google.com" ],
-    "expiry_milestone": 120
-  },
-  {
     "name": "omnibox-domain-suggestions",
     "owners": ["manukh", "chrome-omnibox-team@google.com"],
     "expiry_milestone": 120
@@ -6201,31 +5846,11 @@
     "expiry_milestone": 115
   },
   {
-    "name": "omnibox-rich-autocompletion-min-char",
-    "owners": [ "manukh", "chrome-omnibox-team@google.com" ],
-    "expiry_milestone": 115
-  },
-  {
-    "name": "omnibox-rich-autocompletion-prefer-urls-over-prefixes",
-    "owners": [ "manukh", "chrome-omnibox-team@google.com" ],
-    "expiry_milestone": 115
-  },
-  {
     "name": "omnibox-rich-autocompletion-promising",
     "owners": [ "manukh", "chrome-omnibox-team@google.com" ],
     "expiry_milestone": 115
   },
   {
-    "name": "omnibox-rich-autocompletion-shortcut-text",
-    "owners": [ "manukh", "chrome-omnibox-team@google.com" ],
-    "expiry_milestone": 115
-  },
-  {
-    "name": "omnibox-rich-autocompletion-show-additional-text",
-    "owners": [ "manukh", "chrome-omnibox-team@google.com" ],
-    "expiry_milestone": 115
-  },
-  {
     "name": "omnibox-search-client-prefetch",
     "owners": ["ryansturm", "chrome-brapp-loading@google.com"],
     "expiry_milestone": 120
@@ -6265,11 +5890,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "omnibox-trending-zero-prefix-suggestions-on-ntp",
-    "owners": [ "stkhapugin", "chrome-mobile-search@google.com" ],
-    "expiry_milestone": 130
-  },
-  {
     "name": "omnibox-ui-max-autocomplete-matches",
     "owners": [ "jdonnelly", "chrome-omnibox-team@google.com" ],
     "expiry_milestone": 120
@@ -6280,11 +5900,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "omnibox-updated-connection-security-indicators",
-    "owners": [ "meacer", "chrome-trusty-transport@google.com" ],
-    "expiry_milestone": 110
-  },
-  {
     "name": "omnibox-warm-recycled-view-pool",
     "owners": [ "pnoland", "chrome-omnibox-team@google.com" ],
     "expiry_milestone": 120
@@ -6657,11 +6272,6 @@
     "expiry_milestone": 125
   },
   {
-    "name": "power-bookmarks-side-panel",
-    "owners": [ "emshack", "chrome-desktop-ui-sea" ],
-    "expiry_milestone": 118
-  },
-  {
     "name": "prefer-constant-frame-rate",
     "owners": [ "chromeos-camera-eng@google.com" ],
     "expiry_milestone": 130
@@ -6928,11 +6538,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "query-tiles-local-ordering",
-    "owners": [ "qinmin" ],
-    "expiry_milestone": 100
-  },
-  {
     "name": "query-tiles-ntp",
     "owners": [ "shaktisahu", "qinmin" ],
     "expiry_milestone": 120
@@ -7120,22 +6725,22 @@
   {
     "name": "request-desktop-site-defaults",
     "owners": [ "aishwaryarj@google.com", "skavuluru@google.com", "twellington", "clank-app-team@google.com" ],
-    "expiry_milestone": 120
+    "expiry_milestone": 124
   },
   {
     "name": "request-desktop-site-defaults-downgrade",
     "owners": [ "aishwaryarj@google.com", "skavuluru@google.com", "twellington", "clank-app-team@google.com" ],
-    "expiry_milestone": 120
+    "expiry_milestone": 124
   },
   {
     "name": "request-desktop-site-defaults-logging",
     "owners": [ "shuyng@google.com", "skavuluru@google.com", "clank-app-team@google.com" ],
-    "expiry_milestone": 120
+    "expiry_milestone": 124
   },
   {
     "name": "request-desktop-site-window-setting",
     "owners": [ "shuyng@google.com", "skavuluru@google.com", "clank-app-team@google.com" ],
-    "expiry_milestone": 120
+    "expiry_milestone": 124
   },
   {
     "name": "request-desktop-site-zoom",
@@ -7195,11 +6800,6 @@
     "expiry_milestone": 122
   },
   {
-    "name": "safe-mode-for-cached-flags",
-    "owners": ["hnakashima"],
-    "expiry_milestone": 130
-  },
-  {
     "name": "safe-sites-filter-behavior-policy-android",
     "owners": ["ftirelo"],
     "expiry_milestone": 123
@@ -7519,11 +7119,6 @@
     "expiry_milestone" : 110
   },
   {
-    "name": "sim-lock-policy",
-    "owners": [ "hsuregan@google.com", "cros-connectivity@google.com" ],
-    "expiry_milestone": 112
-  },
-  {
     "name": "simplified-bookmark-save-flow",
     "owners": [ "mdjones@google.com", "chrome-shopping-eng@google.com" ],
     "expiry_milestone": 120
@@ -7807,11 +7402,6 @@
     "expiry_milestone": 120
   },
   {
-    "name": "tab-grid-recency-sort",
-    "owners": [ "gambard", "bling-flags@google.com" ],
-    "expiry_milestone": 120
-  },
-  {
     "name": "tab-grid-refactoring",
     "owners": [ "alionadangla", "lpromero", "pakzhygitov", "bling-flags@google.com" ],
     "expiry_milestone": 125
@@ -7892,7 +7482,7 @@
   {
     "name": "text-based-audio-descriptions",
     "owners": [ "abigailbklein@google.com", "evliu@google.com", "//ui/accessibility/OWNERS" ],
-    "expiry_milestone": 120
+    "expiry_milestone": 130
   },
   {
     "name": "text-in-shelf",
@@ -8216,11 +7806,6 @@
     "expiry_milestone": -1
   },
   {
-    "name": "use-toast-manager",
-    "owners": [ "jinsukkim", "twellington" ],
-    "expiry_milestone": 118
-  },
-  {
     "name": "use-wallpaper-staging-url",
     "owners": [ "cros-customization@google.com", "hsuregan", "khorimoto" ],
     // This flag is required for QA and dogfood testing.
@@ -8268,11 +7853,6 @@
   },
 
   {
-    "name": "uxstudy1",
-    "owners": [ "erikchen", "meredithguo@google.com" ],
-    "expiry_milestone": 110
-  },
-  {
     "name": "vc-background-replace",
     "owners": [ "shafron", "skyostil", "charleszhao", "jmpollock" ],
     "expiry_milestone": 120
@@ -8435,7 +8015,7 @@
     "expiry_milestone": 122
   },
   {
-    "name": "web-identity-mdocs",
+    "name": "web-identity-digital-credentials",
     "owners": ["goto", "web-identity-eng@google.com"],
     "expiry_milestone": 120
   },
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 00966b7..779a6dc 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -794,11 +794,6 @@
     "the current page, ignoring any web app manifest information that may be "
     "available.";
 
-const char kDisableSlowMSAAInGraphiteName[] = "Disable Slow MSAA in Graphite";
-const char kDisableSlowMSAAInGraphiteDescription[] =
-    "Configure Graphite to use single sampling if the device is detected as "
-    "having slow MSAA.";
-
 const char kDeviceForceScheduledRebootName[] =
     "Enable DeviceScheduledReboot policy for all sessions.";
 const char kDeviceForceScheduledRebootDescription[] =
@@ -1180,6 +1175,12 @@
     "Enable peripheral customization to allow users to customize buttons on "
     "their peripherals.";
 
+const char kEnablePeripheralNotificationName[] =
+    "Enable peripheral notification";
+const char kEnablePeripheralNotificationDescription[] =
+    "Enable peripheral notification to notify users when a input device is "
+    "connected to the user's chromebook for the first time.";
+
 const char kExperimentalRgbKeyboardPatternsName[] =
     "Enable experimental RGB Keyboard patterns support";
 const char kExperimentalRgbKeyboardPatternsDescription[] =
@@ -1640,9 +1641,9 @@
     "Enables the FedCM IDP sign-in status API that allows IDPs to notify the "
     "browser about the user's sign-in status.";
 
-const char kWebIdentityMDocsName[] = "MDocs";
-const char kWebIdentityMDocsDescription[] =
-    "Allows relying parties to request the presentation of ISO mdocs.";
+const char kWebIdentityDigitalCredentialsName[] = "DigitalCredentials";
+const char kWebIdentityDigitalCredentialsDescription[] =
+    "Enables the three-party verifier/holder/issuer identity model.";
 
 const char kFileHandlingIconsName[] = "File Handling Icons";
 const char kFileHandlingIconsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index fc30bdf..21af566 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -462,9 +462,6 @@
 extern const char kCreateShortcutIgnoresManifestName[];
 extern const char kCreateShortcutIgnoresManifestDescription[];
 
-extern const char kDisableSlowMSAAInGraphiteName[];
-extern const char kDisableSlowMSAAInGraphiteDescription[];
-
 extern const char kDisableProcessReuse[];
 extern const char kDisableProcessReuseDescription[];
 
@@ -789,6 +786,9 @@
 extern const char kEnablePeripheralCustomizationName[];
 extern const char kEnablePeripheralCustomizationDescription[];
 
+extern const char kEnablePeripheralNotificationName[];
+extern const char kEnablePeripheralNotificationDescription[];
+
 extern const char kEnablePixelCanvasRecordingName[];
 extern const char kEnablePixelCanvasRecordingDescription[];
 
@@ -936,8 +936,8 @@
 extern const char kFedCmWithoutWellKnownEnforcementName[];
 extern const char kFedCmWithoutWellKnownEnforcementDescription[];
 
-extern const char kWebIdentityMDocsName[];
-extern const char kWebIdentityMDocsDescription[];
+extern const char kWebIdentityDigitalCredentialsName[];
+extern const char kWebIdentityDigitalCredentialsDescription[];
 
 extern const char kFileHandlingIconsName[];
 extern const char kFileHandlingIconsDescription[];
diff --git a/chrome/browser/hub/BUILD.gn b/chrome/browser/hub/BUILD.gn
index b768dcc..462c0ef 100644
--- a/chrome/browser/hub/BUILD.gn
+++ b/chrome/browser/hub/BUILD.gn
@@ -25,6 +25,7 @@
     "android/java/src/org/chromium/chrome/browser/hub/PaneListBuilder.java",
     "android/java/src/org/chromium/chrome/browser/hub/PaneManager.java",
     "android/java/src/org/chromium/chrome/browser/hub/PaneOrderController.java",
+    "android/java/src/org/chromium/chrome/browser/hub/PresetHubLayoutAnimatorProvider.java",
     "android/java/src/org/chromium/chrome/browser/hub/RunOnNextLayout.java",
     "android/java/src/org/chromium/chrome/browser/hub/RunOnNextLayoutDelegate.java",
   ]
@@ -42,6 +43,7 @@
   deps = [ ":java" ]
 
   sources = [
+    "internal/android/java/src/org/chromium/chrome/browser/hub/FadeHubLayoutAnimationFactory.java",
     "internal/android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationRunnerFactory.java",
     "internal/android/java/src/org/chromium/chrome/browser/hub/HubManagerFactory.java",
   ]
diff --git a/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationListener.java b/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationListener.java
index 374bbae..6f41a71e 100644
--- a/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationListener.java
+++ b/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationListener.java
@@ -18,4 +18,12 @@
      * @param wasForcedToFinish Whether the animation was forced to finish early.
      */
     default void onEnd(boolean wasForcedToFinish) {}
+
+    /**
+     * Called after all {@link #onEnd(boolean)} calls are finished. If the animation hid the {@link
+     * HubLayout} it is now {@link View#INVISIBLE}. If the animation showed the {@link HubLayout} it
+     * is now {@link View#VISIBLE}. This is a good place to cleanup any state that a hide animation
+     * may leave behind.
+     */
+    default void afterEnd() {}
 }
diff --git a/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/PresetHubLayoutAnimatorProvider.java b/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/PresetHubLayoutAnimatorProvider.java
new file mode 100644
index 0000000..8a13999
--- /dev/null
+++ b/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/PresetHubLayoutAnimatorProvider.java
@@ -0,0 +1,44 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.hub;
+
+import androidx.annotation.NonNull;
+
+import org.chromium.base.supplier.SyncOneshotSupplier;
+import org.chromium.base.supplier.SyncOneshotSupplierImpl;
+
+/**
+ * An implementation of {@link HubLayoutAnimatorProvider} to wrap an already completed {@link
+ * HubLayoutAnimator}. Use this if adding a {@link HubLayoutAnimator} that has no async
+ * dependencies.
+ */
+public class PresetHubLayoutAnimatorProvider implements HubLayoutAnimatorProvider {
+    private final SyncOneshotSupplierImpl<HubLayoutAnimator> mPresetAnimatorSupplier;
+
+    /**
+     * Constructor for the {@link PresetHubLayoutAnimatorProvider}.
+     *
+     * @param animator The {@link HubLayoutAnimator} to use.
+     */
+    public PresetHubLayoutAnimatorProvider(@NonNull HubLayoutAnimator animator) {
+        mPresetAnimatorSupplier = new SyncOneshotSupplierImpl<HubLayoutAnimator>();
+        mPresetAnimatorSupplier.set(animator);
+    }
+
+    @Override
+    public @HubLayoutAnimationType int getPlannedAnimationType() {
+        return mPresetAnimatorSupplier.get().getAnimationType();
+    }
+
+    @Override
+    public @NonNull SyncOneshotSupplier<HubLayoutAnimator> getAnimatorSupplier() {
+        return mPresetAnimatorSupplier;
+    }
+
+    @Override
+    public void supplyAnimatorNow() {
+        assert false : "Not reached.";
+    }
+}
diff --git a/chrome/browser/hub/internal/BUILD.gn b/chrome/browser/hub/internal/BUILD.gn
index 70c1a81e..af16b6d 100644
--- a/chrome/browser/hub/internal/BUILD.gn
+++ b/chrome/browser/hub/internal/BUILD.gn
@@ -9,6 +9,8 @@
   visibility = [ "//chrome/android:*" ]
   sources = [
     "android/java/src/org/chromium/chrome/browser/hub/DelegateButtonData.java",
+    "android/java/src/org/chromium/chrome/browser/hub/FadeHubLayoutAnimationFactory.java",
+    "android/java/src/org/chromium/chrome/browser/hub/FadeHubLayoutAnimationFactoryImpl.java",
     "android/java/src/org/chromium/chrome/browser/hub/HubCoordinator.java",
     "android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationRunnerFactory.java",
     "android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationRunnerImpl.java",
@@ -35,6 +37,7 @@
     "//third_party/android_deps:guava_android_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_appcompat_appcompat_resources_java",
+    "//third_party/androidx:androidx_interpolator_interpolator_java",
     "//ui/android:ui_no_recycler_view_java",
   ]
 }
@@ -47,6 +50,7 @@
   resources_package = "org.chromium.chrome.browser.hub"
   sources = [
     "android/java/src/org/chromium/chrome/browser/hub/DelegateButtonDataUnitTest.java",
+    "android/java/src/org/chromium/chrome/browser/hub/FadeHubLayoutAnimationFactoryImplUnitTest.java",
     "android/java/src/org/chromium/chrome/browser/hub/HubCoordinatorUnitTest.java",
     "android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationRunnerImplUnitTest.java",
     "android/java/src/org/chromium/chrome/browser/hub/HubManagerImplUnitTest.java",
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/FadeHubLayoutAnimationFactory.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/FadeHubLayoutAnimationFactory.java
new file mode 100644
index 0000000..93b8aa4b
--- /dev/null
+++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/FadeHubLayoutAnimationFactory.java
@@ -0,0 +1,74 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.hub;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Factory for creating fade {@link HubLayoutAnimator}s and {@link HubLayoutAnimatorProvider}s to
+ * use as {@link HubLayout} animations.
+ *
+ * <p>When using a fade animation as a primary animator provider use {@link
+ * #createFadeInAnimatorProvider(HubContainerView, long)} and {@link
+ * #createFadeOutAnimatorProvider(HubContainerView, long)}.
+ *
+ * <p>On devices that are not large form factor, the fade animation should be the default fallback
+ * animation if an animation is missing dependencies or will take too long to prepare. When
+ * supplying a fade animation as a fallback use {@link #createFadeInAnimator(HubContainerView,
+ * long)} or {@link #createFadeOutAnimator(HubContainerView, long)} to prepare an animator when
+ * {@link HubLayoutAnimatorProvider#supplyAnimatorNow()} is invoked.
+ */
+public class FadeHubLayoutAnimationFactory {
+    /**
+     * Create a fade in {@link HubLayoutAnimator}.
+     *
+     * @param hubContainerView The {@link HubContainerView} to animate.
+     * @param durationMs The duration of the animation in milliseconds.
+     * @return the requested animator.
+     */
+    public static HubLayoutAnimator createFadeInAnimator(
+            @NonNull HubContainerView hubContainerView, long durationMs) {
+        return FadeHubLayoutAnimationFactoryImpl.createFadeInAnimator(hubContainerView, durationMs);
+    }
+
+    /**
+     * Create a fade out {@link HubLayoutAnimator}.
+     *
+     * @param hubContainerView The {@link HubContainerView} to animate.
+     * @param durationMs The duration of the animation in milliseconds.
+     * @return the requested animator.
+     */
+    public static HubLayoutAnimator createFadeOutAnimator(
+            @NonNull HubContainerView hubContainerView, long durationMs) {
+        return FadeHubLayoutAnimationFactoryImpl.createFadeOutAnimator(
+                hubContainerView, durationMs);
+    }
+
+    /**
+     * Create a fade in {@link HubLayoutAnimatorProvider}.
+     *
+     * @param hubContainerView The {@link HubContainerView} to animate.
+     * @param durationMs The duration of the animation in milliseconds.
+     * @return the requested animator provider
+     */
+    public static HubLayoutAnimatorProvider createFadeInAnimatorProvider(
+            @NonNull HubContainerView hubContainerView, long durationMs) {
+        return FadeHubLayoutAnimationFactoryImpl.createFadeInAnimatorProvider(
+                hubContainerView, durationMs);
+    }
+
+    /**
+     * Create a fade out {@link HubLayoutAnimatorProvider}.
+     *
+     * @param hubContainerView The {@link HubContainerView} to animate.
+     * @param durationMs The duration of the animation in milliseconds.
+     * @return the requested animator provider.
+     */
+    public static HubLayoutAnimatorProvider createFadeOutAnimatorProvider(
+            @NonNull HubContainerView hubContainerView, long durationMs) {
+        return FadeHubLayoutAnimationFactoryImpl.createFadeOutAnimatorProvider(
+                hubContainerView, durationMs);
+    }
+}
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/FadeHubLayoutAnimationFactoryImpl.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/FadeHubLayoutAnimationFactoryImpl.java
new file mode 100644
index 0000000..1a6ca5b
--- /dev/null
+++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/FadeHubLayoutAnimationFactoryImpl.java
@@ -0,0 +1,94 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.hub;
+
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.view.View;
+import android.view.animation.Interpolator;
+
+import androidx.annotation.NonNull;
+
+import org.chromium.ui.interpolators.Interpolators;
+
+/** Implementation of interface exposed by {@link FadeHubLayoutAnimationFactory}. */
+public class FadeHubLayoutAnimationFactoryImpl {
+    /** See {@link FadeHubLayoutAnimationFactory#createFadeInAnimator(HubContainerView, long)}. */
+    public static HubLayoutAnimator createFadeInAnimator(
+            @NonNull HubContainerView hubContainerView, long durationMs) {
+        return createFadeAnimator(
+                HubLayoutAnimationType.FADE_IN,
+                hubContainerView,
+                /* initialAlpha= */ 0.0f,
+                /* finalAlpha= */ 1.0f,
+                Interpolators.LINEAR_OUT_SLOW_IN_INTERPOLATOR,
+                durationMs);
+    }
+
+    /** See {@link FadeHubLayoutAnimationFactory#createFadeOutAnimator(HubContainerView, long)}. */
+    public static HubLayoutAnimator createFadeOutAnimator(
+            @NonNull HubContainerView hubContainerView, long durationMs) {
+        return createFadeAnimator(
+                HubLayoutAnimationType.FADE_OUT,
+                hubContainerView,
+                /* initialAlpha= */ 1.0f,
+                /* finalAlpha= */ 0.0f,
+                Interpolators.FAST_OUT_LINEAR_IN_INTERPOLATOR,
+                durationMs);
+    }
+
+    /**
+     * See {@link FadeHubLayoutAnimationFactory#createFadeInAnimatorProvider(HubContainerView,
+     * long)}.
+     */
+    public static HubLayoutAnimatorProvider createFadeInAnimatorProvider(
+            @NonNull HubContainerView hubContainerView, long durationMs) {
+        return new PresetHubLayoutAnimatorProvider(
+                createFadeInAnimator(hubContainerView, durationMs));
+    }
+
+    /**
+     * See {@link FadeHubLayoutAnimationFactory#createFadeOutAnimatorProvider(HubContainerView,
+     * long)}.
+     */
+    public static HubLayoutAnimatorProvider createFadeOutAnimatorProvider(
+            @NonNull HubContainerView hubContainerView, long durationMs) {
+        return new PresetHubLayoutAnimatorProvider(
+                createFadeOutAnimator(hubContainerView, durationMs));
+    }
+
+    private static HubLayoutAnimator createFadeAnimator(
+            @HubLayoutAnimationType int animationType,
+            @NonNull HubContainerView hubContainerView,
+            float initialAlpha,
+            float finalAlpha,
+            Interpolator interpolator,
+            long durationMs) {
+        ObjectAnimator animator =
+                ObjectAnimator.ofFloat(hubContainerView, View.ALPHA, initialAlpha, finalAlpha);
+        animator.setDuration(durationMs);
+        animator.setInterpolator(interpolator);
+
+        AnimatorSet animatorSet = new AnimatorSet();
+        animatorSet.play(animator);
+
+        HubLayoutAnimationListener listener =
+                new HubLayoutAnimationListener() {
+                    @Override
+                    public void beforeStart() {
+                        hubContainerView.setAlpha(initialAlpha);
+                        hubContainerView.setVisibility(View.VISIBLE);
+                    }
+
+                    @Override
+                    public void afterEnd() {
+                        // Reset alpha for the next animation. If the animation is hiding the view
+                        // will already be INVISIBLE. If the animation is showing this is a noop.
+                        hubContainerView.setAlpha(1f);
+                    }
+                };
+        return new HubLayoutAnimator(animationType, animatorSet, listener);
+    }
+}
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/FadeHubLayoutAnimationFactoryImplUnitTest.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/FadeHubLayoutAnimationFactoryImplUnitTest.java
new file mode 100644
index 0000000..53e889b
--- /dev/null
+++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/FadeHubLayoutAnimationFactoryImplUnitTest.java
@@ -0,0 +1,146 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.hub;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.app.Activity;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.shadows.ShadowLooper;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.ui.base.TestActivity;
+
+/** Unit tests for {@link FadeHubLayoutAnimationFactoryImpl}. */
+@RunWith(BaseRobolectricTestRunner.class)
+@LooperMode(LooperMode.Mode.PAUSED)
+public class FadeHubLayoutAnimationFactoryImplUnitTest {
+    private static final long DURATION_MS = 500L;
+    private static final long TIMEOUT_MS = 100L;
+    private static final float FLOAT_TOLERANCE = 0.001f;
+
+    @Rule
+    public ActivityScenarioRule<TestActivity> mActivityScenarioRule =
+            new ActivityScenarioRule<>(TestActivity.class);
+
+    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    @Spy private HubLayoutAnimationListener mListener;
+
+    private Activity mActivity;
+    private FrameLayout mRootView;
+    private HubContainerView mHubContainerView;
+
+    @Before
+    public void setUp() {
+        mActivityScenarioRule
+                .getScenario()
+                .onActivity(
+                        (activity) -> {
+                            mActivity = activity;
+                            mRootView = new FrameLayout(mActivity);
+                            mActivity.setContentView(mRootView);
+
+                            mHubContainerView = new HubContainerView(mActivity);
+                            mHubContainerView.setVisibility(View.INVISIBLE);
+                            mRootView.addView(mHubContainerView);
+                        });
+        ShadowLooper.runUiThreadTasks();
+    }
+
+    @Test
+    @SmallTest
+    public void testFadeIn() {
+        HubLayoutAnimatorProvider animatorProvider =
+                FadeHubLayoutAnimationFactory.createFadeInAnimatorProvider(
+                        mHubContainerView, DURATION_MS);
+        assertEquals(HubLayoutAnimationType.FADE_IN, animatorProvider.getPlannedAnimationType());
+
+        HubLayoutAnimationRunner runner =
+                HubLayoutAnimationRunnerFactory.createHubLayoutAnimationRunner(animatorProvider);
+
+        mListener =
+                spy(
+                        new HubLayoutAnimationListener() {
+                            @Override
+                            public void beforeStart() {
+                                assertEquals(View.VISIBLE, mHubContainerView.getVisibility());
+                                assertEquals(0.0f, mHubContainerView.getAlpha(), FLOAT_TOLERANCE);
+                            }
+
+                            @Override
+                            public void onEnd(boolean wasForcedToFinish) {
+                                assertEquals(View.VISIBLE, mHubContainerView.getVisibility());
+                                assertEquals(1.0f, mHubContainerView.getAlpha(), FLOAT_TOLERANCE);
+                            }
+                        });
+        runner.addListener(mListener);
+
+        runner.runWithWaitForAnimatorTimeout(TIMEOUT_MS);
+
+        ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
+
+        verify(mListener).beforeStart();
+        verify(mListener).onEnd(eq(false));
+    }
+
+    @Test
+    @SmallTest
+    public void testFadeOut() {
+        HubLayoutAnimatorProvider animatorProvider =
+                FadeHubLayoutAnimationFactory.createFadeOutAnimatorProvider(
+                        mHubContainerView, DURATION_MS);
+        assertEquals(HubLayoutAnimationType.FADE_OUT, animatorProvider.getPlannedAnimationType());
+
+        HubLayoutAnimationRunner runner =
+                HubLayoutAnimationRunnerFactory.createHubLayoutAnimationRunner(animatorProvider);
+
+        HubLayoutAnimationListener mListener =
+                spy(
+                        new HubLayoutAnimationListener() {
+                            @Override
+                            public void beforeStart() {
+                                assertEquals(View.VISIBLE, mHubContainerView.getVisibility());
+                                assertEquals(1.0f, mHubContainerView.getAlpha(), FLOAT_TOLERANCE);
+                            }
+
+                            @Override
+                            public void onEnd(boolean wasForcedToFinish) {
+                                assertEquals(View.VISIBLE, mHubContainerView.getVisibility());
+                                assertEquals(0.0f, mHubContainerView.getAlpha(), FLOAT_TOLERANCE);
+                            }
+
+                            @Override
+                            public void afterEnd() {
+                                assertEquals(1.0f, mHubContainerView.getAlpha(), FLOAT_TOLERANCE);
+                            }
+                        });
+        runner.addListener(mListener);
+
+        runner.runWithWaitForAnimatorTimeout(TIMEOUT_MS);
+
+        ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
+
+        verify(mListener).beforeStart();
+        verify(mListener).onEnd(eq(false));
+        verify(mListener).afterEnd();
+    }
+}
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationRunnerImpl.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationRunnerImpl.java
index f5123a37..c7f2eb0 100644
--- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationRunnerImpl.java
+++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationRunnerImpl.java
@@ -157,6 +157,9 @@
                         for (HubLayoutAnimationListener listener : getListenersIterable()) {
                             listener.onEnd(mWasForcedToFinish);
                         }
+                        for (HubLayoutAnimationListener listener : getListenersIterable()) {
+                            listener.afterEnd();
+                        }
                         mListeners = null;
                     }
                 });
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationRunnerImplUnitTest.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationRunnerImplUnitTest.java
index d77ae58..67a09e7 100644
--- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationRunnerImplUnitTest.java
+++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubLayoutAnimationRunnerImplUnitTest.java
@@ -96,6 +96,8 @@
         assertEquals(HubLayoutAnimationType.FADE_IN, mRunner.getAnimationType());
         verify(mAnimatorListener, never()).onEnd(eq(false));
         verify(mListener, never()).onEnd(eq(false));
+        verify(mAnimatorListener, never()).afterEnd();
+        verify(mListener, never()).afterEnd();
     }
 
     @Test
@@ -119,6 +121,8 @@
         assertEquals(AnimationState.FINISHED, mRunner.getAnimationState());
         verify(mAnimatorListener).onEnd(eq(false));
         verify(mListener, never()).onEnd(eq(false));
+        verify(mAnimatorListener).afterEnd();
+        verify(mListener, never()).afterEnd();
     }
 
     @Test
@@ -150,6 +154,8 @@
         assertEquals(AnimationState.FINISHED, mRunner.getAnimationState());
         verify(mAnimatorListener).onEnd(eq(false));
         verify(mListener).onEnd(eq(false));
+        verify(mAnimatorListener).afterEnd();
+        verify(mListener).afterEnd();
     }
 
     @Test
@@ -175,6 +181,8 @@
         assertEquals(AnimationState.FINISHED, mRunner.getAnimationState());
         verify(mAnimatorListener).onEnd(eq(true));
         verify(mListener).onEnd(eq(true));
+        verify(mAnimatorListener).afterEnd();
+        verify(mListener).afterEnd();
     }
 
     @Test
@@ -202,5 +210,7 @@
 
         verify(mAnimatorListener).onEnd(eq(true));
         verify(mListener).onEnd(eq(true));
+        verify(mAnimatorListener).afterEnd();
+        verify(mListener).afterEnd();
     }
 }
diff --git a/chrome/browser/ip_protection/ip_protection_config_provider.cc b/chrome/browser/ip_protection/ip_protection_config_provider.cc
index 54ab14f1..e6dc84c 100644
--- a/chrome/browser/ip_protection/ip_protection_config_provider.cc
+++ b/chrome/browser/ip_protection/ip_protection_config_provider.cc
@@ -73,13 +73,15 @@
 
 void IpProtectionConfigProvider::TryGetAuthTokens(
     uint32_t batch_size,
+    network::mojom::IpProtectionProxyLayer proxy_layer,
     TryGetAuthTokensCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   CHECK(!is_shutting_down_);
   SetUp();
+  CHECK(proxy_layer == network::mojom::IpProtectionProxyLayer::kProxyA);
 
-  // The `batch_size` is cast to an `int` for use by BlindSignAuth, so check for
-  // overflow here.
+  // The `batch_size` is cast to an `int` for use by BlindSignAuth, so check
+  // for overflow here.
   if (batch_size == 0 || batch_size > INT_MAX) {
     mojo::ReportBadMessage("Invalid batch_size");
     return;
diff --git a/chrome/browser/ip_protection/ip_protection_config_provider.h b/chrome/browser/ip_protection/ip_protection_config_provider.h
index 7de313ba..28b637f99 100644
--- a/chrome/browser/ip_protection/ip_protection_config_provider.h
+++ b/chrome/browser/ip_protection/ip_protection_config_provider.h
@@ -83,6 +83,7 @@
   // It is forbidden for two calls to this method to be outstanding at the same
   // time.
   void TryGetAuthTokens(uint32_t batch_size,
+                        network::mojom::IpProtectionProxyLayer proxy_layer,
                         TryGetAuthTokensCallback callback) override;
 
   // Get the list of IP Protection proxies.
diff --git a/chrome/browser/ip_protection/ip_protection_config_provider_browsertest.cc b/chrome/browser/ip_protection/ip_protection_config_provider_browsertest.cc
index 80bc4a7..c971f938 100644
--- a/chrome/browser/ip_protection/ip_protection_config_provider_browsertest.cc
+++ b/chrome/browser/ip_protection/ip_protection_config_provider_browsertest.cc
@@ -73,6 +73,7 @@
   }
 
   void TryGetAuthTokens(uint32_t batch_size,
+                        network::mojom::IpProtectionProxyLayer proxy_layer,
                         TryGetAuthTokensCallback callback) override {
     if (should_intercept_) {
       // NOTE: We'll ignore batch size and just return one token.
@@ -83,7 +84,8 @@
       std::move(callback).Run(std::move(tokens), base::Time());
       return;
     }
-    GetForwardingInterface()->TryGetAuthTokens(batch_size, std::move(callback));
+    GetForwardingInterface()->TryGetAuthTokens(batch_size, proxy_layer,
+                                               std::move(callback));
   }
 
   void EnableInterception() { should_intercept_ = true; }
diff --git a/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc b/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc
index 5cfeec4..3edfd7ce 100644
--- a/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc
+++ b/chrome/browser/ip_protection/ip_protection_config_provider_unittest.cc
@@ -174,7 +174,9 @@
       }
     }
 
-    getter_->TryGetAuthTokens(num_tokens, tokens_future_.GetCallback());
+    getter_->TryGetAuthTokens(num_tokens,
+                              network::mojom::IpProtectionProxyLayer::kProxyA,
+                              tokens_future_.GetCallback());
 
     switch (primary_account_behavior_) {
       case PrimaryAccountBehavior::kNone:
@@ -485,7 +487,8 @@
       absl::optional<std::vector<network::mojom::BlindSignedAuthTokenPtr>>,
       absl::optional<base::Time>>
       tokens_future;
-  getter_->TryGetAuthTokens(1, tokens_future.GetCallback());
+  getter_->TryGetAuthTokens(1, network::mojom::IpProtectionProxyLayer::kProxyA,
+                            tokens_future.GetCallback());
   const absl::optional<base::Time>& try_again_after =
       tokens_future.Get<absl::optional<base::Time>>();
   ASSERT_TRUE(try_again_after);
@@ -497,7 +500,8 @@
 
   bsa_->tokens_ = {{"single-use-1", absl_expiration_time_}};
   tokens_future.Clear();
-  getter_->TryGetAuthTokens(1, tokens_future.GetCallback());
+  getter_->TryGetAuthTokens(1, network::mojom::IpProtectionProxyLayer::kProxyA,
+                            tokens_future.GetCallback());
   identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
       "access_token", base::Time::Now());
   const absl::optional<std::vector<network::mojom::BlindSignedAuthTokenPtr>>&
diff --git a/chrome/browser/lacros/cert/cert_db_initializer_browsertest.cc b/chrome/browser/lacros/cert/cert_db_initializer_browsertest.cc
index 14f59079..fed132d 100644
--- a/chrome/browser/lacros/cert/cert_db_initializer_browsertest.cc
+++ b/chrome/browser/lacros/cert/cert_db_initializer_browsertest.cc
@@ -36,7 +36,7 @@
 // NOTE: Tests in this file modify the certificate store. That is potentially a
 // lasting side effect that can affect other tests.
 // * To prevent interference with tests that are run in parallel, these tests
-// are a part of lacros_chrome_browsertests_run_in_series test suite.
+// are a part of lacros_chrome_browsertests test suite.
 // * To prevent interference with following tests, they try to clean up all the
 // side effects themself, e.g. if a test adds a cert, it is also responsible for
 // deleting it.
diff --git a/chrome/browser/lacros/embedded_a11y_manager_lacros_browsertest.cc b/chrome/browser/lacros/embedded_a11y_manager_lacros_browsertest.cc
index 822b49d8..642279a 100644
--- a/chrome/browser/lacros/embedded_a11y_manager_lacros_browsertest.cc
+++ b/chrome/browser/lacros/embedded_a11y_manager_lacros_browsertest.cc
@@ -41,7 +41,7 @@
 // NOTE: Tests in this file modify Ash accessibility features. That is
 // potentially a lasting side effect that can affect other tests.
 // * To prevent interference with tests that are run in parallel, these tests
-// are a part of lacros_chrome_browsertests_run_in_series test suite.
+// are a part of lacros_chrome_browsertests test suite.
 // * To prevent interference with following tests, they try to clean up all the
 // side effects themselves, e.g. if a test sets a pref, it is also responsible
 // for unsetting it.
diff --git a/chrome/browser/lacros/keystore_service_lacros_browsertest.cc b/chrome/browser/lacros/keystore_service_lacros_browsertest.cc
index 1628069..79808f3 100644
--- a/chrome/browser/lacros/keystore_service_lacros_browsertest.cc
+++ b/chrome/browser/lacros/keystore_service_lacros_browsertest.cc
@@ -28,7 +28,7 @@
 // NOTE: Some tests in this file modify the certificate store. That is
 // potentially a lasting side effect that can affect other tests.
 // * To prevent interference with tests that are run in parallel, these tests
-// are a part of lacros_chrome_browsertests_run_in_series test suite.
+// are a part of lacros_chrome_browsertests test suite.
 // * To prevent interference with following tests, they try to clean up all the
 // side effects themself, e.g. if a test adds a cert, it is also responsible for
 // deleting it.
diff --git a/chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.cc b/chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.cc
index 724f3e4..01fd1e3 100644
--- a/chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.cc
+++ b/chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.cc
@@ -51,9 +51,10 @@
 OptimizationGuideKeyedServiceFactory::~OptimizationGuideKeyedServiceFactory() =
     default;
 
-KeyedService* OptimizationGuideKeyedServiceFactory::BuildServiceInstanceFor(
+std::unique_ptr<KeyedService> 
+  OptimizationGuideKeyedServiceFactory::BuildServiceInstanceForBrowserContext(
     content::BrowserContext* context) const {
-  return new OptimizationGuideKeyedService(context);
+  return std::make_unique<OptimizationGuideKeyedService>(context);
 }
 
 bool OptimizationGuideKeyedServiceFactory::ServiceIsCreatedWithBrowserContext()
diff --git a/chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h b/chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h
index defc01b..aa25bfd 100644
--- a/chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h
+++ b/chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h
@@ -40,7 +40,7 @@
   ~OptimizationGuideKeyedServiceFactory() override;
 
   // BrowserContextKeyedServiceFactory:
-  KeyedService* BuildServiceInstanceFor(
+  std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext(
       content::BrowserContext* context) const override;
   bool ServiceIsCreatedWithBrowserContext() const override;
   bool ServiceIsNULLWhileTesting() const override;
diff --git a/chrome/browser/os_crypt/os_crypt_async_browsertest.cc b/chrome/browser/os_crypt/os_crypt_async_browsertest.cc
new file mode 100644
index 0000000..eca319c
--- /dev/null
+++ b/chrome/browser/os_crypt/os_crypt_async_browsertest.cc
@@ -0,0 +1,36 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include "base/functional/bind.h"
+#include "base/test/bind.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "components/os_crypt/async/browser/os_crypt_async.h"
+#include "components/os_crypt/async/common/encryptor.h"
+#include "content/public/test/browser_test.h"
+
+using OSCryptAsyncBrowserTest = InProcessBrowserTest;
+
+// Test the basic interface to Encrypt and Decrypt data.
+IN_PROC_BROWSER_TEST_F(OSCryptAsyncBrowserTest, EncryptDecrypt) {
+  std::unique_ptr<os_crypt_async::Encryptor> encryptor;
+  auto sub = g_browser_process->os_crypt_async()->GetInstance(
+      base::BindLambdaForTesting(
+          [&encryptor](os_crypt_async::Encryptor instance, bool result) {
+            EXPECT_TRUE(result);
+            encryptor = std::make_unique<os_crypt_async::Encryptor>(
+                std::move(instance));
+          }));
+  ASSERT_TRUE(encryptor);
+
+  auto ciphertext = encryptor->EncryptString("plaintext");
+  ASSERT_TRUE(ciphertext);
+
+  auto decrypted = encryptor->DecryptData(*ciphertext);
+  ASSERT_TRUE(decrypted);
+
+  EXPECT_EQ(*decrypted, "plaintext");
+}
diff --git a/chrome/browser/payments/journey_logger_browsertest.cc b/chrome/browser/payments/journey_logger_browsertest.cc
index b1c43498..043701b 100644
--- a/chrome/browser/payments/journey_logger_browsertest.cc
+++ b/chrome/browser/payments/journey_logger_browsertest.cc
@@ -108,13 +108,6 @@
   EXPECT_THAT(eval_js_result.ExtractString(),
               testing::StartsWith("NotSupportedError"));
 
-  // Make sure that it is not logged as an abort.
-  for (int i = 0; i < static_cast<int>(JourneyLogger::ABORT_REASON_MAX); ++i) {
-    histogram_tester.ExpectBucketCount(
-        "PaymentRequest.CheckoutFunnel.Aborted",
-        static_cast<JourneyLogger::AbortReason>(i), 0);
-  }
-
   // Make sure that it was logged as a reason why the Payment Request was not
   // shown.
   histogram_tester.ExpectBucketCount(
diff --git a/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.h b/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.h
index c52ce20..6bb2f093 100644
--- a/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.h
+++ b/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.h
@@ -11,6 +11,7 @@
 #include "base/sequence_checker.h"
 #include "base/time/time.h"
 #include "components/performance_manager/public/graph/process_node.h"
+#include "components/performance_manager/public/resource_attribution/cpu_measurement_delegate.h"
 #include "components/performance_manager/public/resource_attribution/cpu_measurement_monitor.h"
 #include "components/performance_manager/public/resource_attribution/query_results.h"
 #include "components/performance_manager/public/resource_attribution/resource_contexts.h"
@@ -30,8 +31,7 @@
   // CPUMeasurementDelegate object will be created for each ProcessNode to be
   // measured. Can be overridden for testing by passing a factory callback to
   // SetCPUMeasurementDelegateFactoryForTesting().
-  using CPUMeasurementDelegate =
-      resource_attribution::CPUMeasurementMonitor::CPUMeasurementDelegate;
+  using CPUMeasurementDelegate = resource_attribution::CPUMeasurementDelegate;
 
   // A map from FrameNode's or WorkerNode's to the estimated CPU usage of each.
   // The estimate is a fraction in the range 0% to 100% *
diff --git a/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor_unittest.cc b/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor_unittest.cc
index 6f97c86f..98659d2 100644
--- a/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor_unittest.cc
+++ b/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor_unittest.cc
@@ -4,20 +4,15 @@
 
 #include "chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.h"
 
-#include <map>
 #include <memory>
 #include <utility>
-#include <vector>
 
 #include "base/check.h"
-#include "base/containers/contains.h"
-#include "base/functional/bind.h"
-#include "base/functional/callback.h"
+
 #include "base/memory/weak_ptr.h"
 #include "base/process/kill.h"
 #include "base/process/process.h"
 #include "base/process/process_handle.h"
-#include "base/run_loop.h"
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
@@ -35,6 +30,8 @@
 #include "components/performance_manager/public/resource_attribution/resource_contexts.h"
 #include "components/performance_manager/test_support/graph_test_harness.h"
 #include "components/performance_manager/test_support/mock_graphs.h"
+#include "components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.h"
+#include "components/performance_manager/test_support/run_in_graph.h"
 #include "components/performance_manager/test_support/test_harness_helper.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/process_type.h"
@@ -72,57 +69,6 @@
   ResourceContext resource_context;
 };
 
-// State of a simulated process for CPU measurements.
-class SimulatedCPUMeasurementDelegate final
-    : public PageTimelineCPUMonitor::CPUMeasurementDelegate {
- public:
-  struct CPUUsagePeriod {
-    base::TimeTicks start_time;
-    base::TimeTicks end_time;
-    double cpu_usage;
-  };
-
-  explicit SimulatedCPUMeasurementDelegate(
-      base::OnceClosure unregister_callback)
-      : unregister_callback_(std::move(unregister_callback)) {}
-
-  ~SimulatedCPUMeasurementDelegate() final {
-    std::move(unregister_callback_).Run();
-  }
-
-  // Returns the simulated CPU usage of the process by summing
-  // `cpu_usage_periods`.
-  base::TimeDelta GetCumulativeCPUUsage() final;
-
-  // List of periods of varying CPU usage.
-  std::vector<CPUUsagePeriod> cpu_usage_periods;
-
-  // If not nullopt, GetCumulativeCPUUsage() will ignore `cpu_usage_periods` and
-  // return this value to simulate an error.
-  absl::optional<base::TimeDelta> usage_error;
-
- private:
-  base::OnceClosure unregister_callback_;
-};
-
-base::TimeDelta SimulatedCPUMeasurementDelegate::GetCumulativeCPUUsage() {
-  if (usage_error.has_value()) {
-    return usage_error.value();
-  }
-  base::TimeDelta cumulative_usage;
-  for (const auto& usage_period : cpu_usage_periods) {
-    CHECK(!usage_period.start_time.is_null());
-    // The last interval in the list will have no end time.
-    const base::TimeTicks end_time = usage_period.end_time.is_null()
-                                         ? base::TimeTicks::Now()
-                                         : usage_period.end_time;
-    CHECK(end_time >= usage_period.start_time);
-    cumulative_usage +=
-        (end_time - usage_period.start_time) * usage_period.cpu_usage;
-  }
-  return cumulative_usage;
-}
-
 // Helpers to lookup measurement results from TestNodeWrapper's.
 
 absl::optional<double> GetMeasurementResult(
@@ -148,27 +94,6 @@
                               worker_wrapper->resource_context());
 }
 
-void RunOnPMSequence(base::OnceClosure closure) {
-  base::RunLoop run_loop;
-  PerformanceManager::CallOnGraph(
-      FROM_HERE, base::BindLambdaForTesting([&run_loop, &closure] {
-        std::move(closure).Run();
-        run_loop.Quit();
-      }));
-  run_loop.Run();
-}
-
-void RunOnPMSequence(base::OnceCallback<void(Graph*)> callback) {
-  base::RunLoop run_loop;
-  PerformanceManager::CallOnGraph(
-      FROM_HERE,
-      base::BindLambdaForTesting([&run_loop, &callback](Graph* graph) {
-        std::move(callback).Run(graph);
-        run_loop.Quit();
-      }));
-  run_loop.Run();
-}
-
 // A GMock matcher that will match 0.0 if the kUseResourceAttributionCPUMonitor
 // feature param is enabled, or absl::nullopt if not.
 //
@@ -209,9 +134,8 @@
     mock_utility_process_->SetProcess(base::Process::Current(),
                                       /*launch_time=*/base::TimeTicks::Now());
 
-    cpu_monitor_.SetCPUMeasurementDelegateFactoryForTesting(base::BindRepeating(
-        &PageTimelineCPUMonitorTest::CPUMeasurementDelegateFactory,
-        base::Unretained(this)));
+    cpu_monitor_.SetCPUMeasurementDelegateFactoryForTesting(
+        delegate_factory_.GetFactoryCallback());
   }
 
   // Creates a renderer process containing a single page and frame, for simple
@@ -254,76 +178,27 @@
   }
 
   void SetProcessCPUUsage(const ProcessNodeImpl* process_node, double usage) {
-    SimulatedCPUMeasurementDelegate::CPUUsagePeriod usage_period{
-        .start_time = base::TimeTicks::Now(),
-        .cpu_usage = usage,
-    };
-    auto& delegate = GetOrCreateCPUMeasurementDelegate(process_node);
-    if (!delegate.cpu_usage_periods.empty()) {
-      delegate.cpu_usage_periods.back().end_time = usage_period.start_time;
-    }
-    delegate.cpu_usage_periods.push_back(std::move(usage_period));
+    delegate_factory_.GetDelegate(process_node).SetCPUUsage(usage);
   }
 
   void SetProcessCPUUsageError(const ProcessNodeImpl* process_node,
                                base::TimeDelta usage_error) {
-    GetOrCreateCPUMeasurementDelegate(process_node).usage_error = usage_error;
-  }
-
-  std::unique_ptr<SimulatedCPUMeasurementDelegate>
-  CreateSimulatedCPUMeasurementDelegate(const ProcessNode* process_node) {
-    CHECK(!base::Contains(pending_cpu_delegates_, process_node));
-    CHECK(!base::Contains(simulated_cpu_delegates_, process_node));
-    auto delegate = std::make_unique<SimulatedCPUMeasurementDelegate>(
-        // Clear pointers to this delegate when it's deleted.
-        base::BindLambdaForTesting([this, process_node] {
-          this->simulated_cpu_delegates_.erase(process_node);
-        }));
-    simulated_cpu_delegates_.emplace(process_node, delegate.get());
-    return delegate;
-  }
-
-  std::unique_ptr<PageTimelineCPUMonitor::CPUMeasurementDelegate>
-  CPUMeasurementDelegateFactory(const ProcessNode* process_node) {
-    auto it = pending_cpu_delegates_.find(process_node);
-    if (it != pending_cpu_delegates_.end()) {
-      auto delegate = std::move(it->second);
-      pending_cpu_delegates_.erase(it);
-      return delegate;
-    }
-    return CreateSimulatedCPUMeasurementDelegate(process_node);
-  }
-
-  SimulatedCPUMeasurementDelegate& GetOrCreateCPUMeasurementDelegate(
-      const ProcessNodeImpl* process_node) {
-    auto it = simulated_cpu_delegates_.find(process_node);
-    if (it != simulated_cpu_delegates_.end()) {
-      return *(it->second);
-    }
-    CHECK(!base::Contains(pending_cpu_delegates_, process_node));
-    auto new_delegate = CreateSimulatedCPUMeasurementDelegate(process_node);
-    auto* delegate_ptr = new_delegate.get();
-    CHECK_EQ(simulated_cpu_delegates_.at(process_node), delegate_ptr);
-    pending_cpu_delegates_.emplace(process_node, std::move(new_delegate));
-    return *delegate_ptr;
+    delegate_factory_.GetDelegate(process_node).SetError(usage_error);
   }
 
   base::test::ScopedFeatureList scoped_feature_list_;
 
+  // Factory to return CPUMeasurementDelegates for `cpu_monitor_`. This must be
+  // created before `cpu_monitor_` and deleted afterward to ensure that it
+  // outlives all delegates it creates.
+  resource_attribution::SimulatedCPUMeasurementDelegateFactory
+      delegate_factory_;
+
+  // The object under test.
   PageTimelineCPUMonitor cpu_monitor_;
 
   TestNodeWrapper<ProcessNodeImpl> mock_utility_process_;
 
-  // Map of ProcessNode to CPUMeasurementDelegate that simulates that process.
-  // The delegates are owned by `cpu_monitor_` or `pending_cpu_delegates_`.
-  std::map<const ProcessNode*, SimulatedCPUMeasurementDelegate*>
-      simulated_cpu_delegates_;
-
-  // CPUMeasurementDelegates that have been created but not passed to
-  // `cpu_monitor_` yet.
-  std::map<const ProcessNode*, std::unique_ptr<SimulatedCPUMeasurementDelegate>>
-      pending_cpu_delegates_;
-
   std::unique_ptr<MockMultiplePagesAndWorkersWithMultipleProcessesGraph>
       mock_graph_;
 };
@@ -679,17 +554,17 @@
   void SetUp() override {
     Super::SetUp();
     pm_helper_.SetUp();
-    RunOnPMSequence(base::BindLambdaForTesting([&](Graph* graph) {
+    RunInGraph([&](Graph* graph) {
       cpu_monitor_ = std::make_unique<PageTimelineCPUMonitor>();
       cpu_monitor_->StartMonitoring(graph);
-    }));
+    });
   }
 
   void TearDown() override {
-    RunOnPMSequence(base::BindLambdaForTesting([&](Graph* graph) {
+    RunInGraph([&](Graph* graph) {
       cpu_monitor_->StopMonitoring(graph);
       cpu_monitor_.reset();
-    }));
+    });
     pm_helper_.TearDown();
     Super::TearDown();
   }
@@ -735,18 +610,18 @@
   // but has no pid. (Equivalent to the time between OnProcessNodeAdded and
   // OnProcessLifetimeChange.)
   LetTimePass();
-  RunOnPMSequence(base::BindLambdaForTesting([&] {
+  RunInGraph([&] {
     ASSERT_TRUE(process_node);
     EXPECT_EQ(process_node->GetProcessId(), base::kNullProcessId);
 
     // Process can't be measured yet.
     EXPECT_THAT(get_measurement_result(frame_node), Eq(absl::nullopt));
-  }));
+  });
 
   // Assign a real process to the ProcessNode. (Will call
   // OnProcessLifetimeChange.)
   LetTimePass();
-  RunOnPMSequence(base::BindLambdaForTesting([&] {
+  RunInGraph([&] {
     ASSERT_TRUE(process_node);
     ProcessNodeImpl::FromNode(process_node.get())
         ->SetProcess(base::Process::Current(), base::TimeTicks::Now());
@@ -755,13 +630,13 @@
     // Process can be measured now.
     ASSERT_TRUE(frame_node);
     EXPECT_THAT(get_measurement_result(frame_node), Optional(_));
-  }));
+  });
 
   // Simulate that the process died.
   LetTimePass();
   process()->SimulateRenderProcessExit(
       base::TERMINATION_STATUS_NORMAL_TERMINATION, 0);
-  RunOnPMSequence(base::BindLambdaForTesting([&] {
+  RunInGraph([&] {
     // Process is no longer running, so can't be measured.
     // TODO(crbug.com/1410503): Capture the final CPU usage correctly.
     ASSERT_TRUE(process_node);
@@ -773,7 +648,7 @@
     if (frame_node) {
       EXPECT_THAT(get_measurement_result(frame_node), Eq(absl::nullopt));
     }
-  }));
+  });
 }
 
 }  // namespace performance_manager::metrics
diff --git a/chrome/browser/performance_manager/metrics/page_timeline_monitor_unittest.cc b/chrome/browser/performance_manager/metrics/page_timeline_monitor_unittest.cc
index 4379ca0..b35bd0e 100644
--- a/chrome/browser/performance_manager/metrics/page_timeline_monitor_unittest.cc
+++ b/chrome/browser/performance_manager/metrics/page_timeline_monitor_unittest.cc
@@ -15,7 +15,6 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
-#include "base/time/time.h"
 #include "build/build_config.h"
 #include "chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.h"
 #include "components/performance_manager/public/decorators/page_live_state_decorator.h"
@@ -25,6 +24,7 @@
 #include "components/performance_manager/public/user_tuning/prefs.h"
 #include "components/performance_manager/test_support/graph_test_harness.h"
 #include "components/performance_manager/test_support/mock_graphs.h"
+#include "components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/ukm/test_ukm_recorder.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
@@ -43,37 +43,6 @@
 using PageMeasurementBackgroundState =
     PageTimelineMonitor::PageMeasurementBackgroundState;
 
-// A class that returns defaults to returning 50% CPU used since it was created,
-// but the divisor for what proportion of a CPU is being used is configurable.
-class FixedCPUMeasurementDelegate final
-    : public PageTimelineCPUMonitor::CPUMeasurementDelegate {
- public:
-  FixedCPUMeasurementDelegate() = default;
-  ~FixedCPUMeasurementDelegate() final = default;
-
-  base::TimeDelta GetCumulativeCPUUsage() final {
-    return (base::TimeTicks::Now() - creation_time_) * cpu_scale_factor_;
-  }
-
-  static std::unique_ptr<CPUMeasurementDelegate> Create(const ProcessNode*) {
-    return std::make_unique<FixedCPUMeasurementDelegate>();
-  }
-
-  static void SetCPUScaleFactor(double scale_factor) {
-    FixedCPUMeasurementDelegate::cpu_scale_factor_ = scale_factor;
-  }
-
-  static void ResetCPUScaleFactor() {
-    FixedCPUMeasurementDelegate::cpu_scale_factor_ = 0.5;
-  }
-
- private:
-  base::TimeTicks creation_time_ = base::TimeTicks::Now();
-  static double cpu_scale_factor_;
-};
-
-double FixedCPUMeasurementDelegate::cpu_scale_factor_ = 0.5;
-
 }  // namespace
 
 class PageTimelineMonitorUnitTest : public GraphTestHarness {
@@ -91,6 +60,9 @@
     graph()->PassToGraph(
         std::make_unique<performance_manager::TabPageDecorator>());
 
+    // Return 50% CPU used by default.
+    cpu_delegate_factory_.SetDefaultCPUUsage(0.5);
+
     std::unique_ptr<PageTimelineMonitor> monitor =
         std::make_unique<PageTimelineMonitor>();
     monitor_ = monitor.get();
@@ -98,7 +70,7 @@
     monitor_->SetShouldCollectSliceCallbackForTesting(
         base::BindRepeating([]() { return true; }));
     monitor_->cpu_monitor_.SetCPUMeasurementDelegateFactoryForTesting(
-        base::BindRepeating(&FixedCPUMeasurementDelegate::Create));
+        cpu_delegate_factory_.GetFactoryCallback());
     graph()->PassToGraph(std::move(monitor));
     ResetUkmRecorder();
   }
@@ -113,6 +85,11 @@
 
   base::HistogramTester histogram_tester_;
 
+  // Factory to return CPUMeasurementDelegates. This must be deleted after
+  // `monitor_` to ensure that it outlives all delegates it creates.
+  resource_attribution::SimulatedCPUMeasurementDelegateFactory
+      cpu_delegate_factory_;
+
  protected:
   ukm::TestUkmRecorder* test_ukm_recorder() { return test_ukm_recorder_.get(); }
   PageTimelineMonitor* monitor() { return monitor_; }
@@ -619,7 +596,7 @@
           // `other_page` is the sum of `other_frame` and `child_frame`
           {mock_source_id2, 1789},
       });
-  // FixedCPUMeasurementDelegate always returns 50% of the CPU is used.
+  // The SimulatedCPUMeasurementDelegate returns 50% of the CPU is used.
   // `process` contains `frame` and `other_frame` -> each gets 25%
   // `other_process` contains `child_frame` -> 50%
   const auto kExpectedCPUUsage =
@@ -695,12 +672,6 @@
 
 #if !BUILDFLAG(IS_ANDROID)
 TEST_P(PageTimelineMonitorWithFeatureTest, TestCPUInterventionMetrics) {
-  // The intervention metrics measure total CPU, not percentage of each core, so
-  // set the measurement delegate to return half of the total available CPU
-  // (100% per processor).
-  FixedCPUMeasurementDelegate::SetCPUScaleFactor(
-      base::SysInfo::NumberOfProcessors() / 2);
-
   MockMultiplePagesWithMultipleProcessesGraph mock_graph(graph());
   const ukm::SourceId mock_source_id = ukm::AssignNewSourceId();
   mock_graph.page->SetType(performance_manager::PageType::kTab);
@@ -711,6 +682,14 @@
   mock_graph.other_page->SetType(performance_manager::PageType::kTab);
   mock_graph.other_page->SetUkmSourceId(mock_source_id2);
 
+  // The intervention metrics measure total CPU, not percentage of each core, so
+  // set the measurement delegates to return half of the total available CPU
+  // (100% per processor).
+  cpu_delegate_factory_.GetDelegate(mock_graph.process.get())
+      .SetCPUUsage(base::SysInfo::NumberOfProcessors() / 2);
+  cpu_delegate_factory_.GetDelegate(mock_graph.other_process.get())
+      .SetCPUUsage(base::SysInfo::NumberOfProcessors() / 2);
+
   // Let an arbitrary amount of time pass so there's some CPU usage to measure.
   task_env().FastForwardBy(base::Minutes(1));
   TriggerCollectPageResourceUsage();
@@ -804,11 +783,19 @@
         "TopNBackgroundCPU.2."
         "Delayed",
         75, 1);
+  } else {
+    // The legacy CPU monitor only measures the CPU during
+    // TriggerCollectPageResourceUsage(), and returns the average CPU since the
+    // last call. Measure now so the next test doesn't include the last minute
+    // of CPU in the average.
+    TriggerCollectPageResourceUsage();
   }
 
   // Lower CPU measurement so the duration is logged.
-  FixedCPUMeasurementDelegate::SetCPUScaleFactor(
-      base::SysInfo::NumberOfProcessors() / 6);
+  cpu_delegate_factory_.GetDelegate(mock_graph.process.get())
+      .SetCPUUsage(base::SysInfo::NumberOfProcessors() / 6);
+  cpu_delegate_factory_.GetDelegate(mock_graph.other_process.get())
+      .SetCPUUsage(base::SysInfo::NumberOfProcessors() / 6);
   task_env().FastForwardBy(base::Minutes(1));
   TriggerCollectPageResourceUsage();
 
@@ -816,8 +803,6 @@
       "PerformanceManager.PerformanceInterventions.CPU."
       "DurationOverThreshold",
       base::Minutes(2).InMilliseconds(), 1);
-
-  FixedCPUMeasurementDelegate::ResetCPUScaleFactor();
 }
 #endif
 
diff --git a/chrome/browser/picture_in_picture/auto_pip_setting_view.cc b/chrome/browser/picture_in_picture/auto_pip_setting_view.cc
index d398ac5..7a27ce89 100644
--- a/chrome/browser/picture_in_picture/auto_pip_setting_view.cc
+++ b/chrome/browser/picture_in_picture/auto_pip_setting_view.cc
@@ -33,16 +33,16 @@
 constexpr int kBubbleFixedWidth = 320;
 
 // Bubble border corner radius.
-constexpr int kBubbleBorderCornerRadius = 15;
+constexpr int kBubbleBorderCornerRadius = 12;
 
 // Bubble border MD shadow elevation.
 constexpr int kBubbleBorderMdShadowElevation = 2;
 
 // Bubble margins.
-constexpr gfx::Insets kBubbleMargins = gfx::Insets::TLBR(0, 20, 15, 20);
+constexpr gfx::Insets kBubbleMargins = gfx::Insets::TLBR(0, 20, 20, 20);
 
 // Bubble title margins.
-constexpr gfx::Insets kBubbleTitleMargins = gfx::Insets::TLBR(15, 20, 10, 20);
+constexpr gfx::Insets kBubbleTitleMargins = gfx::Insets::TLBR(16, 20, 10, 20);
 
 // Maximum origin text width, for cases where the origin needs to be
 // elided.
diff --git a/chrome/browser/policy/messaging_layer/upload/configuration_file_controller.cc b/chrome/browser/policy/messaging_layer/upload/configuration_file_controller.cc
new file mode 100644
index 0000000..8822475f
--- /dev/null
+++ b/chrome/browser/policy/messaging_layer/upload/configuration_file_controller.cc
@@ -0,0 +1,209 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/messaging_layer/upload/configuration_file_controller.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <limits>
+#include <string_view>
+#include <vector>
+
+#include "base/feature_list.h"
+#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/sys_byteorder.h"
+#include "chrome/browser/policy/messaging_layer/upload/record_upload_request_builder.h"
+#include "components/reporting/encryption/primitives.h"
+#include "components/reporting/encryption/verification.h"
+#include "components/reporting/proto/synced/record.pb.h"
+#include "components/reporting/util/status.h"
+#include "components/version_info/version_info.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace reporting {
+namespace {
+// Checks if two lists contain the same destinations.
+bool DestinationListsEqual(ListOfBlockedDestinations list_a,
+                           ListOfBlockedDestinations list_b) {
+  if (list_a.destinations_size() != list_b.destinations_size()) {
+    return false;
+  }
+  return std::equal(list_a.destinations().begin(), list_a.destinations().end(),
+                    list_b.destinations().begin());
+}
+}  // namespace
+
+// Only used in testing. Feature for testing the configuration file in our
+// automated tests. Not exposed on the UI.
+BASE_FEATURE(kReportingConfigurationFileTestSignature,
+             "ReportingConfigurationFileTestSignature",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+ConfigurationFileController::~ConfigurationFileController() = default;
+
+// The default constructor used for this class takes as a parameter a callback
+// that sends information to missive after being verified by this class if
+// needed. It also creates the signature verifier that will be used to verify
+// the signature of the configuration file using the well-known prod key stored
+// in Chrome.
+ConfigurationFileController::ConfigurationFileController(
+    UploadClient::UpdateConfigInMissiveCallback update_config_in_missive_cb)
+    : verifier_(SignatureVerifier(SignatureVerifier::VerificationKey())) {
+  ConfigurationFileController(std::move(update_config_in_missive_cb),
+                              ListOfBlockedDestinations(),
+                              version_info::GetMajorVersionNumberAsInt());
+}
+
+int32_t ConfigurationFileController::HandleConfigurationFile(
+    reporting::ConfigFile config_file) {
+  // Sanity check to verify that the experiment is enabled.
+  if (!base::FeatureList::IsEnabled(kShouldRequestConfigurationFile)) {
+    // Returns -1 since this is not an actual error with the file provided.
+    return kFeatureDisabled;
+  }
+
+  // Check if we got the same version that we were using already.
+  // This might happen if the server returns the configuration file two times
+  // with the same version because of two requests made close to each other, we
+  // just ignore them if that's the case and return the current version. We also
+  // just ignore the config file if the version is negative.
+  if (config_file.version() == current_config_file_version_ ||
+      config_file.version() < 0) {
+    return current_config_file_version_;
+  }
+
+  // Verify signature.
+  const auto signature_verification_status = VerifySignature(config_file);
+  if (!signature_verification_status.ok()) {
+    base::UmaHistogramEnumeration(
+        "Browser.ERP.ConfigFileSignatureVerificationError",
+        signature_verification_status.code(), error::Code::MAX_VALUE);
+    return kConfigurationFileCorrupted;
+  }
+
+  // Check if we should send the list of blocked destinations to missive.
+  if (HandleBlockedEventConfigs(config_file.blocked_event_configs())) {
+    update_config_in_missive_cb_.Run(destinations_list_);
+  }
+
+  // If we reached here it means that we just got a new version of the config
+  // file from the server so we update the version being sent on the payload and
+  // the one stored by this class.
+  current_config_file_version_ = config_file.version();
+  return current_config_file_version_;
+}
+
+Status ConfigurationFileController::VerifySignature(ConfigFile config_file) {
+  // We don't check the signature in our tests. This flag is only used inside
+  // the tast tests.
+  if (base::FeatureList::IsEnabled(kReportingConfigurationFileTestSignature)) {
+    return Status::StatusOK();
+  }
+
+  // Sanity checks, this should never fail.
+  if (!config_file.has_version()) {
+    return Status{error::INVALID_ARGUMENT,
+                  "Missing version information for config file"};
+  }
+
+  if (!config_file.has_config_file_signature()) {
+    return Status{error::INVALID_ARGUMENT,
+                  "Missing signature information for config file"};
+  }
+
+  // Verify the value signed on the server using the big-endian representation
+  // of the configuration file version.
+  const int32_t version_to_verify = base::HostToNet32(config_file.version());
+  return verifier_.Verify(
+      std::string_view(reinterpret_cast<const char*>(&version_to_verify),
+                       sizeof(int32_t)),
+      config_file.config_file_signature());
+}
+
+// static
+std::unique_ptr<ConfigurationFileController>
+ConfigurationFileController::CreateForTesting(
+    UploadClient::UpdateConfigInMissiveCallback update_config_in_missive_cb,
+    ListOfBlockedDestinations destinations_list,
+    int os_version) {
+  return base::WrapUnique(new ConfigurationFileController(
+      std::move(update_config_in_missive_cb), std::move(destinations_list),
+      os_version));
+}
+
+ConfigurationFileController::ConfigurationFileController(
+    UploadClient::UpdateConfigInMissiveCallback update_config_in_missive_cb,
+    ListOfBlockedDestinations destinations_list,
+    int os_version)
+    : update_config_in_missive_cb_(std::move(update_config_in_missive_cb)),
+      verifier_(SignatureVerifier(SignatureVerifier::VerificationKey())),
+      destinations_list_(std::move(destinations_list)),
+      current_os_version_(os_version) {}
+
+bool ConfigurationFileController::HandleBlockedEventConfigs(
+    google::protobuf::RepeatedPtrField<EventConfig> blocked_event_configs) {
+  // If the incoming list is empty and the stored list is also empty
+  // we return false to signal to the parent function that it should not
+  // send the list to missive.
+  if (blocked_event_configs.empty() &&
+      destinations_list_.destinations().empty()) {
+    return false;
+  }
+
+  // If the configuration fetched from the server is empty and the stored list
+  // is not empty we return true to signal to the parent function that it
+  // should update the list in missive to an empty one.
+  if (blocked_event_configs.empty() &&
+      !destinations_list_.destinations().empty()) {
+    destinations_list_ = ListOfBlockedDestinations();
+    return true;
+  }
+
+  ListOfBlockedDestinations current_list;
+  //  Check all the destinations, if they have version information
+  //  we check whether it should be blocked or not.
+  for (const auto& current_event : blocked_event_configs) {
+    // If there is no minimum/maximum release version specified we add it
+    // directly since it should be blocked on all versions.
+    if (!current_event.has_minimum_release_version()) {
+      current_list.add_destinations(current_event.destination());
+      continue;
+    }
+
+    // Check if it should be blocked for the current version or not.
+    absl::optional<int32_t> maximum_version;
+    maximum_version =
+        current_event.has_maximum_release_version()
+            ? absl::optional<int32_t>(current_event.maximum_release_version())
+            : absl::nullopt;
+    if (ShouldBeBlocked(current_event.minimum_release_version(),
+                        maximum_version)) {
+      current_list.add_destinations(current_event.destination());
+    }
+  }
+
+  // Compare to see if the destinations list that we have right now is the same
+  // as the one that is incoming from the server, if not then we swap the lists
+  // and we notify the parent function that it should send the new list to
+  // missive.
+  if (DestinationListsEqual(current_list, destinations_list_)) {
+    return false;
+  }
+
+  destinations_list_ = std::move(current_list);
+  return true;
+}
+
+bool ConfigurationFileController::ShouldBeBlocked(
+    int32_t minimum_version,
+    absl::optional<int32_t> maximum_version) const {
+  if (maximum_version.has_value()) {
+    return current_os_version_ >= minimum_version &&
+           current_os_version_ <= maximum_version.value();
+  }
+  return current_os_version_ >= minimum_version;
+}
+
+}  // namespace reporting
diff --git a/chrome/browser/policy/messaging_layer/upload/configuration_file_controller.h b/chrome/browser/policy/messaging_layer/upload/configuration_file_controller.h
new file mode 100644
index 0000000..1170a9b
--- /dev/null
+++ b/chrome/browser/policy/messaging_layer/upload/configuration_file_controller.h
@@ -0,0 +1,97 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_MESSAGING_LAYER_UPLOAD_CONFIGURATION_FILE_CONTROLLER_H_
+#define CHROME_BROWSER_POLICY_MESSAGING_LAYER_UPLOAD_CONFIGURATION_FILE_CONTROLLER_H_
+
+#include <atomic>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+#include "base/feature_list.h"
+#include "base/values.h"
+#include "chrome/browser/policy/messaging_layer/upload/upload_client.h"
+#include "components/reporting/encryption/verification.h"
+#include "components/reporting/proto/synced/configuration_file.pb.h"
+#include "components/reporting/proto/synced/record.pb.h"
+#include "components/reporting/util/status.h"
+
+namespace reporting {
+
+// Used to let the server know that the feature is disabled on the client side.
+static constexpr int32_t kFeatureDisabled = -1;
+// Used to let the server know that there is something wrong with the
+// configuration file.
+static constexpr int32_t kConfigurationFileCorrupted = -2;
+
+BASE_DECLARE_FEATURE(kReportingConfigurationFileTestSignature);
+class ConfigurationFileControllerTest;
+
+class ConfigurationFileController {
+ public:
+  explicit ConfigurationFileController(
+      UploadClient::UpdateConfigInMissiveCallback update_config_in_missive_cb);
+
+  ConfigurationFileController(const ConfigurationFileController&) = delete;
+  ConfigurationFileController& operator=(const ConfigurationFileController&) =
+      delete;
+
+  ~ConfigurationFileController();
+
+  // Method called via callbacks from `RecordHandlerImpl` that handles the
+  // incoming configuration file and performs the necessary checks to see if
+  // the data needs to be passed to other places. This method returns the
+  // version if it passed the checks or -2 if it didn't, this will signal the
+  // server that something went wrong while verifying the config file provided.
+  int32_t HandleConfigurationFile(ConfigFile config_file);
+
+ private:
+  friend class ConfigurationFileControllerTest;
+  // Private constructors used for testing.
+  static std::unique_ptr<ConfigurationFileController> CreateForTesting(
+      UploadClient::UpdateConfigInMissiveCallback update_config_in_missive_cb,
+      ListOfBlockedDestinations destinations_list,
+      int os_version);
+
+  ConfigurationFileController(
+      UploadClient::UpdateConfigInMissiveCallback update_config_in_missive_cb,
+      ListOfBlockedDestinations destinations_list,
+      int os_version);
+
+  //    Verifies the signature from the configuration file. Returns OK if the
+  //    signature is valid, otherwise returns an error.
+  Status VerifySignature(ConfigFile config_file);
+  // Method that checks the destination list gotten from the server and checks
+  // if the list is the same one as the one stored. Returns true if the list
+  // should be sent to missive and false otherwise.
+  bool HandleBlockedEventConfigs(
+      google::protobuf::RepeatedPtrField<EventConfig> blocked_event_configs);
+  // Method that checks if a metric or destination should be blocked for the
+  // current OS version that the device is on at the moment. Returns true if the
+  // metric or destination should be blocked and false otherwise.
+  bool ShouldBeBlocked(int32_t minimum_version,
+                       absl::optional<int32_t> maximum_version) const;
+
+  // Callback to update the configuration file in missive, only called
+  // after verifying
+  UploadClient::UpdateConfigInMissiveCallback update_config_in_missive_cb_;
+  // Signature verifier used to verify that the configuration file gotten
+  // from the server is valid. Initialized with the well-known public signature
+  // verification key.
+  SignatureVerifier verifier_;
+  // List of blocked destinations, used to see if the incoming list of blocked
+  // destinations should be sent to missive. This list is already filtered to
+  // block/not block depending on the OS version of the device.
+  ListOfBlockedDestinations destinations_list_;
+  //  Populated during the creation of the class, stores the current major
+  //  ChromeOS version number.
+  int current_os_version_;
+  // Stores the latest configuration file version gotten from the server.
+  int32_t current_config_file_version_ = 0;
+};
+
+}  // namespace reporting
+
+#endif  // CHROME_BROWSER_POLICY_MESSAGING_LAYER_UPLOAD_CONFIGURATION_FILE_CONTROLLER_H_
diff --git a/chrome/browser/policy/messaging_layer/upload/configuration_file_controller_unittest.cc b/chrome/browser/policy/messaging_layer/upload/configuration_file_controller_unittest.cc
new file mode 100644
index 0000000..ff8b922
--- /dev/null
+++ b/chrome/browser/policy/messaging_layer/upload/configuration_file_controller_unittest.cc
@@ -0,0 +1,346 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/messaging_layer/upload/configuration_file_controller.h"
+#include <cstdint>
+
+#include "base/task/thread_pool.h"
+#include "base/test/gtest_util.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/test_future.h"
+#include "chrome/browser/policy/messaging_layer/upload/record_upload_request_builder.h"
+#include "components/reporting/encryption/primitives.h"
+#include "components/reporting/proto/synced/record_constants.pb.h"
+#include "components/reporting/util/status.h"
+#include "components/reporting/util/test_support_callbacks.h"
+#include "components/reporting/util/test_util.h"
+#include "content/public/test/browser_task_environment.h"
+
+using ::testing::HasSubstr;
+
+namespace reporting {
+
+static constexpr int kBaseChromeVersion = 50;
+static constexpr int kConfigFileVersion = 11111;
+static constexpr char kSignature[] = "XXXXXXXXXXXXXX";
+static constexpr uint8_t kBadSignature[] = {
+    0xD1, 0x9E, 0x7D, 0x77, 0xD4, 0x8D, 0xC9, 0xAC, 0x27, 0x54, 0x40,
+    0xC2, 0x8A, 0xDE, 0xE1, 0xEE, 0xCE, 0xED, 0x15, 0xC9, 0x9C, 0x87,
+    0xB6, 0xB0, 0x32, 0xC1, 0x37, 0x3D, 0x06, 0x05, 0x5C, 0xFD, 0x63,
+    0x17, 0x54, 0x62, 0x53, 0xBC, 0x79, 0xAD, 0x82, 0xC3, 0xF1, 0xBC,
+    0xB6, 0x0A, 0xC9, 0x2A, 0x42, 0xD0, 0xFC, 0x00, 0xAD, 0xE6, 0x84,
+    0x29, 0xBC, 0x7F, 0x10, 0xC3, 0x19, 0x85, 0xA2, 0x0E};
+static_assert(std::size(kBadSignature) == kSignatureSize);
+
+class ConfigurationFileControllerTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    controller_provider_ = ConfigurationFileController::CreateForTesting(
+        update_config_in_missive_event_.repeating_cb(),
+        ListOfBlockedDestinations(), kBaseChromeVersion);
+    scoped_feature_list_.InitAndEnableFeature(kShouldRequestConfigurationFile);
+  }
+  void TearDown() override {}
+
+  void EnableSignatureTestFlag() {
+    scoped_feature_list_.Reset();
+    std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
+    feature_list->InitializeFromCommandLine(
+        "ReportingConfigurationFileTestSignature, "
+        "ShouldRequestConfigurationFile",
+        "");
+    scoped_feature_list_.InitWithFeatureList(std::move(feature_list));
+  }
+
+  void ControllerWithList(ListOfBlockedDestinations list) {
+    controller_provider_ = ConfigurationFileController::CreateForTesting(
+        update_config_in_missive_event_.repeating_cb(), std::move(list),
+        kBaseChromeVersion);
+  }
+
+  content::BrowserTaskEnvironment task_envrionment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+
+  const scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_ =
+      base::ThreadPool::CreateSequencedTaskRunner({});
+
+  std::unique_ptr<ConfigurationFileController> controller_provider_;
+
+  test::TestEvent<ListOfBlockedDestinations> update_config_in_missive_event_;
+
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+TEST_F(ConfigurationFileControllerTest, EmptyConfigFileDoesNotCallMissive) {
+  ConfigFile test_config_file;
+  const int handle_configuration_file_result =
+      controller_provider_->HandleConfigurationFile(test_config_file);
+  EXPECT_TRUE(update_config_in_missive_event_.no_result());
+  EXPECT_EQ(handle_configuration_file_result, 0);
+}
+
+TEST_F(ConfigurationFileControllerTest, VersionMinusOneDoesNotCallMissive) {
+  ConfigFile test_config_file;
+  test_config_file.set_version(-1);
+  const int handle_configuration_file_result =
+      controller_provider_->HandleConfigurationFile(test_config_file);
+  EXPECT_TRUE(update_config_in_missive_event_.no_result());
+  EXPECT_EQ(handle_configuration_file_result, 0);
+}
+
+TEST_F(ConfigurationFileControllerTest,
+       EmptyBlockedEventConfigsUpdatesVersionButDoesNotCallMissive) {
+  EnableSignatureTestFlag();
+  ConfigFile test_config_file;
+  test_config_file.set_config_file_signature(kSignature);
+  test_config_file.set_version(kConfigFileVersion);
+
+  const int handle_configuration_file_result =
+      controller_provider_->HandleConfigurationFile(test_config_file);
+  EXPECT_TRUE(update_config_in_missive_event_.no_result());
+  EXPECT_EQ(handle_configuration_file_result, kConfigFileVersion);
+}
+
+TEST_F(ConfigurationFileControllerTest,
+       ConfigFileExperimentDisabledDoesNothing) {
+  scoped_feature_list_.Reset();
+  scoped_feature_list_.InitAndDisableFeature(kShouldRequestConfigurationFile);
+  ConfigFile test_config_file;
+  auto* const current_config = test_config_file.add_blocked_event_configs();
+  current_config->set_destination(Destination::DLP_EVENTS);
+  test_config_file.set_config_file_signature(kSignature);
+  test_config_file.set_version(kConfigFileVersion);
+
+  const int handle_configuration_file_result =
+      controller_provider_->HandleConfigurationFile(test_config_file);
+  EXPECT_TRUE(update_config_in_missive_event_.no_result());
+  // We expect -1 when the experiment is disabled.
+  EXPECT_EQ(handle_configuration_file_result, kFeatureDisabled);
+}
+
+TEST_F(ConfigurationFileControllerTest,
+       TestFlagCallsMissiveWithSingleDestination) {
+  EnableSignatureTestFlag();
+  ConfigFile test_config_file;
+
+  // Populate one blocked destination.
+  test_config_file.set_version(kConfigFileVersion);
+  test_config_file.add_blocked_event_configs()->set_destination(
+      Destination::DLP_EVENTS);
+  const int handle_configuration_file_result =
+      controller_provider_->HandleConfigurationFile(test_config_file);
+
+  // Create list to compare against.
+  ListOfBlockedDestinations list;
+  list.add_destinations(Destination::DLP_EVENTS);
+
+  const auto result = update_config_in_missive_event_.result();
+  EXPECT_THAT(result, EqualsProto(list));
+  EXPECT_EQ(handle_configuration_file_result, kConfigFileVersion);
+}
+
+TEST_F(ConfigurationFileControllerTest,
+       TestFlagCallsMissiveWithMultipleDestinations) {
+  EnableSignatureTestFlag();
+  ConfigFile test_config_file;
+
+  // Populate one blocked destination.
+  test_config_file.set_version(kConfigFileVersion);
+  test_config_file.add_blocked_event_configs()->set_destination(
+      Destination::DLP_EVENTS);
+  test_config_file.add_blocked_event_configs()->set_destination(
+      Destination::LOGIN_LOGOUT_EVENTS);
+  test_config_file.add_blocked_event_configs()->set_destination(
+      Destination::OS_EVENTS);
+  const int handle_configuration_file_result =
+      controller_provider_->HandleConfigurationFile(test_config_file);
+
+  // Create list to compare against.
+  ListOfBlockedDestinations list;
+  list.add_destinations(Destination::DLP_EVENTS);
+  list.add_destinations(Destination::LOGIN_LOGOUT_EVENTS);
+  list.add_destinations(Destination::OS_EVENTS);
+
+  const auto result = update_config_in_missive_event_.result();
+  EXPECT_THAT(result, EqualsProto(list));
+  EXPECT_EQ(handle_configuration_file_result, kConfigFileVersion);
+}
+
+TEST_F(ConfigurationFileControllerTest,
+       TestFlagWithMultipleDestinationsNotInRange) {
+  EnableSignatureTestFlag();
+  ConfigFile test_config_file;
+
+  // Populate two blocked destination that are not in the range to be blocked.
+  test_config_file.set_version(kConfigFileVersion);
+  auto* dlp_destination = test_config_file.add_blocked_event_configs();
+  dlp_destination->set_destination(Destination::DLP_EVENTS);
+  dlp_destination->set_minimum_release_version(kBaseChromeVersion + 2);
+  auto* login_destination = test_config_file.add_blocked_event_configs();
+  login_destination->set_destination(Destination::LOGIN_LOGOUT_EVENTS);
+  login_destination->set_minimum_release_version(kBaseChromeVersion + 5);
+  login_destination->set_maximum_release_version(kBaseChromeVersion + 10);
+
+  // Call the public method.
+  const int handle_configuration_file_result =
+      controller_provider_->HandleConfigurationFile(test_config_file);
+
+  // Verify it doesn't call missive but returns the correct version.
+  EXPECT_TRUE(update_config_in_missive_event_.no_result());
+  EXPECT_EQ(handle_configuration_file_result, kConfigFileVersion);
+}
+
+TEST_F(ConfigurationFileControllerTest,
+       TestFlagWithMultipleDestinationsOneInRange) {
+  EnableSignatureTestFlag();
+  ConfigFile test_config_file;
+
+  // Populate two blocked destination one in range and the other one out of
+  // range.
+  test_config_file.set_version(kConfigFileVersion);
+  auto* const dlp_destination = test_config_file.add_blocked_event_configs();
+  dlp_destination->set_destination(Destination::DLP_EVENTS);
+  dlp_destination->set_minimum_release_version(kBaseChromeVersion);
+  auto* const login_destination = test_config_file.add_blocked_event_configs();
+  login_destination->set_destination(Destination::LOGIN_LOGOUT_EVENTS);
+  login_destination->set_minimum_release_version(kBaseChromeVersion + 5);
+  login_destination->set_maximum_release_version(kBaseChromeVersion + 10);
+
+  // Call the public method.
+  const int handle_configuration_file_result =
+      controller_provider_->HandleConfigurationFile(test_config_file);
+  // Create list to compare against.
+  ListOfBlockedDestinations list;
+  list.add_destinations(Destination::DLP_EVENTS);
+
+  const auto result = update_config_in_missive_event_.result();
+  EXPECT_THAT(result, EqualsProto(list));
+  EXPECT_EQ(handle_configuration_file_result, kConfigFileVersion);
+}
+
+// TODO(b/302544753): Add test to verify that the `ConfigurationFileController`
+// calls missive when provided with a valid prod signature. Adding this after
+// server MVP implementation.
+
+TEST_F(ConfigurationFileControllerTest, BadProdSignatureSendsUMA) {
+  base::HistogramTester histogram_tester;
+  ConfigFile test_config_file;
+  test_config_file.set_version(kConfigFileVersion);
+  test_config_file.add_blocked_event_configs()->set_destination(
+      Destination::DLP_EVENTS);
+  test_config_file.add_blocked_event_configs()->set_destination(
+      Destination::OS_EVENTS);
+  test_config_file.set_config_file_signature(std::string(
+      reinterpret_cast<const char*>(kBadSignature), kSignatureSize));
+
+  const int handle_result =
+      controller_provider_->HandleConfigurationFile(test_config_file);
+
+  histogram_tester.ExpectTotalCount(
+      "Browser.ERP.ConfigFileSignatureVerificationError", 1);
+  histogram_tester.ExpectBucketCount(
+      "Browser.ERP.ConfigFileSignatureVerificationError",
+      error::INVALID_ARGUMENT, 1);
+  EXPECT_TRUE(update_config_in_missive_event_.no_result());
+  EXPECT_EQ(handle_result, kConfigurationFileCorrupted);
+}
+
+TEST_F(ConfigurationFileControllerTest, NoConfigFileSignatureSendsUMA) {
+  base::HistogramTester histogram_tester;
+  ConfigFile test_config_file;
+  auto* const current_config = test_config_file.add_blocked_event_configs();
+  current_config->set_destination(Destination::DLP_EVENTS);
+  test_config_file.set_version(kConfigFileVersion);
+
+  const int handle_configuration_file_result =
+      controller_provider_->HandleConfigurationFile(test_config_file);
+  histogram_tester.ExpectTotalCount(
+      "Browser.ERP.ConfigFileSignatureVerificationError", 1);
+  histogram_tester.ExpectBucketCount(
+      "Browser.ERP.ConfigFileSignatureVerificationError",
+      error::INVALID_ARGUMENT, 1);
+  EXPECT_TRUE(update_config_in_missive_event_.no_result());
+  EXPECT_EQ(handle_configuration_file_result, kConfigurationFileCorrupted);
+}
+
+TEST_F(ConfigurationFileControllerTest, BadConfigFileSignatureSizeSendsUMA) {
+  base::HistogramTester histogram_tester;
+  ConfigFile test_config_file;
+  auto* const current_config = test_config_file.add_blocked_event_configs();
+  current_config->set_destination(Destination::DLP_EVENTS);
+  test_config_file.set_config_file_signature(kSignature);
+  test_config_file.set_version(kConfigFileVersion);
+
+  const int handle_configuration_file_result =
+      controller_provider_->HandleConfigurationFile(test_config_file);
+  histogram_tester.ExpectTotalCount(
+      "Browser.ERP.ConfigFileSignatureVerificationError", 1);
+  histogram_tester.ExpectBucketCount(
+      "Browser.ERP.ConfigFileSignatureVerificationError",
+      error::FAILED_PRECONDITION, 1);
+  EXPECT_TRUE(update_config_in_missive_event_.no_result());
+  EXPECT_EQ(handle_configuration_file_result, kConfigurationFileCorrupted);
+}
+
+TEST_F(ConfigurationFileControllerTest,
+       PreviousDestinationListEqualDoesntCallMissive) {
+  EnableSignatureTestFlag();
+  ListOfBlockedDestinations list;
+  list.add_destinations(Destination::LOCK_UNLOCK_EVENTS);
+  ControllerWithList(list);
+
+  ConfigFile test_config_file;
+  test_config_file.add_blocked_event_configs()->set_destination(
+      Destination::LOCK_UNLOCK_EVENTS);
+  test_config_file.set_version(kConfigFileVersion);
+
+  const int handle_configuration_file_result =
+      controller_provider_->HandleConfigurationFile(test_config_file);
+  EXPECT_TRUE(update_config_in_missive_event_.no_result());
+  EXPECT_EQ(handle_configuration_file_result, kConfigFileVersion);
+}
+
+TEST_F(ConfigurationFileControllerTest,
+       PreviousDestinationListDifferentCallsMissive) {
+  EnableSignatureTestFlag();
+  ListOfBlockedDestinations initial_list;
+  initial_list.add_destinations(Destination::OS_EVENTS);
+  ControllerWithList(initial_list);
+
+  ConfigFile test_config_file;
+  test_config_file.add_blocked_event_configs()->set_destination(
+      Destination::LOCK_UNLOCK_EVENTS);
+  test_config_file.set_version(kConfigFileVersion);
+
+  const int handle_configuration_file_result =
+      controller_provider_->HandleConfigurationFile(test_config_file);
+  // Create list to compare against.
+  ListOfBlockedDestinations list;
+  list.add_destinations(Destination::LOCK_UNLOCK_EVENTS);
+
+  const auto result = update_config_in_missive_event_.result();
+  EXPECT_THAT(result, EqualsProto(list));
+  EXPECT_EQ(handle_configuration_file_result, kConfigFileVersion);
+}
+
+TEST_F(ConfigurationFileControllerTest,
+       PreviousDestinationListPopulatedNewDestinationListEmptyCallsMissive) {
+  EnableSignatureTestFlag();
+  ListOfBlockedDestinations initial_list;
+  initial_list.add_destinations(Destination::OS_EVENTS);
+  ControllerWithList(initial_list);
+
+  ConfigFile test_config_file;
+  test_config_file.set_version(kConfigFileVersion);
+
+  const int handle_configuration_file_result =
+      controller_provider_->HandleConfigurationFile(test_config_file);
+
+  const auto result = update_config_in_missive_event_.result();
+  EXPECT_THAT(result, EqualsProto(ListOfBlockedDestinations()));
+  EXPECT_EQ(handle_configuration_file_result, kConfigFileVersion);
+}
+
+}  // namespace reporting
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
index a5426420..e374abd 100644
--- a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
+++ b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
@@ -913,9 +913,8 @@
   EXPECT_FALSE(
       predictor_->PredictPreconnectOrigins(main_frame_url, prediction.get()));
 
-  const char* cdn_origin = "https://cdn%d.google.com";
-  auto gen_origin = [cdn_origin](int n) {
-    return base::StringPrintf(cdn_origin, n);
+  auto gen_origin = [](int n) {
+    return base::StringPrintf("https://cdn%d.google.com", n);
   };
 
   // Add origins associated with the main frame host.
@@ -1011,9 +1010,8 @@
   EXPECT_FALSE(
       predictor_->PredictPreconnectOrigins(main_frame_url, prediction.get()));
 
-  const char* cdn_origin = "https://cdn%d.google.com";
-  auto gen_origin = [cdn_origin](int n) {
-    return base::StringPrintf(cdn_origin, n);
+  auto gen_origin = [](int n) {
+    return base::StringPrintf("https://cdn%d.google.com", n);
   };
 
   // Add origins associated with the main frame host.
diff --git a/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc b/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc
index 254ff19..45cb02b 100644
--- a/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc
+++ b/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc
@@ -84,15 +84,6 @@
   return meta_header;
 }
 
-bool IsWithinExpectedRange(double baseline, double computed) {
-  double ratio = computed / baseline;
-  // Tweaking zlib compression algorithm implementation will impact
-  // compression ratios. Testing for a range makes more sense than a
-  // fixed value and future proofs this test.
-  // The range used is +/- 3%.
-  return ((ratio < 1.04) && (ratio > 0.96));
-}
-
 void CompareEmfHeaders(const ENHMETAHEADER& expected_header,
                        const ENHMETAHEADER& actual_header) {
   // TODO(crbug.com/781403): once the EMF generation is fixed, also compare:
@@ -101,11 +92,8 @@
   EXPECT_EQ(expected_header.nSize, actual_header.nSize);
   EXPECT_EQ(expected_header.dSignature, actual_header.dSignature);
   EXPECT_EQ(expected_header.nVersion, actual_header.nVersion);
-  EXPECT_EQ(IsWithinExpectedRange(expected_header.nBytes, actual_header.nBytes),
-            true);
-  EXPECT_EQ(
-      IsWithinExpectedRange(expected_header.nRecords, actual_header.nRecords),
-      true);
+  EXPECT_EQ(expected_header.nBytes, actual_header.nBytes);
+  EXPECT_EQ(expected_header.nRecords, actual_header.nRecords);
   EXPECT_EQ(expected_header.nHandles, actual_header.nHandles);
   EXPECT_EQ(expected_header.sReserved, actual_header.sReserved);
   EXPECT_EQ(expected_header.nDescription, actual_header.nDescription);
@@ -116,11 +104,10 @@
   EXPECT_EQ(expected_header.bOpenGL, actual_header.bOpenGL);
 }
 
-// FIXME(cavalcantii): see comment further down.
-// std::string HashData(const char* data, size_t len) {
-//   auto span = base::make_span(reinterpret_cast<const uint8_t*>(data), len);
-//   return base::HexEncode(base::SHA1HashSpan(span));
-// }
+std::string HashData(const char* data, size_t len) {
+  auto span = base::make_span(reinterpret_cast<const uint8_t*>(data), len);
+  return base::HexEncode(base::SHA1HashSpan(span));
+}
 
 class PdfToEmfConverterBrowserTest
     : public InProcessBrowserTest,
@@ -204,8 +191,8 @@
   void ComparePageEmfHeader() {
     // TODO(crbug.com/781403): the generated data can differ visually. Until
     // this is fixed only checking the output size and parts of the EMF header.
-    ASSERT_TRUE(IsWithinExpectedRange(expected_current_emf_data_.size(),
-                                      actual_current_emf_data_.size()));
+    ASSERT_EQ(expected_current_emf_data_.size(),
+              actual_current_emf_data_.size());
 
     std::unique_ptr<ENHMETAHEADER> expected_header =
         GetEmfHeader(expected_current_emf_data_);
@@ -217,16 +204,12 @@
   }
 
   void ComparePageEmfPayload() {
-    ASSERT_TRUE(IsWithinExpectedRange(expected_current_emf_data_.size(),
-                                      actual_current_emf_data_.size()));
+    ASSERT_EQ(expected_current_emf_data_.size(),
+              actual_current_emf_data_.size());
     ASSERT_GT(expected_current_emf_data_.size(), kHeaderSize);
-    // FIXME(cavalcantii): Cannot compare compressed data, there are no
-    // warranties of 'stability' of compressed output between zlib releases.
-    // Comparisons should be done on *decompressed* content.
-    // size_t size = expected_current_emf_data_.size() - kHeaderSize;
-    // EXPECT_EQ(HashData(expected_current_emf_data_.data() + kHeaderSize,
-    // size),
-    //           HashData(actual_current_emf_data_.data() + kHeaderSize, size));
+    size_t size = expected_current_emf_data_.size() - kHeaderSize;
+    EXPECT_EQ(HashData(expected_current_emf_data_.data() + kHeaderSize, size),
+              HashData(actual_current_emf_data_.data() + kHeaderSize, size));
   }
 
  private:
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.html b/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.html
index c0ebe09..ab0c4ec 100644
--- a/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.html
+++ b/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.html
@@ -17,6 +17,22 @@
   #renamingDialog {
     --cr-dialog-width: 320px;
   }
+
+  :host([button-name-invalid_]) #inputCount {
+    color: var(--cros-text-color-alert);
+  }
+
+  #inputCount {
+    display: var(--cr-input-error-display, block);
+    font-size: var(--cr-form-field-label-font-size);
+    height: var(--cr-form-field-label-height);
+    line-height: var(--cr-form-field-label-line-height);
+    margin: 8px 0;
+    position: absolute;
+    right: 32px;
+    top: 130px;
+    white-space: var(--cr-input-error-white-space);
+  }
 </style>
 <div class="subsection">
   <template is="dom-repeat"
@@ -37,10 +53,16 @@
     <div slot="body">
       <div id="inputContainer">
         <cr-input id="renamingDialogInput"
+          autofocus
           label="$i18n{buttonRemappingDialogInputLabel}"
+          on-keydown="onKeyDownInRenamingDialog_"
+          invalid="[[buttonNameInvalid_]]"
           value="{{selectedButtonName_}}"
           aria-label="$i18n{buttonRenamingDialogTitle}">
         </cr-input>
+        <div id="inputCount" aria-hidden="true">
+          [[getInputCountString_(selectedButtonName_)]]
+        </div>
       </div>
     </div>
     <div slot="button-container">
@@ -52,7 +74,9 @@
       </div>
       <div>
         <cr-button id="saveButton" class="action-button"
-            on-click="saveRenamingDialogClicked_">
+            on-click="saveRenamingDialogClicked_"
+            disabled$="[[isSaveDisabled_(buttonRemappingList,
+                actionList, selectedButtonName_)]]">
           $i18n{buttonRemappingDialogSaveLabel}
         </cr-button>
       </div>
diff --git a/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.ts b/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.ts
index 555360e..5ae8d97b 100644
--- a/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.ts
+++ b/chrome/browser/resources/ash/settings/device_page/customize_buttons_subsection.ts
@@ -38,6 +38,8 @@
   }
 }
 
+const MAX_BUTTON_NAME_INPUT_LENGTH = 64;
+
 const CustomizeButtonsSubsectionElementBase = I18nMixin(PolymerElement);
 
 export class CustomizeButtonsSubsectionElement extends
@@ -72,11 +74,18 @@
       selectedButtonName_: {
         type: String,
         value: '',
+        observer: 'onNameInputChanged_',
       },
 
       selectedButtonIndex_: {
         type: Number,
       },
+
+      buttonNameInvalid_: {
+        type: Boolean,
+        value: false,
+        reflectToAttribute: true,
+      },
     };
   }
 
@@ -87,6 +96,7 @@
   private shouldShowRenamingDialog_: boolean;
   private selectedButtonName_: string;
   private dragAndDropManager: DragAndDropManager = new DragAndDropManager();
+  private buttonNameInvalid_: boolean;
 
   override connectedCallback(): void {
     super.connectedCallback();
@@ -104,9 +114,24 @@
     this.selectedButtonIndex_ = e.detail.buttonIndex;
     this.selectedButton_ = this.buttonRemappingList[this.selectedButtonIndex_];
     this.selectedButtonName_ = this.selectedButton_.name;
+    this.buttonNameInvalid_ = false;
     this.shouldShowRenamingDialog_ = true;
   }
 
+  /**
+   * Returns a formatted string containing the current number of characters
+   * entered in the input compared to the maximum number of characters allowed.
+   */
+  private getInputCountString_(buttonName: string): string {
+    // minimumIntegerDigits is 2 because we want to show a leading zero if
+    // length is less than 10.
+    return this.i18n(
+        'buttonRenamingDialogInputCharCount',
+        buttonName.length.toLocaleString(
+            /*locales=*/ undefined, {minimumIntegerDigits: 2}),
+        MAX_BUTTON_NAME_INPUT_LENGTH.toLocaleString());
+  }
+
   private showKeyCombinationDialog_(e: ShowKeyCustomizationDialogEvent): void {
     this.selectedButtonIndex_ = e.detail.buttonIndex;
     this.$.keyCombinationInputDialog.showModal();
@@ -117,8 +142,29 @@
   }
 
   private saveRenamingDialogClicked_(): void {
-    this.updateButtonName_();
-    this.shouldShowRenamingDialog_ = false;
+    if (!this.isSaveDisabled_()) {
+      this.updateButtonName_();
+      this.shouldShowRenamingDialog_ = false;
+    }
+  }
+
+  private onKeyDownInRenamingDialog_(event: KeyboardEvent): void {
+    this.buttonNameInvalid_ = false;
+    if (event.key === 'Enter') {
+      this.saveRenamingDialogClicked_();
+    }
+  }
+
+  private onNameInputChanged_(_newValue: string, oldValue: string): void {
+    // If oldValue.length > MAX_BUTTON_NAME_INPUT_LENGTH, the user attempted
+    // to enter more than the max limit, this method was called and it was
+    // truncated, and then this method was called one more time.
+    this.buttonNameInvalid_ =
+        !!oldValue && oldValue.length > MAX_BUTTON_NAME_INPUT_LENGTH;
+
+    // Truncate the name to maxInputLength.
+    this.selectedButtonName_ =
+        this.selectedButtonName_.substring(0, MAX_BUTTON_NAME_INPUT_LENGTH);
   }
 
   private updateButtonName_(): void {
@@ -156,6 +202,18 @@
           composed: true,
         }));
       };
+
+  private isSaveDisabled_(): boolean {
+    if (this.selectedButtonName_ === this.selectedButton_.name) {
+      return true;
+    }
+
+    if (!this.selectedButtonName_.length) {
+      return true;
+    }
+
+    return false;
+  }
 }
 
 declare global {
diff --git a/chrome/browser/resources/ash/settings/device_page/input_device_settings_utils.ts b/chrome/browser/resources/ash/settings/device_page/input_device_settings_utils.ts
index e99968c..1c7b0832 100644
--- a/chrome/browser/resources/ash/settings/device_page/input_device_settings_utils.ts
+++ b/chrome/browser/resources/ash/settings/device_page/input_device_settings_utils.ts
@@ -29,6 +29,17 @@
   return true;
 }
 
+function deviceInList(
+    deviceId: number, deviceList: InputDeviceType[]): boolean {
+  for (const device of deviceList) {
+    if (device.id === deviceId) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 export function settingsAreEqual(
     settings1: DeviceSettings, settings2: DeviceSettings): boolean {
   return objectsAreEqual(settings1, settings2);
@@ -77,13 +88,13 @@
   let msgId: string;
   let devices: InputDeviceType[];
   if (newDeviceList.length > prevDeviceList.length) {
-    devices =
-        newDeviceList.filter((device) => !prevDeviceList.includes(device));
+    devices = newDeviceList.filter(
+        (device) => !deviceInList(device.id, prevDeviceList));
     msgId = 'deviceConnectedA11yLabel';
   } else {
     msgId = 'deviceDisconnectedA11yLabel';
-    devices =
-        prevDeviceList.filter((device) => !newDeviceList.includes(device));
+    devices = prevDeviceList.filter(
+        (device) => !deviceInList(device.id, newDeviceList));
   }
 
   return {msgId, deviceNames: devices.map(device => device.name)};
diff --git a/chrome/browser/resources/ash/settings/internet_page/hotspot_subpage.html b/chrome/browser/resources/ash/settings/internet_page/hotspot_subpage.html
index 4daaab3..2a314333 100644
--- a/chrome/browser/resources/ash/settings/internet_page/hotspot_subpage.html
+++ b/chrome/browser/resources/ash/settings/internet_page/hotspot_subpage.html
@@ -55,7 +55,8 @@
   </settings-toggle-button>
 </template>
 <div id="connectedDeviceCountRow"
-    class="settings-box settings-box-text two-line single-column stretch">
+    class="settings-box settings-box-text two-line single-column stretch"
+    hidden$="[[hideConnectedDeviceCount_(hotspotInfo)]]">
   <div id="connectedDeviceCountLabel">
       $i18n{hotspotConnectedDeviceCountLabel}
   </div>
diff --git a/chrome/browser/resources/ash/settings/internet_page/hotspot_subpage.ts b/chrome/browser/resources/ash/settings/internet_page/hotspot_subpage.ts
index 4e0a20b..541c8c9 100644
--- a/chrome/browser/resources/ash/settings/internet_page/hotspot_subpage.ts
+++ b/chrome/browser/resources/ash/settings/internet_page/hotspot_subpage.ts
@@ -158,6 +158,11 @@
     return ssid || '';
   }
 
+  private hideConnectedDeviceCount_(): boolean {
+    return this.hotspotInfo?.state !== HotspotState.kEnabled &&
+        this.hotspotInfo?.state !== HotspotState.kDisabling;
+  }
+
   private getHotspotConnectedDeviceCount_(clientCount: number|
                                           undefined): number {
     return clientCount || 0;
diff --git a/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.html b/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.html
index 20e7933d..0118432 100644
--- a/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.html
+++ b/chrome/browser/resources/ash/settings/internet_page/internet_detail_subpage.html
@@ -67,6 +67,10 @@
   cr-link-row {
     --cr-secondary-text-color: var(--cros-text-color-positive);
   }
+
+  #apnSubpageButton {
+    height: var(--cr-section-two-line-min-height);
+  }
 </style>
 <!-- Title section: Icon + name + connection state. -->
 <div id="titleDiv" class="settings-box first">
diff --git a/chrome/browser/resources/ash/settings/os_people_page/pin_settings.html b/chrome/browser/resources/ash/settings/os_people_page/pin_settings.html
index 8ca8649..7423bf7 100644
--- a/chrome/browser/resources/ash/settings/os_people_page/pin_settings.html
+++ b/chrome/browser/resources/ash/settings/os_people_page/pin_settings.html
@@ -25,7 +25,7 @@
 </style>
 <div>
   <div class="two-elements-left-right">
-    <div class="label">$i18n{lockScreenPinLabel}</div>
+    <div class="label" id="setupPinLabel">$i18n{lockScreenPinLabel}</div>
     <div class="settings-row">
       <template is="dom-if" if="[[quickUnlockDisabledByPolicy_]]">
         <cr-policy-indicator indicator-type="userPolicy">
@@ -34,6 +34,7 @@
       <template is="dom-if" if="[[!hasPin_]]" restamp>
         <cr-button
             class="set-pin-button"
+            aria-describedby="setupPinLabel"
             on-click="onSetPinButtonClicked_"
             disabled$="[[quickUnlockDisabledByPolicy_]]">
           $i18n{lockScreenSetupPinButton}
@@ -54,7 +55,9 @@
             on-click="onMoreButtonClicked_"
             disabled$="[[quickUnlockDisabledByPolicy_]]">
         </cr-icon-button>
-        <cr-action-menu id="moreMenu">
+        <cr-action-menu id="moreMenu"
+            role-description="$i18n{menu}"
+            accessibility-label="$i18n{moreActions}">
           <button
               class="dropdown-item"
               on-click="onRemovePinButtonClicked_"
diff --git a/chrome/browser/resources/ash/settings/os_settings_menu/os_settings_menu.ts b/chrome/browser/resources/ash/settings/os_settings_menu/os_settings_menu.ts
index c27b5fb..76eb068 100644
--- a/chrome/browser/resources/ash/settings/os_settings_menu/os_settings_menu.ts
+++ b/chrome/browser/resources/ash/settings/os_settings_menu/os_settings_menu.ts
@@ -305,6 +305,7 @@
           path: `/${routesMojom.PRIVACY_AND_SECURITY_SECTION_PATH}`,
           icon: 'cr:security',
           label: this.i18n('privacyPageTitle'),
+          sublabel: this.i18n('privacyMenuItemDescription'),
         },
         {
           section: Section.kApps,
diff --git a/chrome/browser/resources/bluetooth_internals/BUILD.gn b/chrome/browser/resources/bluetooth_internals/BUILD.gn
index 58cb85c..42069fd8 100644
--- a/chrome/browser/resources/bluetooth_internals/BUILD.gn
+++ b/chrome/browser/resources/bluetooth_internals/BUILD.gn
@@ -49,13 +49,13 @@
   mojo_files_deps = [
     "//chrome/browser/ui/webui/bluetooth_internals:mojo_bindings_ts__generator",
     "//device/bluetooth/public/mojom:deprecated_experimental_interfaces_ts__generator",
-    "//device/bluetooth/public/mojom:mojom_js__generator",
+    "//device/bluetooth/public/mojom:mojom_ts__generator",
   ]
   mojo_files = [
     "$root_gen_dir/chrome/browser/ui/webui/bluetooth_internals/bluetooth_internals.mojom-webui.ts",
     "$root_gen_dir/device/bluetooth/public/mojom/adapter.mojom-webui.ts",
     "$root_gen_dir/device/bluetooth/public/mojom/device.mojom-webui.ts",
-    "$root_gen_dir/mojom-webui/device/bluetooth/public/mojom/uuid.mojom-webui.js",
+    "$root_gen_dir/device/bluetooth/public/mojom/uuid.mojom-webui.ts",
   ]
 
   ts_definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ]
diff --git a/chrome/browser/resources/chromeos/BUILD.gn b/chrome/browser/resources/chromeos/BUILD.gn
index 8f27eb2..99f8f74 100644
--- a/chrome/browser/resources/chromeos/BUILD.gn
+++ b/chrome/browser/resources/chromeos/BUILD.gn
@@ -22,6 +22,7 @@
     "borealis_installer:resources",
     "cloud_upload:resources",
     "desk_api:resources",
+    "edu_coexistence:resources",
     "emoji_picker:resources",
     "enterprise_reporting:resources",
     "gaia_action_buttons:resources",
@@ -93,7 +94,6 @@
     "bluetooth_pairing_dialog:closure_compile",
     "crostini_installer:closure_compile",
     "crostini_upgrader:closure_compile",
-    "edu_coexistence:closure_compile",
     "emulator:closure_compile",
     "gaia_action_buttons:closure_compile",
     "internet_config_dialog:closure_compile",
@@ -105,7 +105,6 @@
     "password_change:closure_compile",
     "set_time_dialog:closure_compile",
     "smb_shares:closure_compile",
-    "supervision:closure_compile",
     "sys_internals:closure_compile",
     "vm:closure_compile",
   ]
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/BUILD.gn b/chrome/browser/resources/chromeos/edu_coexistence/BUILD.gn
index dd6cf7a..e9110c2d 100644
--- a/chrome/browser/resources/chromeos/edu_coexistence/BUILD.gn
+++ b/chrome/browser/resources/chromeos/edu_coexistence/BUILD.gn
@@ -1,120 +1,50 @@
 # Copyright 2020 The Chromium Authors
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
+import("//ui/webui/resources/tools/build_webui.gni")
 
-import("//third_party/closure_compiler/compile_js.gni")
-import("//tools/polymer/html_to_js.gni")
-
-js_type_check("closure_compile") {
-  is_polymer3 = true
-  deps = [
-    ":edu_coexistence_app",
-    ":edu_coexistence_browser_proxy",
-    ":edu_coexistence_button",
-    ":edu_coexistence_controller",
-    ":edu_coexistence_error",
-    ":edu_coexistence_offline",
-    ":edu_coexistence_template",
-    ":edu_coexistence_ui",
+build_webui("build") {
+  grd_prefix = "edu_coexistence"
+  grd_resource_path_prefix = "edu_coexistence"
+  static_files = [ "edu_coexistence.html" ]
+  web_component_files = [
+    "edu_coexistence_app.ts",
+    "edu_coexistence_button.ts",
+    "edu_coexistence_error.ts",
+    "edu_coexistence_offline.ts",
+    "edu_coexistence_ui.ts",
+    "edu_coexistence_template.ts",
   ]
-
-  closure_flags =
-      default_closure_args + [
-        "js_module_root=" +
-            rebase_path("//chrome/browser/resources/gaia_auth_host/",
-                        root_build_dir),
-        "js_module_root=./gen/chrome/browser/resources/gaia_auth_host/",
-      ]
-}
-
-js_library("edu_coexistence_app") {
-  deps = [
-    ":edu_coexistence_browser_proxy",
-    ":edu_coexistence_error",
-    ":edu_coexistence_offline",
-    ":edu_coexistence_ui",
-    "//ash/webui/common/resources:assert",
-    "//ash/webui/common/resources:web_ui_listener_behavior",
-    "//chrome/browser/resources/chromeos/arc_account_picker:arc_account_picker_app",
-    "//chrome/browser/resources/chromeos/arc_account_picker:arc_util",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+  non_web_component_files = [
+    "edu_coexistence_controller.ts",
+    "edu_coexistence_browser_proxy.ts",
   ]
-
-  externs_list = [ "//ui/webui/resources/cr_elements/cr_view_manager/cr_view_manager_externs.js" ]
-}
-
-js_library("edu_coexistence_button") {
-  deps = [
-    "//ash/webui/common/resources:i18n_behavior",
-    "//ash/webui/common/resources:util",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+  css_files = [ "common.css" ]
+  ts_composite = true
+  ts_definitions = [
+    "//tools/typescript/definitions/webview_tag.d.ts",
+    "//tools/typescript/definitions/web_request.d.ts",
+    "//tools/typescript/definitions/extension_types.d.ts",
+    "//tools/typescript/definitions/context_menus.d.ts",
+    "//tools/typescript/definitions/tabs.d.ts",
+    "//tools/typescript/definitions/chrome_send.d.ts",
   ]
-}
-
-js_library("edu_coexistence_error") {
-  deps = [
-    ":edu_coexistence_button",
-    ":edu_coexistence_template",
-    "//chrome/browser/resources/chromeos/supervision:supervised_user_error",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+  ts_deps = [
+    "//ash/webui/common/resources:build_ts",
+    "//third_party/polymer/v3_0:library",
+    "//ui/webui/resources/cr_elements:build_ts",
+    "//ui/webui/resources/js:build_ts",
+    "//ui/webui/resources/mojo:build_ts",
   ]
-}
-
-js_library("edu_coexistence_offline") {
-  deps = [
-    ":edu_coexistence_button",
-    ":edu_coexistence_template",
-    "//chrome/browser/resources/chromeos/supervision:supervised_user_offline",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-  ]
-}
-
-js_library("edu_coexistence_ui") {
-  deps = [
-    ":edu_coexistence_browser_proxy",
-    ":edu_coexistence_button",
-    ":edu_coexistence_controller",
-    ":edu_coexistence_template",
-    "//ash/webui/common/resources:web_ui_listener_behavior",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-  ]
-  externs_list = [
-    "$externs_path/chrome_extensions.js",
-    "$externs_path/webview_tag.js",
-  ]
-}
-
-js_library("edu_coexistence_template") {
-  deps = [
-    "//ash/webui/common/resources:cr_scrollable_behavior",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-  ]
-}
-
-js_library("edu_coexistence_controller") {
-  deps = [
-    ":edu_coexistence_browser_proxy",
-    "//ash/webui/common/resources/post_message_api:post_message_api_server",
-    "//chrome/browser/resources/gaia_auth_host:authenticator",
-  ]
-  externs_list = [
-    "$externs_path/chrome_extensions.js",
-    "$externs_path/webview_tag.js",
-  ]
-}
-
-js_library("edu_coexistence_browser_proxy") {
-  deps = [ "//chrome/browser/resources/gaia_auth_host:authenticator" ]
-}
-
-html_to_js("web_components") {
-  js_files = [
-    "edu_coexistence_app.js",
-    "edu_coexistence_button.js",
-    "edu_coexistence_css.js",
-    "edu_coexistence_error.js",
-    "edu_coexistence_offline.js",
-    "edu_coexistence_template.js",
-    "edu_coexistence_ui.js",
-  ]
+  ts_path_mappings =
+      [ "chrome://chrome-signin/gaia_auth_host/*|" +
+        rebase_path("//chrome/browser/resources/gaia_auth_host/*",
+                    target_gen_dir) ]
+  if (is_chromeos_ash) {
+    ts_path_mappings +=
+        [ "chrome://chrome-signin/arc_account_picker/*|" +
+          rebase_path(
+              "//chrome/browser/resources/chromeos/arc_account_picker/*",
+              target_gen_dir) ]
+  }
 }
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/common.css b/chrome/browser/resources/chromeos/edu_coexistence/common.css
new file mode 100644
index 0000000..141f25f
--- /dev/null
+++ b/chrome/browser/resources/chromeos/edu_coexistence/common.css
@@ -0,0 +1,150 @@
+/* Copyright 2023 The Chromium Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+/* #css_wrapper_metadata_start
+ * #type=style
+ * #import=chrome://resources/cr_elements/chromeos/cros_color_overrides.css.js
+ * #import=chrome://resources/cr_elements/cr_shared_style.css.js
+ * #include=cros-color-overrides cr-shared-style
+ * #css_wrapper_metadata_end */
+
+:host {
+  --dialog-top-border-size: 35px;
+}
+
+.signin-frame {
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+}
+
+/* Main container for all page elements */
+.template-container {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  justify-content: flex-start;
+  width: 100%;
+ }
+
+.column-layout {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+}
+
+.content-container {
+  display: flex;
+  height: 100%;
+  width: 100%;
+}
+
+.back-button {
+  padding: 22px 0 0 22px;
+}
+
+@media (orientation: landscape) {
+  .template-container {
+    max-height: 680px;
+    max-width: 1040px;
+  }
+
+  /* In landscape  mode, the main title and content area
+   * are arranged horizontally.
+   */
+  .content-container {
+    flex-direction: row;
+  }
+
+  .buttons-layout {
+    align-items: center;
+    display: flex;
+    justify-content: flex-end;
+    padding-inline-end: 32px;
+    width: 100%;
+  }
+}
+
+@media (orientation: portrait) {
+  .template-container {
+    max-height: 1040px;
+    max-width: 680px;
+  }
+
+  /* In portrait  mode, the main title and content area
+   * is arranged vertically.
+   */
+  .content-container {
+    flex-direction: column;
+  }
+
+  .buttons-layout {
+    display: flex;
+    justify-content: center;
+    width: 100%;
+  }
+}
+
+.main[scrollable].can-scroll:not(.is-scrolled):not(.scrolled-to-bottom) {
+  background: var(--background-gradient-0);
+}
+
+.main[scrollable].can-scroll.is-scrolled:not(.scrolled-to-bottom) {
+  background: var(--background-gradient-0), var(--background-gradient-180);
+}
+
+.main[scrollable].is-scrolled.scrolled-to-bottom {
+  background: var(--background-gradient-180);
+}
+
+.main {
+  height: 100%;
+  width: 100%;
+}
+
+.footer {
+  align-items: center;
+  display: flex;
+  height: 115px;
+  width: 100%;
+}
+
+.signin-frame {
+  background-color: white;
+  overflow: hidden;
+}
+
+paper-spinner-lite {
+  --spinner-size: 25px;
+  display: none;
+  height: var(--spinner-size);
+  width: var(--spinner-size);
+}
+
+paper-spinner-lite[active] {
+  display: inline-block;
+}
+
+edu-coexistence-template {
+  align-items: center;
+  display: flex;
+  height: 100%;
+  justify-content:  center;
+}
+
+span[slot='buttons'] {
+  display: flex;
+  width: 100%;
+}
+
+span[slot='main'] {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+}
+
+edu-coexistence-button[button-type='back'] {
+  margin-inline-start: auto;
+}
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence.html b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence.html
index 4bf3b81..035b76d 100644
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence.html
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence.html
@@ -12,7 +12,7 @@
     </style>
     <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
     <link rel="stylesheet" href="chrome://resources/chromeos/colors/cros_styles.css">
-    <script type="module" src="edu_coexistence_app.js"></script>
+    <script type="module" src="edu_coexistence/edu_coexistence_app.js"></script>
   </head>
   <body>
     <edu-coexistence-app></edu-coexistence-app>
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_app.html b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_app.html
index 51c4a90..5a5b547 100644
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_app.html
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_app.html
@@ -1,4 +1,5 @@
-<cr-view-manager id="viewManager" hidden$="[[isErrorShown_]]">
+<style include="common"></style>
+<cr-view-manager id="viewManager" hidden$="[[isErrorShown]]">
    <edu-coexistence-ui id="edu-coexistence-ui"  slot="view">
    </edu-coexistence-ui>
    <edu-coexistence-offline id="edu-coexistence-offline"  slot="view">
@@ -7,7 +8,7 @@
    </edu-coexistence-error>
    <arc-account-picker-app id="arc-account-picker" slot="view"
       use-two-column-layout="true"
-      on-opened-new-window="closeDialog_"
-      on-add-account="showAddAccount_">
+      on-opened-new-window="closeDialog"
+      on-add-account="showAddAccount">
    </arc-account-picker-app>
  </cr-view-manager>
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_app.js b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_app.js
deleted file mode 100644
index 223c8811..0000000
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_app.js
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import './edu_coexistence_css.js';
-import './edu_coexistence_template.js';
-import './edu_coexistence_button.js';
-import './edu_coexistence_error.js';
-import './edu_coexistence_offline.js';
-import './edu_coexistence_ui.js';
-import './arc_account_picker/arc_account_picker_app.js';
-import 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js';
-
-import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js';
-import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from 'chrome://resources/ash/common/web_ui_listener_behavior.js';
-import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {getAccountAdditionOptionsFromJSON} from './arc_account_picker/arc_util.js';
-import {EduCoexistenceBrowserProxyImpl} from './edu_coexistence_browser_proxy.js';
-
-/** @enum {string} */
-export const Screens = {
-  ONLINE_FLOW: 'edu-coexistence-ui',
-  ERROR: 'edu-coexistence-error',
-  OFFLINE: 'edu-coexistence-offline',
-  ARC_ACCOUNT_PICKER: 'arc-account-picker',
-};
-
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {WebUIListenerBehaviorInterface}
- */
-const EduCoexistenceAppBase =
-    mixinBehaviors([WebUIListenerBehavior], PolymerElement);
-
-/**
- * @polymer
- */
-class EduCoexistenceApp extends EduCoexistenceAppBase {
-  static get is() {
-    return 'edu-coexistence-app';
-  }
-
-  static get template() {
-    return html`{__html_template__}`;
-  }
-
-  static get properties() {
-    return {
-      /**
-       * Whether the error screen should be shown.
-       * @private
-       */
-      isErrorShown_: {
-        type: Boolean,
-        value: false,
-      },
-
-      /*
-       * True if `kArcAccountRestrictions` feature is enabled.
-       * @private
-       */
-      isArcAccountRestrictionsEnabled_: {
-        type: Boolean,
-        value() {
-          return loadTimeData.getBoolean('isArcAccountRestrictionsEnabled');
-        },
-        readOnly: true,
-      },
-    };
-  }
-
-  constructor() {
-    super();
-    /** @type {?Screens} */
-    this.currentScreen_ = null;
-  }
-
-  /** @override */
-  ready() {
-    super.ready();
-    this.addWebUIListener('show-error-screen', () => {
-      this.onError_();
-    });
-
-    this.addEventListener('go-error', () => {
-      this.onError_();
-    });
-
-    window.addEventListener('online', () => {
-      if (this.currentScreen_ !== Screens.ERROR &&
-          this.currentScreen_ !== Screens.ARC_ACCOUNT_PICKER) {
-        this.switchToScreen_(Screens.ONLINE_FLOW);
-      }
-    });
-
-    window.addEventListener('offline', () => {
-      if (this.currentScreen_ !== Screens.ERROR &&
-          this.currentScreen_ !== Screens.ARC_ACCOUNT_PICKER) {
-        this.switchToScreen_(Screens.OFFLINE);
-      }
-    });
-    this.setInitialScreen_(navigator.onLine);
-  }
-
-  /** @return {?Screens} */
-  getCurrentScreenForTest() {
-    return this.currentScreen_;
-  }
-
-  /**
-   * Displays the error screen.
-   * @private
-   */
-  onError_() {
-    this.switchToScreen_(Screens.ERROR);
-  }
-
-  /**
-   * Switches to the specified screen.
-   * @private
-   * @param {Screens} screen
-   */
-  switchToScreen_(screen) {
-    if (this.currentScreen_ === screen) {
-      return;
-    }
-    this.currentScreen_ = screen;
-    /** @type {CrViewManagerElement} */ (this.$.viewManager)
-        .switchView(this.currentScreen_);
-    this.dispatchEvent(new CustomEvent('switch-view-notify-for-testing'));
-  }
-
-  /**
-   * @param {boolean} isOnline Whether or not the browser is online.
-   * @private
-   */
-  setInitialScreen_(isOnline) {
-    const initialScreen = isOnline ? Screens.ONLINE_FLOW : Screens.OFFLINE;
-    if (this.isArcAccountRestrictionsEnabled_) {
-      const options = getAccountAdditionOptionsFromJSON(
-          EduCoexistenceBrowserProxyImpl.getInstance().getDialogArguments());
-      if (!!options && options.showArcAvailabilityPicker) {
-        this.shadowRoot.querySelector('arc-account-picker-app')
-            .loadAccounts()
-            .then(
-                accountsFound => {
-                  this.switchToScreen_(
-                      accountsFound ? Screens.ARC_ACCOUNT_PICKER :
-                                      initialScreen);
-                },
-                reject => {
-                  this.switchToScreen_(initialScreen);
-                });
-        return;
-      }
-    }
-    this.switchToScreen_(initialScreen);
-  }
-
-  /**
-   * Switches to 'Add account' flow.
-   * @private
-   */
-  showAddAccount_() {
-    this.switchToScreen_(
-        navigator.onLine ? Screens.ONLINE_FLOW : Screens.OFFLINE);
-  }
-
-  /**
-   * Attempts to close the dialog.
-   * @private
-   */
-  closeDialog_() {
-    EduCoexistenceBrowserProxyImpl.getInstance().dialogClose();
-  }
-}
-
-customElements.define(EduCoexistenceApp.is, EduCoexistenceApp);
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_app.ts b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_app.ts
new file mode 100644
index 0000000..2ea2f94
--- /dev/null
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_app.ts
@@ -0,0 +1,153 @@
+// Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import './common.css.js';
+import './edu_coexistence_template.js';
+import './edu_coexistence_button.js';
+import './edu_coexistence_error.js';
+import './edu_coexistence_offline.js';
+import './edu_coexistence_ui.js';
+import '../arc_account_picker/arc_account_picker_app.js';
+import 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js';
+
+import {ArcAccountPickerAppElement} from 'chrome://chrome-signin/arc_account_picker/arc_account_picker_app.js';
+import {getAccountAdditionOptionsFromJSON} from 'chrome://chrome-signin/arc_account_picker/arc_util.js';
+import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js';
+import {CrViewManagerElement} from 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js';
+import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {getTemplate} from './edu_coexistence_app.html.js';
+import {EduCoexistenceBrowserProxyImpl} from './edu_coexistence_browser_proxy.js';
+
+export enum Screens {
+  ONLINE_FLOW = 'edu-coexistence-ui',
+  ERROR = 'edu-coexistence-error',
+  OFFLINE = 'edu-coexistence-offline',
+  ARC_ACCOUNT_PICKER = 'arc-account-picker',
+}
+
+export interface EduCoexistenceApp {
+  $: {
+    viewManager: CrViewManagerElement,
+  };
+}
+
+const EduCoexistenceAppBase = WebUiListenerMixin(PolymerElement);
+
+export class EduCoexistenceApp extends EduCoexistenceAppBase {
+  static get is() {
+    return 'edu-coexistence-app';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  static get properties() {
+    return {
+      /**
+       * Whether the error screen should be shown.
+       */
+      isErrorShown: {
+        type: Boolean,
+        value: false,
+      },
+
+      /*
+       * True if `kArcAccountRestrictions` feature is enabled.
+       */
+      isArcAccountRestrictionsEnabled: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('isArcAccountRestrictionsEnabled');
+        },
+        readOnly: true,
+      },
+    };
+  }
+
+  protected isArcAccountRestrictionsEnabled: boolean;
+  protected currentScreen: Screens;
+
+  override ready() {
+    super.ready();
+    this.addWebUiListener('show-error-screen', () => {
+      this.onError();
+    });
+
+    this.addEventListener('go-error', () => {
+      this.onError();
+    });
+
+    window.addEventListener('online', () => {
+      if (this.currentScreen !== Screens.ERROR &&
+          this.currentScreen !== Screens.ARC_ACCOUNT_PICKER) {
+        this.switchToScreen(Screens.ONLINE_FLOW);
+      }
+    });
+
+    window.addEventListener('offline', () => {
+      if (this.currentScreen !== Screens.ERROR &&
+          this.currentScreen !== Screens.ARC_ACCOUNT_PICKER) {
+        this.switchToScreen(Screens.OFFLINE);
+      }
+    });
+    this.setInitialScreen(navigator.onLine);
+  }
+
+  getCurrentScreenForTest(): Screens {
+    return this.currentScreen;
+  }
+
+  private onError() {
+    this.switchToScreen(Screens.ERROR);
+  }
+
+  /** Switches to the specified screen. */
+  private switchToScreen(screen: Screens) {
+    if (this.currentScreen === screen) {
+      return;
+    }
+    this.currentScreen = screen;
+    this.$.viewManager.switchView(this.currentScreen);
+    this.dispatchEvent(new CustomEvent('switch-view-notify-for-testing'));
+  }
+
+  private setInitialScreen(isOnline: boolean) {
+    const initialScreen = isOnline ? Screens.ONLINE_FLOW : Screens.OFFLINE;
+    if (this.isArcAccountRestrictionsEnabled) {
+      const options = getAccountAdditionOptionsFromJSON(
+          EduCoexistenceBrowserProxyImpl.getInstance().getDialogArguments());
+      if (!!options && options.showArcAvailabilityPicker) {
+        const arcAccountPicker =
+            this.shadowRoot!.querySelector('arc-account-picker-app') as
+            ArcAccountPickerAppElement;
+        arcAccountPicker.loadAccounts().then(
+            (accountsFound: boolean) => {
+              this.switchToScreen(
+                  accountsFound ? Screens.ARC_ACCOUNT_PICKER : initialScreen);
+            },
+            () => {
+              this.switchToScreen(initialScreen);
+            });
+        return;
+      }
+    }
+    this.switchToScreen(initialScreen);
+  }
+
+  /** Switches to 'Add account' flow. */
+  private showAddAccount() {
+    this.switchToScreen(
+        navigator.onLine ? Screens.ONLINE_FLOW : Screens.OFFLINE);
+  }
+
+  /** Attempts to close the dialog. */
+  private closeDialog() {
+    EduCoexistenceBrowserProxyImpl.getInstance().dialogClose();
+  }
+}
+
+customElements.define(EduCoexistenceApp.is, EduCoexistenceApp);
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_browser_proxy.js b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_browser_proxy.js
deleted file mode 100644
index d24fae4..0000000
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_browser_proxy.js
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {sendWithPromise} from 'chrome://resources/ash/common/cr.m.js';
-
-import {AuthCompletedCredentials} from '../../gaia_auth_host/authenticator.js';
-
-import {EduCoexistenceParams} from './edu_coexistence_controller.js';
-
-/** TODO(yilkal): Improve the naming of methods in the proxy. */
-
-/** @interface */
-export class EduCoexistenceBrowserProxy {
-  /** Sends 'initialize' message to prepare for starting auth. */
-  initializeLogin() {}
-
-  /**
-   * Sends 'initializeEduArgs' message to provide the parameters.
-   * @return {!Promise<!EduCoexistenceParams>}
-   */
-  initializeEduArgs() {}
-
-  /**
-   * Sends 'authExtensionReady' message to handle tasks after auth extension
-   * loads.
-   */
-  authExtensionReady() {}
-
-  /**
-   * Sends 'completeLogin' message to complete login.
-   * @param {!AuthCompletedCredentials} credentials
-   */
-  completeLogin(credentials) {}
-
-  /**
-   * Sends 'getAccounts' message to the handler. The promise will be resolved
-   * with the list of emails of accounts in session.
-   * @return {!Promise<Array<string>>}
-   */
-  getAccounts() {}
-
-  /**
-   * Sends 'consentValid' message to the handler to notify the handler that
-   * the parental consent is valid.
-   */
-  consentValid() {}
-
-  /**
-   * Sends 'consentLogged' message to the handler to notify the handler that
-   * the parental consent is valid.
-   * @param {string} account Added account email.
-   * @param {string} eduCoexistenceToSVersion The terms of service version.
-   * @return {!Promise<boolean>} Returns a promise which will resolve to true
-   *     when the account has successfully been added. The promise will be used
-   *     by the server flow to show "Account added" page.
-   */
-  consentLogged(account, eduCoexistenceToSVersion) {}
-
-  /** Sends 'dialogClose' message to close the login dialog. */
-  dialogClose() {}
-
-  /**
-   * Sends 'error' message to handler.
-   * @param {Array<string>} msg Error messages.
-   */
-  onError(msg) {}
-
-  /**
-   * @return {?string} JSON-encoded dialog arguments.
-   */
-  getDialogArguments() {}
-}
-
-/**
- * @implements {EduCoexistenceBrowserProxy}
- */
-export class EduCoexistenceBrowserProxyImpl {
-  /** @override */
-  initializeLogin() {
-    chrome.send('initialize');
-  }
-
-  /** @override */
-  initializeEduArgs() {
-    return sendWithPromise('initializeEduArgs');
-  }
-
-
-  /** @override */
-  authExtensionReady() {
-    chrome.send('authExtensionReady');
-  }
-
-  /** @override */
-  completeLogin(credentials) {
-    chrome.send('completeLogin', [credentials]);
-  }
-
-  /** @override */
-  getAccounts() {
-    return sendWithPromise('getAccounts');
-  }
-
-  /** @override */
-  consentValid() {
-    chrome.send('consentValid');
-  }
-
-  /** @override */
-  consentLogged(account, eduCoexistenceToSVersion) {
-    return sendWithPromise(
-        'consentLogged', [account, eduCoexistenceToSVersion]);
-  }
-
-  /** @override */
-  dialogClose() {
-    chrome.send('dialogClose');
-  }
-
-  /** @override */
-  onError(msg) {
-    chrome.send('error', msg);
-  }
-
-  /** @override */
-  getDialogArguments() {
-    return chrome.getVariableValue('dialogArguments');
-  }
-
-  /** @return {!EduCoexistenceBrowserProxy} */
-  static getInstance() {
-    return instance || (instance = new EduCoexistenceBrowserProxyImpl());
-  }
-
-  /** @param {!EduCoexistenceBrowserProxy} obj */
-  static setInstance(obj) {
-    instance = obj;
-  }
-}
-
-/** @type {?EduCoexistenceBrowserProxy} */
-let instance = null;
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_browser_proxy.ts b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_browser_proxy.ts
new file mode 100644
index 0000000..56e7df9
--- /dev/null
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_browser_proxy.ts
@@ -0,0 +1,117 @@
+// Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {AuthCompletedCredentials} from 'chrome://chrome-signin/gaia_auth_host/authenticator.js';
+import {sendWithPromise} from 'chrome://resources/ash/common/cr.m.js';
+
+import {EduCoexistenceParams} from './edu_coexistence_controller.js';
+
+export interface EduCoexistenceBrowserProxy {
+  /** Sends 'initialize' message to prepare for starting auth. */
+  initializeLogin(): void;
+
+  /**
+   * Sends 'initializeEduArgs' message to provide the parameters.
+   */
+  initializeEduArgs(): Promise<EduCoexistenceParams>;
+
+  /**
+   * Sends 'authExtensionReady' message to handle tasks after auth extension
+   * loads.
+   */
+  authExtensionReady(): void;
+
+  /**
+   * Sends 'completeLogin' message to complete login.
+   */
+  completeLogin(credentials: AuthCompletedCredentials): void;
+
+  /**
+   * Sends 'getAccounts' message to the handler. The promise will be resolved
+   * with the list of emails of accounts in session.
+   */
+  getAccounts(): Promise<string[]>;
+
+  /**
+   * Sends 'consentValid' message to the handler to notify the handler that
+   * the parental consent is valid.
+   */
+  consentValid(): void;
+
+  /**
+   * Sends 'consentLogged' message to the handler to notify the handler that
+   * the parental consent is valid. Returns a promise which will resolve to true
+   * when the account has successfully been added. The promise will be used
+   * by the server flow to show "Account added" page.
+   */
+  consentLogged(account: string, eduCoexistenceToSVersion: string):
+      Promise<boolean>;
+
+  /** Sends 'dialogClose' message to close the login dialog. */
+  dialogClose(): void;
+
+  /**
+   * Sends 'error' message to handler.
+   */
+  onError(msg: string[]): void;
+
+  /**
+   * Returns JSON-encoded dialog arguments.
+   */
+  getDialogArguments(): string;
+}
+
+export class EduCoexistenceBrowserProxyImpl implements
+    EduCoexistenceBrowserProxy {
+  initializeLogin() {
+    chrome.send('initialize');
+  }
+
+  initializeEduArgs() {
+    return sendWithPromise('initializeEduArgs');
+  }
+
+  authExtensionReady() {
+    chrome.send('authExtensionReady');
+  }
+
+  completeLogin(credentials: AuthCompletedCredentials) {
+    chrome.send('completeLogin', [credentials]);
+  }
+
+  getAccounts() {
+    return sendWithPromise('getAccounts');
+  }
+
+  consentValid() {
+    chrome.send('consentValid');
+  }
+
+  consentLogged(account: string, eduCoexistenceToSVersion: string) {
+    return sendWithPromise(
+        'consentLogged', [account, eduCoexistenceToSVersion]);
+  }
+
+  dialogClose() {
+    chrome.send('dialogClose');
+  }
+
+  onError(msg: string[]) {
+    chrome.send('error', msg);
+  }
+
+  getDialogArguments() {
+    return chrome.getVariableValue('dialogArguments');
+  }
+
+  static getInstance(): EduCoexistenceBrowserProxy {
+    return instance || (instance = new EduCoexistenceBrowserProxyImpl());
+  }
+
+  static setInstance(obj: EduCoexistenceBrowserProxy) {
+    instance = obj;
+  }
+}
+
+let instance: EduCoexistenceBrowserProxy|null = null;
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_button.html b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_button.html
index cf2fd5e..a6f4124 100644
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_button.html
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_button.html
@@ -5,13 +5,10 @@
     border-radius: 20px;
   }
 </style>
-<cr-button class$="[[buttonClasses]]" on-click="onClick_"
+<cr-button class$="[[buttonClasses]]" on-click="onClick"
     disabled="[[disabled]]">
-  <template is="dom-if" if="[[hasIconBeforeText_(buttonType)]]">
-    <iron-icon icon="[[getIcon_(buttonType)]]"></iron-icon>
+  <template is="dom-if" if="[[hasIconBeforeText(buttonType)]]">
+    <iron-icon icon="[[getIcon(buttonType)]]"></iron-icon>
   </template>
-  [[getDisplayName_(buttonType)]]
-  <template is="dom-if" if="[[hasIconAfterText_(buttonType)]]">
-    <iron-icon icon="[[getIcon_(buttonType)]]"></iron-icon>
-  </template>
+  [[getDisplayName(buttonType)]]
 </cr-button>
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_button.js b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_button.js
deleted file mode 100644
index 8271ff62..0000000
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_button.js
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'chrome://resources/cr_elements/cr_button/cr_button.js';
-import 'chrome://resources/cr_elements/icons.html.js';
-import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
-import './strings.m.js';
-
-import {assert} from 'chrome://resources/ash/common/assert.js';
-import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/ash/common/i18n_behavior.js';
-import {isRTL} from 'chrome://resources/ash/common/util.js';
-import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-/** @enum {string} */
-const ButtonTypes = {
-  ACTION: 'action',
-  BACK: 'back',
-};
-
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {I18nBehaviorInterface}
- */
-const EduCoexistenceButtonBase = mixinBehaviors([I18nBehavior], PolymerElement);
-
-/**
- * @polymer
- */
-class EduCoexistenceButton extends EduCoexistenceButtonBase {
-  static get is() {
-    return 'edu-coexistence-button';
-  }
-
-  static get template() {
-    return html`{__html_template__}`;
-  }
-
-  static get properties() {
-    return {
-      /**
-       * Set button type.
-       */
-      buttonType: {
-        type: String,
-        value: ButtonTypes.ACTION,
-      },
-
-      /**
-       * Button class list string.
-       */
-      buttonClasses: {
-        type: String,
-        computed: 'getClass_(buttonType)',
-      },
-
-      /**
-       * 'disabled' button attribute.
-       */
-      disabled: {
-        type: Boolean,
-        value: false,
-      },
-
-      /**
-       * Whether to use new OOBE style for the button.
-       */
-      newOobeStyleEnabled: {
-        type: Boolean,
-        value: false,
-      },
-    };
-  }
-
-  /** @override */
-  ready() {
-    super.ready();
-    this.assertButtonType_(this.buttonType);
-  }
-
-  /**
-   * @param {string} buttonType
-   * @private
-   */
-  assertButtonType_(buttonType) {
-    assert(Object.values(ButtonTypes).includes(buttonType));
-  }
-
-  /**
-   * @param {!ButtonTypes} buttonType
-   * @return {string} CSS class names
-   * @private
-   */
-  getClass_(buttonType) {
-    this.assertButtonType_(buttonType);
-    return buttonType === ButtonTypes.ACTION ? 'action-button' : '';
-  }
-
-  /**
-   * @param {!ButtonTypes} buttonType
-   * @return {boolean} Whether the button should have an icon before text
-   * @private
-   */
-  hasIconBeforeText_(buttonType) {
-    this.assertButtonType_(buttonType);
-    return buttonType === ButtonTypes.BACK;
-  }
-
-  /**
-   * @param {!ButtonTypes} buttonType
-   * @return {boolean} Whether the button should have an icon after text
-   * @private
-   */
-  hasIconAfterText_(buttonType) {
-    this.assertButtonType_(buttonType);
-    return false;
-  }
-
-  /**
-   * @param {!ButtonTypes} buttonType
-   * @return {string} Icon
-   * @private
-   */
-  getIcon_(buttonType) {
-    this.assertButtonType_(buttonType);
-    if (buttonType === ButtonTypes.BACK) {
-      return isRTL() ? 'cr:chevron-right' : 'cr:chevron-left';
-    }
-    return '';
-  }
-
-  /**
-   * @param {!ButtonTypes} buttonType
-   * @return {string} Localized button text
-   * @private
-   */
-  getDisplayName_(buttonType) {
-    this.assertButtonType_(buttonType);
-
-    if (buttonType === ButtonTypes.BACK) {
-      return this.i18n('backButton');
-    }
-    if (buttonType === ButtonTypes.ACTION) {
-      return this.i18n('nextButton');
-    }
-    return '';  // unreached
-  }
-
-  /**
-   * @param {!Event} e
-   * @private
-   */
-  onClick_(e) {
-    if (this.disabled) {
-      e.stopPropagation();
-      return;
-    }
-    if (this.buttonType === ButtonTypes.BACK) {
-      this.dispatchEvent(new CustomEvent('go-back', {
-        bubbles: true,
-        composed: true,
-      }));
-      return;
-    }
-    if (this.buttonType === ButtonTypes.ACTION) {
-      this.dispatchEvent(new CustomEvent('go-action', {
-        bubbles: true,
-        composed: true,
-      }));
-      return;
-    }
-  }
-}
-
-customElements.define(EduCoexistenceButton.is, EduCoexistenceButton);
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_button.ts b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_button.ts
new file mode 100644
index 0000000..31b93bc
--- /dev/null
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_button.ts
@@ -0,0 +1,116 @@
+// Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/cr_elements/icons.html.js';
+import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
+import '../strings.m.js';
+
+import {assert} from 'chrome://resources/ash/common/assert.js';
+import {isRTL} from 'chrome://resources/ash/common/util.js';
+import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {getTemplate} from './edu_coexistence_button.html.js';
+
+enum ButtonTypes {
+  ACTION = 'action',
+  BACK = 'back',
+}
+
+const EduCoexistenceButtonBase = I18nMixin(PolymerElement);
+
+export class EduCoexistenceButton extends EduCoexistenceButtonBase {
+  static get is() {
+    return 'edu-coexistence-button';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  static get properties() {
+    return {
+      buttonType: {
+        type: String,
+        value: ButtonTypes.ACTION,
+      },
+
+      buttonClasses: {
+        type: String,
+        computed: 'getClass(buttonType)',
+      },
+
+      disabled: {
+        type: Boolean,
+        value: false,
+      },
+    };
+  }
+
+  disabled: boolean;
+  private buttonType: ButtonTypes;
+
+  override ready() {
+    super.ready();
+    this.assertButtonType(this.buttonType);
+  }
+
+  private assertButtonType(buttonType: ButtonTypes) {
+    assert(Object.values(ButtonTypes).includes(buttonType));
+  }
+
+  private getClass(buttonType: ButtonTypes): string {
+    this.assertButtonType(buttonType);
+    return buttonType === ButtonTypes.ACTION ? 'action-button' : '';
+  }
+
+  private hasIconBeforeText(buttonType: ButtonTypes): boolean {
+    this.assertButtonType(buttonType);
+    return buttonType === ButtonTypes.BACK;
+  }
+
+  private getIcon(buttonType: ButtonTypes): string {
+    this.assertButtonType(buttonType);
+    if (buttonType === ButtonTypes.BACK) {
+      return isRTL() ? 'cr:chevron-right' : 'cr:chevron-left';
+    }
+    return '';
+  }
+
+  private getDisplayName(buttonType: ButtonTypes): string {
+    this.assertButtonType(buttonType);
+
+    if (buttonType === ButtonTypes.BACK) {
+      return this.i18n('backButton');
+    }
+    if (buttonType === ButtonTypes.ACTION) {
+      return this.i18n('nextButton');
+    }
+    return '';  // unreached
+  }
+
+  private onClick(e: Event) {
+    if (this.disabled) {
+      e.stopPropagation();
+      return;
+    }
+    if (this.buttonType === ButtonTypes.BACK) {
+      this.dispatchEvent(new CustomEvent('go-back', {
+        bubbles: true,
+        composed: true,
+      }));
+      return;
+    }
+    if (this.buttonType === ButtonTypes.ACTION) {
+      this.dispatchEvent(new CustomEvent('go-action', {
+        bubbles: true,
+        composed: true,
+      }));
+      return;
+    }
+  }
+}
+
+customElements.define(EduCoexistenceButton.is, EduCoexistenceButton);
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_controller.js b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_controller.js
deleted file mode 100644
index 9fc66fd..0000000
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_controller.js
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {PostMessageApiServer} from 'chrome://resources/ash/common/post_message_api/post_message_api_server.js';
-
-import {AuthCompletedCredentials, Authenticator, AuthParams} from '../../gaia_auth_host/authenticator.js';
-
-import {EduCoexistenceBrowserProxyImpl} from './edu_coexistence_browser_proxy.js';
-
-const MILLISECONDS_PER_SECOND = 1000;
-
-/**
- * @typedef {{
- *   hl: (string),
- *   url: (string),
- *   clientId: (string),
- *   sourceUi: (string),
- *   clientVersion: (string),
- *   eduCoexistenceAccessToken: (string),
- *   eduCoexistenceId: (string),
- *   platformVersion: (string),
- *   releaseChannel: (string),
- *   deviceId: (string),
- *   email: (string|undefined),
- *   readOnlyEmail: (string|undefined),
- *   signinTime: (number),
- * }}
- */
-export let EduCoexistenceParams;
-
-
-/**
- * Constructs the EDU Coexistence URL.
- * @param {!EduCoexistenceParams} params Parameters for the flow.
- * @return {URL}
- */
-function constructEduCoexistenceUrl(params) {
-  const url = new URL(params.url);
-  url.searchParams.set('hl', params.hl);
-  url.searchParams.set('source_ui', params.sourceUi);
-  url.searchParams.set('client_id', params.clientId);
-  url.searchParams.set('client_version', params.clientVersion);
-  url.searchParams.set('edu_coexistence_id', params.eduCoexistenceId);
-  url.searchParams.set('platform_version', params.platformVersion);
-  url.searchParams.set('release_channel', params.releaseChannel);
-  url.searchParams.set('device_id', params.deviceId);
-  if (params.email) {
-    url.searchParams.set('email', params.email);
-    if (params.readOnlyEmail) {
-      url.searchParams.set('read_only_email', params.readOnlyEmail);
-    }
-  }
-  return url;
-}
-
-/**
- * Class that orchestrates the EDU Coexistence signin flow.
- */
-export class EduCoexistenceController extends PostMessageApiServer {
-  /**
-   * @param {!Element} ui Polymer object edu-coexistence-ui
-   * @param {!Element} webview  The <webview> element to listen to as a
-   *     client.
-   * @param {!EduCoexistenceParams} params  The params for the flow.
-   */
-  constructor(ui, webview, params) {
-    const flowURL = constructEduCoexistenceUrl(params);
-    const protocol = flowURL.hostname === 'localhost' ? 'http://' : 'https://';
-    const originURLPrefix = protocol + flowURL.host;
-    super(webview, originURLPrefix, originURLPrefix);
-
-    this.ui = ui;
-    this.isOobe_ = params.sourceUi === 'oobe';
-    this.flowURL_ = flowURL;
-    this.originURLPrefix_ = originURLPrefix;
-    this.webview_ = webview;
-    this.userInfo_ = null;
-    this.authCompletedReceived_ = false;
-    this.browserProxy_ = EduCoexistenceBrowserProxyImpl.getInstance();
-    this.eduCoexistenceAccessToken_ = params.eduCoexistenceAccessToken;
-    this.signinTime_ = new Date(params.signinTime);
-
-    this.webview_.request.onBeforeSendHeaders.addListener(
-        (details) => {
-          if (this.originMatchesFilter(details.url)) {
-            details.requestHeaders.push({
-              name: 'Authorization',
-              value: 'Bearer ' + this.eduCoexistenceAccessToken_,
-            });
-          }
-
-          return {requestHeaders: details.requestHeaders};
-        },
-
-        {urls: ['<all_urls>']}, ['blocking', 'requestHeaders']);
-
-    /**
-     * The state of the guest content, saved as requested by
-     * the guest content to ensure that its state outlives content
-     * reload events, which destroy the state of the guest content.
-     * The value itself is opaque encoded binary data.
-     * @private {?Uint8Array}
-     */
-    this.guestFlowState_ = null;
-
-    /**
-     * The auth extension host instance.
-     * @private {Authenticator}
-     */
-    this.authExtHost_ = new Authenticator(
-        /** @type {!WebView} */ (this.webview_));
-
-    /**
-     * @type {boolean}
-     * @private
-     */
-    this.isDomLoaded_ = document.readyState !== 'loading';
-    if (this.isDomLoaded_) {
-      this.initializeAfterDomLoaded_();
-    } else {
-      document.addEventListener(
-          'DOMContentLoaded', this.initializeAfterDomLoaded_.bind(this));
-    }
-  }
-
-  /** @override */
-  onInitializationError(origin) {
-    this.reportError_(
-        ['Error initializing communication channel with origin:' + origin]);
-  }
-
-  /** @return {boolean} */
-  getIsOobe() {
-    return this.isOobe_;
-  }
-
-
-  /**
-   * Returns the hostname of the origin of the flow's URL (the one it was
-   * initialized with, not its current URL).
-   * @return {string}
-   */
-  getFlowOriginHostname() {
-    return this.flowURL_.hostname;
-  }
-
-  /** @private */
-  initializeAfterDomLoaded_() {
-    this.isDomLoaded_ = true;
-    // Register methods with PostMessageAPI.
-    this.registerMethod('consentValid', this.consentValid_.bind(this));
-    this.registerMethod('consentLogged', this.consentLogged_.bind(this));
-    this.registerMethod('requestClose', this.requestClose_.bind(this));
-    this.registerMethod('reportError', this.reportError_.bind(this));
-    this.registerMethod(
-        'saveGuestFlowState', this.saveGuestFlowState_.bind(this));
-    this.registerMethod(
-        'fetchGuestFlowState', this.fetchGuestFlowState_.bind(this));
-    this.registerMethod(
-        'getEduAccountEmail', this.getEduAccountEmail_.bind(this));
-    this.registerMethod(
-        'getTimeDeltaSinceSigninSeconds',
-        this.getTimeDeltaSinceSigninSeconds.bind(this));
-
-    // Add listeners for Authenticator.
-    this.addAuthExtHostListeners_();
-  }
-
-  /**
-   * Loads the flow into the controller.
-   * @param {!AuthParams} data parameters for auth extension.
-   */
-  loadAuthExtension(data) {
-    // We use the Authenticator to set the web flow URL instead
-    // of setting it ourselves, so that the content isn't loaded twice.
-    // This is why this class doesn't directly set webview.src_ (except in
-    // onAuthCompleted below to handle the corner case of loading
-    // accounts.google.com for running against webserver running on localhost).
-    // The EDU Coexistence web flow will be responsible for constructing
-    // and forwarding to the accounts.google.com URL that Authenticator
-    // interacts with.
-    data.frameUrl = this.flowURL_;
-    this.authExtHost_.load(data.authMode, data);
-  }
-
-  /**
-   * Resets the internal state of the controller.
-   */
-  reset() {
-    this.userInfo_ = null;
-    this.authCompletedReceived_ = false;
-  }
-
-  /** @private */
-  addAuthExtHostListeners_() {
-    this.authExtHost_.addEventListener('ready', () => this.onAuthReady_());
-    this.authExtHost_.addEventListener(
-        'getAccounts', () => this.onGetAccounts_());
-    this.authExtHost_.addEventListener(
-        'authCompleted',
-        e => this.onAuthCompleted_(
-            /** @type {!CustomEvent<!AuthCompletedCredentials>} */ (e)));
-  }
-
-  /** @private */
-  onAuthReady_() {
-    this.browserProxy_.authExtensionReady();
-  }
-
-  /** @private */
-  onGetAccounts_() {
-    this.browserProxy_.getAccounts().then(result => {
-      this.authExtHost_.getAccountsResponse(result);
-    });
-  }
-
-  /** @private */
-  onAuthCompleted_(e) {
-    this.authCompletedReceived_ = true;
-    this.userInfo_ = e.detail;
-    this.browserProxy_.completeLogin(e.detail);
-
-    // The EDU Signin page doesn't forward to the next page on success, so we have
-    // to manually update the src to continue to the last page of the flow.
-    const finishURL = this.flowURL_;
-    finishURL.pathname = '/supervision/coexistence/finish';
-    this.webview_.src = finishURL.toString();
-  }
-
-  /**
-   * @private
-   * Informs API that the parent consent is now valid.
-   * @param {!Array} unused Placeholder unused empty parameter.
-   */
-  consentValid_(unused) {
-    this.browserProxy_.consentValid();
-  }
-
-  /*
-   * @private
-   * @param {!Array<string>} An array that contains eduCoexistenceToSVersion.
-   * with a boolean indicating that the local account was created.
-   */
-  consentLogged_(eduCoexistenceToSVersion) {
-    return this.browserProxy_.consentLogged(
-        this.userInfo_.email, eduCoexistenceToSVersion[0]);
-  }
-
-  /**
-   * @private
-   * Attempts to close the widget hosting the flow.
-   */
-  requestClose_() {
-    this.browserProxy_.dialogClose();
-  }
-
-  /*
-   * @private
-   * @param {!Array<Uint8Array>} An array that contains guest flow state in its
-   *    first element.
-   */
-  saveGuestFlowState_(guestFlowState) {
-    this.guestFlowState_ = guestFlowState[0];
-  }
-
-  /**
-   * @param {!Array} unused Placeholder unused empty parameter.
-   * @return {?Object}  The guest flow state previously saved
-   *     using saveGuestFlowState().
-   */
-  fetchGuestFlowState_(unused) {
-    return {'state': this.guestFlowState_};
-  }
-
-  /**
-   * @param {!Array} unused Placeholder unused empty parameter.
-   * @return {!String}  The edu-account email that is being added to the device.
-   */
-  getEduAccountEmail_(unused) {
-    console.assert(this.userInfo_);
-    return this.userInfo_.email;
-  }
-
-  /**
-   * @private
-   * Notifies the API that there was an unrecoverable error during the flow.
-   * @param {!Array<string>} error An array that contains the error message at
-   *     index 0.
-   */
-  reportError_(error) {
-    // Notify the app to switch to error screen.
-    this.ui.fire('go-error');
-
-    // Send the error strings to C++ handler so they are logged.
-    this.browserProxy_.onError(error);
-  }
-
-  /**
-   * Made public for testing purposes.
-   * @return {number} Returns the number of seconds that have elapsed since
-   * the user's initial signin.
-   */
-  getTimeDeltaSinceSigninSeconds() {
-    return (Date.now() - this.signinTime_) / MILLISECONDS_PER_SECOND;
-  }
-}
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_controller.ts b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_controller.ts
new file mode 100644
index 0000000..598bd3f
--- /dev/null
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_controller.ts
@@ -0,0 +1,260 @@
+// Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {AuthCompletedCredentials, Authenticator, AuthParams} from 'chrome://chrome-signin/gaia_auth_host/authenticator.js';
+import {PostMessageApiServer} from 'chrome://resources/ash/common/post_message_api/post_message_api_server.js';
+
+import {EduCoexistenceBrowserProxy, EduCoexistenceBrowserProxyImpl} from './edu_coexistence_browser_proxy.js';
+
+const MILLISECONDS_PER_SECOND = 1000;
+
+export interface EduCoexistenceParams {
+  hl: string;
+  url: string;
+  clientId: string;
+  sourceUi: string;
+  clientVersion: string;
+  eduCoexistenceAccessToken: string;
+  eduCoexistenceId: string;
+  platformVersion: string;
+  releaseChannel: string;
+  deviceId: string;
+  email?: string;
+  readOnlyEmail?: string;
+  signinTime: number;
+}
+
+function constructEduCoexistenceUrl(params: EduCoexistenceParams): URL {
+  const url = new URL(params.url);
+  url.searchParams.set('hl', params.hl);
+  url.searchParams.set('source_ui', params.sourceUi);
+  url.searchParams.set('client_id', params.clientId);
+  url.searchParams.set('client_version', params.clientVersion);
+  url.searchParams.set('edu_coexistence_id', params.eduCoexistenceId);
+  url.searchParams.set('platform_version', params.platformVersion);
+  url.searchParams.set('release_channel', params.releaseChannel);
+  url.searchParams.set('device_id', params.deviceId);
+  if (params.email) {
+    url.searchParams.set('email', params.email);
+    if (params.readOnlyEmail) {
+      url.searchParams.set('read_only_email', params.readOnlyEmail);
+    }
+  }
+  return url;
+}
+
+/**
+ * Class that orchestrates the EDU Coexistence signin flow.
+ */
+export class EduCoexistenceController extends PostMessageApiServer {
+  authExtHost: Authenticator;
+  private ui: Element;
+  private isOobe: boolean;
+  private flowUrl: URL;
+  private originUrlPrefix: string;
+  private webview: chrome.webviewTag.WebView;
+  private authCompletedReceived: boolean;
+  private browserProxy: EduCoexistenceBrowserProxy;
+  private eduCoexistenceAccessToken: string;
+  private signinTime: number;
+  private isDomLoaded: boolean;
+  private guestFlowState: number|null;
+  private userInfo: any;
+
+  constructor(ui: Element, webview: Element, params: EduCoexistenceParams) {
+    const flowUrl = constructEduCoexistenceUrl(params);
+    const protocol = flowUrl.hostname === 'localhost' ? 'http://' : 'https://';
+    const originUrlPrefix = protocol + flowUrl.host;
+    super(webview, originUrlPrefix, originUrlPrefix);
+
+    this.ui = ui;
+    this.isOobe = params.sourceUi === 'oobe';
+    this.flowUrl = flowUrl;
+    this.originUrlPrefix = originUrlPrefix;
+    this.webview = webview as chrome.webviewTag.WebView;
+    this.userInfo = null;
+    this.authCompletedReceived = false;
+    this.browserProxy = EduCoexistenceBrowserProxyImpl.getInstance();
+    this.eduCoexistenceAccessToken = params.eduCoexistenceAccessToken;
+    this.signinTime = params.signinTime;
+
+    this.webview.request.onBeforeSendHeaders.addListener(
+        (details) => {
+          if (this.originMatchesFilter(details.url)) {
+            details.requestHeaders.push({
+              name: 'Authorization',
+              value: 'Bearer ' + this.eduCoexistenceAccessToken,
+            });
+          }
+
+          return {requestHeaders: details.requestHeaders};
+        },
+
+        {urls: ['<all_urls>']}, ['blocking', 'requestHeaders']);
+
+    /**
+     * The state of the guest content, saved as requested by
+     * the guest content to ensure that its state outlives content
+     * reload events, which destroy the state of the guest content.
+     * The value itself is opaque encoded binary data.
+     */
+    this.guestFlowState = null;
+    this.authExtHost = new Authenticator(this.webview);
+
+    this.isDomLoaded = document.readyState !== 'loading';
+    if (this.isDomLoaded) {
+      this.initializeAfterDomLoaded();
+    } else {
+      document.addEventListener(
+          'DOMContentLoaded', this.initializeAfterDomLoaded.bind(this));
+    }
+  }
+
+  override onInitializationError(origin: string) {
+    this.reportError(
+        ['Error initializing communication channel with origin:' + origin]);
+  }
+
+  getIsOobe(): boolean {
+    return this.isOobe;
+  }
+
+  /**
+   * Returns the hostname of the origin of the flow's URL (the one it was
+   * initialized with, not its current URL).
+   */
+  getFlowOriginHostname(): string {
+    return this.flowUrl.hostname;
+  }
+
+  private initializeAfterDomLoaded() {
+    this.isDomLoaded = true;
+    // Register methods with PostMessageAPI.
+    this.registerMethod('consentValid', this.consentValid.bind(this));
+    this.registerMethod('consentLogged', this.consentLogged.bind(this));
+    this.registerMethod('requestClose', this.requestClose.bind(this));
+    this.registerMethod('reportError', this.reportError.bind(this));
+    this.registerMethod(
+        'saveGuestFlowState', this.saveGuestFlowState.bind(this));
+    this.registerMethod(
+        'fetchGuestFlowState', this.fetchGuestFlowState.bind(this));
+    this.registerMethod(
+        'getEduAccountEmail', this.getEduAccountEmail.bind(this));
+    this.registerMethod(
+        'getTimeDeltaSinceSigninSeconds',
+        this.getTimeDeltaSinceSigninSeconds.bind(this));
+
+    // Add listeners for Authenticator.
+    this.addAuthExtHostListeners();
+  }
+
+  /**
+   * Loads the flow into the controller.
+   */
+  loadAuthExtension(data: AuthParams) {
+    // We use the Authenticator to set the web flow URL instead
+    // of setting it ourselves, so that the content isn't loaded twice.
+    // This is why this class doesn't directly set webview.src_ (except in
+    // onAuthCompleted below to handle the corner case of loading
+    // accounts.google.com for running against webserver running on localhost).
+    // The EDU Coexistence web flow will be responsible for constructing
+    // and forwarding to the accounts.google.com URL that Authenticator
+    // interacts with.
+    data.frameUrl = this.flowUrl;
+    this.authExtHost.load(data.authMode, data);
+  }
+
+  /**
+   * Resets the internal state of the controller.
+   */
+  reset() {
+    this.userInfo = null;
+    this.authCompletedReceived = false;
+  }
+
+  private addAuthExtHostListeners() {
+    this.authExtHost.addEventListener('ready', () => this.onAuthReady());
+    this.authExtHost.addEventListener(
+        'getAccounts', () => this.onGetAccounts());
+    this.authExtHost.addEventListener(
+        'authCompleted',
+        e => this.onAuthCompleted(e as CustomEvent<AuthCompletedCredentials>));
+  }
+
+  private onAuthReady() {
+    this.browserProxy.authExtensionReady();
+  }
+
+  private onGetAccounts() {
+    this.browserProxy.getAccounts().then(result => {
+      this.authExtHost.getAccountsResponse(result);
+    });
+  }
+
+  private onAuthCompleted(e: CustomEvent<AuthCompletedCredentials>) {
+    this.authCompletedReceived = true;
+    this.userInfo = e.detail;
+    this.browserProxy.completeLogin(e.detail);
+
+    // The EDU Signin page doesn't forward to the next page on success, so we
+    // have to manually update the src to continue to the last page of the flow.
+    const finishUrl = this.flowUrl;
+    finishUrl.pathname = '/supervision/coexistence/finish';
+    this.webview.src = finishUrl.toString();
+  }
+
+  /** Informs API that the parent consent is now valid. */
+  private consentValid() {
+    this.browserProxy.consentValid();
+  }
+
+  private consentLogged(eduCoexistenceToSVersion: string[]): Promise<boolean> {
+    // The first argument of eduCoexistenceToSVersion contains the ToS version.
+    return this.browserProxy.consentLogged(
+        this.userInfo.email, eduCoexistenceToSVersion[0]);
+  }
+
+  /** Attempts to close the widget hosting the flow. */
+  private requestClose() {
+    this.browserProxy.dialogClose();
+  }
+
+  private saveGuestFlowState(guestFlowState: number[]) {
+    // The first argument of guestFlowState contains the guest flow state.
+    this.guestFlowState = guestFlowState[0];
+  }
+
+  /**
+   * Returns the guest flow state previously saved using saveGuestFlowState().
+   */
+  private fetchGuestFlowState(): {'state': number|null} {
+    return {'state': this.guestFlowState};
+  }
+
+  private getEduAccountEmail(): string {
+    console.assert(this.userInfo);
+    return this.userInfo.email;
+  }
+
+  /**
+   * Notifies the API that there was an unrecoverable error during the flow.
+   * Takes an array that contains the error message at index 0.
+   */
+  private reportError(error: string[]) {
+    // Notify the app to switch to error screen.
+    this.ui.dispatchEvent(new CustomEvent('go-error'));
+
+    // Send the error strings to C++ handler so they are logged.
+    this.browserProxy.onError(error);
+  }
+
+  /**
+   * Made public for testing purposes.
+   * Returns the number of seconds that have elapsed since the user's initial
+   * signin.
+   */
+  getTimeDeltaSinceSigninSeconds(): number {
+    return (Date.now() - this.signinTime) / MILLISECONDS_PER_SECOND;
+  }
+}
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_css.html b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_css.html
deleted file mode 100644
index ad5b8c6..0000000
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_css.html
+++ /dev/null
@@ -1,144 +0,0 @@
-<template>
-  <style include="cr-shared-style cros-color-overrides">
-    :host {
-      --dialog-top-border-size: 35px;
-    }
-
-    .signin-frame {
-      height: 100%;
-      margin: 0;
-      padding: 0;
-      width: 100%;
-    }
-
-    /* Main container for all page elements */
-    .template-container {
-      display: flex;
-      flex-direction: column;
-      height: 100%;
-      justify-content: flex-start;
-      width: 100%;
-     }
-
-    .column-layout {
-      display: flex;
-      flex-direction: column;
-      height: 100%;
-    }
-
-    .content-container {
-      display: flex;
-      height: 100%;
-      width: 100%;
-    }
-
-    .back-button {
-      padding: 22px 0 0 22px;
-    }
-
-    @media (orientation: landscape) {
-      .template-container {
-        max-height: 680px;
-        max-width: 1040px;
-      }
-
-      /* In landscape  mode, the main title and content area 
-       * are arranged horizontally.
-       */
-      .content-container {
-        flex-direction: row;
-      }
-
-      .buttons-layout {
-        align-items: center;
-        display: flex;
-        justify-content: flex-end;
-        padding-inline-end: 32px;
-        width: 100%;
-      }
-    }
-
-    @media (orientation: portrait) {
-      .template-container {
-        max-height: 1040px;
-        max-width: 680px;
-      }
-
-      /* In portrait  mode, the main title and content area
-       * is arranged vertically 
-       */
-      .content-container {
-        flex-direction: column;
-      }
-
-      .buttons-layout {
-        display: flex;
-        justify-content: center;
-        width: 100%;
-      }
-    }
-
-    .main[scrollable].can-scroll:not(.is-scrolled):not(.scrolled-to-bottom) {
-      background: var(--background-gradient-0);
-    }
-
-    .main[scrollable].can-scroll.is-scrolled:not(.scrolled-to-bottom) {
-      background: var(--background-gradient-0), var(--background-gradient-180);
-    }
-
-    .main[scrollable].is-scrolled.scrolled-to-bottom {
-      background: var(--background-gradient-180);
-    }
-
-    .main {
-      height: 100%;
-      width: 100%;
-    }
-
-    .footer {
-      align-items: center;
-      display: flex;
-      height: 115px;
-      width: 100%;
-    }
-
-    .signin-frame {
-      background-color: white;
-      overflow: hidden;
-    }
-
-    paper-spinner-lite {
-      --spinner-size: 25px;
-      display: none;
-      height: var(--spinner-size);
-      width: var(--spinner-size);
-    }
-
-    paper-spinner-lite[active] {
-      display: inline-block;
-    }
-
-    edu-coexistence-template {
-      align-items: center;
-      display: flex;
-      height: 100%;
-      justify-content:  center;
-    }
-
-    span[slot='buttons'] {
-      display: flex;
-      width: 100%;
-    }
-
-    span[slot='main'] {
-      display: flex;
-      flex-direction: column;
-      height: 100%;
-    }
-
-    edu-coexistence-button[button-type='back'] {
-      margin-inline-start: auto;
-    }
-
-  </style>
-</template>
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_css.js b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_css.js
deleted file mode 100644
index 7c044bcc..0000000
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_css.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'chrome://resources/cr_elements/chromeos/cros_color_overrides.css.js';
-import 'chrome://resources/cr_elements/cr_shared_style.css.js';
-import 'chrome://resources/cr_elements/cr_shared_vars.css.js';
-
-import {html} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-const styleMod = document.createElement('dom-module');
-styleMod.appendChild(html`{__html_template__}`.content);
-styleMod.register('edu-coexistence-css');
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_error.html b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_error.html
index 08212be2..57245c7 100644
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_error.html
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_error.html
@@ -1,4 +1,4 @@
-<style include="edu-coexistence-css"></style>
+<style include="common"></style>
 
 <edu-coexistence-template>
   <span slot="main">
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_error.js b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_error.js
deleted file mode 100644
index 23528f8..0000000
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_error.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import './edu_coexistence_css.js';
-import './edu_coexistence_template.js';
-import './edu_coexistence_button.js';
-import './supervision/supervised_user_error.js';
-
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {EduCoexistenceBrowserProxyImpl} from './edu_coexistence_browser_proxy.js';
-
-class EduCoexistenceError extends PolymerElement {
-  static get is() {
-    return 'edu-coexistence-error';
-  }
-
-  static get template() {
-    return html`{__html_template__}`;
-  }
-
-  /** @override */
-  ready() {
-    super.ready();
-    this.shadowRoot.querySelector('edu-coexistence-template')
-        .showButtonFooter(true);
-
-    this.addEventListener('go-action', () => {
-      this.closeDialog_();
-    });
-  }
-
-  /**
-   * Attempts to close the dialog. In OOBE, this will move on
-   * to the next screen of OOBE (not the next screen of this flow).
-   * @private
-   */
-  closeDialog_() {
-    EduCoexistenceBrowserProxyImpl.getInstance().dialogClose();
-  }
-}
-
-customElements.define(EduCoexistenceError.is, EduCoexistenceError);
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_error.ts b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_error.ts
new file mode 100644
index 0000000..9d9897d
--- /dev/null
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_error.ts
@@ -0,0 +1,45 @@
+// Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import './edu_coexistence_template.js';
+import './edu_coexistence_button.js';
+import './common.css.js';
+import '../supervision/supervised_user_error.js';
+
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {EduCoexistenceBrowserProxyImpl} from './edu_coexistence_browser_proxy.js';
+import {getTemplate} from './edu_coexistence_error.html.js';
+import {EduCoexistenceTemplate} from './edu_coexistence_template.js';
+
+class EduCoexistenceError extends PolymerElement {
+  static get is() {
+    return 'edu-coexistence-error';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  override ready() {
+    super.ready();
+    const template = this.shadowRoot!.querySelector(
+                         'edu-coexistence-template') as EduCoexistenceTemplate;
+    template.updateButtonFooterVisibility(true);
+
+    this.addEventListener('go-action', () => {
+      this.closeDialog();
+    });
+  }
+
+  /**
+   * Attempts to close the dialog. In OOBE, this will move on
+   * to the next screen of OOBE (not the next screen of this flow).
+   */
+  private closeDialog() {
+    EduCoexistenceBrowserProxyImpl.getInstance().dialogClose();
+  }
+}
+
+customElements.define(EduCoexistenceError.is, EduCoexistenceError);
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_offline.html b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_offline.html
index bafa44b..c3be570c 100644
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_offline.html
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_offline.html
@@ -1,4 +1,4 @@
-<style include="edu-coexistence-css"></style>
+<style include="common"></style>
 
 <edu-coexistence-template>
   <div slot="main" class="column-layout content-container">
@@ -9,5 +9,4 @@
       <edu-coexistence-button button-type="action"></edu-coexistence-button>
     </div>
   </div>
-
 </edu-coexistence-template>
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_offline.js b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_offline.js
deleted file mode 100644
index dfed5a0..0000000
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_offline.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import './edu_coexistence_css.js';
-import './edu_coexistence_template.js';
-import './edu_coexistence_button.js';
-import './supervision/supervised_user_offline.js';
-
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {EduCoexistenceBrowserProxyImpl} from './edu_coexistence_browser_proxy.js';
-
-class EduCoexistenceOffline extends PolymerElement {
-  static get is() {
-    return 'edu-coexistence-offline';
-  }
-
-  static get template() {
-    return html`{__html_template__}`;
-  }
-
-  /** @override */
-  ready() {
-    super.ready();
-    this.shadowRoot.querySelector('edu-coexistence-template')
-        .showButtonFooter(true);
-
-    this.addEventListener('go-action', () => {
-      this.closeDialog_();
-    });
-  }
-
-  /**
-   * Attempts to close the dialog. In OOBE, this will move on
-   * to the next screen of OOBE (not the next screen of this flow).
-   * @private
-   */
-  closeDialog_() {
-    EduCoexistenceBrowserProxyImpl.getInstance().dialogClose();
-  }
-}
-
-customElements.define(EduCoexistenceOffline.is, EduCoexistenceOffline);
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_offline.ts b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_offline.ts
new file mode 100644
index 0000000..7687ea9a
--- /dev/null
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_offline.ts
@@ -0,0 +1,45 @@
+// Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import './edu_coexistence_template.js';
+import './edu_coexistence_button.js';
+import './common.css.js';
+import '../supervision/supervised_user_offline.js';
+
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {EduCoexistenceBrowserProxyImpl} from './edu_coexistence_browser_proxy.js';
+import {getTemplate} from './edu_coexistence_offline.html.js';
+import {EduCoexistenceTemplate} from './edu_coexistence_template.js';
+
+class EduCoexistenceOffline extends PolymerElement {
+  static get is() {
+    return 'edu-coexistence-offline';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  override ready() {
+    super.ready();
+    const template = this.shadowRoot!.querySelector(
+                         'edu-coexistence-template') as EduCoexistenceTemplate;
+    template.updateButtonFooterVisibility(true);
+
+    this.addEventListener('go-action', () => {
+      this.closeDialog();
+    });
+  }
+
+  /**
+   * Attempts to close the dialog. In OOBE, this will move on
+   * to the next screen of OOBE (not the next screen of this flow).
+   */
+  private closeDialog() {
+    EduCoexistenceBrowserProxyImpl.getInstance().dialogClose();
+  }
+}
+
+customElements.define(EduCoexistenceOffline.is, EduCoexistenceOffline);
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_template.html b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_template.html
index d6f32db1..c4f7e8066 100644
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_template.html
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_template.html
@@ -1,5 +1,5 @@
-<style include="edu-coexistence-css">
-  :host {
+<style include="common">  
+ :host {
     overflow-y: hidden;
     --background-gradient-0: linear-gradient(0deg,
         rgba(var(--google-grey-100-rgb), 1) 0,
@@ -15,7 +15,7 @@
       <slot name="main"></slot>
     </div>
   </div>
-  <div class="footer" hidden$="[[!showButtonFooter_]]">
+  <div class="footer" hidden$="[[!showButtonFooter]]">
     <slot name="buttons"></slot>
   </div>
 </div>
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_template.js b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_template.js
deleted file mode 100644
index 82914c0..0000000
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_template.js
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {CrScrollableBehavior, CrScrollableBehaviorInterface} from 'chrome://resources/ash/common/cr_scrollable_behavior.js';
-import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {CrScrollableBehaviorInterface}
- */
-const EduCoexistenceTemplateBase =
-    mixinBehaviors([CrScrollableBehavior], PolymerElement);
-
-/**
- * @polymer
- */
-class EduCoexistenceTemplate extends EduCoexistenceTemplateBase {
-  static get is() {
-    return 'edu-coexistence-template';
-  }
-
-  static get template() {
-    return html`{__html_template__}`;
-  }
-
-  static get properties() {
-    return {
-      /**
-       * Indicates whether the footer/button div should be shown.
-       * @private
-       */
-      showButtonFooter_: {
-        type: Boolean,
-        value: false,
-      },
-    };
-  }
-
-  /**
-   * Shows/hides the button footer.
-   * @param {boolean} show Whether to show the footer.
-   */
-  showButtonFooter(show) {
-    this.showButtonFooter_ = show;
-  }
-}
-
-customElements.define(EduCoexistenceTemplate.is, EduCoexistenceTemplate);
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_template.ts b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_template.ts
new file mode 100644
index 0000000..40e0c20
--- /dev/null
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_template.ts
@@ -0,0 +1,48 @@
+// Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import './common.css.js';
+
+import {CrScrollableMixin} from 'chrome://resources/cr_elements/cr_scrollable_mixin.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {getTemplate} from './edu_coexistence_template.html.js';
+
+const EduCoexistenceTemplateBase = CrScrollableMixin(PolymerElement);
+
+export class EduCoexistenceTemplate extends EduCoexistenceTemplateBase {
+  static get is() {
+    return 'edu-coexistence-template';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  static get properties() {
+    return {
+      /**
+       * Indicates whether the footer/button div should be shown.
+       */
+      showButtonFooter: {
+        type: Boolean,
+        value: false,
+      },
+    };
+  }
+
+  protected showButtonFooter: boolean;
+
+  updateButtonFooterVisibility(visible: boolean) {
+    this.showButtonFooter = visible;
+  }
+
+  getContentContainer(): HTMLElement {
+    const contentContainer =
+        this.shadowRoot!.querySelector<HTMLElement>('.content-container');
+    return contentContainer!;
+  }
+}
+
+customElements.define(EduCoexistenceTemplate.is, EduCoexistenceTemplate);
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_ui.html b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_ui.html
index e6b0a67d..ea10a6d0 100644
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_ui.html
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_ui.html
@@ -1,4 +1,4 @@
-<style include="edu-coexistence-css">
+<style include="common">
   paper-spinner-lite {
     --spinner-size: 38px;
     display: none;
@@ -23,17 +23,17 @@
 
 <edu-coexistence-template>
   <span slot="main">
-    <div class="back-button" hidden$="[[!showGaiaButtons_]]">
+    <div class="back-button" hidden$="[[!showGaiaButtons]]">
       <edu-coexistence-button button-type="back"
          id="gaia-back-button"
-         on-go-back="handleGaiaLoginGoBack_">
+         on-go-back="handleGaiaLoginGoBack">
       </edu-coexistence-button>
     </div>
 
-    <webview id="signinFrame" hidden$="[[loading_]]" class="signin-frame"
+    <webview id="signinFrame" hidden$="[[loading]]" class="signin-frame"
              allowscaling></webview>
-    <div class ="spinner-container" hidden$="[[!loading_]]">
-      <paper-spinner-lite class="spinner" active="[[loading_]]">
+    <div class ="spinner-container" hidden$="[[!loading]]">
+      <paper-spinner-lite class="spinner" active="[[loading]]">
       </paper-spinner-lite>
       <div id="comment" aria-live="polite"
            aria-label$="$i18n{loadingMessage}">
@@ -41,11 +41,11 @@
       </div>
     </div>
   </span>
-  <span slot="buttons" hidden$="[[!showGaiaButtons_]]" class="buttons-layout">
+  <span slot="buttons" hidden$="[[!showGaiaButtons]]" class="buttons-layout">
     <gaia-action-buttons id="gaiaNextButton"
-      authenticator="[[controller_.authExtHost_]]"
+      authenticator="[[controller.authExtHost]]"
       rounded-button="true"
-      hidden$="[[!showGaiaNextButton_]]">
+      hidden$="[[!showGaiaNextButton]]">
     </gaia-action-buttons>
   </span>
 </edu-coexistence-template>
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_ui.js b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_ui.js
deleted file mode 100644
index 6b14d60..0000000
--- a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_ui.js
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import './edu_coexistence_css.js';
-import './edu_coexistence_template.js';
-import './edu_coexistence_button.js';
-import './gaia_action_buttons/gaia_action_buttons.js';
-import 'chrome://resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js';
-
-import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from '//resources/ash/common/web_ui_listener_behavior.js';
-import {assert} from 'chrome://resources/ash/common/assert.js';
-import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {EduCoexistenceBrowserProxyImpl} from './edu_coexistence_browser_proxy.js';
-import {EduCoexistenceController} from './edu_coexistence_controller.js';
-
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {WebUIListenerBehaviorInterface}
- */
-const EduCoexistenceUiBase =
-    mixinBehaviors([WebUIListenerBehavior], PolymerElement);
-
-/**
- * @polymer
- */
-class EduCoexistenceUi extends EduCoexistenceUiBase {
-  static get is() {
-    return 'edu-coexistence-ui';
-  }
-
-  static get template() {
-    return html`{__html_template__}`;
-  }
-
-  static get properties() {
-    return {
-      /**
-       * Indicates whether the page is loading.
-       * @private
-       */
-      loading_: {
-        type: Boolean,
-        value: true,
-      },
-
-      /**
-       * Indicates whether the GAIA buttons should be shown.
-       * @private
-       */
-      showGaiaButtons_: {
-        type: Boolean,
-        value: false,
-      },
-
-      /**
-       * Indicates whether the GAIA "Next" button should be shown.
-       * @private
-       */
-      showGaiaNextButton_: {
-        type: Boolean,
-        value: false,
-      },
-
-      /**
-       * The EDU Coexistence controller instance.
-       * @private
-       */
-      controller_: Object,
-    };
-  }
-
-  constructor() {
-    super();
-    this.webview_ = null;
-  }
-
-  /** @override */
-  ready() {
-    super.ready();
-    this.addWebUIListener(
-        'load-auth-extension', data => this.loadAuthExtension_(data));
-    this.webview_ = this.$.signinFrame;
-
-    this.webview_.addEventListener('loadabort', () => {
-      this.loading_ = false;
-      this.showError_();
-    });
-
-    EduCoexistenceBrowserProxyImpl.getInstance().initializeEduArgs().then(
-        (data) => {
-          this.controller_ =
-              new EduCoexistenceController(this, assert(this.webview_), data);
-          EduCoexistenceBrowserProxyImpl.getInstance().initializeLogin();
-        },
-        (err) => {
-          this.showError_();
-          EduCoexistenceBrowserProxyImpl.getInstance().onError(
-              ['There was an error getting edu coexistence data']);
-        });
-  }
-
-  /** @param {WebView} webview */
-  setWebviewForTest(webview) {
-    this.webview_ = webview;
-  }
-
-  /** @private */
-  showError_() {
-    this.dispatchEvent(new CustomEvent('go-error', {
-      bubbles: true,
-      composed: true,
-    }));
-  }
-
-  /**
-   * Attempts to close the dialog
-   * @private
-   */
-  closeDialog_() {
-    EduCoexistenceBrowserProxyImpl.getInstance().dialogClose();
-  }
-
-  /** @private */
-  loadAuthExtension_(data) {
-    // Set up the controller.
-    this.controller_.loadAuthExtension(data);
-
-    this.webview_.addEventListener('contentload', () => {
-      this.loading_ = false;
-      this.configureUiForGaiaFlow_();
-    });
-  }
-
-  /** @private */
-  handleGaiaLoginGoBack_(e) {
-    e.stopPropagation();
-    const backButton = this.root.getElementById('gaia-back-button');
-    if (backButton.disabled) {
-      // This is a safeguard against this method getting called somehow
-      // despite the button being disabled.
-      return;
-    }
-    backButton.disabled = true;
-
-    this.webview_.back((success /* ignored */) => {
-      // Wait a full second after the callback fires before processing another
-      // click on the back button.  This delay is needed because the callback
-      // fires before the content finishes navigating to the previous page.
-      setTimeout(() => {
-        backButton.disabled = false;
-      }, 1000 /* 1 second */);
-      this.webview_.focus();
-    });
-  }
-
-  /**
-   * Configures the UI for showing/hiding the GAIA login flow.
-   * @private
-   */
-  configureUiForGaiaFlow_() {
-    const currentUrl = new URL(this.webview_.src);
-    const template = this.shadowRoot.querySelector('edu-coexistence-template');
-    const contentContainer = template.$$('div.content-container');
-
-    if (currentUrl.hostname !== this.controller_.getFlowOriginHostname()) {
-      // Show the GAIA Buttons.
-      this.showGaiaButtons_ = true;
-      // Shrink the content-container so that the buttons line up more closely
-      // with the server rendered buttons.
-      contentContainer.style.height = 'calc(100% - 90px)';
-
-      // Don't show the "Next" button if the EDU authentication got forwarded to
-      // a non-Google SSO page.
-      this.showGaiaNextButton_ = currentUrl.hostname.endsWith('.google.com');
-    } else {
-      // Hide the GAIA Buttons.
-      this.showGaiaButtons_ = false;
-
-      // Hide the GAIA Next button.
-      this.showGaiaNextButton_ = false;
-
-      // Restore the content container div to 100%
-      contentContainer.style.height = '100%';
-    }
-
-    template.showButtonFooter(this.showGaiaButtons_);
-  }
-}
-
-customElements.define(EduCoexistenceUi.is, EduCoexistenceUi);
diff --git a/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_ui.ts b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_ui.ts
new file mode 100644
index 0000000..11803c6
--- /dev/null
+++ b/chrome/browser/resources/chromeos/edu_coexistence/edu_coexistence_ui.ts
@@ -0,0 +1,178 @@
+// Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import './common.css.js';
+import './edu_coexistence_template.js';
+import './edu_coexistence_button.js';
+import '../gaia_action_buttons/gaia_action_buttons.js';
+import 'chrome://resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js';
+
+import {AuthParams} from 'chrome://chrome-signin/gaia_auth_host/authenticator.js';
+import {assert} from 'chrome://resources/ash/common/assert.js';
+import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {EduCoexistenceBrowserProxyImpl} from './edu_coexistence_browser_proxy.js';
+import {EduCoexistenceButton} from './edu_coexistence_button.js';
+import {EduCoexistenceController, EduCoexistenceParams} from './edu_coexistence_controller.js';
+import {EduCoexistenceTemplate} from './edu_coexistence_template.js';
+import {getTemplate} from './edu_coexistence_ui.html.js';
+
+export interface EduCoexistenceUi {
+  $: {
+    signinFrame: chrome.webviewTag.WebView,
+  };
+}
+
+const EduCoexistenceUiBase = WebUiListenerMixin(PolymerElement);
+
+export class EduCoexistenceUi extends EduCoexistenceUiBase {
+  static get is() {
+    return 'edu-coexistence-ui';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  static get properties() {
+    return {
+      /** Indicates whether the page is loading. */
+      loading: {
+        type: Boolean,
+        value: true,
+      },
+
+      /** Indicates whether the GAIA buttons should be shown. */
+      showGaiaButtons: {
+        type: Boolean,
+        value: false,
+      },
+
+      /** Indicates whether the GAIA "Next" button should be shown. */
+      showGaiaNextButton: {
+        type: Boolean,
+        value: false,
+      },
+
+      /** The EDU Coexistence controller instance. */
+      controller: Object,
+    };
+  }
+
+  protected loading: boolean;
+  protected showGaiaButtons: boolean;
+  protected showGaiaNextButton: boolean;
+  private webview: chrome.webviewTag.WebView;
+  private controller: EduCoexistenceController;
+
+  override ready() {
+    super.ready();
+    this.addWebUiListener(
+        'load-auth-extension',
+        (data: AuthParams) => this.loadAuthExtension(data));
+    this.webview = this.$.signinFrame;
+
+    this.webview.addEventListener('loadabort', () => {
+      this.loading = false;
+      this.showError();
+    });
+
+    EduCoexistenceBrowserProxyImpl.getInstance().initializeEduArgs().then(
+        (data: EduCoexistenceParams) => {
+          this.controller =
+              new EduCoexistenceController(this, assert(this.webview), data);
+          EduCoexistenceBrowserProxyImpl.getInstance().initializeLogin();
+        },
+        () => {
+          this.showError();
+          EduCoexistenceBrowserProxyImpl.getInstance().onError(
+              ['There was an error getting edu coexistence data']);
+        });
+  }
+
+  setWebviewForTest(webview: chrome.webviewTag.WebView) {
+    this.webview = webview;
+  }
+
+  private showError() {
+    this.dispatchEvent(new CustomEvent('go-error', {
+      bubbles: true,
+      composed: true,
+    }));
+  }
+
+  private closeDialog() {
+    EduCoexistenceBrowserProxyImpl.getInstance().dialogClose();
+  }
+
+  private loadAuthExtension(data: AuthParams) {
+    // Set up the controller.
+    this.controller.loadAuthExtension(data);
+
+    this.webview.addEventListener('contentload', () => {
+      this.loading = false;
+      this.configureUiForGaiaFlow();
+    });
+  }
+
+  private handleGaiaLoginGoBack(e: Event) {
+    e.stopPropagation();
+    const backButton = this.shadowRoot!.querySelector('#gaia-back-button') as
+        EduCoexistenceButton;
+    if (backButton!.disabled) {
+      // This is a safeguard against this method getting called somehow
+      // despite the button being disabled.
+      return;
+    }
+    backButton!.disabled = true;
+
+    this.webview.back(() => {
+      // Wait a full second after the callback fires before processing another
+      // click on the back button.  This delay is needed because the callback
+      // fires before the content finishes navigating to the previous page.
+      setTimeout(() => {
+        backButton!.disabled = false;
+      }, 1000 /* 1 second */);
+      this.webview.focus();
+    });
+  }
+
+  /**
+   * Configures the UI for showing/hiding the GAIA login flow.
+   */
+  private configureUiForGaiaFlow() {
+    const currentUrl = new URL(this.webview.src);
+    const template = this.shadowRoot!.querySelector(
+                         'edu-coexistence-template') as EduCoexistenceTemplate;
+    // const contentContainer = template!.getContentContainer();
+    const contentContainer =
+        template.shadowRoot!.querySelector<HTMLElement>('.content-container')!;
+
+    if (currentUrl.hostname !== this.controller.getFlowOriginHostname()) {
+      // Show the GAIA Buttons.
+      this.showGaiaButtons = true;
+      // Shrink the content-container so that the buttons line up more closely
+      // with the server rendered buttons.
+      contentContainer.style.height = 'calc(100% - 90px)';
+
+      // Don't show the "Next" button if the EDU authentication got forwarded to
+      // a non-Google SSO page.
+      this.showGaiaNextButton = currentUrl.hostname.endsWith('.google.com');
+    } else {
+      // Hide the GAIA Buttons.
+      this.showGaiaButtons = false;
+
+      // Hide the GAIA Next button.
+      this.showGaiaNextButton = false;
+
+      // Restore the content container div to 100%
+      contentContainer.style.height = '100%';
+    }
+
+    template!.updateButtonFooterVisibility(this.showGaiaButtons);
+  }
+}
+
+customElements.define(EduCoexistenceUi.is, EduCoexistenceUi);
diff --git a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html
index 3899c59..1dc1dc9b 100644
--- a/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html
+++ b/chrome/browser/resources/chromeos/internet_detail_dialog/internet_detail_dialog.html
@@ -33,6 +33,10 @@
     margin-inline-start: 0;
   }
 
+  #apnRow {
+    height: var(--cr-section-two-line-min-height);
+  }
+
   #apnRowSublabel {
     color: var(--cros-text-color-positive);
   }
@@ -134,7 +138,7 @@
   <template is="dom-if"
       if="[[shouldShowApnSection_(managedProperties_,
           isApnRevampEnabled_)]]">
-    <cr-expand-button class="settings-box cr-row"
+    <cr-expand-button id="apnRow" class="settings-box cr-row"
         expanded="{{apnExpanded_}}">
       <div id="apnRowTitle">$i18n{internetApnPageTitle}</div>
       <div id="apnRowSublabel" class="cr-secondary-text">
diff --git a/chrome/browser/resources/chromeos/supervision/BUILD.gn b/chrome/browser/resources/chromeos/supervision/BUILD.gn
index 79aed62..5f31440 100644
--- a/chrome/browser/resources/chromeos/supervision/BUILD.gn
+++ b/chrome/browser/resources/chromeos/supervision/BUILD.gn
@@ -2,15 +2,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//chrome/common/features.gni")
-import("//third_party/closure_compiler/compile_js.gni")
-import("//tools/grit/grit_rule.gni")
-import("//tools/polymer/html_to_js.gni")
+import("//ui/webui/resources/tools/build_webui.gni")
 import("//ui/webui/resources/tools/generate_grd.gni")
 
-generated_grd = "$target_gen_dir/resources.grd"
-resource_path_prefix = "supervision"
-
 # grdp for resources shared by OOBE.
 generate_grd("build_oobe_grdp") {
   out_grd = "$target_gen_dir/supervision_oobe_resources.grdp"
@@ -20,62 +14,15 @@
   resource_path_prefix = "images"
 }
 
-generate_grd("build_grd") {
-  out_grd = generated_grd
+build_webui("build") {
   grd_prefix = "supervision"
+  grd_resource_path_prefix = "supervision"
+  static_files = [ "supervision_icon.png" ]
 
-  input_files_base_dir =
-      rebase_path(
-          "$root_gen_dir/chrome/browser/resources/chromeos/supervision/",
-          root_build_dir)
-  input_files = [
-    "supervised_user_error.js",
-    "supervised_user_offline.js",
+  web_component_files = [
+    "supervised_user_error.ts",
+    "supervised_user_offline.ts",
   ]
-}
 
-grit("resources") {
-  defines = chrome_grit_defines
-
-  # These arguments are needed since the grd is generated at build time.
-  enable_input_discovery_for_gn_analyze = false
-  source = generated_grd
-  deps = [
-    ":build_grd",
-    ":web_components",
-  ]
-  outputs = [
-    "grit/supervision_resources.h",
-    "grit/supervision_resources_map.cc",
-    "grit/supervision_resources_map.h",
-    "supervision_resources.pak",
-  ]
-  output_dir = "$root_gen_dir/chrome"
-}
-
-js_type_check("closure_compile") {
-  is_polymer3 = true
-  deps = [
-    ":supervised_user_error",
-    ":supervised_user_offline",
-  ]
-}
-
-js_library("supervised_user_error") {
-  deps = [
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-  ]
-}
-
-js_library("supervised_user_offline") {
-  deps = [
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-  ]
-}
-
-html_to_js("web_components") {
-  js_files = [
-    "supervised_user_error.js",
-    "supervised_user_offline.js",
-  ]
+  ts_deps = [ "//third_party/polymer/v3_0:library" ]
 }
diff --git a/chrome/browser/resources/chromeos/supervision/supervised_user_error.js b/chrome/browser/resources/chromeos/supervision/supervised_user_error.ts
similarity index 66%
rename from chrome/browser/resources/chromeos/supervision/supervised_user_error.js
rename to chrome/browser/resources/chromeos/supervision/supervised_user_error.ts
index eed9a55..90940b2 100644
--- a/chrome/browser/resources/chromeos/supervision/supervised_user_error.js
+++ b/chrome/browser/resources/chromeos/supervision/supervised_user_error.ts
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {getTemplate} from './supervised_user_error.html.js';
 
 class SupervisedUserError extends PolymerElement {
   static get is() {
@@ -10,7 +11,7 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 }
 customElements.define(SupervisedUserError.is, SupervisedUserError);
diff --git a/chrome/browser/resources/chromeos/supervision/supervised_user_offline.js b/chrome/browser/resources/chromeos/supervision/supervised_user_offline.ts
similarity index 62%
rename from chrome/browser/resources/chromeos/supervision/supervised_user_offline.js
rename to chrome/browser/resources/chromeos/supervision/supervised_user_offline.ts
index 204e1e1..4f0c2bb 100644
--- a/chrome/browser/resources/chromeos/supervision/supervised_user_offline.js
+++ b/chrome/browser/resources/chromeos/supervision/supervised_user_offline.ts
@@ -2,9 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js';
-
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {getTemplate} from './supervised_user_offline.html.js';
 
 class SupervisedUserOffline extends PolymerElement {
   static get is() {
@@ -12,7 +11,7 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 }
 customElements.define(SupervisedUserOffline.is, SupervisedUserOffline);
\ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/web_app_install/web_app_install_dialog.html b/chrome/browser/resources/chromeos/web_app_install/web_app_install_dialog.html
index 3aa98c4..2ff48de 100644
--- a/chrome/browser/resources/chromeos/web_app_install/web_app_install_dialog.html
+++ b/chrome/browser/resources/chromeos/web_app_install/web_app_install_dialog.html
@@ -40,7 +40,9 @@
   <div slot="body">
     <!-- TODO(crbug.com/1488697): Add app details (name, icon, url, description,
                                   screenshots). -->
-    Body
+    <p id="name"></p>
+    <p id="url"></p>
+    <p id="description"></p>
   </div>
   <div slot="button-container">
     <cr-button class="cancel-button">
diff --git a/chrome/browser/resources/chromeos/web_app_install/web_app_install_dialog.ts b/chrome/browser/resources/chromeos/web_app_install/web_app_install_dialog.ts
index 74d0e45e..ad365d6 100644
--- a/chrome/browser/resources/chromeos/web_app_install/web_app_install_dialog.ts
+++ b/chrome/browser/resources/chromeos/web_app_install/web_app_install_dialog.ts
@@ -27,12 +27,38 @@
     return getTemplate();
   }
 
+  private proxy = BrowserProxy.getInstance();
+
   constructor() {
     super();
     const template = document.createElement('template');
     template.innerHTML = WebAppInstallDialogElement.template as string;
     const fragment = template.content.cloneNode(true);
     this.attachShadow({mode: 'open'}).appendChild(fragment);
+
+    this.initDynamicContent();
+  }
+
+  async initDynamicContent() {
+    try {
+      const dialogArgs = await this.proxy.handler.getDialogArgs();
+      assert(dialogArgs.args);
+
+      const nameElement = this.$<HTMLSpanElement>('#name');
+      assert(nameElement);
+      nameElement.textContent = dialogArgs.args.name;
+
+      const urlElement = this.$<HTMLSpanElement>('#url');
+      assert(urlElement);
+      urlElement.textContent = dialogArgs.args.url.url;
+
+      const descriptionElement = this.$<HTMLSpanElement>('#description');
+      assert(descriptionElement);
+      descriptionElement.textContent = dialogArgs.args.description;
+    } catch (e) {
+      // TODO(crbug.com/1488697) Define expected behavior.
+      console.error(`Unable to get dialog arguments . Error: ${e}.`);
+    }
   }
 
   $<T extends Element>(query: string): T {
@@ -51,8 +77,7 @@
   }
 
   private onCancelButtonClick(): void {
-    const proxy = BrowserProxy.getInstance();
-    proxy.handler.closeDialog();
+    this.proxy.handler.closeDialog();
   }
 
   private async onInstallButtonClick(event: MouseEvent) {
diff --git a/chrome/browser/resources/compose/app.html b/chrome/browser/resources/compose/app.html
index fdbb91ae..066f696b 100644
--- a/chrome/browser/resources/compose/app.html
+++ b/chrome/browser/resources/compose/app.html
@@ -146,12 +146,15 @@
   </compose-textarea>
 
   <div id="loading" hidden="[[!loading_]]">
-    <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="43">
-      <rect x="0" y="0" width="100%" height="11" rx="4" fill="#D9D9D9"></rect>
-      <rect x="0" y="16" width="100%" height="10.8333" rx="4" fill="#D9D9D9">
-      </rect>
-      <rect x="0" y="32" width="75%" height="11" rx="4" fill="#D9D9D9"></rect>
-    </svg>
+    <cr-loading-gradient>
+      <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="43">
+        <clipPath>
+          <rect x="0" y="0" width="100%" height="11" rx="4"></rect>
+          <rect x="0" y="16" width="100%" height="10.8333" rx="4"></rect>
+          <rect x="0" y="32" width="75%" height="11" rx="4"></rect>
+        </clipPath>
+      </svg>
+    </cr-loading-gradient>
   </div>
 
   <div id="resultContainer" hidden="[[!result_]]">
diff --git a/chrome/browser/resources/compose/app.ts b/chrome/browser/resources/compose/app.ts
index d842552a..5c9a41ef 100644
--- a/chrome/browser/resources/compose/app.ts
+++ b/chrome/browser/resources/compose/app.ts
@@ -6,6 +6,7 @@
 import '//resources/cr_elements/cr_button/cr_button.js';
 import '//resources/cr_elements/cr_hidden_style.css.js';
 import '//resources/cr_elements/cr_icon_button/cr_icon_button.js';
+import '//resources/cr_elements/cr_loading_gradient/cr_loading_gradient.js';
 import '//resources/cr_elements/icons.html.js';
 import '//resources/cr_elements/md_select.css.js';
 
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.d.ts b/chrome/browser/resources/gaia_auth_host/authenticator.d.ts
index aedcd14..85ada75 100644
--- a/chrome/browser/resources/gaia_auth_host/authenticator.d.ts
+++ b/chrome/browser/resources/gaia_auth_host/authenticator.d.ts
@@ -67,6 +67,7 @@
   showTos: string;
   ssoProfile: string;
   urlParameterToAutofillSAMLUsername: string;
+  frameUrl: URL;
 }
 
 export enum AuthMode {
diff --git a/chrome/browser/resources/gaia_auth_host/authenticator.js b/chrome/browser/resources/gaia_auth_host/authenticator.js
index 10ea5fb..52164fb 100644
--- a/chrome/browser/resources/gaia_auth_host/authenticator.js
+++ b/chrome/browser/resources/gaia_auth_host/authenticator.js
@@ -107,7 +107,8 @@
  *   isSupervisedUser: boolean,
  *   isDeviceOwner: boolean,
  *   ssoProfile: string,
- *   urlParameterToAutofillSAMLUsername: string
+ *   urlParameterToAutofillSAMLUsername: string,
+ *   frameUrl: URL,
  * }}
  */
 export let AuthParams;
diff --git a/chrome/browser/resources/new_tab_page/modules/drive/module.html b/chrome/browser/resources/new_tab_page/modules/drive/module.html
index 7523c21..fcf4e259 100644
--- a/chrome/browser/resources/new_tab_page/modules/drive/module.html
+++ b/chrome/browser/resources/new_tab_page/modules/drive/module.html
@@ -68,15 +68,9 @@
   }
 </style>
 <ntp-module-header
-    dismiss-text="[[i18nRecursive('',
-                                  'modulesDismissButtonText',
-                                  'modulesDriveFilesLower')]]"
-    disable-text="[[i18nRecursive('',
-                                  'modulesDisableButtonText',
-                                  'modulesDriveSentence2')]]"
-    more-actions-text="[[i18nRecursive('',
-                                       'modulesMoreActions',
-                                       'modulesDriveSentence')]]"
+    dismiss-text="[[i18n('modulesDriveDismissButtonText')]]"
+    disable-text="[[i18n('modulesDriveDisableButtonText')]]"
+    more-actions-text="[[i18n('modulesDriveMoreActionsButtonText')]]"
     show-info-button on-info-button-click="onInfoButtonClick_"
     show-dismiss-button on-dismiss-button-click="onDismissButtonClick_"
     on-disable-button-click="onDisableButtonClick_"
diff --git a/chrome/browser/resources/new_tab_page/modules/v2/drive/module.ts b/chrome/browser/resources/new_tab_page/modules/v2/drive/module.ts
index 207d98ef..7f5867c 100644
--- a/chrome/browser/resources/new_tab_page/modules/v2/drive/module.ts
+++ b/chrome/browser/resources/new_tab_page/modules/v2/drive/module.ts
@@ -59,14 +59,12 @@
         {
           action: 'dismiss',
           icon: 'modules:visibility_off',
-          text: this.i18nRecursive(
-              '', 'modulesDismissButtonText', 'modulesDriveFilesLower'),
+          text: this.i18n('modulesDriveDismissButtonText'),
         },
         {
           action: 'disable',
           icon: 'modules:block',
-          text: this.i18nRecursive(
-              '', 'modulesDisableButtonTextV2', 'modulesDriveSentenceV2'),
+          text: this.i18n('modulesDriveDisableButtonTextV2'),
         },
         {
           action: 'info',
diff --git a/chrome/browser/resources/omnibox/ml/ml_browser_proxy.ts b/chrome/browser/resources/omnibox/ml/ml_browser_proxy.ts
index b5b0a1c63..c7cf4db 100644
--- a/chrome/browser/resources/omnibox/ml/ml_browser_proxy.ts
+++ b/chrome/browser/resources/omnibox/ml/ml_browser_proxy.ts
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 import {AutocompleteControllerType, AutocompleteMatch, OmniboxPageCallbackRouter, OmniboxPageHandler, OmniboxPageHandlerRemote, OmniboxResponse, Signals} from '../omnibox.mojom-webui.js';
+import {MlVersionObj} from '../omnibox_util.js';
 
 export enum ResponseFilter {
   FINAL = 'Final results',
@@ -13,13 +14,13 @@
     (responseFilter: ResponseFilter, controllerType: AutocompleteControllerType,
      input: string, matches: AutocompleteMatch[]) => void;
 
-
 export class MlBrowserProxy {
   private readonly callbackRouter: OmniboxPageCallbackRouter =
       new OmniboxPageCallbackRouter();
   private readonly handler: OmniboxPageHandlerRemote =
       OmniboxPageHandler.getRemote();
   private onResponseCallbacks: OnResponseCallback[] = [];
+  private version: Promise<MlVersionObj>;
 
   constructor() {
     this.callbackRouter.handleNewAutocompleteResponse.addListener(
@@ -55,8 +56,9 @@
     this.onResponse(ResponseFilter.ALL, controllerType, input, matches);
   }
 
-  getModelVersion(): Promise<number> {
-    return this.handler.getMlModelVersion().then(({version}) => version);
+  get modelVersion(): Promise<MlVersionObj> {
+    return this.version ||= this.handler.getMlModelVersion().then(
+               ({version}) => new MlVersionObj(version));
   }
 
   makeMlRequest(signals: Signals): Promise<number> {
diff --git a/chrome/browser/resources/omnibox/ml/ml_calculator.ts b/chrome/browser/resources/omnibox/ml/ml_calculator.ts
index d1d3921..1542bfe8 100644
--- a/chrome/browser/resources/omnibox/ml/ml_calculator.ts
+++ b/chrome/browser/resources/omnibox/ml/ml_calculator.ts
@@ -38,10 +38,10 @@
       return input;
     });
 
-    this.getRequiredElement('#copy').addEventListener('click', () => {
+    this.getRequiredElement('#copy').addEventListener('click', async () => {
       const copyObj = {
         url: window.location.href,
-        version: this.versionString,
+        version: (await this.mlBrowserProxy_.modelVersion).string,
         signals: this.signals,
         score: this.score,
       };
@@ -68,23 +68,14 @@
 
   set mlBrowserProxy(mlBrowserProxy: MlBrowserProxy) {
     this.mlBrowserProxy_ = mlBrowserProxy;
+    mlBrowserProxy.modelVersion.then(
+        version =>
+            createEl(
+                'a', this.getRequiredElement('#version'), [], version.string)
+                .href = version.url);
     this.update();
   }
 
-  private get versionString(): string {
-    return this.getRequiredElement('#version a').textContent || '';
-  }
-
-  set version(version: number) {
-    const versionString = version === -1 ?
-        String(version) :
-        `${version} (${new Date(version * 1000).toLocaleDateString()})`;
-    const codeSearchPrefix =
-        'https://source.corp.google.com/search?q=file:google3/googledata/chrome/breve/cacao/models/data/omnibox/url_scoring/';
-    createEl('a', this.getRequiredElement('#version'), [], versionString).href =
-        `${codeSearchPrefix} ${version}`;
-  }
-
   private static parseSignalStrings(signalStrings: string[]): Signals {
     assert(signalStrings.length === signalNames.length);
     return Object.fromEntries(
diff --git a/chrome/browser/resources/omnibox/ml/ml_table.ts b/chrome/browser/resources/omnibox/ml/ml_table.ts
index 3a18ec7..ec6e03ab 100644
--- a/chrome/browser/resources/omnibox/ml/ml_table.ts
+++ b/chrome/browser/resources/omnibox/ml/ml_table.ts
@@ -8,7 +8,7 @@
 import {AutocompleteControllerType, AutocompleteMatch} from '../omnibox.mojom-webui.js';
 import {clearChildren, createEl, signalNames} from '../omnibox_util.js';
 
-import {ResponseFilter} from './ml_browser_proxy.js';
+import {MlBrowserProxy, ResponseFilter} from './ml_browser_proxy.js';
 // @ts-ignore:next-line
 import sheet from './ml_table.css' assert {type : 'css'};
 import {getTemplate} from './ml_table.html.js';
@@ -45,6 +45,11 @@
     });
   }
 
+  set mlBrowserProxy(mlBrowserProxy: MlBrowserProxy) {
+    mlBrowserProxy.addResponseListener(
+        (...args) => this.onNewResponse(...args));
+  }
+
   onNewResponse(
       responseFilter: ResponseFilter,
       controllerType: AutocompleteControllerType, input: string,
diff --git a/chrome/browser/resources/omnibox/ml/ml_ui.ts b/chrome/browser/resources/omnibox/ml/ml_ui.ts
index bea598c7d..bbc3e541f 100644
--- a/chrome/browser/resources/omnibox/ml/ml_ui.ts
+++ b/chrome/browser/resources/omnibox/ml/ml_ui.ts
@@ -43,13 +43,14 @@
 
     this.getRequiredElement('#ml-sync-batch-url-scoring-disabled-warning')
         .hidden = loadTimeData.getBoolean('isMlSyncBatchUrlScoringEnabled');
-    mlCalculator.mlBrowserProxy = this.mlBrowserProxy;
-    this.mlBrowserProxy.getModelVersion().then(
-        version => mlCalculator.version = version);
-    this.mlBrowserProxy.addResponseListener(
-        (...args) => mlTable.onNewResponse(...args));
     mlTable.addEventListener(
         'match-selected', ({detail}) => mlCalculator.signals = detail);
+
+    this.mlBrowserProxy.modelVersion.then(() => {
+      // ML model was loaded.
+      mlCalculator.mlBrowserProxy = this.mlBrowserProxy;
+      mlTable.mlBrowserProxy = this.mlBrowserProxy;
+    });
   }
 }
 
diff --git a/chrome/browser/resources/omnibox/omnibox_util.ts b/chrome/browser/resources/omnibox/omnibox_util.ts
index 6f2edeb..f1eb076 100644
--- a/chrome/browser/resources/omnibox/omnibox_util.ts
+++ b/chrome/browser/resources/omnibox/omnibox_util.ts
@@ -63,3 +63,19 @@
 export function clamp(value: number, min: number, max: number) {
   return Math.min(Math.max(value, min), max);
 }
+
+export class MlVersionObj {
+  version: number;
+  string: string;
+  url: string;
+
+  constructor(version: number) {
+    this.version = version;
+    this.string = version === -1 ?
+        String(version) :
+        `${version} (${new Date(version * 1000).toLocaleDateString()})`;
+    const codeSearchPrefix =
+        'https://source.corp.google.com/search?q=file:google3/googledata/chrome/breve/cacao/models/data/omnibox/url_scoring/';
+    this.url = `${codeSearchPrefix} ${version}`;
+  }
+}
diff --git a/chrome/browser/resources/pdf/viewport.ts b/chrome/browser/resources/pdf/viewport.ts
index 95a04a25..8b5e1d0 100644
--- a/chrome/browser/resources/pdf/viewport.ts
+++ b/chrome/browser/resources/pdf/viewport.ts
@@ -1535,8 +1535,12 @@
     // Compute the space on the left of the document if the document fits
     // completely in the screen.
     const zoom = this.getZoom();
-    let spaceOnLeft =
-        (this.size.width - this.documentDimensions_.width * zoom) / 2;
+    const scrollbarWidth = this.documentHasScrollbars().vertical ?
+        this.scrollContent_.scrollbarWidth :
+        0;
+    let spaceOnLeft = (this.size.width - scrollbarWidth -
+                       this.documentDimensions_.width * zoom) /
+        2;
     spaceOnLeft = Math.max(spaceOnLeft, 0);
 
     return {
diff --git a/chrome/browser/resources/settings/icons.html b/chrome/browser/resources/settings/icons.html
index ee2e7cf..fafa9363 100644
--- a/chrome/browser/resources/settings/icons.html
+++ b/chrome/browser/resources/settings/icons.html
@@ -137,6 +137,9 @@
       <g id="vr-headset"><path d="M20.907 6.678A2.54 2.54 0 0019.16 6H4.9c-.659 0-1.28.24-1.747.678a2.229 2.229 0 00-.723 1.637v7.37c0 .618.256 1.2.723 1.637A2.54 2.54 0 004.9 18h3.424c.448 0 .884-.114 1.268-.33.384-.216.697-.522.908-.893l.967-1.68a.572.572 0 01.16-.74.67.67 0 01.806 0c.235.18.302.49.16.74l.967 1.68c.21.365.524.677.908.893.384.216.82.33 1.268.33h3.424c.659 0 1.28-.24 1.747-.678.467-.437.723-1.02.723-1.637v-7.37c0-.618-.256-1.2-.723-1.637zM7.83 13.8c-1.328 0-2.4-1.08-2.4-2.4 0-1.32 1.08-2.4 2.4-2.4 1.32 0 2.4 1.08 2.4 2.4 0 1.32-1.072 2.4-2.4 2.4zm8.4 0c-1.328 0-2.4-1.08-2.4-2.4 0-1.32 1.08-2.4 2.4-2.4 1.32 0 2.4 1.08 2.4 2.4 0 1.32-1.072 2.4-2.4 2.4z"></path></g>
       <g id="vr-headset-off"><path d="M2.81,2.81L1.39,4.22L3.68,6.5C3.26,6.87,3,7.41,3,8v8c0,1.1,0.9,2,2,2h3.53c1.42,0,2.02-1.24,2.03-1.27l0.91-1.76 c0.08-0.16,0.22-0.26,0.37-0.31l1.11,1.11l0.49,0.96c0.01,0.03,0.52,1.08,1.71,1.25l4.63,4.63l1.41-1.41L2.81,2.81z M9.87,12.7 C9.59,13.46,8.85,14,8,14c-1.1,0-2-0.9-2-2c0-0.85,0.54-1.59,1.3-1.87l0,0L9.87,12.7L9.87,12.7z M16.7,13.87l3.62,3.62 C20.74,17.13,21,16.59,21,16V8c0-1.1-0.9-2-2-2H8.83c0,0,5.3,5.3,5.3,5.3C14.41,10.54,15.15,10,16,10c1.1,0,2,0.9,2,2 C18,12.85,17.46,13.59,16.7,13.87z"></path></g>
 
+      <!-- "Off" version of the picture-in-picture iron-icon. -->
+      <g id="picture-in-picture-off"><path d="M15.852 13H19V7h-8v1.148l2 2V9h4v2h-3.148Zm5.921 5.926L20 17.148V6H8.852l-2-2H20c.55 0 1.02.195 1.414.586.39.394.586.863.586 1.414v12c0 .168-.016.328-.05.488-.032.157-.09.305-.177.438Zm-12.199-6.5Zm4.852-.852Zm6.023 11.727L17.15 20H4c-.55 0-1.02-.195-1.414-.586A1.935 1.935 0 0 1 2 18V6c0-.55.195-1.02.586-1.414C2.98 4.196 3.449 4 4 4l2 2H4v12h11.148L.648 3.5l1.426-1.426 19.801 19.801Zm0 0"></path></g>
+
       <!--
       These icons are copied from Polymer's iron-icons and kept in sorted order.
       See http://goo.gl/Y1OdAq for instructions on adding additional icons.
@@ -190,6 +193,7 @@
       <g id="performance"><path d="M0 0h24v24H0z" fill="none"></path><path d="m20.38 8.57-1.23 1.85a8 8 0 0 1-.22 7.58H5.07A8 8 0 0 1 15.58 6.85l1.85-1.23A10 10 0 0 0 3.35 19a2 2 0 0 0 1.72 1h13.85a2 2 0 0 0 1.74-1 10 10 0 0 0-.27-10.44zm-9.79 6.84a2 2 0 0 0 2.83 0l5.66-8.49-8.49 5.66a2 2 0 0 0 0 2.83z"></path></g>
       <g id="photo"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"></path></g>
       <g id="photo-off"><path d="M21,5c0-1.1-0.9-2-2-2H5.83L21,18.17V5z"></path><path d="M2.81,2.81L1.39,4.22L3,5.83V19c0,1.1,0.9,2,2,2h13.17l1.61,1.61l1.41-1.41L2.81,2.81z M6,17l3-4l2.25,3l0.82-1.1l2.1,2.1 H6z"></path></g>
+      <g id="picture-in-picture"><path d="M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z"></path></g>
       <g id="power-settings-new"><path d="M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z"></path></g>
       <g id="protocol-handler"><path d="M21.72 11.33l-6.644-7.035a.97.97 0 0 0-1.38-.01l-1.67 1.72-1.617-1.712a.97.97 0 0 0-1.38-.01l-6.737 6.935c-.187.191-.29.447-.292.719-.002.272.099.529.28.722l6.644 7.034a.949.949 0 0 0 1.38.011l1.671-1.718 1.615 1.71a.949.949 0 0 0 1.381.01l6.74-6.935a1.054 1.054 0 0 0 .01-1.44zM6.947 12.464l3.657 3.785-.974.98-5.273-5.456 5.349-5.378.929.962-3.677 3.7a.998.998 0 0 0-.292.702 1 1 0 0 0 .28.705zm7.35 4.768l-.931-.963 3.68-3.7a1.012 1.012 0 0 0 .007-1.407l-3.656-3.784.974-.98 5.273 5.456-5.348 5.378z"></path></g>
       <g id="protocol-handler-off"><path d="M7.95,5.12l0.73-0.8C8.88,4.11,9.15,4,9.42,4c0.27,0,0.54,0.11,0.74,0.32L12,6.34l1.85-2.01C14.04,4.11,14.31,4,14.58,4 c0.27,0,0.54,0.11,0.74,0.32l6.42,7c0.35,0.38,0.35,0.97,0,1.35l-2.98,3.25l-1.42-1.42l2.3-2.51l-5.06-5.52l-1.23,1.34l3.21,3.51 c0.35,0.38,0.35,0.97,0,1.35l-0.51,0.56L7.95,5.12z M19.78,22.61l-3.73-3.73l-0.73,0.8c-0.2,0.22-0.47,0.32-0.74,0.32 c-0.27,0-0.54-0.11-0.74-0.32L12,17.66l-1.85,2.01C9.96,19.89,9.69,20,9.42,20c-0.27,0-0.54-0.11-0.74-0.32l-6.42-7 c-0.35-0.38-0.35-0.97,0-1.35l2.98-3.25L1.39,4.22l1.41-1.41l18.38,18.38L19.78,22.61z M10.64,16.18l-3.21-3.51 c-0.35-0.38-0.35-0.97,0-1.35l0.51-0.56L6.66,9.49L4.36,12l5.06,5.52L10.64,16.18z"></path></g>
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html
index 41897155..549d2a4 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_page.html
+++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -165,7 +165,7 @@
       </template>
 
       <template is="dom-if" if="[[enableSafetyHub_]]">
-        <template is="dom-if" route-path="/safetyHub">
+        <template is="dom-if" route-path="/safetyCheck">
           <!-- TODO(crbug.com/1443466): Make the page searchable.-->
           <settings-subpage id="safetyHub" page-title="$i18n{safetyHub}"
               class="multi-card" no-search>
@@ -1347,14 +1347,13 @@
             <div class="content-settings-header secondary">
               $i18n{siteSettingsAutoPictureInPictureDescription}
             </div>
-            <!-- TODO(https://crbug.com/1471051): Use real icons. -->
             <settings-category-default-radio-group
                 category="[[contentSettingsTypesEnum_.AUTO_PICTURE_IN_PICTURE]]"
                 allow-option-label=
                     "$i18n{siteSettingsAutoPictureInPictureAllowed}"
-                allow-option-icon="settings:window-management"
+                allow-option-icon="settings:picture-in-picture"
                 block-option-label="$i18n{siteSettingsAutoPictureInPictureBlocked}"
-                block-option-icon="settings:window-management-off">
+                block-option-icon="settings:picture-in-picture-off">
             </settings-category-default-radio-group>
             <category-setting-exceptions
                 category="[[contentSettingsTypesEnum_.AUTO_PICTURE_IN_PICTURE]]"
diff --git a/chrome/browser/resources/settings/route.ts b/chrome/browser/resources/settings/route.ts
index b342813..2bdbfd14 100644
--- a/chrome/browser/resources/settings/route.ts
+++ b/chrome/browser/resources/settings/route.ts
@@ -18,7 +18,7 @@
   r.CLEAR_BROWSER_DATA.isNavigableDialog = true;
 
   if (loadTimeData.getBoolean('enableSafetyHub')) {
-    r.SAFETY_HUB = r.PRIVACY.createChild('/safetyHub');
+    r.SAFETY_HUB = r.PRIVACY.createChild('/safetyCheck');
   } else {
     r.SAFETY_CHECK = r.PRIVACY.createSection('/safetyCheck', 'safetyCheck');
   }
diff --git a/chrome/browser/resources/settings/site_settings/site_details.html b/chrome/browser/resources/settings/site_settings/site_details.html
index 6c6fa2b2..273cb0f 100644
--- a/chrome/browser/resources/settings/site_settings/site_details.html
+++ b/chrome/browser/resources/settings/site_settings/site_details.html
@@ -275,10 +275,9 @@
           icon="settings:local-fonts" label="$i18n{fonts}">
       </site-details-permission>
       <template is="dom-if" if="[[autoPictureInPictureEnabled_]]">
-        <!-- TODO(https://crbug.com/1471051): Use real icon. -->
         <site-details-permission
             category="[[contentSettingsTypesEnum_.AUTO_PICTURE_IN_PICTURE]]"
-            icon="settings:window-management"
+            icon="settings:picture-in-picture"
             label="$i18n{siteSettingsAutoPictureInPicture}">
         </site-details-permission>
       </template>
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts b/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts
index 2e8e109..c90719a43 100644
--- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts
+++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.ts
@@ -59,8 +59,7 @@
       route: routes.SITE_SETTINGS_AUTO_PICTURE_IN_PICTURE,
       id: Id.AUTO_PICTURE_IN_PICTURE,
       label: 'siteSettingsAutoPictureInPicture',
-      // TODO(https://crbug.com/1471051): Use real icon.
-      icon: 'settings:window-management',
+      icon: 'settings:picture-in-picture',
       enabledLabel: 'siteSettingsAutoPictureInPictureAllowed',
       disabledLabel: 'siteSettingsAutoPictureInPictureBlocked',
       shouldShow: () => loadTimeData.getBoolean('autoPictureInPictureEnabled'),
diff --git a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts
index 45c3280..1acb8e9 100644
--- a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts
+++ b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts
@@ -1038,6 +1038,9 @@
           {bookmark: chrome.bookmarks.BookmarkTreeNode, event: MouseEvent}>) {
     event.preventDefault();
     event.stopPropagation();
+    if (!event.detail.bookmark) {
+      return;
+    }
     const priceTracked = this.isPriceTracked(event.detail.bookmark);
     const priceTrackingEligible =
         this.isPriceTrackingEligible_(event.detail.bookmark);
diff --git a/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search.html b/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search.html
index 9d919897..0beb62c 100644
--- a/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search.html
+++ b/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search.html
@@ -7,6 +7,19 @@
     margin: 16px 16px 8px;
   }
 
+  #descriptorMenuD cr-button {
+    background-color: var(--sys-color-neutral-container);
+    height: 40px;
+    min-width: 40px;
+    padding: 0px;
+  }
+
+  .descriptor-d {
+    border-radius: 50%;
+    height: 28px;
+    width: 28px;
+  }
+
   #btnContainer {
     display: flex;
     justify-content: flex-end;
@@ -114,6 +127,14 @@
         </button>
       </template>
     </cr-action-menu>
+    <div id="descriptorMenuD">
+      <template is="dom-repeat" items="[[descriptorD_]]">
+        <cr-button on-click="onDescriptorLabelClickD_">
+          <span class="descriptor-d" style$="background-color: [[item]];">
+          </span>
+        </cr-button>
+      </template>
+    </div>
     <div id="btnContainer">
       <cr-button
           id="submitButton"
diff --git a/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search.ts b/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search.ts
index 932707d5..8c3f907 100644
--- a/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search.ts
+++ b/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search.ts
@@ -21,12 +21,16 @@
 import {CustomizeChromeApiProxy} from './customize_chrome_api_proxy.js';
 import {getTemplate} from './wallpaper_search.html.js';
 
+export const DESCRIPTOR_C_VALUE =
+    ['#EF4837', '#0984E3', '#F9CC18', '#23CC6A', '#474747'];
+
 export interface WallpaperSearchElement {
   $: {
     combobox: CustomizeChromeCombobox,
     descriptorMenuA: CrActionMenuElement,
     descriptorMenuB: CrActionMenuElement,
     descriptorMenuC: CrActionMenuElement,
+    descriptorMenuD: CrActionMenuElement,
     heading: SpHeading,
     submitButton: CrButtonElement,
   };
@@ -54,6 +58,10 @@
         type: Object,
         value: null,
       },
+      descriptorD_: {
+        type: Array,
+        value: DESCRIPTOR_C_VALUE,
+      },
       emptyContainers_: Object,
       results_: Object,
       submitBtnText_: {
@@ -65,11 +73,13 @@
   }
 
   private descriptors_: Descriptors|null;
+  private descriptorD_: string[];
   private emptyContainers_: number[];
   private results_: WallpaperSearchResult[];
   private selectedDescriptorA_: string|null;
   private selectedDescriptorB_: string|null;
   private selectedDescriptorC_: string|null;
+  private selectedDescriptorD_: string|null;
   private submitBtnText_: string;
 
   private pageHandler_: CustomizeChromePageHandlerInterface;
@@ -116,6 +126,11 @@
     this.$.descriptorMenuC.close();
   }
 
+  private onDescriptorLabelClickD_(e: DomRepeatEvent<string>) {
+    this.selectedDescriptorD_ = e.model.item;
+    this.$.descriptorMenuC.close();
+  }
+
   private onDescriptorMenuClickA_(e: Event) {
     this.$.descriptorMenuA.showAt(e.target as HTMLElement);
   }
@@ -128,12 +143,17 @@
     this.$.descriptorMenuC.showAt(e.target as HTMLElement);
   }
 
+  private onDescriptorMenuClickD_(e: Event) {
+    this.$.descriptorMenuD.showAt(e.target as HTMLElement);
+  }
+
   private async onSearchClick_() {
     assert(this.descriptors_);
     const descriptorA = this.selectedDescriptorA_ ||
         getRandomDescriptorA(this.descriptors_.descriptorA);
     const {results} = await this.pageHandler_.getWallpaperSearchResults(
-        descriptorA, this.selectedDescriptorB_, this.selectedDescriptorC_);
+        descriptorA, this.selectedDescriptorB_, this.selectedDescriptorC_,
+        this.selectedDescriptorD_);
     this.results_ = results;
     this.emptyContainers_ = Array.from(
         {length: results.length > 0 ? 6 - results.length : 0}, () => 0);
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.html b/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.html
index 5c21ded6..6d18d0b 100644
--- a/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.html
+++ b/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.html
@@ -38,18 +38,24 @@
     min-width: 180px;
     font-size: 13px;
   }
+  #voiceSelectionMenu::part(dialog) {
+    min-width: 304px;
+    width: 304px;
+    margin-left: var(--sp-body-padding);
+    max-height: 95%;
+  }
   .dropdown-voice-selection {
     display: flex;
-    min-width: 312px;
     align-items: center;
     justify-content: space-between;
   }
   .dropdown-voice-selection cr-icon-button {
     margin: 0;
   }
-  .dropdown-voice-selection p {
-    margin: 8px 0;
-    display: inline;
+  .voice-name {
+    max-width: 220px;
+    overflow: hidden;
+    text-overflow: ellipsis;
   }
   .item-invisible-true {
     visibility: hidden;
@@ -244,11 +250,11 @@
             listing the languages of the locale -->
       <button class="dropdown-item dropdown-voice-selection"
         on-click="onVoiceSelectClick_">
-        <span>
+        <span class="voice-name">
           <iron-icon
           class$="button-image item-invisible-[[!item.data.selected]]"
             icon="read-anything-20:check-mark"></iron-icon>
-          <p>[[item.title]]</p>
+          [[item.title]]
         </span>
         <cr-icon-button on-click="onVoicePreviewClick_"
           class$="button-image display-[[!item.data.previewPlaying]]"
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.ts b/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.ts
index 54ed7dd..e909e409 100644
--- a/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.ts
+++ b/chrome/browser/resources/side_panel/read_anything/read_anything_toolbar.ts
@@ -504,7 +504,8 @@
               ]),
           []);
 
-      this.openMenu_(this.$.voiceSelectionMenu, event.target as HTMLElement);
+      this.openMenu_(
+          this.$.voiceSelectionMenu, event.target as HTMLElement, true);
     }
   }
 
@@ -512,7 +513,9 @@
     this.openMenu_(this.$.moreOptionsMenu, event.target as HTMLElement);
   }
 
-  private openMenu_(menuToOpen: CrActionMenuElement, target: HTMLElement) {
+  private openMenu_(
+      menuToOpen: CrActionMenuElement, target: HTMLElement,
+      fullScreen: boolean = false) {
     // The button should stay active while the menu is open and deactivate when
     // the menu closes.
     menuToOpen.addEventListener('close', () => {
@@ -523,11 +526,22 @@
 
     const shadowRoot = this.shadowRoot;
     assert(shadowRoot);
-    menuToOpen.showAt(target, {
-      anchorAlignmentX: AnchorAlignment.AFTER_START,
-      anchorAlignmentY: AnchorAlignment.AFTER_END,
-      noOffset: true,
-    });
+    const minY = target.getBoundingClientRect().bottom;
+    if (fullScreen) {
+      menuToOpen.showAt(target, {
+        minY: minY,
+        left: 0,
+        anchorAlignmentY: AnchorAlignment.AFTER_END,
+        noOffset: true,
+      });
+    } else {
+      menuToOpen.showAt(target, {
+        minY: minY,
+        anchorAlignmentX: AnchorAlignment.AFTER_START,
+        anchorAlignmentY: AnchorAlignment.AFTER_END,
+        noOffset: true,
+      });
+    }
   }
 
   private onHighlightClick_() {
diff --git a/chrome/browser/resources/signin/BUILD.gn b/chrome/browser/resources/signin/BUILD.gn
index e0f26ff3..e54cb32 100644
--- a/chrome/browser/resources/signin/BUILD.gn
+++ b/chrome/browser/resources/signin/BUILD.gn
@@ -40,6 +40,7 @@
   }
   if (enable_dice_support) {
     static_files += [
+      "dice_web_signin_intercept/chrome_signin/chrome_signin.html",
       "dice_web_signin_intercept/dice_web_signin_intercept.html",
       "dice_web_signin_intercept/images/split_header.svg",
     ]
@@ -60,8 +61,10 @@
     ]
   }
   if (enable_dice_support) {
-    web_component_files +=
-        [ "dice_web_signin_intercept/dice_web_signin_intercept_app.ts" ]
+    web_component_files += [
+      "dice_web_signin_intercept/chrome_signin/chrome_signin_app.ts",
+      "dice_web_signin_intercept/dice_web_signin_intercept_app.ts",
+    ]
   }
 
   non_web_component_files = [
diff --git a/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin.html b/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin.html
new file mode 100644
index 0000000..b296cea
--- /dev/null
+++ b/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html dir="$i18n{textdirection}" lang="$i18n{language}">
+  <head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" href="chrome://resources/css/md_colors.css">
+    <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
+    <link rel="import" href="signin_vars_css.html">
+    <style>
+      body {
+        height: 100vh;
+        margin: 0;
+        width: 100vw;
+      }
+      @media (prefers-color-scheme: dark) {
+        body {
+          --md-background-color: var(--signin-dark-customized-background-color);
+          background-color: var(--md-background-color);
+        }
+      }
+    </style>
+  </head>
+  <body>
+    <chrome-signin-app></chrome-signin-app>
+    <script type="module" src="chrome_signin/chrome_signin_app.js"></script>
+  </body>
+</html>
diff --git a/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin_app.html b/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin_app.html
new file mode 100644
index 0000000..9484c14
--- /dev/null
+++ b/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin_app.html
@@ -0,0 +1,9 @@
+<div id="interceptDialog">
+
+  <div>Chrome Signin Intercept!</div>
+  <div>(To be implemented)</div>
+  <cr-button id="cancelButton" on-click="onCancel_">
+    Cancel
+  </cr-button>
+
+</div>
diff --git a/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin_app.ts b/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin_app.ts
new file mode 100644
index 0000000..5f6d38d
--- /dev/null
+++ b/chrome/browser/resources/signin/dice_web_signin_intercept/chrome_signin/chrome_signin_app.ts
@@ -0,0 +1,47 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import '../strings.m.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {DiceWebSigninInterceptBrowserProxy, DiceWebSigninInterceptBrowserProxyImpl} from '../dice_web_signin_intercept_browser_proxy.js';
+
+import {getTemplate} from './chrome_signin_app.html.js';
+
+export class ChromeSigninAppElement extends PolymerElement {
+  static get is() {
+    return 'chrome-signin-app';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  private diceWebSigninInterceptBrowserProxy_:
+      DiceWebSigninInterceptBrowserProxy =
+          DiceWebSigninInterceptBrowserProxyImpl.getInstance();
+
+  override connectedCallback() {
+    super.connectedCallback();
+
+    const height =
+        this.shadowRoot!.querySelector<HTMLElement>(
+                            '#interceptDialog')!.offsetHeight;
+    this.diceWebSigninInterceptBrowserProxy_.initializedWithHeight(height);
+  }
+
+  private onCancel_() {
+    this.diceWebSigninInterceptBrowserProxy_.cancel();
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    'chrome-signin-app': ChromeSigninAppElement;
+  }
+}
+
+customElements.define(ChromeSigninAppElement.is, ChromeSigninAppElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.html b/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.html
index 8275d95b..7cf979e 100644
--- a/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.html
+++ b/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.html
@@ -18,6 +18,20 @@
       --paper-spinner-color: var(--google-blue-300);
     }
   }
+
+  #gradientWithBorder {
+    border: solid 1px var(--google-blue-300);
+    border-radius: 16px;
+    box-sizing: border-box;
+    padding: 16px;
+    width: 100%;
+  }
+
+  #customColors {
+    --cr-loading-gradient-color1: cyan;
+    --cr-loading-gradient-color2: gold;
+    --cr-loading-gradient-color3: hotpink;
+  }
 </style>
 <h1>paper-progress</h1>
 <div class="demos">
@@ -28,3 +42,49 @@
 <div class="demos">
   <paper-spinner-lite active></paper-spinner-lite>
 </div>
+
+<h1>Loading gradients</h1>
+<div class="demos">
+  <h2>Avatar icon clipPath</h2>
+  <cr-loading-gradient>
+    <svg width="24" height="24">
+      <clipPath>
+        <path
+          d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0
+              2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z">
+        </path>
+      </clipPath>
+    </svg>
+  </cr-loading-gradient>
+
+  <h2>Rectangular clipPath</h2>
+  <cr-loading-gradient>
+    <svg width="100%" height="5">
+      <clipPath>
+        <rect x="0" y="0" width="100%" height="5" rx="5"></rect>
+      </clipPath>
+    </svg>
+  </cr-loading-gradient>
+
+  <h2>Multiple regions clipPath with external border</h2>
+  <div id="gradientWithBorder">
+    <cr-loading-gradient>
+      <svg width="100%" height="64">
+        <clipPath>
+          <rect x="0" y="0" width="100%" height="16" rx="8"></rect>
+          <rect x="0" y="24" width="100%" height="16" rx="8"></rect>
+          <rect x="0" y="48" width="100%" height="16" rx="8"></rect>
+        </clipPath>
+      </svg>
+    </cr-loading-gradient>
+  </div>
+
+  <h2>Custom colors</h2>
+  <cr-loading-gradient id="customColors">
+    <svg width="200" height="200">
+      <clipPath>
+        <circle cx="100" cy="100" r="100"></circle>
+      </clipPath>
+    </svg>
+  </cr-loading-gradient>
+</div>
diff --git a/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.ts b/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.ts
index c30d423c..b2c5513 100644
--- a/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.ts
+++ b/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.ts
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-
+import '//resources/cr_elements/cr_loading_gradient/cr_loading_gradient.js';
 import '//resources/cr_elements/cr_shared_vars.css.js';
 import '//resources/polymer/v3_0/paper-progress/paper-progress.js';
 import '//resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js';
diff --git a/chrome/browser/safe_browsing/android/password_reuse_controller_android.cc b/chrome/browser/safe_browsing/android/password_reuse_controller_android.cc
index 26ae853..6c2d28ca 100644
--- a/chrome/browser/safe_browsing/android/password_reuse_controller_android.cc
+++ b/chrome/browser/safe_browsing/android/password_reuse_controller_android.cc
@@ -13,6 +13,10 @@
 #include "ui/android/window_android.h"
 #include "ui/base/l10n/l10n_util.h"
 
+#if BUILDFLAG(IS_ANDROID)
+#include "base/android/build_info.h"
+#endif
+
 namespace safe_browsing {
 
 PasswordReuseControllerAndroid::PasswordReuseControllerAndroid(
@@ -73,8 +77,16 @@
   if (password_type_.account_type() == ReusedPasswordAccountType::GMAIL &&
       password_type_.is_account_syncing()) {
     return l10n_util::GetStringUTF16(IDS_PAGE_INFO_PROTECT_ACCOUNT_BUTTON);
-  } else if (password_type_.account_type() ==
-             ReusedPasswordAccountType::SAVED_PASSWORD) {
+  }
+#if BUILDFLAG(IS_ANDROID)
+  // The modal can be shown on automotive, but should not lead users to the
+  // GMSCore Password Check UI, as that is not optimized for automotive.
+  else if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    return l10n_util::GetStringUTF16(IDS_CLOSE);
+  }
+#endif
+  else if (password_type_.account_type() ==
+           ReusedPasswordAccountType::SAVED_PASSWORD) {
     return l10n_util::GetStringUTF16(IDS_PAGE_INFO_CHECK_PASSWORDS_BUTTON);
   }
 
@@ -82,10 +94,20 @@
 }
 
 std::u16string PasswordReuseControllerAndroid::GetSecondaryButtonText() const {
-  if ((password_type_.account_type() == ReusedPasswordAccountType::GMAIL &&
-       password_type_.is_account_syncing()) ||
-      (password_type_.account_type() ==
-       ReusedPasswordAccountType::SAVED_PASSWORD)) {
+  if (password_type_.account_type() == ReusedPasswordAccountType::GMAIL &&
+      password_type_.is_account_syncing()) {
+    return l10n_util::GetStringUTF16(
+        IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON);
+  }
+#if BUILDFLAG(IS_ANDROID)
+  // The modal can be shown on automotive, but without any call to action as
+  // those are not optimized for automotive.
+  else if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    return std::u16string();
+  }
+#endif
+  else if (password_type_.account_type() ==
+           ReusedPasswordAccountType::SAVED_PASSWORD) {
     return l10n_util::GetStringUTF16(
         IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON);
   }
diff --git a/chrome/browser/safe_browsing/android/password_reuse_controller_android_unittest.cc b/chrome/browser/safe_browsing/android/password_reuse_controller_android_unittest.cc
index aafd0278..1669fb4 100644
--- a/chrome/browser/safe_browsing/android/password_reuse_controller_android_unittest.cc
+++ b/chrome/browser/safe_browsing/android/password_reuse_controller_android_unittest.cc
@@ -17,6 +17,10 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
 
+#if BUILDFLAG(IS_ANDROID)
+#include "base/android/build_info.h"
+#endif
+
 namespace safe_browsing {
 
 using ReusedPasswordAccountType = safe_browsing::LoginReputationClientRequest::
@@ -68,6 +72,12 @@
 }
 
 TEST_F(PasswordReuseControllerAndroidTest, VerifyButtonText) {
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should not run on automotive.";
+  }
+#endif  // BUILDFLAG(IS_ANDROID)
+
   MockOnWarningDone empty_callback;
   ReusedPasswordAccountType password_type;
 
@@ -125,6 +135,67 @@
   delete controller;
 }
 
+#if BUILDFLAG(IS_ANDROID)
+TEST_F(PasswordReuseControllerAndroidTest, VerifyButtonTextOnAutomotive) {
+  if (!base::android::BuildInfo::GetInstance()->is_automotive()) {
+    GTEST_SKIP() << "This test should only run on automotive.";
+  }
+  MockOnWarningDone empty_callback;
+  ReusedPasswordAccountType password_type;
+
+  PasswordReuseControllerAndroid* controller =
+      MakeController(nullptr, password_type, empty_callback.Get());
+
+  {
+    ASSERT_EQ(l10n_util::GetStringUTF16(IDS_CLOSE),
+              controller->GetPrimaryButtonText());
+    ASSERT_EQ(std::u16string(), controller->GetSecondaryButtonText());
+  }
+  {
+    password_type.set_account_type(ReusedPasswordAccountType::SAVED_PASSWORD);
+    password_type.set_is_account_syncing(false);
+
+    controller->SetReusedPasswordAccountTypeForTesting(password_type);
+
+    ASSERT_EQ(l10n_util::GetStringUTF16(IDS_CLOSE),
+              controller->GetPrimaryButtonText());
+    ASSERT_EQ(std::u16string(), controller->GetSecondaryButtonText());
+  }
+  {
+    password_type.set_account_type(ReusedPasswordAccountType::GMAIL);
+    password_type.set_is_account_syncing(true);
+
+    controller->SetReusedPasswordAccountTypeForTesting(password_type);
+
+    ASSERT_EQ(l10n_util::GetStringUTF16(IDS_PAGE_INFO_PROTECT_ACCOUNT_BUTTON),
+              controller->GetPrimaryButtonText());
+    ASSERT_EQ(
+        l10n_util::GetStringUTF16(IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON),
+        controller->GetSecondaryButtonText());
+  }
+  {
+    ReusedPasswordAccountType empty_reused_password;
+    controller->SetReusedPasswordAccountTypeForTesting(empty_reused_password);
+
+    ASSERT_EQ(l10n_util::GetStringUTF16(IDS_CLOSE),
+              controller->GetPrimaryButtonText());
+    ASSERT_EQ(std::u16string(), controller->GetSecondaryButtonText());
+  }
+  {
+    password_type.set_account_type(ReusedPasswordAccountType::GMAIL);
+    password_type.set_is_account_syncing(false);
+
+    controller->SetReusedPasswordAccountTypeForTesting(password_type);
+
+    ASSERT_EQ(l10n_util::GetStringUTF16(IDS_CLOSE),
+              controller->GetPrimaryButtonText());
+    ASSERT_EQ(std::u16string(), controller->GetSecondaryButtonText());
+  }
+
+  delete controller;
+}
+#endif  // BUILDFLAG(IS_ANDROID)
+
 TEST_F(PasswordReuseControllerAndroidTest, WebContentDestroyed) {
   base::HistogramTester histograms;
   ReusedPasswordAccountType password_type;
diff --git a/chrome/browser/search/background/ntp_background_service.cc b/chrome/browser/search/background/ntp_background_service.cc
index 55f38d1..c1e0a4d 100644
--- a/chrome/browser/search/background/ntp_background_service.cc
+++ b/chrome/browser/search/background/ntp_background_service.cc
@@ -155,6 +155,11 @@
   if (features::IsChromeWebuiRefresh2023()) {
     request.add_filtering_label(base::StrCat({kFilteringLabel, ".gm3"}));
   }
+  if (base::FeatureList::IsEnabled(
+          ntp_features::kNtpBackgroundImageErrorDetection)) {
+    request.add_filtering_label(
+        base::StrCat({kFilteringLabel, ".error_detection"}));
+  }
 
   std::string serialized_proto;
   request.SerializeToString(&serialized_proto);
diff --git a/chrome/browser/search/background/ntp_background_service_unittest.cc b/chrome/browser/search/background/ntp_background_service_unittest.cc
index 26055a13..c09d0d4 100644
--- a/chrome/browser/search/background/ntp_background_service_unittest.cc
+++ b/chrome/browser/search/background/ntp_background_service_unittest.cc
@@ -111,7 +111,7 @@
 
 INSTANTIATE_TEST_SUITE_P(All, NtpBackgroundServiceTest, ::testing::Bool());
 
-TEST_P(NtpBackgroundServiceTest, CorrectCollectionRequest) {
+TEST_P(NtpBackgroundServiceTest, CollectionRequest) {
   g_browser_process->SetApplicationLocale("foo");
   service()->FetchCollectionInfo();
   base::RunLoop().RunUntilIdle();
@@ -127,7 +127,13 @@
   ntp::background::GetCollectionsRequest collection_request;
   EXPECT_TRUE(collection_request.ParseFromString(request_body));
   EXPECT_EQ("foo", collection_request.language());
-  EXPECT_EQ(3, collection_request.filtering_label_size());
+  if (BackgroundImageErrorDetectionEnabled()) {
+    EXPECT_EQ(4, collection_request.filtering_label_size());
+    EXPECT_EQ("chrome_desktop_ntp.error_detection",
+              collection_request.filtering_label(3));
+  } else {
+    EXPECT_EQ(3, collection_request.filtering_label_size());
+  }
   EXPECT_EQ("chrome_desktop_ntp", collection_request.filtering_label(0));
   EXPECT_EQ("chrome_desktop_ntp.M" + version_info::GetMajorVersionNumber(),
             collection_request.filtering_label(1));
@@ -135,9 +141,7 @@
             collection_request.filtering_label(2));
 }
 
-// Add GM3 filter if ChromeWebuiRefresh2023 flag is enabled.
-TEST_P(NtpBackgroundServiceTest, CollectionRequestWithGM3Flag) {
-  // Enable ChromeWebuiRefresh2023.
+TEST_P(NtpBackgroundServiceTest, CollectionRequestWithGM3Enabled) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitWithFeatures(
       {features::kChromeRefresh2023, features::kChromeWebuiRefresh2023}, {});
@@ -157,7 +161,13 @@
   ntp::background::GetCollectionsRequest collection_request;
   EXPECT_TRUE(collection_request.ParseFromString(request_body));
   EXPECT_EQ("foo", collection_request.language());
-  EXPECT_EQ(4, collection_request.filtering_label_size());
+  if (BackgroundImageErrorDetectionEnabled()) {
+    EXPECT_EQ(5, collection_request.filtering_label_size());
+    EXPECT_EQ("chrome_desktop_ntp.error_detection",
+              collection_request.filtering_label(4));
+  } else {
+    EXPECT_EQ(4, collection_request.filtering_label_size());
+  }
   EXPECT_EQ("chrome_desktop_ntp", collection_request.filtering_label(0));
   EXPECT_EQ("chrome_desktop_ntp.M" + version_info::GetMajorVersionNumber(),
             collection_request.filtering_label(1));
diff --git a/chrome/browser/sharesheet/sharesheet_service.cc b/chrome/browser/sharesheet/sharesheet_service.cc
index 1550d3a..b4e134f4 100644
--- a/chrome/browser/sharesheet/sharesheet_service.cc
+++ b/chrome/browser/sharesheet/sharesheet_service.cc
@@ -11,7 +11,6 @@
 #include "base/ranges/algorithm.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/app_service/launch_utils.h"
@@ -21,6 +20,7 @@
 #include "chrome/grit/generated_resources.h"
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/app_types.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "components/services/app_service/public/cpp/intent.h"
 #include "content/public/browser/web_contents.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/chrome/browser/signin/dice_web_signin_interceptor.cc b/chrome/browser/signin/dice_web_signin_interceptor.cc
index 1599ee68..aba1f460 100644
--- a/chrome/browser/signin/dice_web_signin_interceptor.cc
+++ b/chrome/browser/signin/dice_web_signin_interceptor.cc
@@ -714,8 +714,8 @@
                          base::Unretained(this), info, profile_color);
       break;
     case WebSigninInterceptor::SigninInterceptionType::kChromeSignin:
-      // TODO(b/301431278): Attach the right callback here.
-      callback = base::DoNothing();
+      callback = base::BindOnce(&DiceWebSigninInterceptor::OnChromeSigninChoice,
+                                base::Unretained(this));
       break;
   }
   ShowSigninInterceptionBubble(bubble_parameters, std::move(callback));
@@ -768,6 +768,16 @@
                          base::Unretained(this), profile_color));
 }
 
+void DiceWebSigninInterceptor::OnChromeSigninChoice(
+    SigninInterceptionResult result) {
+  if (result == SigninInterceptionResult::kDeclined) {
+    Reset();
+    return;
+  }
+
+  // TODO(b/301431278): Implement the rest of the cases.
+}
+
 void DiceWebSigninInterceptor::OnProfileSwitchChoice(
     const std::string& email,
     const base::FilePath& profile_path,
diff --git a/chrome/browser/signin/dice_web_signin_interceptor.h b/chrome/browser/signin/dice_web_signin_interceptor.h
index fc0e475..750dd1d7 100644
--- a/chrome/browser/signin/dice_web_signin_interceptor.h
+++ b/chrome/browser/signin/dice_web_signin_interceptor.h
@@ -205,6 +205,9 @@
   void OnProfileSwitchChoice(const std::string& email,
                              const base::FilePath& profile_path,
                              SigninInterceptionResult switch_profile);
+  // Called after the user chose whether they want to sign in to chrome or not
+  // via the Chrome Signin Bubble.
+  void OnChromeSigninChoice(SigninInterceptionResult result);
 
   // Called when the new profile is created or loaded from disk.
   // `profile_color` is set as theme color for the profile ; it should be
diff --git a/chrome/browser/sync/test/integration/web_apps_sync_test_base.cc b/chrome/browser/sync/test/integration/web_apps_sync_test_base.cc
index b24cc12..bdbc42c 100644
--- a/chrome/browser/sync/test/integration/web_apps_sync_test_base.cc
+++ b/chrome/browser/sync/test/integration/web_apps_sync_test_base.cc
@@ -26,6 +26,12 @@
 WebAppsSyncTestBase::WebAppsSyncTestBase(TestType test_type)
     : SyncTest(test_type) {
   std::vector<base::test::FeatureRef> disabled_features;
+
+#if BUILDFLAG(IS_CHROMEOS)
+  // TODO(crbug.com/1357905): Update test driver to work with new UI.
+  disabled_features.push_back(apps::features::kLinkCapturingUiUpdate);
+#endif
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // Disable Lacros, so that Web Apps get synced in the Ash browser.
   // TODO(crbug.com/1462253): Also test with Lacros flags enabled.
diff --git a/chrome/browser/tpcd/metadata/devtools_observer.cc b/chrome/browser/tpcd/metadata/devtools_observer.cc
new file mode 100644
index 0000000..63c1a036
--- /dev/null
+++ b/chrome/browser/tpcd/metadata/devtools_observer.cc
@@ -0,0 +1,67 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "chrome/browser/tpcd/metadata/devtools_observer.h"
+
+#include "chrome/browser/content_settings/cookie_settings_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/content_settings/core/browser/cookie_settings.h"
+#include "components/content_settings/core/common/cookie_settings_base.h"
+#include "content/public/browser/cookie_access_details.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom.h"
+
+namespace tpcd::metadata {
+
+TpcdMetadataDevtoolsObserver::TpcdMetadataDevtoolsObserver(
+    content::WebContents* web_contents)
+    : content::WebContentsObserver(web_contents),
+      content::WebContentsUserData<TpcdMetadataDevtoolsObserver>(
+          *web_contents) {
+  cookie_settings_ = CookieSettingsFactory::GetForProfile(
+      Profile::FromBrowserContext(web_contents->GetBrowserContext()));
+}
+
+TpcdMetadataDevtoolsObserver::~TpcdMetadataDevtoolsObserver() = default;
+
+void TpcdMetadataDevtoolsObserver::OnCookiesAccessed(
+    content::RenderFrameHost* render_frame_host,
+    const content::CookieAccessDetails& details) {
+  OnCookiesAccessedImpl(details.url, details.first_party_url);
+}
+
+void TpcdMetadataDevtoolsObserver::OnCookiesAccessed(
+    content::NavigationHandle* navigation_handle,
+    const content::CookieAccessDetails& details) {
+  OnCookiesAccessedImpl(details.url, details.first_party_url);
+}
+
+void TpcdMetadataDevtoolsObserver::OnCookiesAccessedImpl(
+    const GURL& url,
+    const GURL& first_party_url) {
+  if (cookie_settings_->IsAllowedByTpcdMetadataGrant(url, first_party_url)) {
+    EmitMetadataGrantDevtoolsIssue(url);
+  }
+}
+
+void TpcdMetadataDevtoolsObserver::EmitMetadataGrantDevtoolsIssue(
+    const GURL& url) {
+  auto details = blink::mojom::InspectorIssueDetails::New();
+
+  auto metadata_issue_details =
+      blink::mojom::CookieDeprecationMetadataIssueDetails::New();
+  metadata_issue_details->allowed_sites.push_back(url.host());
+  details->cookie_deprecation_metadata_issue_details =
+      std::move(metadata_issue_details);
+
+  web_contents()->GetPrimaryMainFrame()->ReportInspectorIssue(
+      blink::mojom::InspectorIssueInfo::New(
+          blink::mojom::InspectorIssueCode::kCookieDeprecationMetadataIssue,
+          std::move(details)));
+}
+
+WEB_CONTENTS_USER_DATA_KEY_IMPL(TpcdMetadataDevtoolsObserver);
+
+}  // namespace tpcd::metadata
diff --git a/chrome/browser/tpcd/metadata/devtools_observer.h b/chrome/browser/tpcd/metadata/devtools_observer.h
new file mode 100644
index 0000000..75daa4f0
--- /dev/null
+++ b/chrome/browser/tpcd/metadata/devtools_observer.h
@@ -0,0 +1,46 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_TPCD_METADATA_DEVTOOLS_OBSERVER_H_
+#define CHROME_BROWSER_TPCD_METADATA_DEVTOOLS_OBSERVER_H_
+
+#include "chrome/browser/dips/dips_service.h"
+#include "chrome/browser/tpcd/heuristics/opener_heuristic_tab_helper.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_observer.h"
+
+namespace tpcd::metadata {
+
+class TpcdMetadataDevtoolsObserver
+    : public content::WebContentsObserver,
+      public content::WebContentsUserData<TpcdMetadataDevtoolsObserver> {
+ public:
+  explicit TpcdMetadataDevtoolsObserver(content::WebContents* web_contents);
+  TpcdMetadataDevtoolsObserver() = delete;
+  ~TpcdMetadataDevtoolsObserver() override;
+
+ private:
+  // To allow use of WebContentsUserData::CreateForWebContents()
+  friend class content::WebContentsUserData<TpcdMetadataDevtoolsObserver>;
+
+  // WebContentsObserver overrides:
+  void OnCookiesAccessed(content::RenderFrameHost* render_frame_host,
+                         const content::CookieAccessDetails& details) override;
+  void OnCookiesAccessed(content::NavigationHandle* navigation_handle,
+                         const content::CookieAccessDetails& details) override;
+
+  void OnCookiesAccessedImpl(const GURL& url, const GURL& first_party_url);
+
+  // Emit a devtools issue when `url` is allowed cookie access as a third-party
+  // site on the current page.
+  void EmitMetadataGrantDevtoolsIssue(const GURL& url);
+
+  scoped_refptr<content_settings::CookieSettings> cookie_settings_;
+
+  WEB_CONTENTS_USER_DATA_KEY_DECL();
+};
+
+}  // namespace tpcd::metadata
+
+#endif  // CHROME_BROWSER_TPCD_METADATA_DEVTOOLS_OBSERVER_H_
diff --git a/chrome/browser/tpcd/metadata/devtools_observer_browsertest.cc b/chrome/browser/tpcd/metadata/devtools_observer_browsertest.cc
new file mode 100644
index 0000000..e3a7644d
--- /dev/null
+++ b/chrome/browser/tpcd/metadata/devtools_observer_browsertest.cc
@@ -0,0 +1,186 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "base/files/file_path.h"
+#include "chrome/browser/content_settings/cookie_settings_factory.h"
+#include "chrome/browser/dips/dips_service.h"
+#include "chrome/browser/dips/dips_test_utils.h"
+#include "chrome/browser/tpcd/metadata/devtools_observer.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/chrome_test_utils.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "components/content_settings/core/browser/cookie_settings.h"
+#include "components/content_settings/core/common/features.h"
+#include "components/tpcd/metadata/parser.h"
+#include "components/tpcd/metadata/parser_test_helper.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/test_devtools_protocol_client.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom.h"
+
+namespace tpcd::metadata {
+namespace {
+
+using ::chrome_test_utils::GetActiveWebContents;
+
+}  // namespace
+
+class TpcdMetadataDevtoolsObserverBrowserTest
+    : public PlatformBrowserTest,
+      public content::TestDevToolsProtocolClient {
+ public:
+  explicit TpcdMetadataDevtoolsObserverBrowserTest(
+      bool enable_metadata_feature = true)
+      : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
+    feature_list_.InitWithFeatureStates(
+        {{content_settings::features::kTrackingProtection3pcd, true},
+         {net::features::kTpcdMetadataGrants, enable_metadata_feature}});
+  }
+
+  void SetUpOnMainThread() override {
+    ASSERT_TRUE(embedded_test_server()->Start());
+    host_resolver()->AddRule("a.test", "127.0.0.1");
+    host_resolver()->AddRule("b.test", "127.0.0.1");
+    host_resolver()->AddRule("c.test", "127.0.0.1");
+
+    // Set up HTTPS server with image for cookie.
+    https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
+    https_server_.AddDefaultHandlers(
+        base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
+    ASSERT_TRUE(https_server_.Start());
+
+    // Open and reset DevTools.
+    AttachToWebContents(GetActiveWebContents(this));
+    SendCommandSync("Audits.enable");
+    ClearNotifications();
+
+    // Initialize mock 3PCD metadata component.
+    std::vector<MetadataPair> metadata_pairs;
+    const std::string first_party_pattern_spec = "[*.]a.test";
+    const std::string third_party_pattern_spec_1 = "[*.]b.test";
+    const std::string third_party_pattern_spec_2 = "c.test";
+    metadata_pairs.emplace_back(third_party_pattern_spec_1,
+                                first_party_pattern_spec);
+    metadata_pairs.emplace_back(third_party_pattern_spec_2,
+                                first_party_pattern_spec);
+    Metadata metadata = MakeMetadataProtoFromVectorOfPair(metadata_pairs);
+    tpcd::metadata::Parser::GetInstance()->ParseMetadata(
+        metadata.SerializeAsString());
+
+    // Initialize devtools WebContentsObserver.
+    devtools_observer_ = TpcdMetadataDevtoolsObserver::FromWebContents(
+        GetActiveWebContents(this));
+  }
+
+  void TearDownOnMainThread() override {
+    DetachProtocolClient();
+    devtools_observer_ = nullptr;
+  }
+
+ protected:
+  void AddCookieAccess(const std::string& first_party_site,
+                       const std::string& third_party_site) {
+    ASSERT_TRUE(NavigateToSetCookie(GetActiveWebContents(this), &https_server_,
+                                    third_party_site,
+                                    /*is_secure_cookie_set=*/true));
+    ASSERT_TRUE(content::NavigateToURL(
+        GetActiveWebContents(this),
+        embedded_test_server()->GetURL(first_party_site, "/title1.html")));
+    CreateImageAndWaitForCookieAccess(
+        GetActiveWebContents(this),
+        https_server_.GetURL(third_party_site, "/favicon/icon.png"));
+  }
+
+  void WaitForIssueAndCheckAllowedSites(const std::vector<std::string>& sites) {
+    auto is_metadata_issue = [](const base::Value::Dict& params) {
+      return *(params.FindStringByDottedPath("issue.code")) ==
+             "CookieDeprecationMetadataIssue";
+    };
+
+    // Wait for notification of a Metadata Issue.
+    base::Value::Dict params = WaitForMatchingNotification(
+        "Audits.issueAdded", base::BindRepeating(is_metadata_issue));
+    ASSERT_EQ(*params.FindStringByDottedPath("issue.code"),
+              "CookieDeprecationMetadataIssue");
+
+    base::Value::Dict* metadata_issue_details = params.FindDictByDottedPath(
+        "issue.details.cookieDeprecationMetadataIssueDetails");
+    ASSERT_TRUE(metadata_issue_details);
+
+    std::vector<std::string> allowed_sites;
+    base::Value::List* allowed_sites_list =
+        metadata_issue_details->FindList("allowedSites");
+    if (allowed_sites_list) {
+      for (const auto& val : *allowed_sites_list) {
+        allowed_sites.push_back(val.GetString());
+      }
+    }
+
+    // Verify the reported allowed sites match the expected sites.
+    EXPECT_THAT(allowed_sites, testing::ElementsAreArray(sites));
+
+    // Clear existing notifications so subsequent calls don't fail by checking
+    // `sites` against old notifications.
+    ClearNotifications();
+  }
+
+  void CheckNoAddedIssue() {
+    ReportDummyIssue();
+
+    WaitForIssueAndCheckAllowedSites({"dummy.test"});
+  }
+
+ private:
+  void ReportDummyIssue() {
+    auto details = blink::mojom::InspectorIssueDetails::New();
+
+    auto metadata_issue_details =
+        blink::mojom::CookieDeprecationMetadataIssueDetails::New();
+    metadata_issue_details->allowed_sites.push_back("dummy.test");
+    details->cookie_deprecation_metadata_issue_details =
+        std::move(metadata_issue_details);
+
+    GetActiveWebContents(this)->GetPrimaryMainFrame()->ReportInspectorIssue(
+        blink::mojom::InspectorIssueInfo::New(
+            blink::mojom::InspectorIssueCode::kCookieDeprecationMetadataIssue,
+            std::move(details)));
+  }
+
+  base::test::ScopedFeatureList feature_list_;
+  net::EmbeddedTestServer https_server_;
+  raw_ptr<TpcdMetadataDevtoolsObserver> devtools_observer_ = nullptr;
+};
+
+IN_PROC_BROWSER_TEST_F(TpcdMetadataDevtoolsObserverBrowserTest,
+                       EmitsDevtoolsIssues) {
+  AddCookieAccess("a.test", "b.test");
+  WaitForIssueAndCheckAllowedSites({"b.test"});
+
+  AddCookieAccess("a.test", "c.test");
+  WaitForIssueAndCheckAllowedSites({"c.test"});
+}
+
+IN_PROC_BROWSER_TEST_F(TpcdMetadataDevtoolsObserverBrowserTest,
+                       DoesNotEmitDevtoolsIssueForSiteNotInAllowlist) {
+  AddCookieAccess("b.test", "a.test");
+
+  CheckNoAddedIssue();
+}
+
+class TpcdMetadataDevtoolsObserverDisabledBrowserTest
+    : public TpcdMetadataDevtoolsObserverBrowserTest {
+ public:
+  TpcdMetadataDevtoolsObserverDisabledBrowserTest()
+      : TpcdMetadataDevtoolsObserverBrowserTest(
+            /*enable_metadata_feature=*/false) {}
+};
+
+IN_PROC_BROWSER_TEST_F(TpcdMetadataDevtoolsObserverDisabledBrowserTest,
+                       DoesNotEmitDevtoolsIssueWithMissingFeature) {
+  AddCookieAccess("a.test", "b.test");
+
+  CheckNoAddedIssue();
+}
+
+}  // namespace tpcd::metadata
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 830e82f..2fad37d 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -3305,6 +3305,10 @@
       "webui/ash/settings/pages/multidevice/multidevice_handler.h",
       "webui/ash/settings/pages/multidevice/multidevice_section.cc",
       "webui/ash/settings/pages/multidevice/multidevice_section.h",
+      "webui/ash/settings/pages/os_settings_section.cc",
+      "webui/ash/settings/pages/os_settings_section.h",
+      "webui/ash/settings/pages/os_settings_sections.cc",
+      "webui/ash/settings/pages/os_settings_sections.h",
       "webui/ash/settings/pages/people/account_manager_ui_handler.cc",
       "webui/ash/settings/pages/people/account_manager_ui_handler.h",
       "webui/ash/settings/pages/people/fingerprint_handler.cc",
@@ -3411,10 +3415,6 @@
       "webui/settings/ash/os_settings_manager_factory.h",
       "webui/settings/ash/os_settings_metrics_provider.cc",
       "webui/settings/ash/os_settings_metrics_provider.h",
-      "webui/settings/ash/os_settings_section.cc",
-      "webui/settings/ash/os_settings_section.h",
-      "webui/settings/ash/os_settings_sections.cc",
-      "webui/settings/ash/os_settings_sections.h",
       "webui/settings/ash/os_settings_ui.cc",
       "webui/settings/ash/os_settings_ui.h",
 
@@ -5854,6 +5854,14 @@
       "views/web_apps/frame_toolbar/web_app_toolbar_button_container.h",
       "views/web_apps/frame_toolbar/window_controls_overlay_toggle_button.cc",
       "views/web_apps/frame_toolbar/window_controls_overlay_toggle_button.h",
+      "views/web_apps/isolated_web_apps/isolated_web_app_installer_coordinator.cc",
+      "views/web_apps/isolated_web_apps/isolated_web_app_installer_coordinator.h",
+      "views/web_apps/isolated_web_apps/isolated_web_app_installer_model.cc",
+      "views/web_apps/isolated_web_apps/isolated_web_app_installer_model.h",
+      "views/web_apps/isolated_web_apps/isolated_web_app_installer_view.cc",
+      "views/web_apps/isolated_web_apps/isolated_web_app_installer_view.h",
+      "views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.cc",
+      "views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.h",
       "views/web_apps/launch_app_user_choice_dialog_view.cc",
       "views/web_apps/launch_app_user_choice_dialog_view.h",
       "views/web_apps/protocol_handler_launch_dialog_view.cc",
@@ -6330,14 +6338,6 @@
       "web_applications/diagnostics/web_app_icon_health_checks.h",
       "web_applications/draggable_region_host_impl.cc",
       "web_applications/draggable_region_host_impl.h",
-      "web_applications/isolated_web_apps/isolated_web_app_installer_coordinator.cc",
-      "web_applications/isolated_web_apps/isolated_web_app_installer_coordinator.h",
-      "web_applications/isolated_web_apps/isolated_web_app_installer_model.cc",
-      "web_applications/isolated_web_apps/isolated_web_app_installer_model.h",
-      "web_applications/isolated_web_apps/isolated_web_app_installer_view.cc",
-      "web_applications/isolated_web_apps/isolated_web_app_installer_view.h",
-      "web_applications/isolated_web_apps/isolated_web_app_installer_view_controller.cc",
-      "web_applications/isolated_web_apps/isolated_web_app_installer_view_controller.h",
       "web_applications/share_target_utils.cc",
       "web_applications/share_target_utils.h",
       "web_applications/sub_apps_install_dialog_controller.cc",
diff --git a/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediator.java b/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediator.java
index 2d5c295..6d60d5c 100644
--- a/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediator.java
+++ b/chrome/browser/ui/android/device_lock/java/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediator.java
@@ -126,11 +126,16 @@
             onSuccess.run();
             return;
         }
-        mWindowAndroid.showIntent(intent, (resultCode, data) -> {
-            if (isDeviceLockPresent()) {
-                onSuccess.run();
-            }
-        }, null);
+        mWindowAndroid.showIntent(
+                intent,
+                (resultCode, data) -> {
+                    if (isDeviceLockPresent()) {
+                        onSuccess.run();
+                    } else {
+                        mModel.set(UI_ENABLED, true);
+                    }
+                },
+                null);
     }
 
     private void triggerDeviceLockChallenge(Runnable onSuccess) {
@@ -139,11 +144,14 @@
             onSuccess.run();
             return;
         }
-        mDeviceLockAuthenticatorBridge.reauthenticate((authSucceeded) -> {
-            if (authSucceeded) {
-                onSuccess.run();
-            }
-        });
+        mDeviceLockAuthenticatorBridge.reauthenticate(
+                (authSucceeded) -> {
+                    if (authSucceeded) {
+                        onSuccess.run();
+                    } else {
+                        mModel.set(UI_ENABLED, true);
+                    }
+                });
     }
 
     private void maybeTriggerAccountReauthenticationChallenge(Runnable onSuccess) {
@@ -157,11 +165,17 @@
                         ChromeFeatureList.ACCOUNT_REAUTHENTICATION_RECENT_TIME_WINDOW,
                         ACCOUNT_REAUTHENTICATION_RECENT_TIME_WINDOW_PARAM, 10);
         mAccountReauthenticationUtils.confirmCredentialsOrRecentAuthentication(
-                getAccountManager(), mAccount, mActivity, (confirmationResult) -> {
+                getAccountManager(),
+                mAccount,
+                mActivity,
+                (confirmationResult) -> {
                     if (confirmationResult
                             == AccountReauthenticationUtils.ConfirmationResult.SUCCESS) {
                         onSuccess.run();
+                    } else {
+                        mModel.set(UI_ENABLED, true);
                     }
-                }, TimeUnit.MINUTES.toMillis(accountReauthenticationRecentTimeWindowMinutes));
+                },
+                TimeUnit.MINUTES.toMillis(accountReauthenticationRecentTimeWindowMinutes));
     }
 }
diff --git a/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediatorUnitTest.java b/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediatorUnitTest.java
index 3caa38f..1fa71508 100644
--- a/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediatorUnitTest.java
+++ b/chrome/browser/ui/android/device_lock/junit/src/org/chromium/chrome/browser/ui/device_lock/DeviceLockMediatorUnitTest.java
@@ -574,7 +574,10 @@
                     ContextUtils.getAppSharedPreferences()
                             .getBoolean(DEVICE_LOCK_PAGE_HAS_BEEN_PASSED, false));
         }
-        if (onClick.equals(ON_DISMISS_CLICKED)) {
+        // The UI should only be disabled if the user chose to continue and passed all the
+        // necessary steps - the UI should be enabled if the user chooses to dismiss or fails the
+        // challenges.
+        if (onClick.equals(ON_DISMISS_CLICKED) || (onDeviceLockReadyCalls < 1)) {
             assertTrue(
                     "The UI should still be in an enabled state.",
                     deviceLockMediator.getModel().get(UI_ENABLED));
diff --git a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java
index 98ff97e3..7976034d 100644
--- a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java
+++ b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java
@@ -39,7 +39,7 @@
  * Status Bar.
  */
 public class EdgeToEdgeControllerImpl implements EdgeToEdgeController {
-    private static final String TAG = "E2EControllerImpl";
+    private static final String TAG = "E2E_ControllerImpl";
 
     /** The outermost view in our view hierarchy that is identified with a resource ID. */
     private static final int ROOT_UI_VIEW_ID = android.R.id.content;
@@ -51,10 +51,12 @@
     /** Multiplier to convert from pixels to DPs. */
     private final float mPxToDp;
 
-    private Tab mRecentTab;
+    private Tab mCurrentTab;
     private TabObserver mTabObserver;
     private WebContentsObserver mWebContentsObserver;
-    private boolean mToEdge;
+    private boolean mIsActivityToEdge;
+    private Insets mSystemInsets;
+    private boolean mDidSetDecorAndListener;
 
     /**
      * Creates an implementation of the EdgeToEdgeController that will use the Android APIs to allow
@@ -85,8 +87,8 @@
     @Override
     @RequiresApi(VERSION_CODES.R)
     public void onTabSwitched(@Nullable Tab tab) {
-        removeAnyTabObserver();
-        mRecentTab = tab;
+        removeCurrentTabObserver();
+        mCurrentTab = tab;
         if (tab != null) {
             if (mTabObserver != null) {
                 tab.removeObserver(mTabObserver);
@@ -138,27 +140,68 @@
     /**
      * Conditionally sets the given view ToEdge or ToNormal based on the {@code toEdge} param.
      *
-     * @param viewId The Root UI View, or some view for testing.
+     * @param viewId The ID of the Root UI View, or some view for testing.
      * @param toEdge Whether to draw ToEdge.
      * @param webContents The {@link WebContents} to notify of inset env() changes.
      */
     @RequiresApi(VERSION_CODES.R)
     @SuppressWarnings("WrongConstant") // For WindowInsets.Type on U+
     private void drawToEdge(int viewId, boolean toEdge, @Nullable WebContents webContents) {
-        if (toEdge == mToEdge) return;
-        mToEdge = toEdge;
+        if (toEdge == mIsActivityToEdge) return;
 
-        Log.i(TAG, "Switching " + (toEdge ? "ToEdge" : "ToNormal"));
+        mIsActivityToEdge = toEdge;
+        Log.v(TAG, "Switching " + (toEdge ? "ToEdge" : "ToNormal"));
         View rootView = mActivity.findViewById(viewId);
         assert rootView != null : "Root view for Edge To Edge not found!";
 
-        // Setup the basic enabling / disabling of the Edge to Edge Android Feature.
-        // Sets up this window to open up all edges to be drawn underneath, or not.
-        // Note that fitInsideSystemWindows == true means we do NOT draw under the Bars, rather
-        // we fit within them. So a value of false is needed to activate ToEdge.
-        boolean fitInsideSystemWindows = !toEdge;
-        mEdgeToEdgeOSWrapper.setDecorFitsSystemWindows(
-                mActivity.getWindow(), fitInsideSystemWindows);
+        // Setup the basic enabling of the Edge to Edge Android Feature.
+        // Sets up this window to open up System edges to be drawn underneath.
+        if (toEdge && mSystemInsets == null && !mDidSetDecorAndListener) {
+            mDidSetDecorAndListener = true;
+            mEdgeToEdgeOSWrapper.setDecorFitsSystemWindows(mActivity.getWindow(), false);
+            mEdgeToEdgeOSWrapper.setOnApplyWindowInsetsListener(
+                    rootView,
+                    (view, windowInsets) -> {
+                        Insets newInsets =
+                                windowInsets.getInsets(
+                                        WindowInsets.Type.navigationBars()
+                                                + WindowInsets.Type.statusBars());
+                        if (!newInsets.equals(mSystemInsets)) {
+                            mSystemInsets = newInsets;
+                            Log.w(TAG, "System Bar insets changed to %s", mSystemInsets);
+                            // Note that we cannot adjustEdges earlier since we need the system
+                            // insets.
+                            adjustEdges(toEdge, viewId, webContents);
+                        }
+                        return windowInsets;
+                    });
+        } else {
+            adjustEdges(toEdge, viewId, webContents);
+        }
+    }
+
+    /**
+     * Adjusts whether the given view draws ToEdge or ToNormal. The ability to draw under System
+     * Bars should have already been set. This method only sets the padding of the view and
+     * transparency of the Nav Bar, etc.
+     *
+     * @param toEdge Whether to adjust the drawing environment ToEdge.
+     * @param viewId The ID of the view to adjust.
+     * @param webContents A {@link WebContents} to notify Blink of the adjusted insets.
+     */
+    private void adjustEdges(boolean toEdge, int viewId, @Nullable WebContents webContents) {
+        assert mSystemInsets != null : "Trying to adjustToEdge without mSystemInsets!";
+
+        // Adjust the bottom padding to reflect whether ToEdge or ToNormal for the Gesture Nav Bar.
+        // All the other edges need to be padded to prevent drawing under an edge that we
+        // don't want drawn ToEdge (e.g. the Status Bar).
+        int bottomInset = toEdge ? 0 : mSystemInsets.bottom;
+        mEdgeToEdgeOSWrapper.setPadding(
+                mActivity.findViewById(viewId),
+                mSystemInsets.left,
+                mSystemInsets.top,
+                mSystemInsets.right,
+                bottomInset);
 
         // We only make the Nav Bar transparent because it's the only thing we want to draw
         // underneath.
@@ -168,35 +211,23 @@
         int navBarColor = toEdge ? Color.TRANSPARENT : Color.BLACK;
         mEdgeToEdgeOSWrapper.setNavigationBarColor(mActivity.getWindow(), navBarColor);
 
-        // Now fix all the edges other than the bottom Gesture Nav Bar by insetting with padding, or
-        // cancelling the previous padding when we adjust back ToNormal. This keeps the
-        // setDecorFitsSystemWindows from actually drawing under the edges that we don't want ToEdge
-        // (e.g. Status Bar). When moving back ToNormal we need to clear the padding that we added
-        // to prevent drawing under the Status Bar otherwise we'll be inset too much at the top of
-        // the screen.
-        mEdgeToEdgeOSWrapper.setOnApplyWindowInsetsListener(
-                rootView,
-                (view, windowInsets) -> {
-                    Insets systemInsets = windowInsets.getInsets(WindowInsets.Type.systemBars());
-                    int bottomInset = toEdge ? 0 : systemInsets.bottom;
-                    // Restore the drawing to normal on all edges, except for the bottom (Nav Bar).
-                    mEdgeToEdgeOSWrapper.setPadding(
-                            view,
-                            systemInsets.left,
-                            systemInsets.top,
-                            systemInsets.right,
-                            bottomInset);
+        if (webContents != null) pushInsetsToBlink(toEdge, webContents);
+    }
 
-                    // Push the insets back to the webpage if we have one.
-                    // TODO(https://crbug.com/1475820) Move this work into the nascent
-                    // SafeAreaInsetsTracker.
-                    if (webContents != null) {
-                        Rect insetsRect = new Rect(0, 0, 0, scale(systemInsets.bottom));
-                        webContents.setDisplayCutoutSafeArea(insetsRect);
-                    }
-
-                    return windowInsets;
-                });
+    /**
+     * Pushes the current insets to Blink so the page will know how to pad bottom UI.
+     *
+     * @param toEdge Whether we're drawing all the way to the edge of the screen.
+     * @param webContents A {@link WebContents} that leads to a Blink Renderer.
+     */
+    private void pushInsetsToBlink(boolean toEdge, @NonNull WebContents webContents) {
+        // Push the insets back to the webpage if we have one.
+        // TODO(https://crbug.com/1475820) Move this work into the nascent
+        // SafeAreaInsetsTracker.
+        assert mSystemInsets != null : "Error, trying to notify Blink without system insets set";
+        Rect insetsRect = new Rect(0, 0, 0, toEdge ? scale(mSystemInsets.bottom) : 0);
+        Log.v(TAG, "Pushing back insets to Blink %s", insetsRect);
+        webContents.setDisplayCutoutSafeArea(insetsRect);
     }
 
     /**
@@ -245,9 +276,9 @@
     }
 
     /** Removes any existing TabObserver tracked by private members for the Tab and TabObserver. */
-    private void removeAnyTabObserver() {
-        if (mRecentTab != null && mTabObserver != null) {
-            mRecentTab.removeObserver(mTabObserver);
+    private void removeCurrentTabObserver() {
+        if (mCurrentTab != null && mTabObserver != null) {
+            mCurrentTab.removeObserver(mTabObserver);
             mTabObserver = null;
         }
     }
@@ -259,7 +290,7 @@
             mWebContentsObserver.destroy();
             mWebContentsObserver = null;
         }
-        removeAnyTabObserver();
+        removeCurrentTabObserver();
         mTabSupplierObserver.destroy();
     }
 
@@ -271,11 +302,14 @@
 
     @VisibleForTesting
     boolean isToEdge() {
-        return mToEdge;
+        return mIsActivityToEdge;
     }
 
     void setToEdgeForTesting(boolean toEdge) {
-        mToEdge = toEdge;
+        mIsActivityToEdge = toEdge;
     }
 
+    void setSystemInsetsForTesting(Insets systemInsetsForTesting) {
+        mSystemInsets = systemInsetsForTesting;
+    }
 }
diff --git a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerTest.java b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerTest.java
index b9a72d2..6039ab3e 100644
--- a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerTest.java
+++ b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerTest.java
@@ -20,11 +20,13 @@
 import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.when;
 import static org.mockito.hamcrest.MockitoHamcrest.intThat;
+import static org.robolectric.Shadows.shadowOf;
 
 import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.graphics.Color;
 import android.os.Build.VERSION_CODES;
+import android.os.Looper;
 import android.view.View;
 
 import androidx.appcompat.app.AppCompatActivity;
@@ -177,14 +179,15 @@
     @Test
     @SuppressLint("NewApi")
     public void onObservingDifferentTab_changeToWebDisabled() {
+        ChromeFeatureList.sDrawWebEdgeToEdge.setForTesting(false);
         // First go ToEdge by invoking the changeToTabSwitcher test logic.
         mEdgeToEdgeControllerImpl.setToEdgeForTesting(true);
 
         // Now test that a Web page causes a transition ToNormal (when Web forcing is disabled).
-        ChromeFeatureList.sDrawWebEdgeToEdge.setForTesting(false);
+        mEdgeToEdgeControllerImpl.setSystemInsetsForTesting(SYSTEM_INSETS);
         when(mTab.isNativePage()).thenReturn(false);
         mObservableSupplierImpl.set(mTab);
-        verify(mTab).isNativePage(); // Verify it was false.
+        verify(mTab).isNativePage(); // Verify isNativePage() returned false.
         assertFalse(mEdgeToEdgeControllerImpl.isToEdge());
         assertToNormalExpectations();
     }
@@ -194,7 +197,17 @@
         ChromeFeatureList.sDrawWebEdgeToEdge.setForTesting(true);
         when(mTab.isNativePage()).thenReturn(false);
         mObservableSupplierImpl.set(mTab);
-        verify(mTab).isNativePage();
+        verify(mTab).isNativePage(); // Verify isNativePage() returned false.
+        assertTrue(mEdgeToEdgeControllerImpl.isToEdge());
+        assertToEdgeExpectations();
+    }
+
+    @Test
+    public void onObservingDifferentTab_changeToWebEnabled_SetsDecor() {
+        ChromeFeatureList.sDrawWebEdgeToEdge.setForTesting(true);
+        when(mTab.isNativePage()).thenReturn(false);
+        mObservableSupplierImpl.set(mTab);
+        verify(mTab).isNativePage(); // Verify isNativePage() returned false.
         assertTrue(mEdgeToEdgeControllerImpl.isToEdge());
         assertToEdgeExpectations();
     }
@@ -225,16 +238,21 @@
     /** Test the OSWrapper implementation without mocking it. Native ToEdge. */
     @Test
     public void onObservingDifferentTab_osWrapperImpl() {
+        // Force a shift ToEdge by enabling all native and saying it is native.
         ChromeFeatureList.sDrawNativeEdgeToEdge.setForTesting(true);
         EdgeToEdgeControllerImpl liveController =
                 (EdgeToEdgeControllerImpl)
                         EdgeToEdgeControllerFactory.create(mActivity, mObservableSupplierImpl);
         assertNotNull(liveController);
+        liveController.setToEdgeForTesting(false);
         when(mTab.isNativePage()).thenReturn(true);
         mObservableSupplierImpl.set(mTab);
+        // Process the WindowInsetsListener callback.
+        shadowOf(Looper.getMainLooper()).idle();
         verify(mTab, times(2)).isNativePage();
         assertTrue(liveController.isToEdge());
-        // Check the Navigation Bar color, as an indicator that we really changed the window.
+        // Check the Navigation Bar color, as an indicator that we really changed the window,
+        // since we didn't use the OS Wrapper mock.
         assertEquals(Color.TRANSPARENT, mActivity.getWindow().getNavigationBarColor());
     }
 
@@ -245,11 +263,14 @@
                 (EdgeToEdgeControllerImpl)
                         EdgeToEdgeControllerFactory.create(mActivity, mObservableSupplierImpl);
         assertNotNull(liveController);
-        when(mTab.isNativePage()).thenReturn(true);
+        liveController.setToEdgeForTesting(true);
+        liveController.setSystemInsetsForTesting(SYSTEM_INSETS);
+        when(mTab.isNativePage()).thenReturn(false);
         mObservableSupplierImpl.set(mTab);
         verify(mTab, times(2)).isNativePage();
         assertFalse(liveController.isToEdge());
-        // Check the Navigation Bar color, as an indicator that we really changed the window.
+        // Check the Navigation Bar color, as an indicator that we really changed the window,
+        // since we didn't use the OS Wrapper mock.
         assertNotEquals(Color.TRANSPARENT, mActivity.getWindow().getNavigationBarColor());
     }
 
@@ -257,13 +278,25 @@
     @Test
     public void onObservingDifferentTab_nullTabSwitcher() {
         mEdgeToEdgeControllerImpl.setToEdgeForTesting(true);
+        mEdgeToEdgeControllerImpl.setSystemInsetsForTesting(SYSTEM_INSETS);
         mEdgeToEdgeControllerImpl.onTabSwitched(null);
         assertFalse(mEdgeToEdgeControllerImpl.isToEdge());
         // Check the Navigation Bar color, as an indicator that we really changed the window.
         assertNotEquals(Color.TRANSPARENT, mActivity.getWindow().getNavigationBarColor());
-        assertToNormalExpectations();
+        verify(mOsWrapper).setNavigationBarColor(any(), eq(Color.BLACK));
+        verify(mOsWrapper, times(0)).setDecorFitsSystemWindows(any(), anyBoolean());
+        verify(mOsWrapper, times(0)).setOnApplyWindowInsetsListener(any(), any());
+        // Pad the top and the bottom to keep it all normal.
+        verify(mOsWrapper, times(1))
+                .setPadding(
+                        any(),
+                        eq(0),
+                        intThat(Matchers.greaterThan(0)),
+                        eq(0),
+                        intThat(Matchers.greaterThan(0)));
     }
 
+
     /** Test that we update WebContentsObservers when a Tab changes WebContents. */
     @Test
     public void onTabSwitched_onWebContentsSwapped() {
@@ -292,20 +325,31 @@
                 mEdgeToEdgeControllerImpl.getWebContentsObserver());
     }
 
+    @Test
+    public void onObservingDifferentTab_simple() {
+        ChromeFeatureList.sDrawNativeEdgeToEdge.setForTesting(true);
+        // For the Tab Switcher we need to switch from some non-null Tab to null.
+        when(mTab.isNativePage()).thenReturn(true);
+        mObservableSupplierImpl.set(mTab);
+        verify(mTab).isNativePage();
+        verify(mOsWrapper)
+                .setOnApplyWindowInsetsListener(any(), mWindowInsetsListenerCaptor.capture());
+        assertToEdgeExpectations();
+    }
+
     void assertToEdgeExpectations() {
-        verify(mOsWrapper).setNavigationBarColor(any(), eq(Color.TRANSPARENT));
-        verify(mOsWrapper).setDecorFitsSystemWindows(any(), eq(false));
-        verify(mOsWrapper).setOnApplyWindowInsetsListener(any(), any());
         mWindowInsetsListenerCaptor.getValue().onApplyWindowInsets(mViewMock, mWindowInsetsMock);
         // Pad the top only, bottom is ToEdge.
         verify(mOsWrapper).setPadding(any(), eq(0), intThat(Matchers.greaterThan(0)), eq(0), eq(0));
+        verify(mOsWrapper).setNavigationBarColor(any(), eq(Color.TRANSPARENT));
+        verify(mOsWrapper).setDecorFitsSystemWindows(any(), eq(false));
+        verify(mOsWrapper).setOnApplyWindowInsetsListener(any(), any());
     }
 
     void assertToNormalExpectations() {
         verify(mOsWrapper).setNavigationBarColor(any(), eq(Color.BLACK));
-        verify(mOsWrapper).setDecorFitsSystemWindows(any(), eq(true));
-        verify(mOsWrapper).setOnApplyWindowInsetsListener(any(), any());
-        mWindowInsetsListenerCaptor.getValue().onApplyWindowInsets(mViewMock, mWindowInsetsMock);
+        verify(mOsWrapper, times(0)).setDecorFitsSystemWindows(any(), anyBoolean());
+        verify(mOsWrapper, times(0)).setOnApplyWindowInsetsListener(any(), any());
         // Pad the top and the bottom to keep it all normal.
         verify(mOsWrapper)
                 .setPadding(
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java
index 6697986..22f15f0 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java
@@ -813,12 +813,25 @@
     }
 
     /**
-     * @see LocationBarMediator#setUrlBarHintTextColorForSurfacePolish(boolean, boolean)
+     * @see LocationBarMediator#setIsSurfacePolishOmniboxColorEnabled(boolean)
      */
-    public void setUrlBarHintTextColorForSurfacePolish(
-            boolean useColorfulOmniboxType, boolean usePreviousHintTextColor) {
-        mLocationBarMediator.setUrlBarHintTextColorForSurfacePolish(
-                useColorfulOmniboxType, usePreviousHintTextColor);
+    public void setIsSurfacePolishOmniboxColorEnabled(boolean isSurfacePolishOmniboxColorEnabled) {
+        mLocationBarMediator.setIsSurfacePolishOmniboxColorEnabled(
+                isSurfacePolishOmniboxColorEnabled);
+    }
+
+    /**
+     * @see LocationBarMediator#updateButtonTints(boolean)
+     */
+    public void updateButtonTints() {
+        mLocationBarMediator.updateButtonTints();
+    }
+
+    /**
+     * @see LocationBarMediator#setUrlBarHintTextColor(boolean)
+     */
+    public void setUrlBarHintTextColor(boolean isStartOrNtp) {
+        mLocationBarMediator.setUrlBarHintTextColor(isStartOrNtp);
     }
 
     /**
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java
index d724507..30dc5b49 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java
@@ -10,6 +10,7 @@
 import android.annotation.SuppressLint;
 import android.content.ComponentCallbacks;
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.graphics.Typeface;
@@ -203,6 +204,7 @@
             new ObservableSupplierImpl<>();
     private boolean mShouldClearOmniboxOnFocus = true;
     private ObservableSupplier<TabModelSelector> mTabModelSelectorSupplier;
+    private boolean mIsSurfacePolishOmniboxColorEnabled;
 
     /*package */ LocationBarMediator(
             @NonNull Context context,
@@ -343,6 +345,9 @@
 
         mLocationBarLayout.onFinishNativeInitialization();
         if (mProfileSupplier.hasValue()) setProfile(mProfileSupplier.get());
+
+        mLocationBarLayout.setMicButtonDrawable(
+                AppCompatResources.getDrawable(mContext, R.drawable.btn_mic));
         onPrimaryColorChanged();
 
         for (Runnable deferredRunnable : mDeferredNativeRunnables) {
@@ -1017,20 +1022,6 @@
         }
     }
 
-    @VisibleForTesting
-    /* package */ void updateAssistantVoiceSearchDrawableAndColors() {
-        mLocationBarLayout.setMicButtonTint(
-                ThemeUtils.getThemedToolbarIconTint(mContext, mBrandedColorScheme));
-        mLocationBarLayout.setMicButtonDrawable(
-                AppCompatResources.getDrawable(mContext, R.drawable.btn_mic));
-    }
-
-    @VisibleForTesting
-    /* package */ void updateLensButtonColors() {
-        mLocationBarLayout.setLensButtonTint(
-                ThemeUtils.getThemedToolbarIconTint(mContext, mBrandedColorScheme));
-    }
-
     /** Update visuals to use a correct color scheme depending on the primary color. */
     @VisibleForTesting
     /* package */ void updateBrandedColorScheme() {
@@ -1040,6 +1031,8 @@
                         mLocationBarDataProvider.isIncognito(),
                         getPrimaryBackgroundColor());
 
+        // The delete button only appears when the url bar has focus, so its tint is rather static,
+        // and need not be assigned in updateButtonTints().
         mLocationBarLayout.setDeleteButtonTint(
                 ThemeUtils.getThemedToolbarIconTint(mContext, mBrandedColorScheme));
         // If the URL changed colors and is not focused, update the URL to account for the new
@@ -1264,11 +1257,9 @@
 
     @Override
     public void onPrimaryColorChanged() {
-        // This method needs to be called first as it computes |mBrandedColorScheme|.
+        // Compute |mBrandedColorScheme| first.
         updateBrandedColorScheme();
-
-        updateAssistantVoiceSearchDrawableAndColors();
-        updateLensButtonColors();
+        updateButtonTints();
     }
 
     @Override
@@ -1570,21 +1561,37 @@
     }
 
     /**
-     * Sets the color of the hint text in the search box based on the current page. If the current
-     * page is Start Surface or NTP, we set the hint text color to be colorOnSurface or
-     * colorOnPrimaryContainer based on whether useColorfulOmniboxType is true or not. If the
-     * current page is not Start Surface or NTP, we set the hint text color back to the previous
-     * value set before entering Start Surface or NTP.
+     * Sets mIsSurfacePolishOmniboxColorEnabled.
      *
-     * @param useColorfulOmniboxType True if the surface polish flag and omnibox color variant are
-     *     both enabled and we need to use the colorful type for the url bar hint color.
-     * @param usePreviousHintTextColor True if we leave the Start Surface or NTP and return to the
-     *     value set originally.
+     * @param isSurfacePolishOmniboxColorEnabled True if the surface polish flag and omnibox color
+     *     variant are are both enabled, thus requiring colorful type for the url bar hint color and
+     *     icons.
      */
-    public void setUrlBarHintTextColorForSurfacePolish(
-            boolean useColorfulOmniboxType, boolean usePreviousHintTextColor) {
-        mUrlCoordinator.setUrlBarHintTextColorForSurfacePolish(
-                useColorfulOmniboxType, usePreviousHintTextColor, mBrandedColorScheme);
+    public void setIsSurfacePolishOmniboxColorEnabled(boolean isSurfacePolishOmniboxColorEnabled) {
+        mIsSurfacePolishOmniboxColorEnabled = isSurfacePolishOmniboxColorEnabled;
+    }
+
+    /** Updates the tints of UI buttons. */
+    public void updateButtonTints() {
+        ColorStateList tint = ThemeUtils.getThemedToolbarIconTint(mContext, mBrandedColorScheme);
+        mLocationBarLayout.setMicButtonTint(tint);
+        mLocationBarLayout.setLensButtonTint(tint);
+    }
+
+    /**
+     * Sets the search box hint text color, depending on whether or not the the current page is
+     * Start Surface or NTP.
+     *
+     * @param isStartOrNtp Whether the current page is Start Surface or NTP. If true, then a
+     *     colorful theme may be applied.
+     */
+    public void setUrlBarHintTextColor(boolean isStartOrNtp) {
+        if (isStartOrNtp) {
+            mUrlCoordinator.setUrlBarHintTextColorForSurfacePolish(
+                    mIsSurfacePolishOmniboxColorEnabled);
+        } else {
+            mUrlCoordinator.setUrlBarHintTextColorForDefault(mBrandedColorScheme);
+        }
     }
 
     /**
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarCoordinator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarCoordinator.java
index c2ce20b..90fcee3 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarCoordinator.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarCoordinator.java
@@ -315,14 +315,17 @@
     }
 
     /**
-     * @see UrlBarMediator#setUrlBarHintTextColorForSurfacePolish(boolean, boolean, int)
+     * @see UrlBarMediator#setUrlBarHintTextColorForDefault(int)
      */
-    public void setUrlBarHintTextColorForSurfacePolish(
-            boolean useColorfulOmniboxType,
-            boolean usePreviousHintTextColor,
-            @BrandedColorScheme int brandedColorScheme) {
-        mMediator.setUrlBarHintTextColorForSurfacePolish(
-                useColorfulOmniboxType, usePreviousHintTextColor, brandedColorScheme);
+    public void setUrlBarHintTextColorForDefault(@BrandedColorScheme int brandedColorScheme) {
+        mMediator.setUrlBarHintTextColorForDefault(brandedColorScheme);
+    }
+
+    /**
+     * @see UrlBarMediator#setUrlBarHintTextColorForSurfacePolish(boolean)
+     */
+    public void setUrlBarHintTextColorForSurfacePolish(boolean useColorfulOmniboxType) {
+        mMediator.setUrlBarHintTextColorForSurfacePolish(useColorfulOmniboxType);
     }
 
     /**
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarMediator.java
index a94ad20..2b794f1 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarMediator.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarMediator.java
@@ -374,31 +374,29 @@
     }
 
     /**
-     * Sets the color of the hint text in the search box to be colorOnSurface or
-     * colorOnPrimaryContainer based on whether useColorfulOmniboxType is true or not.
+     * Sets search box hint text color to brandedColorScheme.
+     *
+     * @param brandedColorScheme The {@link @BrandedColorScheme}.
+     */
+    void setUrlBarHintTextColorForDefault(@BrandedColorScheme int brandedColorScheme) {
+        mIsHintTextFixedForStartOrNtp = false;
+        setBrandedColorScheme(brandedColorScheme);
+    }
+
+    /**
+     * Sets search box hint text color for Surface Polish. The color may be colorOnSurface or
+     * colorOnPrimaryContainer, depending on useColorfulOmniboxType.
      *
      * @param useColorfulOmniboxType True if the surface polish flag and omnibox color variant are
      *     both enabled and we need to use the colorful type for the url bar hint color.
-     * @param usePreviousHintTextColor True if we leave the Start Surface or NTP and return to the
-     *     value set originally.
-     * @param brandedColorScheme The {@link @BrandedColorScheme}.
      */
-    void setUrlBarHintTextColorForSurfacePolish(
-            boolean useColorfulOmniboxType,
-            boolean usePreviousHintTextColor,
-            @BrandedColorScheme int brandedColorScheme) {
-        if (usePreviousHintTextColor) {
-            mIsHintTextFixedForStartOrNtp = false;
-            setBrandedColorScheme(brandedColorScheme);
-            return;
-        }
-
+    void setUrlBarHintTextColorForSurfacePolish(boolean useColorfulOmniboxType) {
+        mIsHintTextFixedForStartOrNtp = true;
         final @ColorInt int hintTextColor =
                 useColorfulOmniboxType
                         ? SemanticColorUtils.getDefaultTextColorOnAccent1Container(mContext)
                         : SemanticColorUtils.getDefaultTextColor(mContext);
         mModel.set(UrlBarProperties.HINT_TEXT_COLOR, hintTextColor);
-        mIsHintTextFixedForStartOrNtp = true;
     }
 
     /**
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
index 56b78bfc..38cc5cf 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -292,11 +292,10 @@
     private final boolean mIsSurfacePolishOmniboxColorEnabled;
 
     // For both Start Surface and NTP, when the surface polish flag is enabled, we will change the
-    // appearance(G logo background, search text color and style) of the real search box after it is
-    // pinned at top when scrolling up the surface. This variable is used to distinguish whether the
-    // current page is Start Surface or NTP and we have changed the appearance of the real search
-    // box.
-    private boolean mHasSetLocationBarStyling;
+    // appearance (G logo background, search text color and style) of the real search box after it's
+    // pinned at top when scrolling up the surface. This variable distinguishes whether the current
+    // page is Start Surface / NTP, to indicate that the appearance of the real search box changed.
+    private boolean mIsStartOrNtpWithSurfacePolish;
 
     // The following are some properties used during animation.  We use explicit property classes
     // to avoid the cost of reflection for each animation setup.
@@ -365,6 +364,7 @@
     @Override
     public void setLocationBarCoordinator(LocationBarCoordinator locationBarCoordinator) {
         mLocationBar = locationBarCoordinator;
+        mLocationBar.setIsSurfacePolishOmniboxColorEnabled(mIsSurfacePolishOmniboxColorEnabled);
         initLocationBarBackground();
     }
 
@@ -2474,37 +2474,29 @@
             return;
         }
 
-        Typeface typeface;
-        boolean isNightMode = ColorUtils.inNightMode(getContext());
-        // If the current page is Start surface or NTP instead of the search results page or other
-        // browser tabs.
-        boolean isStartOrNtp =
+        // Detect whether state has changed and update only when that happens.
+        boolean prevIsStartOrNtpWithSurfacePolish = mIsStartOrNtpWithSurfacePolish;
+        mIsStartOrNtpWithSurfacePolish =
                 (visualState == VisualState.NEW_TAB_NORMAL || mIsShowingStartSurfaceHomepage)
-                && !hasFocus;
-        if (isStartOrNtp) {
-            // If the real omnibox's appearance has been changed, we don't change it again.
-            if (!mHasSetLocationBarStyling) {
-                mHasSetLocationBarStyling = true;
-
-                mLocationBar.setStatusIconBackgroundVisibility(!isNightMode);
-
-                mLocationBar.setUrlBarHintTextColorForSurfacePolish(
-                        mIsSurfacePolishOmniboxColorEnabled, /*usePreviousHintTextColor*/ false);
-                typeface = Typeface.create("google-sans-medium", Typeface.NORMAL);
-                mLocationBar.setUrlBarTypeface(typeface);
-            }
-        } else if (mHasSetLocationBarStyling) {
-            // We only need to change back the appearance of the real search box when the current
-            // page is not Start surface or NTP and we haven't changed back the appearance yet.
-            mHasSetLocationBarStyling = false;
-
-            mLocationBar.setStatusIconBackgroundVisibility(false);
-
-            mLocationBar.setUrlBarHintTextColorForSurfacePolish(
-                    mIsSurfacePolishOmniboxColorEnabled, /*usePreviousHintTextColor*/ true);
-            typeface = Typeface.defaultFromStyle(Typeface.NORMAL);
-            mLocationBar.setUrlBarTypeface(typeface);
+                        && !hasFocus;
+        if (mIsStartOrNtpWithSurfacePolish == prevIsStartOrNtpWithSurfacePolish) {
+            return;
         }
+
+        // TODO(crbug.com/1487760): Use TextAppearance style instead.
+        Typeface typeface;
+        if (mIsStartOrNtpWithSurfacePolish) {
+            boolean isNightMode = ColorUtils.inNightMode(getContext());
+            mLocationBar.setStatusIconBackgroundVisibility(!isNightMode);
+            typeface = Typeface.create("google-sans-medium", Typeface.NORMAL);
+        } else {
+            // Restore the appearance of the real search box when transitioning from Start Surface
+            // or NTP to the search results page.
+            mLocationBar.setStatusIconBackgroundVisibility(false);
+            typeface = Typeface.defaultFromStyle(Typeface.NORMAL);
+        }
+        mLocationBar.setUrlBarTypeface(typeface);
+        mLocationBar.setUrlBarHintTextColor(mIsStartOrNtpWithSurfacePolish);
     }
 
     private void updateVisualsForLocationBarState() {
diff --git a/chrome/browser/ui/ash/shelf/app_service/app_service_promise_app_shelf_context_menu_browsertest.cc b/chrome/browser/ui/ash/shelf/app_service/app_service_promise_app_shelf_context_menu_browsertest.cc
index e2ef394..6d8d868f 100644
--- a/chrome/browser/ui/ash/shelf/app_service/app_service_promise_app_shelf_context_menu_browsertest.cc
+++ b/chrome/browser/ui/ash/shelf/app_service/app_service_promise_app_shelf_context_menu_browsertest.cc
@@ -14,12 +14,12 @@
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
 #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller_util.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "content/public/test/browser_test.h"
 #include "ui/base/models/simple_menu_model.h"
 #include "ui/display/display.h"
diff --git a/chrome/browser/ui/ash/shelf/app_service/shelf_app_service_promise_app_updater.h b/chrome/browser/ui/ash/shelf/app_service/shelf_app_service_promise_app_updater.h
index a41a1a3..9c8b43f 100644
--- a/chrome/browser/ui/ash/shelf/app_service/shelf_app_service_promise_app_updater.h
+++ b/chrome/browser/ui/ash/shelf/app_service/shelf_app_service_promise_app_updater.h
@@ -7,9 +7,9 @@
 
 #include "base/memory/raw_ptr.h"
 #include "base/scoped_observation.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
 #include "chrome/browser/ui/ash/shelf/shelf_app_updater.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 
 class Profile;
 
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
index 7671405..80d98a18 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
@@ -41,7 +41,6 @@
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/app_service/extension_apps_utils.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_service.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_update.h"
 #include "chrome/browser/apps/icon_standardizer.h"
@@ -106,6 +105,7 @@
 #include "components/app_constants/constants.h"
 #include "components/favicon/content/content_favicon_driver.h"
 #include "components/services/app_service/public/cpp/app_types.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "components/services/app_service/public/cpp/shortcut/shortcut.h"
 #include "components/services/app_service/public/cpp/shortcut/shortcut_update.h"
 #include "components/strings/grit/components_strings.h"
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
index fefb639f..3d0745dac 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
@@ -67,7 +67,6 @@
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/app_service/app_service_test.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/apps/app_service/policy_util.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app.h"
 #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h"
@@ -159,6 +158,7 @@
 #include "components/services/app_service/public/cpp/app_update.h"
 #include "components/services/app_service/public/cpp/instance.h"
 #include "components/services/app_service/public/cpp/instance_registry.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "components/services/app_service/public/cpp/shortcut/shortcut.h"
 #include "components/services/app_service/public/cpp/shortcut/shortcut_registry_cache.h"
 #include "components/services/app_service/public/cpp/stub_icon_loader.h"
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index a5c51af..c0d80b1 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -659,6 +659,9 @@
     case IDC_VIRTUAL_CARD_ENROLL:
       ShowVirtualCardEnrollBubble(browser_);
       break;
+    case IDC_ORGANIZE_TABS:
+      StartTabOrganizationRequest(browser_);
+      break;
     case IDC_SHOW_TRANSLATE:
       ShowTranslateBubble(browser_);
       break;
@@ -1199,6 +1202,7 @@
   UpdateTabRestoreCommandState();
   command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
   command_updater_.UpdateCommandEnabled(IDC_NAME_WINDOW, true);
+  command_updater_.UpdateCommandEnabled(IDC_ORGANIZE_TABS, true);
 #if BUILDFLAG(IS_CHROMEOS)
   command_updater_.UpdateCommandEnabled(IDC_TOGGLE_MULTITASK_MENU, true);
 #endif
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index 70cd2774..733298b 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -90,6 +90,9 @@
 #include "chrome/browser/ui/status_bubble.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
 #include "chrome/browser/ui/tab_dialogs.h"
+#include "chrome/browser/ui/tabs/organization/tab_organization_service.h"
+#include "chrome/browser/ui/tabs/organization/tab_organization_service_factory.h"
+#include "chrome/browser/ui/tabs/organization/tab_organization_session.h"
 #include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.h"
 #include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.h"
 #include "chrome/browser/ui/tabs/tab_enums.h"
@@ -1509,6 +1512,19 @@
   }
 }
 
+void StartTabOrganizationRequest(Browser* browser) {
+  TabOrganizationService* service =
+      TabOrganizationServiceFactory::GetForProfile(browser->profile());
+  TabOrganizationSession* session = service->GetSessionForBrowser(browser);
+  if (session == nullptr) {
+    session = service->CreateSessionForBrowser(browser);
+  }
+  if (session->request()->state() ==
+      TabOrganizationRequest::State::NOT_STARTED) {
+    session->StartRequest();
+  }
+}
+
 void ShowTranslateBubble(Browser* browser) {
   if (!browser->window()->IsActive()) {
     return;
diff --git a/chrome/browser/ui/browser_commands.h b/chrome/browser/ui/browser_commands.h
index 33ad055c..a6878b41c 100644
--- a/chrome/browser/ui/browser_commands.h
+++ b/chrome/browser/ui/browser_commands.h
@@ -176,6 +176,7 @@
 void SaveAutofillAddress(Browser* browser);
 void ShowVirtualCardManualFallbackBubble(Browser* browser);
 void ShowVirtualCardEnrollBubble(Browser* browser);
+void StartTabOrganizationRequest(Browser* browser);
 void ShowTranslateBubble(Browser* browser);
 void ManagePasswordsForPage(Browser* browser);
 bool CanSendTabToSelf(const Browser* browser);
diff --git a/chrome/browser/ui/browser_commands_browsertest.cc b/chrome/browser/ui/browser_commands_browsertest.cc
index f3090159..08c1476 100644
--- a/chrome/browser/ui/browser_commands_browsertest.cc
+++ b/chrome/browser/ui/browser_commands_browsertest.cc
@@ -12,6 +12,9 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/tabs/organization/tab_organization_service.h"
+#include "chrome/browser/ui/tabs/organization/tab_organization_service_factory.h"
+#include "chrome/browser/ui/tabs/organization/tab_organization_session.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -24,13 +27,18 @@
 #include "content/public/test/browser_test.h"
 #include "net/cookies/cookie_util.h"
 #include "net/dns/mock_host_resolver.h"
+#include "ui/base/ui_base_features.h"
 
 namespace chrome {
 
 class BrowserCommandsTest : public InProcessBrowserTest {
  public:
-  BrowserCommandsTest() : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
+  BrowserCommandsTest() : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
+    feature_list_.InitWithFeatures(
+        {features::kTabOrganization, features::kChromeRefresh2023}, {});
+  }
 
+  base::test::ScopedFeatureList feature_list_;
   net::test_server::EmbeddedTestServer https_server_;
 
   void SetUpOnMainThread() override {
@@ -326,4 +334,16 @@
             url3);
 }
 
+IN_PROC_BROWSER_TEST_F(BrowserCommandsTest, StartsOrganizationRequest) {
+  chrome::ExecuteCommand(browser(), IDC_ORGANIZE_TABS);
+
+  TabOrganizationService* service =
+      TabOrganizationServiceFactory::GetForProfile(browser()->profile());
+  const TabOrganizationSession* session =
+      service->GetSessionForBrowser(browser());
+
+  EXPECT_NE(TabOrganizationRequest::State::NOT_STARTED,
+            session->request()->state());
+}
+
 }  // namespace chrome
diff --git a/chrome/browser/ui/color/chrome_color_id.h b/chrome/browser/ui/color/chrome_color_id.h
index 2e2cac6..813e5b8b 100644
--- a/chrome/browser/ui/color/chrome_color_id.h
+++ b/chrome/browser/ui/color/chrome_color_id.h
@@ -477,6 +477,8 @@
   E_CPONLY(kColorTabBackgroundSelectedHoverFrameInactive) \
   E_CPONLY(kColorTabCloseButtonFocusRingActive) \
   E_CPONLY(kColorTabCloseButtonFocusRingInactive) \
+  E_CPONLY(kColorTabDiscardRingFrameActive) \
+  E_CPONLY(kColorTabDiscardRingFrameInactive) \
   E_CPONLY(kColorTabFocusRingActive) \
   E_CPONLY(kColorTabFocusRingInactive) \
   E_CPONLY(kColorTabForegroundActiveFrameActive) \
diff --git a/chrome/browser/ui/color/material_tab_strip_color_mixer.cc b/chrome/browser/ui/color/material_tab_strip_color_mixer.cc
index f8bd90d..93a18e5f 100644
--- a/chrome/browser/ui/color/material_tab_strip_color_mixer.cc
+++ b/chrome/browser/ui/color/material_tab_strip_color_mixer.cc
@@ -55,7 +55,8 @@
   mixer[kColorTabBackgroundSelectedHoverFrameInactive] = {
       ui::GetResultingPaintColor(ui::kColorSysStateHoverDimBlendProtection,
                                  kColorTabBackgroundSelectedFrameInactive)};
-
+  mixer[kColorTabDiscardRingFrameActive] = {ui::kColorSysStateDisabled};
+  mixer[kColorTabDiscardRingFrameInactive] = {kColorTabDiscardRingFrameActive};
   mixer[kColorTabForegroundActiveFrameActive] = {ui::kColorSysOnSurface};
   mixer[kColorTabForegroundActiveFrameInactive] = {
       kColorTabForegroundActiveFrameActive};
diff --git a/chrome/browser/ui/color/new_tab_page_color_mixer.cc b/chrome/browser/ui/color/new_tab_page_color_mixer.cc
index 471edb1..ab2ad77 100644
--- a/chrome/browser/ui/color/new_tab_page_color_mixer.cc
+++ b/chrome/browser/ui/color/new_tab_page_color_mixer.cc
@@ -63,6 +63,38 @@
   return base::BindRepeating(generator, std::move(input_transform), percent);
 }
 
+ui::ColorTransform SelectBasedOnNtpBackground(
+    ui::ColorTransform output_transform_for_white_input,
+    ui::ColorTransform output_transform_for_black_input,
+    ui::ColorTransform default_output_transform_for_input) {
+  const auto generator =
+      [](ui::ColorTransform output_transform_for_white_input,
+         ui::ColorTransform output_transform_for_black_input,
+         ui::ColorTransform default_output_transform_for_input,
+         SkColor input_color, const ui::ColorMixer& mixer) {
+        const ui::ColorTransform input_transform = {kColorNewTabPageBackground};
+        const SkColor color = input_transform.Run(input_color, mixer);
+        const auto& output_transform =
+            (color == SK_ColorWHITE)
+                ? output_transform_for_white_input
+                : ((color == SK_ColorBLACK)
+                       ? output_transform_for_black_input
+                       : default_output_transform_for_input);
+        const SkColor result_color = output_transform.Run(input_color, mixer);
+        DVLOG(2) << "ColorTransform SelectBasedOnNtpBackground:"
+                 << " Input Color: " << ui::SkColorName(input_color)
+                 << " Input Transform: " << ui::SkColorName(color)
+                 << " IsWhite: " << (color == SK_ColorWHITE ? "true" : "false")
+                 << " IsBlack: " << (color == SK_ColorBLACK ? "true" : "false")
+                 << " Result Color: " << ui::SkColorName(result_color);
+        return result_color;
+      };
+  return base::BindRepeating(generator,
+                             std::move(output_transform_for_white_input),
+                             std::move(output_transform_for_black_input),
+                             std::move(default_output_transform_for_input));
+}
+
 ui::ColorTransform SelectBasedOnWhiteInput(
     const ui::ColorTransform input_transform,
     ui::ColorTransform output_transform_for_white_input,
@@ -103,9 +135,15 @@
 // compute appropriate contrasting background and foreground element colors and
 // use these to style elements.
 void AddGeneratedThemeComprehensiveColors(ui::ColorMixer& mixer) {
-  ui::ColorTransform element_background_color = SelectBasedOnWhiteNtpBackground(
-      kColorNewTabPageBackground,
-      GetContrastingColorTransform(kColorNewTabPageBackground));
+  ui::ColorTransform element_background_color =
+      base::FeatureList::IsEnabled(ntp_features::kNtpModulesRedesigned)
+          ? SelectBasedOnNtpBackground(
+                kColorNewTabPageBackground, {gfx::kGoogleGrey900},
+                GetContrastingColorTransform(kColorNewTabPageBackground))
+          : SelectBasedOnWhiteNtpBackground(
+                kColorNewTabPageBackground,
+                GetContrastingColorTransform(kColorNewTabPageBackground));
+
   ui::ColorTransform primary_foreground_color =
       ui::GetColorWithMaxContrast(element_background_color);
   ui::ColorTransform themed_foreground_color = SelectBasedOnWhiteNtpBackground(
@@ -154,9 +192,9 @@
       select_topmost_element_foreground_color;
 
   if (base::FeatureList::IsEnabled(ntp_features::kNtpModulesRedesigned)) {
-    mixer[kColorNewTabPageModuleBackground] = SelectBasedOnWhiteInput(
-        {kColorNewTabPageBackground}, gfx::kGoogleGrey100,
-        element_background_color);
+    mixer[kColorNewTabPageModuleBackground] =
+        SelectBasedOnWhiteInput({kColorNewTabPageBackground},
+                                gfx::kGoogleGrey100, element_background_color);
   } else {
     mixer[kColorNewTabPageModuleBackground] = element_background_color;
   }
diff --git a/chrome/browser/ui/color/tab_strip_color_mixer.cc b/chrome/browser/ui/color/tab_strip_color_mixer.cc
index 50864f5f..177ecda 100644
--- a/chrome/browser/ui/color/tab_strip_color_mixer.cc
+++ b/chrome/browser/ui/color/tab_strip_color_mixer.cc
@@ -164,6 +164,13 @@
   mixer[kColorTabDividerFrameActive] = {kColorToolbar};
   mixer[kColorTabDividerFrameInactive] = {kColorToolbar};
 
+  // This is not used for text and this contrast ratio most closely matches the
+  // approved ChromeRefresh2023 colors
+  mixer[kColorTabDiscardRingFrameActive] = ui::PickGoogleColor(
+      gfx::kGoogleGrey500, kColorTabBackgroundInactiveFrameActive, 2.0);
+  mixer[kColorTabDiscardRingFrameInactive] = ui::PickGoogleColor(
+      gfx::kGoogleGrey500, kColorTabBackgroundInactiveFrameInactive, 2.0);
+
   mixer[kColorNewTabButtonForegroundFrameActive] = {
       kColorTabForegroundActiveFrameActive};
   mixer[kColorNewTabButtonForegroundFrameInactive] = {
diff --git a/chrome/browser/ui/global_error/global_error.cc b/chrome/browser/ui/global_error/global_error.cc
index 4969ef0..b6a21a3 100644
--- a/chrome/browser/ui/global_error/global_error.cc
+++ b/chrome/browser/ui/global_error/global_error.cc
@@ -6,7 +6,6 @@
 
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/ui/global_error/global_error_bubble_view_base.h"
-#include "ui/base/ui_base_types.h"
 
 // GlobalError ---------------------------------------------------------------
 
@@ -63,10 +62,6 @@
   return false;
 }
 
-int GlobalErrorWithStandardBubble::GetDefaultDialogButton() const {
-  return ui::DIALOG_BUTTON_OK;
-}
-
 void GlobalErrorWithStandardBubble::BubbleViewDidClose(Browser* browser) {
   DCHECK(browser);
   bubble_view_ = nullptr;
diff --git a/chrome/browser/ui/global_error/global_error.h b/chrome/browser/ui/global_error/global_error.h
index e9a21f3..841f8285 100644
--- a/chrome/browser/ui/global_error/global_error.h
+++ b/chrome/browser/ui/global_error/global_error.h
@@ -75,7 +75,6 @@
   virtual bool ShouldShowCloseButton() const;
   virtual bool ShouldAddElevationIconToAcceptButton();
   virtual std::u16string GetBubbleViewCancelButtonLabel() = 0;
-  virtual int GetDefaultDialogButton() const;
   virtual bool ShouldCloseOnDeactivate() const;
   virtual std::u16string GetBubbleViewDetailsButtonLabel();
 
diff --git a/chrome/browser/ui/intent_picker_tab_helper.cc b/chrome/browser/ui/intent_picker_tab_helper.cc
index f909330..636ab06 100644
--- a/chrome/browser/ui/intent_picker_tab_helper.cc
+++ b/chrome/browser/ui/intent_picker_tab_helper.cc
@@ -329,8 +329,8 @@
   browser->window()->UpdatePageActionIcon(PageActionIconType::kIntentPicker);
 
   icon_resolved_after_last_navigation_ = true;
-  if (icon_update_callback_for_testing_) {
-    std::move(icon_update_callback_for_testing_).Run(should_show_icon);
+  if (icon_update_closure_for_testing_) {
+    std::move(icon_update_closure_for_testing_).Run();
   }
 }
 
@@ -410,13 +410,13 @@
 }
 
 void IntentPickerTabHelper::SetIconUpdateCallbackForTesting(
-    base::OnceCallback<void(bool)> icon_update_callback,
+    base::OnceClosure callback,
     bool include_latest_navigation) {
   if (icon_resolved_after_last_navigation_ && include_latest_navigation) {
-    std::move(icon_update_callback).Run(should_show_icon_);
+    std::move(callback).Run();
     return;
   }
-  icon_update_callback_for_testing_ = std::move(icon_update_callback);
+  icon_update_closure_for_testing_ = std::move(callback);
 }
 
 void IntentPickerTabHelper::DidStartNavigation(
diff --git a/chrome/browser/ui/intent_picker_tab_helper.h b/chrome/browser/ui/intent_picker_tab_helper.h
index 7b9a5511..a8b6de5 100644
--- a/chrome/browser/ui/intent_picker_tab_helper.h
+++ b/chrome/browser/ui/intent_picker_tab_helper.h
@@ -63,13 +63,12 @@
 
   const ui::ImageModel& app_icon() const { return current_app_icon_; }
 
-  // Sets a OnceCallback which is called with the result of whether the intent
-  // chip button is shown or not. If include_latest_navigation is true, and the
-  // latest navigation was finished, the callback is called immediately with the
-  // current value of should_show_icon_.
-  void SetIconUpdateCallbackForTesting(
-      base::OnceCallback<void(bool)> icon_update_callback,
-      bool include_latest_navigation = false);
+
+  // Sets a OnceClosure callback which will be called next time the icon is
+  // updated. If include_latest_navigation is true, and the latest navigation
+  // was finished, the callback is called immediately.
+  void SetIconUpdateCallbackForTesting(base::OnceClosure callback,
+                                       bool include_latest_navigation = false);
 
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 
@@ -146,7 +145,7 @@
   bool current_app_is_preferred_ = false;
   ui::ImageModel current_app_icon_;
 
-  base::OnceCallback<void(bool)> icon_update_callback_for_testing_;
+  base::OnceClosure icon_update_closure_for_testing_;
 
   std::unique_ptr<apps::AppsIntentPickerDelegate> intent_picker_delegate_;
 
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
index e70ef86..410f57c 100644
--- a/chrome/browser/ui/tab_helpers.cc
+++ b/chrome/browser/ui/tab_helpers.cc
@@ -84,6 +84,7 @@
 #include "chrome/browser/sync/sessions/sync_sessions_web_contents_router_factory.h"
 #include "chrome/browser/tab_contents/navigation_metrics_recorder.h"
 #include "chrome/browser/tpcd/heuristics/opener_heuristic_tab_helper.h"
+#include "chrome/browser/tpcd/metadata/devtools_observer.h"
 #include "chrome/browser/translate/chrome_translate_client.h"
 #include "chrome/browser/trusted_vault/trusted_vault_encryption_keys_tab_helper.h"
 #include "chrome/browser/ui/autofill/chrome_autofill_client.h"
@@ -352,8 +353,9 @@
     }
   }
   autofill::ChromeAutofillClient::CreateForWebContents(web_contents);
-  if (breadcrumbs::IsEnabled())
+  if (breadcrumbs::IsEnabled()) {
     BreadcrumbManagerTabHelper::CreateForWebContents(web_contents);
+  }
   chrome::ChainedBackNavigationTracker::CreateForWebContents(web_contents);
   chrome_browser_net::NetErrorTabHelper::CreateForWebContents(web_contents);
 #if BUILDFLAG(ENABLE_COMPOSE)
@@ -388,18 +390,21 @@
   webapps::InstallableManager::CreateForWebContents(web_contents);
   login_detection::LoginDetectionTabHelper::MaybeCreateForWebContents(
       web_contents);
-  if (MediaEngagementService::IsEnabled())
+  if (MediaEngagementService::IsEnabled()) {
     MediaEngagementService::CreateWebContentsObserver(web_contents);
-  if (base::FeatureList::IsEnabled(media::kUseMediaHistoryStore))
+  }
+  if (base::FeatureList::IsEnabled(media::kUseMediaHistoryStore)) {
     MediaHistoryContentsObserver::CreateForWebContents(web_contents);
+  }
   metrics::MetricsServicesWebContentsObserver::CreateForWebContents(
       web_contents);
   MixedContentSettingsTabHelper::CreateForWebContents(web_contents);
   NavigationMetricsRecorder::CreateForWebContents(web_contents);
   NavigationPredictorPreconnectClient::CreateForWebContents(web_contents);
   OpenerHeuristicTabHelper::CreateForWebContents(web_contents);
-  if (optimization_guide::features::IsOptimizationHintsEnabled())
+  if (optimization_guide::features::IsOptimizationHintsEnabled()) {
     OptimizationGuideWebContentsObserver::CreateForWebContents(web_contents);
+  }
   optimization_guide::PageContentAnnotationsService*
       page_content_annotations_service =
           PageContentAnnotationsServiceFactory::GetForProfile(profile);
@@ -453,8 +458,9 @@
   blocked_content::PopupOpenerTabHelper::CreateForWebContents(
       web_contents, base::DefaultTickClock::GetInstance(),
       HostContentSettingsMapFactory::GetForProfile(profile));
-  if (predictors::LoadingPredictorFactory::GetForProfile(profile))
+  if (predictors::LoadingPredictorFactory::GetForProfile(profile)) {
     predictors::LoadingPredictorTabHelper::CreateForWebContents(web_contents);
+  }
   PrefsTabHelper::CreateForWebContents(web_contents);
   prerender::NoStatePrefetchTabHelper::CreateForWebContents(web_contents);
   RecentlyAudibleHelper::CreateForWebContents(web_contents);
@@ -501,6 +507,8 @@
           profile));
   TabUIHelper::CreateForWebContents(web_contents);
   tasks::TaskTabHelper::CreateForWebContents(web_contents);
+  tpcd::metadata::TpcdMetadataDevtoolsObserver::CreateForWebContents(
+      web_contents);
   TrustedVaultEncryptionKeysTabHelper::CreateForWebContents(web_contents);
   ukm::InitializeSourceUrlRecorderForWebContents(web_contents);
   v8_compile_hints::V8CompileHintsTabHelper::MaybeCreateForWebContents(
@@ -555,8 +563,9 @@
     OneTimePermissionsTrackerHelper::CreateForWebContents(web_contents);
   }
   ManagePasswordsUIController::CreateForWebContents(web_contents);
-  if (PrivacySandboxPromptHelper::ProfileRequiresPrompt(profile))
+  if (PrivacySandboxPromptHelper::ProfileRequiresPrompt(profile)) {
     PrivacySandboxPromptHelper::CreateForWebContents(web_contents);
+  }
 
 #if BUILDFLAG(ENABLE_SEARCH_ENGINE_CHOICE)
   if (search_engines::IsChoiceScreenFlagEnabled(
@@ -623,8 +632,9 @@
 #endif
 
 #if BUILDFLAG(IS_MAC)
-  if (screentime::TabHelper::IsScreentimeEnabledForProfile(profile))
+  if (screentime::TabHelper::IsScreentimeEnabledForProfile(profile)) {
     screentime::TabHelper::CreateForWebContents(web_contents);
+  }
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -690,17 +700,19 @@
 #endif
 
 #if defined(TOOLKIT_VIEWS)
-  if (IsSideSearchEnabled(profile))
+  if (IsSideSearchEnabled(profile)) {
     SideSearchTabContentsHelper::CreateForWebContents(web_contents);
+  }
 #endif
 
 #if !BUILDFLAG(IS_ANDROID)
-  if (customize_chrome::IsSidePanelEnabled())
+  if (customize_chrome::IsSidePanelEnabled()) {
     CustomizeChromeTabHelper::CreateForWebContents(web_contents);
+  }
 #endif
 
-    // --- Section 3: Feature tab helpers behind BUILDFLAGs ---
-    // NOT for "if enabled"; put those in section 1.
+  // --- Section 3: Feature tab helpers behind BUILDFLAGs ---
+  // NOT for "if enabled"; put those in section 1.
 
 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
   captive_portal::CaptivePortalTabHelper::CreateForWebContents(
@@ -723,11 +735,13 @@
   }
 
   extensions::WebNavigationTabObserver::CreateForWebContents(web_contents);
-  if (web_app::AreWebAppsEnabled(profile))
+  if (web_app::AreWebAppsEnabled(profile)) {
     web_app::WebAppTabHelper::CreateForWebContents(web_contents);
+  }
   // Note WebAppMetricsTabHelper must be created after AppBannerManager.
-  if (web_app::WebAppMetricsTabHelper::IsEnabled(web_contents))
+  if (web_app::WebAppMetricsTabHelper::IsEnabled(web_contents)) {
     web_app::WebAppMetricsTabHelper::CreateForWebContents(web_contents);
+  }
 #endif
 
 #if BUILDFLAG(ENABLE_OFFLINE_PAGES)
@@ -753,8 +767,9 @@
 #endif
 
 #if BUILDFLAG(ENABLE_FEED_V2)
-  if (base::FeatureList::IsEnabled(feed::kWebUiFeed))
+  if (base::FeatureList::IsEnabled(feed::kWebUiFeed)) {
     feed::WebFeedTabHelper::CreateForWebContents(web_contents);
+  }
 #endif  // BUILDFLAG(ENABLE_FEED_V2)
 
   // --- Section 4: The warning ---
diff --git a/chrome/browser/ui/tabs/organization/tab_organization_service.cc b/chrome/browser/ui/tabs/organization/tab_organization_service.cc
index 31c1cc8b..a253b87c 100644
--- a/chrome/browser/ui/tabs/organization/tab_organization_service.cc
+++ b/chrome/browser/ui/tabs/organization/tab_organization_service.cc
@@ -39,14 +39,18 @@
 
 const TabOrganizationSession* TabOrganizationService::GetSessionForBrowser(
     const Browser* browser) const {
-  CHECK(base::Contains(browser_session_map_, browser));
-  return browser_session_map_.at(browser).get();
+  if (base::Contains(browser_session_map_, browser)) {
+    return browser_session_map_.at(browser).get();
+  }
+  return nullptr;
 }
 
 TabOrganizationSession* TabOrganizationService::GetSessionForBrowser(
     const Browser* browser) {
-  CHECK(base::Contains(browser_session_map_, browser));
-  return browser_session_map_.at(browser).get();
+  if (base::Contains(browser_session_map_, browser)) {
+    return browser_session_map_.at(browser).get();
+  }
+  return nullptr;
 }
 
 TabOrganizationSession* TabOrganizationService::CreateSessionForBrowser(
diff --git a/chrome/browser/ui/tabs/organization/tab_organization_service.h b/chrome/browser/ui/tabs/organization/tab_organization_service.h
index 283e6771..3719a0c 100644
--- a/chrome/browser/ui/tabs/organization/tab_organization_service.h
+++ b/chrome/browser/ui/tabs/organization/tab_organization_service.h
@@ -44,6 +44,11 @@
       const Browser* browser) const;
   TabOrganizationSession* GetSessionForBrowser(const Browser* browser);
 
+  // Creates a new tab organization session, checking to ensure one does not
+  // already exist for the browser. If callers are unsure whether there is an
+  // existing session, they should first call GetSessionForBrowser to confirm.
+  TabOrganizationSession* CreateSessionForBrowser(const Browser* browser);
+
   void AddObserver(TabOrganizationObserver* observer) {
     observers_.AddObserver(observer);
   }
@@ -53,8 +58,6 @@
   }
 
  private:
-  TabOrganizationSession* CreateSessionForBrowser(const Browser* browser);
-
   // mapping of browser to session.
   BrowserSessionMap browser_session_map_;
 
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc
index 6b967ac..176eba7 100644
--- a/chrome/browser/ui/toolbar/app_menu_model.cc
+++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -1606,6 +1606,11 @@
       AddItemWithStringId(IDC_SHOW_SEARCH_COMPANION, IDS_SHOW_SEARCH_COMPANION);
     }
 #endif
+    if (features::IsTabOrganization()) {
+      AddItemWithStringId(IDC_ORGANIZE_TABS, IDS_TAB_ORGANIZE_MENU);
+      SetIsNewFeatureAt(GetIndexOfCommandId(IDC_ORGANIZE_TABS).value(), true);
+    }
+
     AddItemWithStringId(IDC_SHOW_TRANSLATE, IDS_SHOW_TRANSLATE);
 
     CreateFindAndEditSubMenu();
@@ -1750,6 +1755,7 @@
     SetCommandIcon(this, IDC_VIEW_PASSWORDS, kKeyOpenChromeRefreshIcon);
     SetCommandIcon(this, IDC_ZOOM_MENU, kZoomInIcon);
     SetCommandIcon(this, IDC_PRINT, kPrintMenuIcon);
+    SetCommandIcon(this, IDC_ORGANIZE_TABS, kPaintbrushIcon);
     SetCommandIcon(this, IDC_SHOW_TRANSLATE, kTranslateIcon);
     SetCommandIcon(this, IDC_FIND_AND_EDIT_MENU, kSearchMenuIcon);
     SetCommandIcon(this, IDC_SAVE_AND_SHARE_MENU, kFileSaveChromeRefreshIcon);
diff --git a/chrome/browser/ui/toolbar/app_menu_model_unittest.cc b/chrome/browser/ui/toolbar/app_menu_model_unittest.cc
index f668c87..5b2bef13 100644
--- a/chrome/browser/ui/toolbar/app_menu_model_unittest.cc
+++ b/chrome/browser/ui/toolbar/app_menu_model_unittest.cc
@@ -168,7 +168,8 @@
 class TestAppMenuModelCR2023 : public AppMenuModelTest {
  public:
   TestAppMenuModelCR2023() {
-    feature_list_.InitAndEnableFeature(features::kChromeRefresh2023);
+    feature_list_.InitWithFeatures(
+        {features::kTabOrganization, features::kChromeRefresh2023}, {});
   }
 
   TestAppMenuModelCR2023(const TestAppMenuModelCR2023&) = delete;
@@ -366,6 +367,14 @@
   EXPECT_TRUE(toolModel.IsEnabledAt(performance_index));
 }
 
+TEST_F(TestAppMenuModelCR2023, OrganizeTabsItem) {
+  AppMenuModel model(this, browser());
+  model.Init();
+  size_t organize_tabs_index =
+      model.GetIndexOfCommandId(IDC_ORGANIZE_TABS).value();
+  EXPECT_TRUE(model.IsEnabledAt(organize_tabs_index));
+}
+
 TEST_F(TestAppMenuModelCR2023, ModelHasIcons) {
   // Skip the items that are either not supposed to have an icon, or are not
   // ready to be tested. Remove items once they're ready for testing.
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc
index e05fa9f3..f778132 100644
--- a/chrome/browser/ui/ui_features.cc
+++ b/chrome/browser/ui/ui_features.cc
@@ -195,7 +195,12 @@
 // Enables configuring tab hover card image previews in the settings.
 BASE_FEATURE(kTabHoverCardImageSettings,
              "TabHoverCardImageSettings",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+#if BUILDFLAG(IS_MAC)
+             base::FEATURE_DISABLED_BY_DEFAULT
+#else
+             base::FEATURE_ENABLED_BY_DEFAULT
+#endif
+);
 
 // Enables preview images in tab-hover cards.
 // https://crbug.com/928954
diff --git a/chrome/browser/ui/views/commerce/price_insights_icon_view.cc b/chrome/browser/ui/views/commerce/price_insights_icon_view.cc
index 6b55370d..c4a9190 100644
--- a/chrome/browser/ui/views/commerce/price_insights_icon_view.cc
+++ b/chrome/browser/ui/views/commerce/price_insights_icon_view.cc
@@ -127,6 +127,7 @@
     SetLabel(u"", l10n_util::GetStringUTF16(
                       IDS_SHOPPING_INSIGHTS_ICON_TOOLTIP_TEXT));
   }
+  SetPaintLabelOverSolidBackground(true);
 }
 
 void PriceInsightsIconView::AnimationProgressed(
diff --git a/chrome/browser/ui/views/download/download_shelf_context_menu_view.h b/chrome/browser/ui/views/download/download_shelf_context_menu_view.h
index ff24f90..1100b436 100644
--- a/chrome/browser/ui/views/download/download_shelf_context_menu_view.h
+++ b/chrome/browser/ui/views/download/download_shelf_context_menu_view.h
@@ -72,7 +72,7 @@
   base::TimeTicks close_time_;
 
   // Determines whether we should record if a DownloadCommand was executed.
-  bool download_commands_executed_recorded_[DownloadCommands::MAX + 1] = {
+  bool download_commands_executed_recorded_[DownloadCommands::kMaxValue + 1] = {
       false};
 };
 
diff --git a/chrome/browser/ui/views/enable_link_capturing_infobar_browsertest.cc b/chrome/browser/ui/views/enable_link_capturing_infobar_browsertest.cc
index 8796e31..aca6ff7 100644
--- a/chrome/browser/ui/views/enable_link_capturing_infobar_browsertest.cc
+++ b/chrome/browser/ui/views/enable_link_capturing_infobar_browsertest.cc
@@ -134,7 +134,7 @@
   }
 
   testing::AssertionResult ClickIntentPickerAndWaitForBubble() {
-    base::test::TestFuture<bool> future;
+    base::test::TestFuture<void> future;
     auto* tab_helper =
         IntentPickerTabHelper::FromWebContents(GetActiveWebContents(browser()));
     tab_helper->SetIconUpdateCallbackForTesting(
diff --git a/chrome/browser/ui/views/extensions/web_file_handlers/web_file_handlers_file_launch_browsertest.cc b/chrome/browser/ui/views/extensions/web_file_handlers/web_file_handlers_file_launch_browsertest.cc
index 1eefc92..74ef411 100644
--- a/chrome/browser/ui/views/extensions/web_file_handlers/web_file_handlers_file_launch_browsertest.cc
+++ b/chrome/browser/ui/views/extensions/web_file_handlers/web_file_handlers_file_launch_browsertest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include <memory>
+#include <string_view>
 #include <utility>
 #include <vector>
 
@@ -123,7 +124,7 @@
 
   // Load an extension with a few extra files for testing multiple-clients.
   const extensions::Extension* WriteCustomDirForFileHandlingExtension(
-      const std::string& manifest,
+      std::string_view manifest,
       const base::flat_map<std::string, std::string>& files) {
     extension_dir_.WriteManifest(manifest);
     for (const auto& [name, content] : files) {
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
index f6177c8..336b32c4 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.cc
@@ -16,6 +16,8 @@
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/color/chrome_color_id.h"
+#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
+#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
 #include "chrome/browser/ui/sad_tab_helper.h"
 #include "chrome/browser/ui/views/frame/browser_frame.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
@@ -648,12 +650,30 @@
 
   ImmersiveModeController* immersive_mode_controller =
       browser_view()->immersive_mode_controller();
-  const bool was_enabled = immersive_mode_controller->IsEnabled();
+  ExclusiveAccessManager* exclusive_access_manager =
+      browser_view()->browser()->exclusive_access_manager();
+
+  const bool was_immersive = immersive_mode_controller->IsEnabled();
+  const bool was_fullscreen =
+      exclusive_access_manager->context()->IsFullscreen();
+
+  // If fullscreen mode is not what it should be, toggle fullscreen mode.
+  if (ShouldEnableFullscreenMode() != was_fullscreen) {
+    exclusive_access_manager->fullscreen_controller()
+        ->ToggleBrowserFullscreenMode();
+  }
+
+  // Set immersive mode to what it should be. Note that we need to call this
+  // after updating fullscreen mode since it may override immersive mode to not
+  // wanted state (e.g. Non TabStrip frame with tablet mode enabled).
   immersive_mode_controller->SetEnabled(ShouldEnableImmersiveModeController());
 
-  // Do not relayout if immersive mode has not changed.
-  if (was_enabled == immersive_mode_controller->IsEnabled())
+  // Do not relayout if neither of immersive mode nor fullscreen mode has
+  // changed because the non client frame area will not change.
+  if (was_immersive == immersive_mode_controller->IsEnabled() &&
+      was_fullscreen == exclusive_access_manager->context()->IsFullscreen()) {
     return;
+  }
 
   InvalidateLayout();
   // Can be null in tests.
@@ -1214,6 +1234,10 @@
     // Tabbed browsers do not support immersive mode in tablet mode. We use the
     // web ui touchable tabstrip, which has its own sliding mechanism to view
     // the tabs.
+    // TODO(elkurin): TabStrip supports imemrsive mode now, but this code is
+    // needed to keep the expected behavior to disable immersive mode on
+    // entering tablet mode. We should remove this and explicitly exit immersive
+    // mode on this scenario for the readability.
     if (browser_view()->GetSupportsTabStrip())
       return false;
 
@@ -1229,6 +1253,35 @@
   return frame()->IsFullscreen();
 }
 
+bool BrowserNonClientFrameViewChromeOS::ShouldEnableFullscreenMode() const {
+  // In kiosk mode, we always want to be fullscreen.
+  if (chromeos::IsKioskSession()) {
+    return true;
+  }
+
+  // If user cannot exit fullscreen, we always want to be fullscreen. This must
+  // comes before the tablet mode condition since there is a case where the user
+  // is not allowed to exit fullscreen while tablet mode (LockedFullscreen).
+  if (!CanUserExitFullscreen()) {
+    return true;
+  }
+
+  if (chromeos::TabletState::Get()->InTabletMode()) {
+    // Tabbed browsers do not support immersive mode in tablet mode. We use the
+    // web ui touchable tabstrip, which has its own sliding mechanism to view
+    // the tabs.
+    // TODO(elkurin): TabStrip supports imemrsive mode now, but this code is
+    // needed to keep the expected behavior to disable immersive mode on
+    // entering tablet mode. We should remove this and explicitly exit immersive
+    // mode on this scenario for the readability.
+    if (browser_view()->GetSupportsTabStrip()) {
+      return false;
+    }
+  }
+
+  return frame()->IsFullscreen();
+}
+
 bool BrowserNonClientFrameViewChromeOS::UseWebUITabStrip() const {
   return WebUITabStripContainerView::UseTouchableTabStrip(
              browser_view()->browser()) &&
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.h
index a772754..cdc3bfdd 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.h
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.h
@@ -206,6 +206,9 @@
   // Helper to check whether we should enable immersive mode.
   bool ShouldEnableImmersiveModeController() const;
 
+  // Helper to check whether we should enable fullscreen mode.
+  bool ShouldEnableFullscreenMode() const;
+
   // True if the the associated browser window should be using the WebUI tab
   // strip.
   bool UseWebUITabStrip() const;
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
index a586b1ee..2cf504f4 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
@@ -1362,6 +1362,48 @@
   EXPECT_EQ(inset_normal, inset_in_overview_mode);
 }
 
+IN_PROC_BROWSER_TEST_P(BrowserNonClientFrameViewChromeOSTest,
+                       ToggleTabletModeWhileImmersiveModeEnabled) {
+  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
+  ImmersiveModeController* immersive_mode_controller =
+      browser_view->immersive_mode_controller();
+  ASSERT_FALSE(immersive_mode_controller->IsEnabled());
+  ASSERT_FALSE(browser_view->IsFullscreen());
+
+  // Enter immersive mode.
+  ToggleFullscreenModeAndWait(browser());
+  ASSERT_TRUE(immersive_mode_controller->IsEnabled());
+  ASSERT_TRUE(browser_view->IsFullscreen());
+
+  // Enable tablet mode.
+  ASSERT_NO_FATAL_FAILURE(
+      ash::ShellTestApi().SetTabletModeEnabledForTest(true));
+
+  // Should exit immersive mode + fullscreen when tablet mode is enabled.
+  EXPECT_FALSE(immersive_mode_controller->IsEnabled());
+  EXPECT_FALSE(browser_view->IsFullscreen());
+}
+
+IN_PROC_BROWSER_TEST_P(BrowserNonClientFrameViewChromeOSTest,
+                       ToggleImmersiveModeWhileTabletModeEnabled) {
+  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser());
+  ImmersiveModeController* immersive_mode_controller =
+      browser_view->immersive_mode_controller();
+  ASSERT_FALSE(immersive_mode_controller->IsEnabled());
+  ASSERT_FALSE(browser_view->IsFullscreen());
+
+  // Enter tablet mode.
+  ASSERT_NO_FATAL_FAILURE(
+      ash::ShellTestApi().SetTabletModeEnabledForTest(true));
+
+  // Enter immersive mode.
+  ToggleFullscreenModeAndWait(browser());
+  // Should be able to enter immersive mode even when the tablet mode is
+  // enabled.
+  ASSERT_TRUE(immersive_mode_controller->IsEnabled());
+  ASSERT_TRUE(browser_view->IsFullscreen());
+}
+
 // TODO(b/270175923): Consider using WebUiTabStripOverrideTest, since it
 // makes sense for it to always be enabled.
 using FloatBrowserNonClientFrameViewChromeOSTest =
@@ -1606,11 +1648,16 @@
   BrowserNonClientFrameViewChromeOS* frame_view =
       GetFrameViewChromeOS(browser_view);
   EXPECT_TRUE(frame_view->caption_button_container()->GetVisible());
+  ImmersiveModeController* immersive_mode_controller =
+      browser_view->immersive_mode_controller();
+  EXPECT_FALSE(immersive_mode_controller->IsEnabled());
 
   // Tablet mode doesn't affect app's caption button's visibility.
   ASSERT_NO_FATAL_FAILURE(
       ash::ShellTestApi().SetTabletModeEnabledForTest(true));
   EXPECT_TRUE(frame_view->caption_button_container()->GetVisible());
+  EXPECT_FALSE(browser_view->IsFullscreen());
+  EXPECT_TRUE(immersive_mode_controller->IsEnabled());
 
   // However, overview mode does.
   StartOverview();
@@ -1621,6 +1668,8 @@
   ASSERT_NO_FATAL_FAILURE(
       ash::ShellTestApi().SetTabletModeEnabledForTest(false));
   EXPECT_TRUE(frame_view->caption_button_container()->GetVisible());
+  EXPECT_FALSE(browser_view->IsFullscreen());
+  EXPECT_FALSE(immersive_mode_controller->IsEnabled());
 }
 
 namespace {
diff --git a/chrome/browser/ui/views/global_error_bubble_view.cc b/chrome/browser/ui/views/global_error_bubble_view.cc
index 698666d..011b3ae03 100644
--- a/chrome/browser/ui/views/global_error_bubble_view.cc
+++ b/chrome/browser/ui/views/global_error_bubble_view.cc
@@ -67,7 +67,7 @@
   WidgetDelegate::RegisterWindowClosingCallback(base::BindOnce(
       &GlobalErrorWithStandardBubble::BubbleViewDidClose, error_, browser));
 
-  SetDefaultButton(error_->GetDefaultDialogButton());
+  SetDefaultButton(ui::DIALOG_BUTTON_OK);
   SetButtons(!error_->GetBubbleViewCancelButtonLabel().empty()
                  ? (ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL)
                  : ui::DIALOG_BUTTON_OK);
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc
index 9eaae03..2e5a2105 100644
--- a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc
@@ -5,8 +5,8 @@
 #include <string>
 
 #include "base/functional/bind.h"
+#include "base/run_loop.h"
 #include "base/test/scoped_feature_list.h"
-#include "base/test/test_future.h"
 #include "build/build_config.h"
 #include "chrome/browser/apps/link_capturing/link_capturing_features.h"
 #include "chrome/browser/ui/browser.h"
@@ -47,11 +47,11 @@
 
   template <typename Action>
   void DoAndWaitForIntentPickerIconUpdate(Action action) {
-    base::test::TestFuture<bool> future;
+    base::RunLoop run_loop;
     auto* tab_helper = IntentPickerTabHelper::FromWebContents(GetWebContents());
-    tab_helper->SetIconUpdateCallbackForTesting(future.GetCallback());
+    tab_helper->SetIconUpdateCallbackForTesting(run_loop.QuitClosure());
     action();
-    EXPECT_TRUE(future.Wait()) << " intent picker icon did not update";
+    run_loop.Run();
   }
 
   content::WebContents* OpenNewTab(const GURL& url,
@@ -161,12 +161,12 @@
   auto* tab_helper = IntentPickerTabHelper::FromWebContents(GetWebContents());
   NavigateToLaunchingPage(browser());
 
-  base::test::TestFuture<bool> future;
-  tab_helper->SetIconUpdateCallbackForTesting(future.GetCallback());
+  base::RunLoop run_loop;
+  tab_helper->SetIconUpdateCallbackForTesting(run_loop.QuitClosure());
   TestTabActionDoesNotOpenAppWindow(
       in_scope_url, base::BindOnce(&ClickLinkAndWait, GetWebContents(),
                                    in_scope_url, LinkTarget::SELF, GetParam()));
-  EXPECT_TRUE(future.Get());
+  run_loop.Run();
 
   views::Button* intent_picker_icon = GetIntentPickerIcon();
   EXPECT_TRUE(intent_picker_icon->GetVisible());
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc
index 26a1641..3d0b8d60 100644
--- a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc
+++ b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_chromeos.cc
@@ -1,6 +1,9 @@
 // Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
+
+#include "base/memory/raw_ptr.h"
+#include "build/build_config.h"
 #include "chrome/browser/ui/views/intent_picker_bubble_view.h"
 
 #include <memory>
@@ -11,13 +14,10 @@
 #include "ash/components/arc/test/arc_util_test_support.h"
 #include "ash/components/arc/test/connection_holder_util.h"
 #include "ash/components/arc/test/fake_app_instance.h"
-#include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
 #include "base/scoped_observation.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_feature_list.h"
-#include "base/test/test_future.h"
-#include "build/build_config.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/link_capturing/link_capturing_features.h"
@@ -362,11 +362,11 @@
 
   template <typename Action>
   void DoAndWaitForIntentPickerIconUpdate(Action action) {
-    base::test::TestFuture<bool> test_future;
+    base::RunLoop run_loop;
     auto* tab_helper = IntentPickerTabHelper::FromWebContents(GetWebContents());
-    tab_helper->SetIconUpdateCallbackForTesting(test_future.GetCallback());
+    tab_helper->SetIconUpdateCallbackForTesting(run_loop.QuitClosure());
     action();
-    EXPECT_TRUE(test_future.Wait()) << " intent picker icon did not update";
+    run_loop.Run();
   }
 
  private:
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_mac.cc b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_mac.cc
index 833014e6..7afa9d7 100644
--- a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_mac.cc
+++ b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest_mac.cc
@@ -4,7 +4,6 @@
 
 #include <string>
 
-#include "base/test/test_future.h"
 #include "chrome/browser/apps/link_capturing/mac_intent_picker_helpers.h"
 #include "chrome/browser/ui/intent_picker_tab_helper.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
@@ -37,11 +36,11 @@
 
   template <typename Action>
   void DoAndWaitForIntentPickerIconUpdate(Action action) {
-    base::test::TestFuture<bool> test_future;
+    base::RunLoop run_loop;
     auto* tab_helper = IntentPickerTabHelper::FromWebContents(GetWebContents());
-    tab_helper->SetIconUpdateCallbackForTesting(test_future.GetCallback());
+    tab_helper->SetIconUpdateCallbackForTesting(run_loop.QuitClosure());
     action();
-    EXPECT_TRUE(test_future.Wait()) << " intent picker icon did not update";
+    run_loop.Run();
   }
 
   size_t GetItemContainerSize(IntentPickerBubbleView* bubble) {
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc
index 7af9581..bb81240 100644
--- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc
+++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.cc
@@ -116,20 +116,45 @@
 void CookieControlsBubbleViewController::ApplyThirdPartyCookiesAllowedState(
     base::Time expiration) {
   bool is_permanent_exception = expiration == base::Time();
-  bubble_view_->UpdateTitle(l10n_util::GetStringUTF16(
-      IDS_COOKIE_CONTROLS_BUBBLE_COOKIES_ALLOWED_TITLE));
+  std::u16string label_title;
+  int bubble_title, label_description;
+  if (latest_blocking_status_ == CookieBlocking3pcdStatus::kNotIn3pcd) {
+    bubble_title = IDS_COOKIE_CONTROLS_BUBBLE_COOKIES_ALLOWED_TITLE;
+    if (is_permanent_exception) {
+      label_title = l10n_util::GetStringUTF16(
+          IDS_COOKIE_CONTROLS_BUBBLE_PERMANENT_ALLOWED_TITLE);
+      label_description =
+          IDS_COOKIE_CONTROLS_BUBBLE_PERMANENT_ALLOWED_DESCRIPTION;
+    } else {
+      label_title = l10n_util::GetPluralStringFUTF16(
+          IDS_COOKIE_CONTROLS_BUBBLE_BLOCKING_RESTART_TITLE,
+          content_settings::CookieControlsUtil::GetDaysToExpiration(
+              expiration));
+      label_description =
+          IDS_COOKIE_CONTROLS_BUBBLE_BLOCKING_RESTART_DESCRIPTION_TODAY;
+    }
+  } else {
+    bubble_title = IDS_TRACKING_PROTECTION_BUBBLE_TITLE;
+    if (is_permanent_exception) {
+      label_title = l10n_util::GetStringUTF16(
+          IDS_TRACKING_PROTECTION_BUBBLE_PERMANENT_ALLOWED_TITLE);
+      label_description =
+          IDS_TRACKING_PROTECTION_BUBBLE_PERMANENT_ALLOWED_DESCRIPTION;
+    } else {
+      label_title = l10n_util::GetPluralStringFUTF16(
+          latest_blocking_status_ == CookieBlocking3pcdStatus::kAll
+              ? IDS_TRACKING_PROTECTION_BUBBLE_BLOCKING_RESTART_TITLE
+              : IDS_TRACKING_PROTECTION_BUBBLE_LIMITING_RESTART_TITLE,
+          content_settings::CookieControlsUtil::GetDaysToExpiration(
+              expiration));
+      label_description =
+          IDS_TRACKING_PROTECTION_BUBBLE_BLOCKING_RESTART_DESCRIPTION;
+    }
+  }
+
+  bubble_view_->UpdateTitle(l10n_util::GetStringUTF16(bubble_title));
   bubble_view_->GetContentView()->UpdateContentLabels(
-      is_permanent_exception
-          ? l10n_util::GetStringUTF16(
-                IDS_COOKIE_CONTROLS_BUBBLE_PERMANENT_ALLOWED_TITLE)
-          : l10n_util::GetPluralStringFUTF16(
-                IDS_COOKIE_CONTROLS_BUBBLE_BLOCKING_RESTART_TITLE,
-                content_settings::CookieControlsUtil::GetDaysToExpiration(
-                    expiration)),
-      l10n_util::GetStringUTF16(
-          is_permanent_exception
-              ? IDS_COOKIE_CONTROLS_BUBBLE_PERMANENT_ALLOWED_DESCRIPTION
-              : IDS_COOKIE_CONTROLS_BUBBLE_BLOCKING_RESTART_DESCRIPTION_TODAY));
+      label_title, l10n_util::GetStringUTF16(label_description));
   bubble_view_->GetContentView()->SetFeedbackSectionVisibility(true);
   bubble_view_->GetContentView()->SetToggleIsOn(true);
   bubble_view_->GetContentView()->SetToggleIcon(GetToggleIcon(true));
@@ -138,15 +163,24 @@
 void CookieControlsBubbleViewController::ApplyThirdPartyCookiesBlockedState() {
   auto default_exception_expiration =
       content_settings::features::kUserBypassUIExceptionExpiration.Get();
-  bubble_view_->UpdateTitle(l10n_util::GetStringUTF16(
-      IDS_COOKIE_CONTROLS_BUBBLE_COOKIES_BLOCKED_TITLE));
+  int label_title, label_description;
+  if (latest_blocking_status_ == CookieBlocking3pcdStatus::kNotIn3pcd) {
+    label_title = IDS_COOKIE_CONTROLS_BUBBLE_COOKIES_BLOCKED_TITLE;
+    label_description =
+        default_exception_expiration.is_zero()
+            ? IDS_COOKIE_CONTROLS_BUBBLE_SITE_NOT_WORKING_DESCRIPTION_PERMANENT
+            : IDS_COOKIE_CONTROLS_BUBBLE_SITE_NOT_WORKING_DESCRIPTION_TEMPORARY;
+  } else {
+    label_title = IDS_TRACKING_PROTECTION_BUBBLE_TITLE;
+    label_description =
+        IDS_TRACKING_PROTECTION_BUBBLE_SITE_NOT_WORKING_DESCRIPTION_PERMANENT;
+  }
+
+  bubble_view_->UpdateTitle(l10n_util::GetStringUTF16(label_title));
   bubble_view_->GetContentView()->UpdateContentLabels(
       l10n_util::GetStringUTF16(
           IDS_COOKIE_CONTROLS_BUBBLE_SITE_NOT_WORKING_TITLE),
-      l10n_util::GetStringUTF16(
-          default_exception_expiration.is_zero()
-              ? IDS_COOKIE_CONTROLS_BUBBLE_SITE_NOT_WORKING_DESCRIPTION_PERMANENT
-              : IDS_COOKIE_CONTROLS_BUBBLE_SITE_NOT_WORKING_DESCRIPTION_TEMPORARY));
+      l10n_util::GetStringUTF16(label_description));
   bubble_view_->GetContentView()->SetFeedbackSectionVisibility(false);
   bubble_view_->GetContentView()->SetToggleIsOn(false);
   bubble_view_->GetContentView()->SetToggleIcon(GetToggleIcon(false));
@@ -160,6 +194,9 @@
     CookieControlsEnforcement enforcement,
     CookieBlocking3pcdStatus blocking_status,
     base::Time expiration) {
+  latest_status_ = status;
+  latest_blocking_status_ = blocking_status;
+
   switch (status) {
     case CookieControlsStatus::kEnabled:
       ApplyThirdPartyCookiesBlockedState();
@@ -199,13 +236,29 @@
           bubble_view_->GetContentView()->SetEnforcedIconVisible(true);
       break;
   }
-
-  latest_status_ = status;
+  // If we're in 3PCD, update toggle label based on status.
+  if (latest_blocking_status_ != CookieBlocking3pcdStatus::kNotIn3pcd) {
+    int label;
+    if (latest_status_ == CookieControlsStatus::kDisabledForSite) {
+      label = IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_ALLOWED_LABEL;
+    } else {
+      label = latest_blocking_status_ == CookieBlocking3pcdStatus::kAll
+                  ? IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_BLOCKED_LABEL
+                  : IDS_TRACKING_PROTECTION_BUBBLE_COOKIES_LIMITED_LABEL;
+    }
+    bubble_view_->GetContentView()->SetToggleLabel(
+        l10n_util::GetStringUTF16(label));
+  }
 }
 
 void CookieControlsBubbleViewController::OnSitesCountChanged(
     int allowed_third_party_sites_count,
     int blocked_third_party_sites_count) {
+  // We don't surface site counts in the UB bubble for 3PCD instead we will set
+  // the label in `OnStatusChange`.
+  if (latest_blocking_status_ != CookieBlocking3pcdStatus::kNotIn3pcd) {
+    return;
+  }
   std::u16string label;
   switch (latest_status_) {
     case CookieControlsStatus::kEnabled:
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h
index 4a7be73..2cadb81 100644
--- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h
+++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_view_controller.h
@@ -72,6 +72,10 @@
   // The most recent status provided by the CookieControlsController. Cached
   // so that updates to site counts can use the appropriate label.
   CookieControlsStatus latest_status_ = CookieControlsStatus::kUninitialized;
+  // The most recent status provided by the CookieControlsController, used to
+  // determine the user's 3PCD status.
+  CookieBlocking3pcdStatus latest_blocking_status_ =
+      CookieBlocking3pcdStatus::kNotIn3pcd;
 
   raw_ptr<CookieControlsBubbleView> bubble_view_ = nullptr;
 
diff --git a/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc b/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc
index b680cdd..3211e07 100644
--- a/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc
@@ -11,7 +11,6 @@
 #include "base/scoped_observation.h"
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
-#include "base/test/test_future.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/apps/app_service/app_registry_cache_waiter.h"
@@ -72,11 +71,11 @@
   void DoAndWaitForIntentPickerIconUpdate(Action action) {
     content::WebContents* web_contents =
         browser()->tab_strip_model()->GetActiveWebContents();
-    base::test::TestFuture<bool> test_future;
+    base::RunLoop run_loop;
     auto* tab_helper = IntentPickerTabHelper::FromWebContents(web_contents);
-    tab_helper->SetIconUpdateCallbackForTesting(test_future.GetCallback());
+    tab_helper->SetIconUpdateCallbackForTesting(run_loop.QuitClosure());
     action();
-    EXPECT_TRUE(test_future.Wait());
+    run_loop.Run();
   }
 
   void OpenNewTab(const GURL& url) {
@@ -116,10 +115,10 @@
                                      const GURL& link_url) {
     auto* tab_helper = IntentPickerTabHelper::FromWebContents(web_contents);
 
-    base::test::TestFuture<bool> test_future;
-    tab_helper->SetIconUpdateCallbackForTesting(test_future.GetCallback());
+    base::RunLoop run_loop;
+    tab_helper->SetIconUpdateCallbackForTesting(run_loop.QuitClosure());
     ClickLinkAndWait(web_contents, link_url, LinkTarget::SELF, "");
-    EXPECT_TRUE(test_future.Wait());
+    run_loop.Run();
   }
 
   // Installs a web app on the same host as InstallTestWebApp(), but with "/" as
@@ -318,11 +317,11 @@
   auto* const web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   auto* const tab_helper = IntentPickerTabHelper::FromWebContents(web_contents);
-  base::test::TestFuture<bool> test_future;
-  tab_helper->SetIconUpdateCallbackForTesting(test_future.GetCallback());
+  base::RunLoop run_loop;
+  tab_helper->SetIconUpdateCallbackForTesting(run_loop.QuitClosure());
   tab_helper->MaybeShowIconForApps(
       {{apps::PickerEntryType::kWeb, ui::ImageModel(), "app_id", "Test app"}});
-  EXPECT_TRUE(test_future.Wait());
+  run_loop.Run();
 }
 
 bool IntentChipButtonBrowserUiTest::VerifyUi() {
diff --git a/chrome/browser/ui/views/page_info/page_info_view_factory.cc b/chrome/browser/ui/views/page_info/page_info_view_factory.cc
index 63c61e4..e8293142 100644
--- a/chrome/browser/ui/views/page_info/page_info_view_factory.cc
+++ b/chrome/browser/ui/views/page_info/page_info_view_factory.cc
@@ -504,8 +504,7 @@
       icon = &vector_icons::kStorageAccessIcon;
       break;
     case ContentSettingsType::AUTO_PICTURE_IN_PICTURE:
-      // TODO(https://crbug.com/1471051): Use real icon.
-      icon = &vector_icons::kSelectWindowIcon;
+      icon = &vector_icons::kPictureInPictureIcon;
       break;
     default:
       // All other |ContentSettingsType|s do not have icons on desktop or are
diff --git a/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc
index d97c43f..8929b1b5 100644
--- a/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_completion_status_metrics_browsertest.cc
@@ -94,11 +94,6 @@
                               "(function() { location.reload(); })();"));
   ASSERT_TRUE(WaitForObservedEvent());
 
-  // Make sure the metrics are logged correctly.
-  histogram_tester.ExpectUniqueSample(
-      "PaymentRequest.CheckoutFunnel.Aborted",
-      JourneyLogger::ABORT_REASON_MERCHANT_NAVIGATION, 1);
-
   // Make sure the correct events were logged.
   std::vector<base::Bucket> buckets =
       histogram_tester.GetAllSamples("PaymentRequest.Events");
@@ -158,11 +153,6 @@
                               "})();"));
   ASSERT_TRUE(WaitForObservedEvent());
 
-  // Make sure the metrics are logged correctly.
-  histogram_tester.ExpectUniqueSample(
-      "PaymentRequest.CheckoutFunnel.Aborted",
-      JourneyLogger::ABORT_REASON_MERCHANT_NAVIGATION, 1);
-
   // Make sure the correct events were logged.
   std::vector<base::Bucket> buckets =
       histogram_tester.GetAllSamples("PaymentRequest.Events");
@@ -222,11 +212,6 @@
   ASSERT_TRUE(content::ExecJs(GetActiveWebContents(), click_buy_button_js));
   ASSERT_TRUE(WaitForObservedEvent());
 
-  // Make sure the metrics are logged correctly.
-  histogram_tester.ExpectUniqueSample(
-      "PaymentRequest.CheckoutFunnel.Aborted",
-      JourneyLogger::ABORT_REASON_ABORTED_BY_MERCHANT, 1);
-
   // Make sure the correct events were logged.
   std::vector<base::Bucket> buckets =
       histogram_tester.GetAllSamples("PaymentRequest.Events");
@@ -281,11 +266,6 @@
   // Navigate away.
   NavigateTo("/payment_request_email_test.html");
 
-  // Make sure the metrics are logged correctly.
-  histogram_tester.ExpectUniqueSample(
-      "PaymentRequest.CheckoutFunnel.Aborted",
-      JourneyLogger::ABORT_REASON_USER_NAVIGATION, 1);
-
   // Make sure the correct events were logged.
   std::vector<base::Bucket> buckets =
       histogram_tester.GetAllSamples("PaymentRequest.Events");
@@ -341,11 +321,6 @@
   // Click on the cancel button.
   ClickOnCancel();
 
-  // Make sure the metrics are logged correctly.
-  histogram_tester.ExpectUniqueSample(
-      "PaymentRequest.CheckoutFunnel.Aborted",
-      JourneyLogger::ABORT_REASON_ABORTED_BY_USER, 1);
-
   // Make sure the correct events were logged.
   std::vector<base::Bucket> buckets =
       histogram_tester.GetAllSamples("PaymentRequest.Events");
@@ -403,11 +378,6 @@
   chrome::CloseTab(browser());
   ASSERT_TRUE(WaitForObservedEvent());
 
-  // Make sure the metrics are logged correctly.
-  histogram_tester.ExpectUniqueSample(
-      "PaymentRequest.CheckoutFunnel.Aborted",
-      JourneyLogger::ABORT_REASON_ABORTED_BY_USER, 1);
-
   // Make sure the correct events were logged.
   std::vector<base::Bucket> buckets =
       histogram_tester.GetAllSamples("PaymentRequest.Events");
@@ -464,11 +434,6 @@
   chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
   ASSERT_TRUE(WaitForObservedEvent());
 
-  // Make sure the metrics are logged correctly.
-  histogram_tester.ExpectUniqueSample(
-      "PaymentRequest.CheckoutFunnel.Aborted",
-      JourneyLogger::ABORT_REASON_USER_NAVIGATION, 1);
-
   // Make sure the correct events were logged.
   std::vector<base::Bucket> buckets =
       histogram_tester.GetAllSamples("PaymentRequest.Events");
@@ -515,11 +480,6 @@
   // Navigate away.
   NavigateTo("/payment_request_email_test.html");
 
-  // Make sure the metrics are logged correctly.
-  histogram_tester.ExpectUniqueSample(
-      "PaymentRequest.CheckoutFunnel.Aborted",
-      JourneyLogger::ABORT_REASON_USER_NAVIGATION, 1);
-
   // There is one sample, because the request was initiated.
   std::vector<base::Bucket> buckets =
       histogram_tester.GetAllSamples("PaymentRequest.Events");
diff --git a/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc
index b1214ef..1aa3000 100644
--- a/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_journey_logger_browsertest.cc
@@ -767,11 +767,6 @@
   // Navigate away to abort the Payment Request and trigger the logs.
   NavigateTo("/payment_request_email_test.html");
 
-  // Abort should be logged.
-  histogram_tester.ExpectBucketCount(
-      "PaymentRequest.CheckoutFunnel.Aborted",
-      JourneyLogger::ABORT_REASON_USER_NAVIGATION, 1);
-
   // Some events should be logged.
   std::vector<base::Bucket> buckets =
       histogram_tester.GetAllSamples("PaymentRequest.Events");
diff --git a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc
index 87c2e51..4fc048e 100644
--- a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc
+++ b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view.cc
@@ -146,8 +146,13 @@
   // Create the web view in the native bubble.
   std::unique_ptr<views::WebView> web_view =
       std::make_unique<views::WebView>(browser->profile());
-  // TODO(b/301431278): Use the new URL for the Chrome Signin intercept.
-  web_view->LoadInitialURL(GURL(chrome::kChromeUIDiceWebSigninInterceptURL));
+  GURL intercept_url =
+      bubble_parameters_.interception_type ==
+              WebSigninInterceptor::SigninInterceptionType::kChromeSignin
+          ? GURL(chrome::kChromeUIDiceWebSigninInterceptChromeSigninURL)
+          : GURL(chrome::kChromeUIDiceWebSigninInterceptURL);
+  web_view->LoadInitialURL(intercept_url);
+
   web_view->GetWebContents()->SetDelegate(this);
   web_view->SetPreferredSize(
       gfx::Size(kInterceptionBubbleWidth, kInterceptionBubbleBaseHeight));
diff --git a/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc b/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc
index 9f47e9a21..965b258 100644
--- a/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc
+++ b/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc
@@ -2216,8 +2216,19 @@
   EXPECT_EQ(0u, requests_received_on_server());
 }
 
+// TODO(crbug.com/1491942): This fails with the field trial testing config.
+class SidePanelCompanion2BrowserEnabledTestNoTestingConfig
+    : public SidePanelCompanion2BrowserEnabledTest {
+ public:
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    SidePanelCompanion2BrowserEnabledTest::SetUpCommandLine(command_line);
+    command_line->AppendSwitch("disable-field-trial-config");
+  }
+};
+
 // Verify that Companion is enabled when `kSidePanelCompanion2` is enabled.
-IN_PROC_BROWSER_TEST_F(SidePanelCompanion2BrowserEnabledTest, FeatureEnabled) {
+IN_PROC_BROWSER_TEST_F(SidePanelCompanion2BrowserEnabledTestNoTestingConfig,
+                       FeatureEnabled) {
   EXPECT_TRUE(companion::IsCompanionFeatureEnabled());
 
   // Load a page on the active tab and open companion side panel
diff --git a/chrome/browser/ui/views/tabs/tab_icon.cc b/chrome/browser/ui/views/tabs/tab_icon.cc
index 64853977..dc77699 100644
--- a/chrome/browser/ui/views/tabs/tab_icon.cc
+++ b/chrome/browser/ui/views/tabs/tab_icon.cc
@@ -38,6 +38,7 @@
 #include "ui/views/border.h"
 #include "ui/views/cascading_property.h"
 #include "ui/views/interaction/element_tracker_views.h"
+#include "ui/views/widget/widget.h"
 #include "url/gurl.h"
 
 namespace {
@@ -308,7 +309,12 @@
 
   // Painting Discard Ring
   const ui::ColorProvider* color_provider = GetColorProvider();
-  SkColor ring_color = color_provider->GetColor(ui::kColorSysStateDisabled);
+  const views::Widget* widget = GetWidget();
+  SkColor ring_color =
+      color_provider->GetColor(widget && widget->ShouldPaintAsActive()
+                                   ? kColorTabDiscardRingFrameActive
+                                   : kColorTabDiscardRingFrameInactive);
+
   float ring_color_opacity =
       static_cast<float>(SkColorGetA(ring_color)) / SK_AlphaOPAQUE;
   cc::PaintFlags flags;
diff --git a/chrome/browser/ui/views/user_education/browser_user_education_service.cc b/chrome/browser/ui/views/user_education/browser_user_education_service.cc
index 488a311..ee1e29e 100644
--- a/chrome/browser/ui/views/user_education/browser_user_education_service.cc
+++ b/chrome/browser/ui/views/user_education/browser_user_education_service.cc
@@ -540,6 +540,29 @@
       &feature_engagement::kIPHTabSearchFeature, kTabSearchButtonElementId,
       IDS_TAB_SEARCH_PROMO));
 
+  // Tracking Protection Offboarding IPH
+  registry.RegisterFeature(std::move(
+      FeaturePromoSpecification::CreateForCustomAction(
+          feature_engagement::kIPHTrackingProtectionOffboardingFeature,
+          kLocationIconElementId,
+          IDS_TRACKING_PROTECTION_OFFBOARDING_NOTICE_BODY,
+          IDS_TRACKING_PROTECTION_ONBOARDING_NOTICE_SETTINGS_BUTTON_LABEL,
+          base::BindRepeating(
+              [](ui::ElementContext ctx,
+                 user_education::FeaturePromoHandle promo_handle) {
+                auto* browser = chrome::FindBrowserWithUiElementContext(ctx);
+                if (!browser) {
+                  return;
+                }
+                chrome::ShowSettingsSubPage(browser,
+                                            chrome::kCookieSettingsSubPage);
+              }))
+          .SetBubbleTitleText(IDS_TRACKING_PROTECTION_OFFBOARDING_NOTICE_TITLE)
+          .SetPromoSubtype(
+              FeaturePromoSpecification::PromoSubtype::kLegalNotice)
+          .SetBubbleArrow(HelpBubbleArrow::kTopLeft)
+          .SetCustomActionIsDefault(false)));
+
   // Tracking Protection Onboarding IPH
   registry.RegisterFeature(std::move(
       FeaturePromoSpecification::CreateForCustomAction(
diff --git a/chrome/browser/ui/web_applications/isolated_web_apps/DIR_METADATA b/chrome/browser/ui/views/web_apps/isolated_web_apps/DIR_METADATA
similarity index 100%
rename from chrome/browser/ui/web_applications/isolated_web_apps/DIR_METADATA
rename to chrome/browser/ui/views/web_apps/isolated_web_apps/DIR_METADATA
diff --git a/chrome/browser/ui/web_applications/isolated_web_apps/OWNERS b/chrome/browser/ui/views/web_apps/isolated_web_apps/OWNERS
similarity index 100%
rename from chrome/browser/ui/web_applications/isolated_web_apps/OWNERS
rename to chrome/browser/ui/views/web_apps/isolated_web_apps/OWNERS
diff --git a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_coordinator.cc b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_coordinator.cc
similarity index 64%
rename from chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_coordinator.cc
rename to chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_coordinator.cc
index b1a17df..f5af315d 100644
--- a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_coordinator.cc
+++ b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_coordinator.cc
@@ -2,21 +2,35 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_coordinator.h"
+#include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_coordinator.h"
+
+#include <memory>
 
 #include "base/files/file_path.h"
 #include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/task/single_thread_task_runner.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_model.h"
-#include "chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view_controller.h"
+#include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_model.h"
+#include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "components/webapps/common/web_app_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace web_app {
 
+void LaunchIsolatedWebAppInstaller(Profile* profile,
+                                   const base::FilePath& bundle_path) {
+  auto coordinator = std::make_unique<IsolatedWebAppInstallerCoordinator>(
+      profile, bundle_path);
+  IsolatedWebAppInstallerCoordinator* raw_coordinator = coordinator.get();
+  base::OnceClosure delete_callback =
+      base::DoNothingWithBoundArgs(std::move(coordinator));
+  raw_coordinator->Show(base::IgnoreArgs<absl::optional<webapps::AppId>>(
+      std::move(delete_callback)));
+}
+
 IsolatedWebAppInstallerCoordinator::IsolatedWebAppInstallerCoordinator(
     Profile* profile,
     const base::FilePath& bundle_path)
diff --git a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_coordinator.h b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_coordinator.h
similarity index 76%
rename from chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_coordinator.h
rename to chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_coordinator.h
index c7564d2..95af4088 100644
--- a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_coordinator.h
+++ b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_coordinator.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_COORDINATOR_H_
-#define CHROME_BROWSER_UI_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_COORDINATOR_H_
+#ifndef CHROME_BROWSER_UI_VIEWS_WEB_APPS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_COORDINATOR_H_
+#define CHROME_BROWSER_UI_VIEWS_WEB_APPS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_COORDINATOR_H_
 
 #include <memory>
 
@@ -41,4 +41,4 @@
 
 }  // namespace web_app
 
-#endif  // CHROME_BROWSER_UI_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_COORDINATOR_H_
+#endif  // CHROME_BROWSER_UI_VIEWS_WEB_APPS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_COORDINATOR_H_
diff --git a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_model.cc b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_model.cc
similarity index 89%
rename from chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_model.cc
rename to chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_model.cc
index d76953d..725cee3 100644
--- a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_model.cc
+++ b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_model.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_model.h"
+#include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_model.h"
 
 #include <string>
 
diff --git a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_model.h b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_model.h
similarity index 82%
rename from chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_model.h
rename to chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_model.h
index cbe96b4..420f3bb 100644
--- a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_model.h
+++ b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_model.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_MODEL_H_
-#define CHROME_BROWSER_UI_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_MODEL_H_
+#ifndef CHROME_BROWSER_UI_VIEWS_WEB_APPS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_MODEL_H_
+#define CHROME_BROWSER_UI_VIEWS_WEB_APPS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_MODEL_H_
 
 #include <string>
 
@@ -54,4 +54,4 @@
 
 }  // namespace web_app
 
-#endif  // CHROME_BROWSER_UI_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_MODEL_H_
+#endif  // CHROME_BROWSER_UI_VIEWS_WEB_APPS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_MODEL_H_
diff --git a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view.cc b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view.cc
similarity index 93%
rename from chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view.cc
rename to chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view.cc
index 49b6618..b5abe59d 100644
--- a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view.cc
+++ b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view.cc
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view.h"
+#include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view.h"
 
-#include "chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_model.h"
+#include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_model.h"
 #include "chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_metadata.h"
 #include "chrome/grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view.h b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view.h
similarity index 81%
rename from chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view.h
rename to chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view.h
index 2a249f4..fd85445 100644
--- a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view.h
+++ b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view.h
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_VIEW_H_
-#define CHROME_BROWSER_UI_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_VIEW_H_
+#ifndef CHROME_BROWSER_UI_VIEWS_WEB_APPS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_VIEW_H_
+#define CHROME_BROWSER_UI_VIEWS_WEB_APPS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_VIEW_H_
 
 #include "base/memory/raw_ptr.h"
-#include "chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_model.h"
+#include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_model.h"
 #include "chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_metadata.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/views/layout/box_layout_view.h"
@@ -62,4 +62,4 @@
 
 }  // namespace web_app
 
-#endif  // CHROME_BROWSER_UI_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_VIEW_H_
+#endif  // CHROME_BROWSER_UI_VIEWS_WEB_APPS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_VIEW_H_
diff --git a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view_controller.cc b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.cc
similarity index 93%
rename from chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view_controller.cc
rename to chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.cc
index d4ee846..ea8ecb4 100644
--- a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view_controller.cc
+++ b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view_controller.h"
+#include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.h"
 
 #include <memory>
 
 #include "base/functional/callback.h"
 #include "base/logging.h"
-#include "chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_model.h"
-#include "chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view.h"
+#include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_model.h"
+#include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view.h"
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/webapps/common/web_app_id.h"
diff --git a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view_controller.h b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.h
similarity index 79%
rename from chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view_controller.h
rename to chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.h
index c01beb0..79a30c1 100644
--- a/chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view_controller.h
+++ b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_VIEW_CONTROLLER_H_
-#define CHROME_BROWSER_UI_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_VIEW_CONTROLLER_H_
+#ifndef CHROME_BROWSER_UI_VIEWS_WEB_APPS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_VIEW_CONTROLLER_H_
+#define CHROME_BROWSER_UI_VIEWS_WEB_APPS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_VIEW_CONTROLLER_H_
 
 #include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
-#include "chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_view.h"
+#include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view.h"
 
 namespace views {
 class DialogDelegate;
@@ -58,4 +58,4 @@
 
 }  // namespace web_app
 
-#endif  // CHROME_BROWSER_UI_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_VIEW_CONTROLLER_H_
+#endif  // CHROME_BROWSER_UI_VIEWS_WEB_APPS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_INSTALLER_VIEW_CONTROLLER_H_
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
index ef17268..b643565 100644
--- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
@@ -25,8 +25,6 @@
 #include "base/memory/raw_ptr.h"
 #include "base/notreached.h"
 #include "base/path_service.h"
-#include "base/run_loop.h"
-#include "base/scoped_observation.h"
 #include "base/strings/pattern.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_util.h"
@@ -63,7 +61,6 @@
 #include "chrome/browser/ui/views/frame/toolbar_button_provider.h"
 #include "chrome/browser/ui/views/intent_picker_bubble_view.h"
 #include "chrome/browser/ui/views/location_bar/custom_tab_bar_view.h"
-#include "chrome/browser/ui/views/location_bar/intent_chip_button.h"
 #include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
 #include "chrome/browser/ui/views/page_info/page_info_bubble_view.h"
 #include "chrome/browser/ui/views/page_info/page_info_view_factory.h"
@@ -145,10 +142,7 @@
 #include "third_party/blink/public/mojom/manifest/display_mode.mojom-shared.h"
 #include "third_party/re2/src/re2/re2.h"
 #include "ui/accessibility/ax_action_data.h"
-#include "ui/events/event.h"
-#include "ui/gfx/geometry/point.h"
 #include "ui/views/controls/button/image_button.h"
-#include "ui/views/test/button_test_api.h"
 #include "ui/views/test/dialog_test.h"
 #include "ui/views/test/widget_test.h"
 #include "ui/views/widget/widget.h"
@@ -743,25 +737,6 @@
 
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 
-class IntentChipVisibilityObserver : public OmniboxChipButton::Observer {
- public:
-  explicit IntentChipVisibilityObserver(IntentChipButton* intent_chip) {
-    observation_.Observe(intent_chip);
-  }
-
-  void WaitForChipToBeVisible() { run_loop_.Run(); }
-  void OnChipVisibilityChanged(bool is_visible) override {
-    if (is_visible) {
-      run_loop_.Quit();
-    }
-  }
-
- private:
-  base::ScopedObservation<IntentChipButton, OmniboxChipButton::Observer>
-      observation_{this};
-  base::RunLoop run_loop_;
-};
-
 }  // anonymous namespace
 
 BrowserState::BrowserState(
@@ -1677,14 +1652,20 @@
 
   NavigateTabbedBrowserToSite(GetInScopeURL(site), NavigationMode::kNewTab);
 
+  ASSERT_TRUE(intent_picker_view()->GetVisible());
   BrowserAddedWaiter browser_added_waiter;
-  views::NamedWidgetShownWaiter waiter(views::test::AnyWidgetTestPasskey{},
-                                       IntentPickerBubbleView::kViewClassName);
-  views::test::ButtonTestApi test_api(intent_picker_view());
-  test_api.NotifyClick(ui::MouseEvent(
-      ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), base::TimeTicks(),
-      ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON));
-  waiter.WaitIfNeededAndGet();
+
+  if (IntentPickerBubbleView::intent_picker_bubble()) {
+    // This means that the intent_picker_bubble has shown up before the scoped
+    // response was provided. Manually accept the bubble.
+    IntentPickerBubbleView::intent_picker_bubble()->AcceptDialog();
+  } else {
+    views::NamedWidgetShownWaiter waiter(
+        views::test::AnyWidgetTestPasskey{},
+        IntentPickerBubbleView::kViewClassName);
+    intent_picker_view()->ExecuteForTesting();
+    waiter.WaitIfNeededAndGet();
+  }
 
   browser_added_waiter.Wait();
   app_browser_ = browser_added_waiter.browser_added();
@@ -4016,7 +3997,13 @@
       bool launch_icon_shown = false;
       bool is_app_browser = AppBrowserController::IsWebApp(browser);
       if (!is_app_browser && active_tab != nullptr) {
-        AwaitIntentPickerIconInit();
+        auto* tab_helper = IntentPickerTabHelper::FromWebContents(active_tab);
+        base::RunLoop run_loop;
+        tab_helper->SetIconUpdateCallbackForTesting(
+            run_loop.QuitClosure(),
+            /*include_latest_navigation*/ true);
+        run_loop.Run();
+
         launch_icon_shown = intent_picker_view()->GetVisible();
       }
       webapps::AppId app_id;
@@ -4557,73 +4544,15 @@
   return pwa_install_view;
 }
 
-views::Button* WebAppIntegrationTestDriver::intent_picker_view() {
-  views::Button* intent_picker_view = nullptr;
-  if (apps::features::LinkCapturingUiUpdateEnabled()) {
-    intent_picker_view = BrowserView::GetBrowserViewForBrowser(browser())
-                             ->toolbar_button_provider()
-                             ->GetIntentChipButton();
-  } else {
-    intent_picker_view =
-        BrowserView::GetBrowserViewForBrowser(browser())
-            ->toolbar_button_provider()
-            ->GetPageActionIconView(PageActionIconType::kIntentPicker);
-  }
+PageActionIconView* WebAppIntegrationTestDriver::intent_picker_view() {
+  PageActionIconView* intent_picker_view =
+      BrowserView::GetBrowserViewForBrowser(browser())
+          ->toolbar_button_provider()
+          ->GetPageActionIconView(PageActionIconType::kIntentPicker);
   CHECK(intent_picker_view);
   return intent_picker_view;
 }
 
-testing::AssertionResult
-WebAppIntegrationTestDriver::AwaitIntentPickerIconInit() {
-  base::test::TestFuture<bool> future;
-  auto* tab_helper = IntentPickerTabHelper::FromWebContents(
-      browser()->tab_strip_model()->GetActiveWebContents());
-  tab_helper->SetIconUpdateCallbackForTesting(
-      future.GetCallback(), /*include_latest_navigation=*/true);
-  if (!future.Wait()) {
-    return testing::AssertionFailure()
-           << "Intent picker app did not resolve an applicable app.";
-  }
-
-  views::Button* intent_picker_icon = intent_picker_view();
-  if (!intent_picker_icon) {
-    return testing::AssertionFailure() << "Intent picker icon does not exist.";
-  }
-
-  // The callback from IntentPickerTabHelper returning true is an indication
-  // that app icons have been loaded and an asynchronous wait might be needed
-  // for the intent picker to load.
-  if (future.Get()) {
-    testing::AssertionResult intent_visible_result =
-        WaitForIntentPickerIconToBeVisible();
-    if (!intent_visible_result) {
-      return intent_visible_result;
-    }
-  }
-
-  return testing::AssertionSuccess();
-}
-
-testing::AssertionResult
-WebAppIntegrationTestDriver::WaitForIntentPickerIconToBeVisible() {
-  views::Button* intent_picker_view_button = intent_picker_view();
-  if (!intent_picker_view_button->GetVisible() &&
-      apps::features::LinkCapturingUiUpdateEnabled()) {
-    // The views::Button element can only be static casted to an
-    // IntentChipButton if the link capturing flag is switched on, otherwise, it
-    // is a PageActionIconView and cannot be static casted.
-    IntentChipVisibilityObserver intent_chip_observer(
-        static_cast<IntentChipButton*>(intent_picker_view_button));
-    intent_chip_observer.WaitForChipToBeVisible();
-    if (!intent_picker_view_button->GetVisible()) {
-      return testing::AssertionFailure()
-             << "Intent picker chip never became visible.";
-    }
-  }
-
-  return testing::AssertionSuccess();
-}
-
 const net::EmbeddedTestServer&
 WebAppIntegrationTestDriver::GetTestServerForSiteMode(Site site) const {
   return *delegate_->EmbeddedTestServer();
@@ -4654,6 +4583,10 @@
   // TODO(crbug.com/1462253): Also test with Lacros flags enabled.
   base::Extend(disabled_features, ash::standalone_browser::GetFeatureRefs());
 #endif
+#if BUILDFLAG(IS_CHROMEOS)
+  // TODO(crbug.com/1357905): Update test driver to work with new UI.
+  disabled_features.push_back(apps::features::kLinkCapturingUiUpdate);
+#endif  // BUILDFLAG(IS_CHROMEOS)
   scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
 }
 
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h
index 06ccc5a..475f30c 100644
--- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h
+++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.h
@@ -31,7 +31,6 @@
 #include "components/webapps/browser/install_result_code.h"
 #include "components/webapps/common/web_app_id.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
-#include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/views/widget/any_widget_observer.h"
 #include "url/gurl.h"
@@ -495,9 +494,7 @@
   Browser* app_browser() { return app_browser_; }
   WebAppProvider* provider() { return WebAppProvider::GetForTest(profile()); }
   PageActionIconView* pwa_install_view();
-  testing::AssertionResult AwaitIntentPickerIconInit();
-  testing::AssertionResult WaitForIntentPickerIconToBeVisible();
-  views::Button* intent_picker_view();
+  PageActionIconView* intent_picker_view();
 
   const net::EmbeddedTestServer& GetTestServerForSiteMode(Site site_mode) const;
 
diff --git a/chrome/browser/ui/web_applications/web_app_dialogs.h b/chrome/browser/ui/web_applications/web_app_dialogs.h
index 5946217..dbeed51e 100644
--- a/chrome/browser/ui/web_applications/web_app_dialogs.h
+++ b/chrome/browser/ui/web_applications/web_app_dialogs.h
@@ -170,6 +170,10 @@
 // user interaction.
 void SetAutoAcceptPWAInstallConfirmationForTesting(bool auto_accept);
 
+// Shows the Isolated Web App manual install wizard.
+void LaunchIsolatedWebAppInstaller(Profile* profile,
+                                   const base::FilePath& bundle_path);
+
 }  // namespace web_app
 
 #endif  // CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_DIALOGS_H_
diff --git a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc
index e844c61..daa8f4d 100644
--- a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc
+++ b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc
@@ -35,7 +35,6 @@
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/browser/ui/web_applications/app_browser_controller.h"
 #include "chrome/browser/ui/web_applications/commands/launch_web_app_command.h"
-#include "chrome/browser/ui/web_applications/isolated_web_apps/isolated_web_app_installer_coordinator.h"
 #include "chrome/browser/ui/web_applications/web_app_dialog_utils.h"
 #include "chrome/browser/ui/web_applications/web_app_dialogs.h"
 #include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
@@ -62,6 +61,13 @@
 #include "url/origin.h"
 #include "url/url_constants.h"
 
+#if !BUILDFLAG(IS_CHROMEOS)
+#include "chrome/browser/apps/link_capturing/enable_link_capturing_infobar_delegate.h"
+#include "chrome/browser/infobars/confirm_infobar_creator.h"
+#include "components/infobars/content/content_infobar_manager.h"
+#include "components/infobars/core/infobar.h"
+#endif  // !BUILDFLAG(IS_CHROMEOS)
+
 #if !BUILDFLAG(IS_MAC)
 #include "ui/aura/window.h"
 #endif  // !BUILDFLAG(IS_MAC)
@@ -466,21 +472,21 @@
 
 void WebAppUiManagerImpl::LaunchIsolatedWebAppInstaller(
     const base::FilePath& bundle_path) {
-  auto installer = std::make_unique<IsolatedWebAppInstallerCoordinator>(
-      profile_, bundle_path);
-  IsolatedWebAppInstallerCoordinator* installer_ptr = installer.get();
-  isolated_web_app_installers_.insert(std::move(installer));
-
-  installer_ptr->Show(base::BindOnce(
-      &WebAppUiManagerImpl::OnIsolatedWebAppInstallerClosed,
-      weak_ptr_factory_.GetWeakPtr(), base::Unretained(installer_ptr)));
+  ::web_app::LaunchIsolatedWebAppInstaller(profile_, bundle_path);
 }
 
-void WebAppUiManagerImpl::OnIsolatedWebAppInstallerClosed(
-    IsolatedWebAppInstallerCoordinator* installer,
-    absl::optional<webapps::AppId> result) {
-  isolated_web_app_installers_.erase(
-      isolated_web_app_installers_.find(installer));
+void WebAppUiManagerImpl::MaybeCreateEnableSupportedLinksInfobar(
+    content::WebContents* web_contents,
+    const std::string& launch_name) {
+#if !BUILDFLAG(IS_CHROMEOS)
+  std::unique_ptr<apps::EnableLinkCapturingInfoBarDelegate> delegate =
+      apps::EnableLinkCapturingInfoBarDelegate::MaybeCreate(web_contents,
+                                                            launch_name);
+  if (delegate) {
+    infobars::ContentInfoBarManager::FromWebContents(web_contents)
+        ->AddInfoBar(CreateConfirmInfoBar(std::move(delegate)));
+  }
+#endif  // !BUILDFLAG(IS_CHROMEOS)
 }
 
 void WebAppUiManagerImpl::OnBrowserAdded(Browser* browser) {
diff --git a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.h b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.h
index 2b48c51..beb511a 100644
--- a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.h
+++ b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.h
@@ -8,11 +8,9 @@
 #include <stddef.h>
 #include <map>
 #include <memory>
-#include <set>
 #include <string>
 #include <vector>
 
-#include "base/containers/unique_ptr_adapters.h"
 #include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
@@ -52,7 +50,6 @@
 namespace web_app {
 
 class AppLock;
-class IsolatedWebAppInstallerCoordinator;
 
 // Implementation of WebAppUiManager that depends upon //c/b/ui.
 // Allows //c/b/web_applications code to call into //c/b/ui without directly
@@ -143,6 +140,10 @@
   void LaunchIsolatedWebAppInstaller(
       const base::FilePath& bundle_path) override;
 
+  void MaybeCreateEnableSupportedLinksInfobar(
+      content::WebContents* web_contents,
+      const std::string& launch_name) override;
+
   // BrowserListObserver:
   void OnBrowserAdded(Browser* browser) override;
   void OnBrowserRemoved(Browser* browser) override;
@@ -188,17 +189,10 @@
       UninstallCompleteCallback uninstall_complete_callback,
       webapps::UninstallResultCode uninstall_code);
 
-  void OnIsolatedWebAppInstallerClosed(
-      IsolatedWebAppInstallerCoordinator* installer,
-      absl::optional<webapps::AppId> result);
-
   const raw_ptr<Profile> profile_;
   std::map<webapps::AppId, std::vector<base::OnceClosure>>
       windows_closed_requests_map_;
   std::map<webapps::AppId, size_t> num_windows_for_apps_map_;
-  std::set<std::unique_ptr<IsolatedWebAppInstallerCoordinator>,
-           base::UniquePtrComparator>
-      isolated_web_app_installers_;
   bool started_ = false;
 
   base::WeakPtrFactory<WebAppUiManagerImpl> weak_ptr_factory_{this};
diff --git a/chrome/browser/ui/webui/app_service_internals/app_service_internals_page_handler_impl.cc b/chrome/browser/ui/webui/app_service_internals/app_service_internals_page_handler_impl.cc
index 5285911..f614da6 100644
--- a/chrome/browser/ui/webui/app_service_internals/app_service_internals_page_handler_impl.cc
+++ b/chrome/browser/ui/webui/app_service_internals/app_service_internals_page_handler_impl.cc
@@ -15,7 +15,6 @@
 #include "base/ranges/algorithm.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
-#include "chrome/browser/apps/app_service/package_id.h"
 #include "chrome/browser/ui/webui/app_service_internals/app_service_internals.mojom-forward.h"
 #include "chrome/browser/ui/webui/app_service_internals/app_service_internals.mojom.h"
 #include "chrome/common/chrome_features.h"
@@ -23,6 +22,7 @@
 #include "components/services/app_service/public/cpp/capability_access_update.h"
 #include "components/services/app_service/public/cpp/intent_filter_util.h"
 #include "components/services/app_service/public/cpp/intent_util.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 #include "components/services/app_service/public/cpp/preferred_app.h"
 #include "third_party/abseil-cpp/absl/utility/utility.h"
 
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/cloud_open_metrics.cc b/chrome/browser/ui/webui/ash/cloud_upload/cloud_open_metrics.cc
index 2385dda6..967f0151 100644
--- a/chrome/browser/ui/webui/ash/cloud_upload/cloud_open_metrics.cc
+++ b/chrome/browser/ui/webui/ash/cloud_upload/cloud_open_metrics.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "base/debug/dump_without_crashing.h"
 #include "chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_util.h"
 
 namespace ash::cloud_upload {
@@ -83,19 +84,139 @@
   bool google_drive = cloud_provider_ == CloudProvider::kGoogleDrive;
   // TODO(cassycc): Add the rest of inconsistency checks.
   ExpectLogged(task_result_);
-  if (task_result_.logged() &&
-      (task_result_.value == OfficeTaskResult::kFallbackQuickOffice ||
-       task_result_.value == OfficeTaskResult::kCancelledAtFallback)) {
-    if (google_drive) {
-      ExpectLoggedWith(drive_open_error_,
-                       {OfficeDriveOpenErrors::kOffline,
-                        OfficeDriveOpenErrors::kDriveFsInterface});
+  if (task_result_.logged()) {
+    if (task_result_.value == OfficeTaskResult::kFallbackQuickOffice ||
+        task_result_.value == OfficeTaskResult::kCancelledAtFallback) {
+      ExpectNotLogged(transfer_required_);
+      ExpectNotLogged(upload_result_);
+      if (google_drive) {
+        ExpectLoggedWith(drive_open_error_,
+                         {OfficeDriveOpenErrors::kOffline,
+                          OfficeDriveOpenErrors::kDriveFsInterface});
+      } else {
+        ExpectLoggedWith(one_drive_open_error_,
+                         {OfficeOneDriveOpenErrors::kOffline});
+      }
     } else {
-      ExpectLoggedWith(one_drive_open_error_,
-                       {OfficeOneDriveOpenErrors::kOffline});
+      ExpectLogged(source_volume_);
+      ExpectLogged(transfer_required_);
+      if (task_result_.value == OfficeTaskResult::kCancelledAtConfirmation) {
+        ExpectLoggedWith(transfer_required_,
+                         {OfficeFilesTransferRequired::kCopy,
+                          OfficeFilesTransferRequired::kMove});
+        ExpectNotLogged(upload_result_);
+        ExpectNotLogged(drive_open_error_);
+        ExpectNotLogged(one_drive_open_error_);
+      } else if (task_result_.value == OfficeTaskResult::kFailedToOpen) {
+        if (google_drive) {
+          ExpectNotLoggedWith(drive_open_error_,
+                              {OfficeDriveOpenErrors::kSuccess});
+        } else {
+          ExpectNotLoggedWith(one_drive_open_error_,
+                              {OfficeOneDriveOpenErrors::kSuccess});
+        }
+      } else if (task_result_.value == OfficeTaskResult::kOpened ||
+                 task_result_.value == OfficeTaskResult::kCopied ||
+                 task_result_.value == OfficeTaskResult::kMoved) {
+        if (google_drive) {
+          ExpectLoggedWith(drive_open_error_,
+                           {OfficeDriveOpenErrors::kSuccess});
+        } else {
+          ExpectLoggedWith(one_drive_open_error_,
+                           {OfficeOneDriveOpenErrors::kSuccess});
+        }
+        if (task_result_.value == OfficeTaskResult::kOpened) {
+          ExpectNotLogged(upload_result_);
+          ExpectLoggedWith(transfer_required_,
+                           {OfficeFilesTransferRequired::kNotRequired});
+        } else {
+          ExpectLoggedWith(upload_result_, {OfficeFilesUploadResult::kSuccess});
+          if (task_result_.value == OfficeTaskResult::kCopied) {
+            ExpectLoggedWith(transfer_required_,
+                             {OfficeFilesTransferRequired::kCopy});
+          } else {
+            ExpectLoggedWith(transfer_required_,
+                             {OfficeFilesTransferRequired::kMove});
+          }
+        }
+      }
     }
-    ExpectNotLogged(transfer_required_);
-    ExpectNotLogged(upload_result_);
+  }
+
+  if (transfer_required_.logged()) {
+    if (transfer_required_.value == OfficeFilesTransferRequired::kNotRequired) {
+      ExpectNotLogged(upload_result_);
+      if (google_drive) {
+        ExpectLogged(drive_open_error_);
+        ExpectLoggedWith(source_volume_,
+                         {OfficeFilesSourceVolume::kGoogleDrive});
+      } else {
+        ExpectLogged(one_drive_open_error_);
+        ExpectLoggedWith(source_volume_,
+                         {OfficeFilesSourceVolume::kMicrosoftOneDrive});
+      }
+    } else {
+      if (google_drive) {
+        ExpectNotLoggedWith(source_volume_,
+                            {OfficeFilesSourceVolume::kGoogleDrive});
+      } else {
+        ExpectNotLoggedWith(source_volume_,
+                            {OfficeFilesSourceVolume::kMicrosoftOneDrive});
+      }
+      if (task_result_.logged() &&
+          task_result_.value != OfficeTaskResult::kCancelledAtConfirmation) {
+        ExpectLogged(upload_result_);
+      }
+    }
+  }
+
+  if (upload_result_.logged()) {
+    if (upload_result_.value == OfficeFilesUploadResult::kCopyOperationError) {
+      ExpectLogged(copy_error_);
+    } else if (upload_result_.value ==
+               OfficeFilesUploadResult::kMoveOperationError) {
+      ExpectLogged(move_error_);
+    }
+  }
+
+  if (copy_error_.logged() || move_error_.logged()) {
+    ExpectLogged(upload_result_);
+  }
+
+  if (google_drive) {
+    base::UmaHistogramEnumeration(kGoogleDriveCopyErrorMetricStateMetricName,
+                                  copy_error_.state);
+    base::UmaHistogramEnumeration(kGoogleDriveMoveErrorMetricStateMetricName,
+                                  move_error_.state);
+    base::UmaHistogramEnumeration(kDriveErrorMetricStateMetricName,
+                                  drive_open_error_.state);
+    base::UmaHistogramEnumeration(kDriveOpenSourceVolumeMetricStateMetric,
+                                  source_volume_.state);
+    base::UmaHistogramEnumeration(kGoogleDriveTaskResultMetricStateMetricName,
+                                  task_result_.state);
+    base::UmaHistogramEnumeration(kDriveTransferRequiredMetricStateMetric,
+                                  transfer_required_.state);
+    base::UmaHistogramEnumeration(kGoogleDriveUploadResultMetricStateMetricName,
+                                  upload_result_.state);
+  } else {
+    base::UmaHistogramEnumeration(kOneDriveCopyErrorMetricStateMetricName,
+                                  copy_error_.state);
+    base::UmaHistogramEnumeration(kOneDriveMoveErrorMetricStateMetricName,
+                                  move_error_.state);
+    base::UmaHistogramEnumeration(kOneDriveErrorMetricStateMetricName,
+                                  one_drive_open_error_.state);
+    base::UmaHistogramEnumeration(kOneDriveOpenSourceVolumeMetricStateMetric,
+                                  source_volume_.state);
+    base::UmaHistogramEnumeration(kOneDriveTaskResultMetricStateMetricName,
+                                  task_result_.state);
+    base::UmaHistogramEnumeration(kOneDriveTransferRequiredMetricStateMetric,
+                                  transfer_required_.state);
+    base::UmaHistogramEnumeration(kOneDriveUploadResultMetricStateMetricName,
+                                  upload_result_.state);
+  }
+
+  if (inconsistency_found_) {
+    base::debug::DumpWithoutCrashing();
   }
 }
 
@@ -153,26 +274,19 @@
 void CloudOpenMetrics::PrintDebugInformationIfInconsistent(
     Metric<MetricType>& metric,
     bool destructor) {
-  switch (metric.state) {
-    case MetricState::kCorrectlyNotLogged:
-    case MetricState::kCorrectlyLogged:
-      // Consistent state.
-      return;
-    case MetricState::kIncorrectlyLoggedMultipleTimes:
-      // TODO(cassycc): Log old vs new value as this information cannot be
-      // derived.
-      if (destructor) {
-        // This inconsistency is detected during the cloud upload flow and
-        // should not be re-detected in the destructor.
-        return;
-      }
-      [[fallthrough]];
-    case MetricState::kIncorrectlyNotLogged:
-    case MetricState::kIncorrectlyLogged:
-    case MetricState::kWrongValueLogged:
-      LOG(ERROR) << "Inconsistent metric found: " << metric;
-      break;
+  if (metric.state == MetricState::kCorrectlyNotLogged ||
+      metric.state == MetricState::kCorrectlyLogged) {
+    // Consistent state.
+    return;
   }
+  if (destructor &&
+      metric.state == MetricState::kIncorrectlyLoggedMultipleTimes) {
+    // This inconsistency is detected during the cloud upload flow and
+    // should not be re-detected in the destructor.
+    return;
+  }
+  inconsistency_found_ = true;
+  LOG(ERROR) << "Inconsistent metric found: " << metric;
   PrintMetrics();
 }
 
@@ -183,6 +297,14 @@
 }
 
 template <typename MetricType>
+void CloudOpenMetrics::ExpectNotLoggedWith(
+    Metric<MetricType>& metric,
+    const std::vector<MetricType>& values) {
+  metric.MakeInconsistentIfLoggedWith(values);
+  PrintDebugInformationIfInconsistent(metric);
+}
+
+template <typename MetricType>
 void CloudOpenMetrics::ExpectLogged(Metric<MetricType>& metric) {
   metric.MakeInconsistentIfNotLogged();
   PrintDebugInformationIfInconsistent(metric);
@@ -196,15 +318,15 @@
 }
 
 void CloudOpenMetrics::PrintMetrics() {
-  LOG(WARNING) << "Metrics: " << std::endl
-               << copy_error_ << std::endl
-               << move_error_ << std::endl
-               << drive_open_error_ << std::endl
-               << one_drive_open_error_ << std::endl
-               << source_volume_ << std::endl
-               << task_result_ << std::endl
-               << transfer_required_ << std::endl
-               << upload_result_;
+  LOG(ERROR) << "Metrics: " << std::endl
+             << copy_error_ << std::endl
+             << move_error_ << std::endl
+             << drive_open_error_ << std::endl
+             << one_drive_open_error_ << std::endl
+             << source_volume_ << std::endl
+             << task_result_ << std::endl
+             << transfer_required_ << std::endl
+             << upload_result_;
 }
 
 }  // namespace ash::cloud_upload
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/cloud_open_metrics.h b/chrome/browser/ui/webui/ash/cloud_upload/cloud_open_metrics.h
index 9ad53f7..74306bbd4 100644
--- a/chrome/browser/ui/webui/ash/cloud_upload/cloud_open_metrics.h
+++ b/chrome/browser/ui/webui/ash/cloud_upload/cloud_open_metrics.h
@@ -13,17 +13,18 @@
 
 enum class MetricState {
   // Not logged and it shouldn’t have been.
-  kCorrectlyNotLogged,
+  kCorrectlyNotLogged = 0,
   // Logged when it should have been.
-  kCorrectlyLogged,
+  kCorrectlyLogged = 1,
   // Not logged when it should have been.
-  kIncorrectlyNotLogged,
+  kIncorrectlyNotLogged = 2,
   // Logged when it shouldn’t have been.
-  kIncorrectlyLogged,
+  kIncorrectlyLogged = 3,
   // Logged more than once.
-  kIncorrectlyLoggedMultipleTimes,
+  kIncorrectlyLoggedMultipleTimes = 4,
   // An unexpected value was logged.
-  kWrongValueLogged,
+  kWrongValueLogged = 5,
+  kMaxValue = kWrongValueLogged,
 };
 
 // Represents a metric identified by `metric_name` that logs value of type
@@ -68,18 +69,30 @@
     }
   }
 
+  // Metric should not be logged.
   void MakeInconsistentIfLogged() {
     if (logged()) {
       state = MetricState::kIncorrectlyLogged;
     }
   }
 
+  // Metric should be logged but not with a value in `values`.
+  void MakeInconsistentIfLoggedWith(const std::vector<MetricType>& values) {
+    if (!logged()) {
+      state = MetricState::kIncorrectlyNotLogged;
+    } else if (base::Contains(values, value)) {
+      state = MetricState::kWrongValueLogged;
+    }
+  }
+
+  // Metric should be logged.
   void MakeInconsistentIfNotLogged() {
     if (!logged()) {
       state = MetricState::kIncorrectlyNotLogged;
     }
   }
 
+  // Metric should be logged with a value in `values`.
   void MakeInconsistentIfNotLoggedWith(const std::vector<MetricType>& values) {
     if (!logged()) {
       state = MetricState::kIncorrectlyNotLogged;
@@ -173,6 +186,12 @@
   template <typename MetricType>
   void ExpectNotLogged(Metric<MetricType>& metric);
 
+  // Expect that the `metric` is logged but not with a value in `values`.
+  // Otherwise update the state and print debug information.
+  template <typename MetricType>
+  void ExpectNotLoggedWith(Metric<MetricType>& metric,
+                           const std::vector<MetricType>& values);
+
   // Expect that the `metric` metric is logged with a value. Otherwise update
   // the state and print debug information.
   template <typename MetricType>
@@ -184,6 +203,7 @@
   void ExpectLoggedWith(Metric<MetricType>& metric,
                         const std::vector<MetricType>& values);
 
+  bool inconsistency_found_ = false;
   CloudProvider cloud_provider_;
   Metric<base::File::Error> copy_error_;
   Metric<base::File::Error> move_error_;
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/cloud_open_metrics_unittest.cc b/chrome/browser/ui/webui/ash/cloud_upload/cloud_open_metrics_unittest.cc
index 037b471..c14ee06e 100644
--- a/chrome/browser/ui/webui/ash/cloud_upload/cloud_open_metrics_unittest.cc
+++ b/chrome/browser/ui/webui/ash/cloud_upload/cloud_open_metrics_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/webui/ash/cloud_upload/cloud_open_metrics.h"
 
+#include "base/debug/dump_without_crashing.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -67,6 +68,35 @@
   ASSERT_EQ(metric_.state, MetricState::kIncorrectlyLogged);
 }
 
+// Tests that Metric::MakeInconsistentIfLoggedWith() doesn't update the `state`
+// when logged with the correct value.
+TEST_F(MetricTest, MakeInconsistentIfLoggedWithWhenLoggedWithWrongValue) {
+  metric_.Log(TestEnum::kTwo);
+  ASSERT_EQ(metric_.state, MetricState::kCorrectlyLogged);
+
+  metric_.MakeInconsistentIfLoggedWith({TestEnum::kZero, TestEnum::kOne});
+  ASSERT_EQ(metric_.state, MetricState::kCorrectlyLogged);
+}
+
+// Tests that Metric::MakeInconsistentIfLoggedWith() updates the `state` when
+// logged with the incorrect value.
+TEST_F(MetricTest, MakeInconsistentIfLoggedWithWhenLoggedWithIncorrectValue) {
+  metric_.Log(TestEnum::kOne);
+  ASSERT_EQ(metric_.state, MetricState::kCorrectlyLogged);
+
+  metric_.MakeInconsistentIfLoggedWith({TestEnum::kZero, TestEnum::kOne});
+  ASSERT_EQ(metric_.state, MetricState::kWrongValueLogged);
+}
+
+// Tests Metric::MakeInconsistentIfLoggedWith() updates the `state` correctly
+// when not logged.
+TEST_F(MetricTest, MakeInconsistentIfLoggedWithWhenNotLogged) {
+  ASSERT_EQ(metric_.state, MetricState::kCorrectlyNotLogged);
+
+  metric_.MakeInconsistentIfLoggedWith({TestEnum::kZero, TestEnum::kOne});
+  ASSERT_EQ(metric_.state, MetricState::kIncorrectlyNotLogged);
+}
+
 // Tests that Metric::MakeInconsistentIfNotLogged() doesn't update the `state`
 // when the metric was logged.
 TEST_F(MetricTest, MakeInconsistentIfNotLoggedWhenLogged) {
@@ -115,4 +145,451 @@
   ASSERT_EQ(metric_.state, MetricState::kWrongValueLogged);
 }
 
+class CloudOpenMetricsTest : public testing::Test {
+ public:
+  CloudOpenMetricsTest() = default;
+
+  static void FakeDumpWithoutCrashing() { number_of_dump_calls_++; }
+
+  static int number_of_dump_calls() { return number_of_dump_calls_; }
+
+ protected:
+  void SetUp() override {
+    base::debug::SetDumpWithoutCrashingFunction(
+        &CloudOpenMetricsTest::FakeDumpWithoutCrashing);
+    number_of_dump_calls_ = 0;
+  }
+
+  void TearDown() override {
+    base::debug::SetDumpWithoutCrashingFunction(nullptr);
+    base::debug::ClearMapsForTesting();
+  }
+
+  static int number_of_dump_calls_;
+  base::HistogramTester histogram_;
+};
+
+int CloudOpenMetricsTest::number_of_dump_calls_ = 0;
+
+// Tests that the TaskResult companion metric is set correctly when TaskResult
+// is logged.
+TEST_F(CloudOpenMetricsTest, TaskResultLogged) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kGoogleDrive);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kOpened);
+  }
+  histogram_.ExpectUniqueSample(kGoogleDriveTaskResultMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+}
+
+// Tests that the TaskResult companion metric is set correctly when TaskResult
+// is not logged.
+TEST_F(CloudOpenMetricsTest, TaskResultNotLogged) {
+  { CloudOpenMetrics cloud_open_metrics(CloudProvider::kGoogleDrive); }
+  histogram_.ExpectUniqueSample(kGoogleDriveTaskResultMetricStateMetricName,
+                                MetricState::kIncorrectlyNotLogged, 1);
+  ASSERT_EQ(1, CloudOpenMetricsTest::number_of_dump_calls());
+}
+
+// Tests that the TaskResult companion metric is set correctly when TaskResult
+// is logged twice.
+TEST_F(CloudOpenMetricsTest, TaskResultLoggedTwice) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kGoogleDrive);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kOpened);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kFailedToOpen);
+  }
+  histogram_.ExpectUniqueSample(kGoogleDriveTaskResultMetricStateMetricName,
+                                MetricState::kIncorrectlyLoggedMultipleTimes,
+                                1);
+  ASSERT_EQ(1, CloudOpenMetricsTest::number_of_dump_calls());
+}
+
+// Tests that the TransferRequired, UploadResult and OpenErrors companion
+// metrics are set correctly when TaskResult is logged as kFallbackQuickOffice
+// and they are logged consistently.
+TEST_F(CloudOpenMetricsTest,
+       MetricsConsistentWhenTaskResultIsFallbackQuickOffice) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kGoogleDrive);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kFallbackQuickOffice);
+    cloud_open_metrics.LogGoogleDriveOpenError(OfficeDriveOpenErrors::kOffline);
+  }
+  histogram_.ExpectUniqueSample(kDriveTransferRequiredMetricStateMetric,
+                                MetricState::kCorrectlyNotLogged, 1);
+  histogram_.ExpectUniqueSample(kGoogleDriveUploadResultMetricStateMetricName,
+                                MetricState::kCorrectlyNotLogged, 1);
+  histogram_.ExpectUniqueSample(kDriveErrorMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+}
+
+// Tests that the TransferRequired, UploadResult and OpenErrors companion
+// metrics are set correctly when TaskResult is logged as kFallbackQuickOffice
+// and they are logged inconsistently.
+TEST_F(CloudOpenMetricsTest,
+       MetricsInconsistentWhenTaskResultIsFallbackQuickOffice) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kGoogleDrive);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kFallbackQuickOffice);
+    cloud_open_metrics.LogTransferRequired(
+        OfficeFilesTransferRequired::kNotRequired);
+    cloud_open_metrics.LogUploadResult(OfficeFilesUploadResult::kCloudError);
+    cloud_open_metrics.LogGoogleDriveOpenError(OfficeDriveOpenErrors::kSuccess);
+  }
+  histogram_.ExpectUniqueSample(kDriveTransferRequiredMetricStateMetric,
+                                MetricState::kIncorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kGoogleDriveUploadResultMetricStateMetricName,
+                                MetricState::kIncorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kDriveErrorMetricStateMetricName,
+                                MetricState::kWrongValueLogged, 1);
+  ASSERT_EQ(1, CloudOpenMetricsTest::number_of_dump_calls());
+}
+
+// Tests that the SourceVolume, TransferRequired, UploadResult and OpenErrors
+// companion metrics are set correctly when TaskResult is logged as
+// kCancelledAtConfirmation and they are logged consistently.
+TEST_F(CloudOpenMetricsTest,
+       MetricsConsistentWhenTaskResultIsCancelledAtConfirmation) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kOneDrive);
+    cloud_open_metrics.LogTaskResult(
+        OfficeTaskResult::kCancelledAtConfirmation);
+    cloud_open_metrics.LogSourceVolume(
+        OfficeFilesSourceVolume::kDownloadsDirectory);
+    cloud_open_metrics.LogTransferRequired(OfficeFilesTransferRequired::kMove);
+  }
+  histogram_.ExpectUniqueSample(kOneDriveOpenSourceVolumeMetricStateMetric,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveTransferRequiredMetricStateMetric,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveUploadResultMetricStateMetricName,
+                                MetricState::kCorrectlyNotLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveErrorMetricStateMetricName,
+                                MetricState::kCorrectlyNotLogged, 1);
+}
+
+// Tests that the SourceVolume, TransferRequired, UploadResult and OpenErrors
+// companion metrics are set correctly when TaskResult is logged as
+// kCancelledAtConfirmation and they are logged inconsistently.
+TEST_F(CloudOpenMetricsTest,
+       MetricsInconsistentWhenTaskResultIsCancelledAtConfirmation) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kOneDrive);
+    cloud_open_metrics.LogTaskResult(
+        OfficeTaskResult::kCancelledAtConfirmation);
+    cloud_open_metrics.LogUploadResult(
+        OfficeFilesUploadResult::kCloudAccessDenied);
+    cloud_open_metrics.LogOneDriveOpenError(
+        OfficeOneDriveOpenErrors::kGetActionsAccessDenied);
+  }
+  histogram_.ExpectUniqueSample(kOneDriveOpenSourceVolumeMetricStateMetric,
+                                MetricState::kIncorrectlyNotLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveTransferRequiredMetricStateMetric,
+                                MetricState::kIncorrectlyNotLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveUploadResultMetricStateMetricName,
+                                MetricState::kIncorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveErrorMetricStateMetricName,
+                                MetricState::kIncorrectlyLogged, 1);
+  ASSERT_EQ(1, CloudOpenMetricsTest::number_of_dump_calls());
+}
+
+// Tests that the SourceVolume companion metric is set correctly when TaskResult
+// is logged as kFailedToOpen and it is logged consistently.
+TEST_F(CloudOpenMetricsTest, MetricsConsistentWhenTaskResultIsFailedToOpen) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kOneDrive);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kFailedToOpen);
+    cloud_open_metrics.LogOneDriveOpenError(
+        OfficeOneDriveOpenErrors::kConversionToODFSUrlError);
+  }
+  histogram_.ExpectUniqueSample(kOneDriveErrorMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+}
+
+// Tests that the SourceVolume companion metric is set correctly when TaskResult
+// is logged as kFailedToOpen and it is logged inconsistently.
+TEST_F(CloudOpenMetricsTest, MetricsInconsistentWhenTaskResultIsFailedToOpen) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kOneDrive);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kFailedToOpen);
+    cloud_open_metrics.LogOneDriveOpenError(OfficeOneDriveOpenErrors::kSuccess);
+  }
+  histogram_.ExpectUniqueSample(kOneDriveErrorMetricStateMetricName,
+                                MetricState::kWrongValueLogged, 1);
+  ASSERT_EQ(1, CloudOpenMetricsTest::number_of_dump_calls());
+}
+
+// Tests that the OpenErrors, UploadResult and TransferRequired companion
+// metrics are set correctly when TaskResult is logged as kOpened and they are
+// logged consistently.
+TEST_F(CloudOpenMetricsTest, MetricsConsistentWhenTaskResultIsOpened) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kOneDrive);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kOpened);
+    cloud_open_metrics.LogOneDriveOpenError(OfficeOneDriveOpenErrors::kSuccess);
+    cloud_open_metrics.LogTransferRequired(
+        OfficeFilesTransferRequired::kNotRequired);
+  }
+  histogram_.ExpectUniqueSample(kOneDriveErrorMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveUploadResultMetricStateMetricName,
+                                MetricState::kCorrectlyNotLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveTransferRequiredMetricStateMetric,
+                                MetricState::kCorrectlyLogged, 1);
+}
+
+// Tests that the OpenErrors, UploadResult and TransferRequired companion
+// metrics are set correctly when TaskResult is logged as kOpened and they are
+// logged inconsistently.
+TEST_F(CloudOpenMetricsTest, MetricsInconsistentWhenTaskResultIsOpened) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kOneDrive);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kOpened);
+    cloud_open_metrics.LogUploadResult(OfficeFilesUploadResult::kSuccess);
+    cloud_open_metrics.LogTransferRequired(OfficeFilesTransferRequired::kCopy);
+  }
+  histogram_.ExpectUniqueSample(kOneDriveErrorMetricStateMetricName,
+                                MetricState::kIncorrectlyNotLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveUploadResultMetricStateMetricName,
+                                MetricState::kIncorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveTransferRequiredMetricStateMetric,
+                                MetricState::kWrongValueLogged, 1);
+  ASSERT_EQ(1, CloudOpenMetricsTest::number_of_dump_calls());
+}
+
+// Tests that the OpenErrors, UploadResult and TransferRequired companion
+// metrics are set correctly when TaskResult is logged as kMoved and they are
+// logged consistently.
+TEST_F(CloudOpenMetricsTest, MetricsConsistentWhenTaskResultIsMoved) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kGoogleDrive);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kMoved);
+    cloud_open_metrics.LogGoogleDriveOpenError(OfficeDriveOpenErrors::kSuccess);
+    cloud_open_metrics.LogUploadResult(OfficeFilesUploadResult::kSuccess);
+    cloud_open_metrics.LogTransferRequired(OfficeFilesTransferRequired::kMove);
+  }
+  histogram_.ExpectUniqueSample(kDriveErrorMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kGoogleDriveUploadResultMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kDriveTransferRequiredMetricStateMetric,
+                                MetricState::kCorrectlyLogged, 1);
+}
+
+// Tests that the OpenErrors, UploadResult and TransferRequired companion
+// metrics are set correctly when TaskResult is logged as kMoved and they are
+// logged inconsistently.
+TEST_F(CloudOpenMetricsTest, MetricsInconsistentWhenTaskResultIsMoved) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kGoogleDrive);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kMoved);
+    cloud_open_metrics.LogGoogleDriveOpenError(
+        OfficeDriveOpenErrors::kNoMetadata);
+    cloud_open_metrics.LogUploadResult(OfficeFilesUploadResult::kInvalidURL);
+  }
+  histogram_.ExpectUniqueSample(kDriveErrorMetricStateMetricName,
+                                MetricState::kWrongValueLogged, 1);
+  histogram_.ExpectUniqueSample(kGoogleDriveUploadResultMetricStateMetricName,
+                                MetricState::kWrongValueLogged, 1);
+  histogram_.ExpectUniqueSample(kDriveTransferRequiredMetricStateMetric,
+                                MetricState::kIncorrectlyNotLogged, 1);
+  ASSERT_EQ(1, CloudOpenMetricsTest::number_of_dump_calls());
+}
+
+// Tests that the UploadResult, OpenErrors and SourceVolume companion metrics
+// are set correctly when TransferRequired is logged as kNotRequired and they
+// are logged consistently.
+TEST_F(CloudOpenMetricsTest,
+       MetricsConsistentWhenTransferRequiredIsNotRequired) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kGoogleDrive);
+    cloud_open_metrics.LogTransferRequired(
+        OfficeFilesTransferRequired::kNotRequired);
+    cloud_open_metrics.LogGoogleDriveOpenError(
+        OfficeDriveOpenErrors::kNoMetadata);
+    cloud_open_metrics.LogSourceVolume(OfficeFilesSourceVolume::kGoogleDrive);
+  }
+  histogram_.ExpectUniqueSample(kGoogleDriveUploadResultMetricStateMetricName,
+                                MetricState::kCorrectlyNotLogged, 1);
+  histogram_.ExpectUniqueSample(kDriveErrorMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kDriveOpenSourceVolumeMetricStateMetric,
+                                MetricState::kCorrectlyLogged, 1);
+}
+
+// Tests that the UploadResult, OpenErrors and SourceVolume companion metrics
+// are set correctly when TransferRequired is logged as kNotRequired and they
+// are logged inconsistently.
+TEST_F(CloudOpenMetricsTest,
+       MetricsInconsistentWhenTransferRequiredIsNotRequired) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kGoogleDrive);
+    cloud_open_metrics.LogTransferRequired(
+        OfficeFilesTransferRequired::kNotRequired);
+    cloud_open_metrics.LogUploadResult(
+        OfficeFilesUploadResult::kDestinationUrlError);
+    cloud_open_metrics.LogSourceVolume(
+        OfficeFilesSourceVolume::kDownloadsDirectory);
+  }
+  histogram_.ExpectUniqueSample(kGoogleDriveUploadResultMetricStateMetricName,
+                                MetricState::kIncorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kDriveErrorMetricStateMetricName,
+                                MetricState::kIncorrectlyNotLogged, 1);
+  histogram_.ExpectUniqueSample(kDriveOpenSourceVolumeMetricStateMetric,
+                                MetricState::kWrongValueLogged, 1);
+  ASSERT_EQ(1, CloudOpenMetricsTest::number_of_dump_calls());
+}
+
+// Tests that the UploadResult and SourceVolume companion metrics are set
+// correctly when TransferRequired is logged as kCopy and TaskResult is not
+// kCancelledAtConfirmation and they are logged consistently.
+TEST_F(CloudOpenMetricsTest,
+       MetricsConsistentWhenTransferRequiredIsCopyAndTaskResultIsFailedToOpen) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kGoogleDrive);
+    cloud_open_metrics.LogTransferRequired(OfficeFilesTransferRequired::kCopy);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kFailedToOpen);
+    cloud_open_metrics.LogUploadResult(
+        OfficeFilesUploadResult::kCloudQuotaFull);
+    cloud_open_metrics.LogSourceVolume(
+        OfficeFilesSourceVolume::kMicrosoftOneDrive);
+  }
+  histogram_.ExpectUniqueSample(kGoogleDriveUploadResultMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kDriveOpenSourceVolumeMetricStateMetric,
+                                MetricState::kCorrectlyLogged, 1);
+}
+
+// Tests that the UploadResult and SourceVolume companion metrics are set
+// correctly when TransferRequired is logged as kCopy and TaskResult is not
+// kCancelledAtConfirmation and they are logged inconsistently.
+TEST_F(
+    CloudOpenMetricsTest,
+    MetricsInconsistentWhenTransferRequiredIsCopyAndTaskResultIsFailedToOpen) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kGoogleDrive);
+    cloud_open_metrics.LogTransferRequired(OfficeFilesTransferRequired::kCopy);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kFailedToOpen);
+    cloud_open_metrics.LogSourceVolume(OfficeFilesSourceVolume::kGoogleDrive);
+  }
+  histogram_.ExpectUniqueSample(kGoogleDriveUploadResultMetricStateMetricName,
+                                MetricState::kIncorrectlyNotLogged, 1);
+  histogram_.ExpectUniqueSample(kDriveOpenSourceVolumeMetricStateMetric,
+                                MetricState::kWrongValueLogged, 1);
+  ASSERT_EQ(1, CloudOpenMetricsTest::number_of_dump_calls());
+}
+
+// Tests that the CopyError companion metric is set correctly when UploadResult
+// is logged as kCopyOperationError and CopyError is logged consistently.
+TEST_F(CloudOpenMetricsTest,
+       MetricsConsistentWhenUploadResultIsCopyOperationError) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kGoogleDrive);
+    cloud_open_metrics.LogUploadResult(
+        OfficeFilesUploadResult::kCopyOperationError);
+    cloud_open_metrics.LogCopyError(
+        base::File::Error::FILE_ERROR_ACCESS_DENIED);
+  }
+  histogram_.ExpectUniqueSample(kGoogleDriveCopyErrorMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+}
+
+// Tests that the CopyError companion metric is set correctly when UploadResult
+// is logged as kCopyOperationError and CopyError is logged inconsistently.
+TEST_F(CloudOpenMetricsTest,
+       MetricsInconsistentWhenUploadResultIsCopyOperationError) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kGoogleDrive);
+    cloud_open_metrics.LogUploadResult(
+        OfficeFilesUploadResult::kCopyOperationError);
+  }
+  histogram_.ExpectUniqueSample(kGoogleDriveCopyErrorMetricStateMetricName,
+                                MetricState::kIncorrectlyNotLogged, 1);
+  ASSERT_EQ(1, CloudOpenMetricsTest::number_of_dump_calls());
+}
+
+// Tests that the UploadResult companion metric is set correctly when MoveError
+// is logged and UploadResult is logged consistently.
+TEST_F(CloudOpenMetricsTest, MetricsConsistentWhenMoveErrorIsLogged) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kOneDrive);
+    cloud_open_metrics.LogMoveError(base::File::Error::FILE_ERROR_NO_SPACE);
+    cloud_open_metrics.LogUploadResult(
+        OfficeFilesUploadResult::kMoveOperationError);
+  }
+  histogram_.ExpectUniqueSample(kOneDriveUploadResultMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+}
+
+// Tests that the UploadResult companion metric is set correctly when MoveError
+// is logged and UploadResult is logged inconsistently.
+TEST_F(CloudOpenMetricsTest, MetricsInconsistentWhenMoveErrorIsLogged) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kOneDrive);
+    cloud_open_metrics.LogMoveError(base::File::Error::FILE_ERROR_NO_SPACE);
+  }
+  histogram_.ExpectUniqueSample(kOneDriveUploadResultMetricStateMetricName,
+                                MetricState::kIncorrectlyNotLogged, 1);
+  ASSERT_EQ(1, CloudOpenMetricsTest::number_of_dump_calls());
+}
+
+// Tests that when all metrics are consistent for the cloud open flow, there is
+// no dump without crashing.
+TEST_F(CloudOpenMetricsTest, NoDumpWhenAllMetricsAreConsistentForOpenFlow) {
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kOneDrive);
+    cloud_open_metrics.LogSourceVolume(
+        OfficeFilesSourceVolume::kMicrosoftOneDrive);
+    cloud_open_metrics.LogTransferRequired(
+        OfficeFilesTransferRequired::kNotRequired);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kOpened);
+    cloud_open_metrics.LogOneDriveOpenError(OfficeOneDriveOpenErrors::kSuccess);
+  }
+  histogram_.ExpectUniqueSample(kOneDriveCopyErrorMetricStateMetricName,
+                                MetricState::kCorrectlyNotLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveMoveErrorMetricStateMetricName,
+                                MetricState::kCorrectlyNotLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveErrorMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveOpenSourceVolumeMetricStateMetric,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveTaskResultMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveTransferRequiredMetricStateMetric,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kOneDriveUploadResultMetricStateMetricName,
+                                MetricState::kCorrectlyNotLogged, 1);
+  ASSERT_EQ(0, CloudOpenMetricsTest::number_of_dump_calls());
+}
+
+// Tests that when all metrics are consistent for the cloud upload flow, there
+// is no dump without crashing.
+TEST_F(CloudOpenMetricsTest, NoDumpWhenAllMetricsAreConsistentForMoveFlow) {
+  ASSERT_EQ(0, CloudOpenMetricsTest::number_of_dump_calls());
+  {
+    CloudOpenMetrics cloud_open_metrics(CloudProvider::kGoogleDrive);
+    cloud_open_metrics.LogSourceVolume(
+        OfficeFilesSourceVolume::kMicrosoftOneDrive);
+    cloud_open_metrics.LogTransferRequired(OfficeFilesTransferRequired::kMove);
+    cloud_open_metrics.LogUploadResult(OfficeFilesUploadResult::kSuccess);
+    cloud_open_metrics.LogTaskResult(OfficeTaskResult::kMoved);
+    cloud_open_metrics.LogGoogleDriveOpenError(OfficeDriveOpenErrors::kSuccess);
+  }
+  histogram_.ExpectUniqueSample(kGoogleDriveCopyErrorMetricStateMetricName,
+                                MetricState::kCorrectlyNotLogged, 1);
+  histogram_.ExpectUniqueSample(kGoogleDriveMoveErrorMetricStateMetricName,
+                                MetricState::kCorrectlyNotLogged, 1);
+  histogram_.ExpectUniqueSample(kDriveErrorMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kDriveOpenSourceVolumeMetricStateMetric,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kGoogleDriveTaskResultMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kDriveTransferRequiredMetricStateMetric,
+                                MetricState::kCorrectlyLogged, 1);
+  histogram_.ExpectUniqueSample(kGoogleDriveUploadResultMetricStateMetricName,
+                                MetricState::kCorrectlyLogged, 1);
+  ASSERT_EQ(0, CloudOpenMetricsTest::number_of_dump_calls());
+}
+
 }  // namespace ash::cloud_upload
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_util.h b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_util.h
index 6e52830..2b916a8b 100644
--- a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_util.h
+++ b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_util.h
@@ -192,38 +192,75 @@
 
 constexpr char kGoogleDriveTaskResultMetricName[] =
     "FileBrowser.OfficeFiles.TaskResult.Drive";
+constexpr char kGoogleDriveTaskResultMetricStateMetricName[] =
+    "FileBrowser.OfficeFiles.TaskResult.GoogleDrive.MetricState";
+
 constexpr char kOneDriveTaskResultMetricName[] =
     "FileBrowser.OfficeFiles.TaskResult.OneDrive";
+constexpr char kOneDriveTaskResultMetricStateMetricName[] =
+    "FileBrowser.OfficeFiles.TaskResult.OneDrive.MetricState";
+
 constexpr char kGoogleDriveUploadResultMetricName[] =
     "FileBrowser.OfficeFiles.Open.UploadResult.GoogleDrive";
+constexpr char kGoogleDriveUploadResultMetricStateMetricName[] =
+    "FileBrowser.OfficeFiles.Open.UploadResult.GoogleDrive.MetricState";
+
 constexpr char kOneDriveUploadResultMetricName[] =
     "FileBrowser.OfficeFiles.Open.UploadResult.OneDrive";
+constexpr char kOneDriveUploadResultMetricStateMetricName[] =
+    "FileBrowser.OfficeFiles.Open.UploadResult.OneDrive.MetricState";
 
 constexpr char kGoogleDriveMoveErrorMetricName[] =
     "FileBrowser.OfficeFiles.Open.IOTaskError.GoogleDrive.Move";
+constexpr char kGoogleDriveMoveErrorMetricStateMetricName[] =
+    "FileBrowser.OfficeFiles.Open.IOTaskError.GoogleDrive.Move.MetricState";
+
 constexpr char kGoogleDriveCopyErrorMetricName[] =
     "FileBrowser.OfficeFiles.Open.IOTaskError.GoogleDrive.Copy";
+constexpr char kGoogleDriveCopyErrorMetricStateMetricName[] =
+    "FileBrowser.OfficeFiles.Open.IOTaskError.GoogleDrive.Copy.MetricState";
+
 constexpr char kOneDriveMoveErrorMetricName[] =
     "FileBrowser.OfficeFiles.Open.IOTaskError.OneDrive.Move";
+constexpr char kOneDriveMoveErrorMetricStateMetricName[] =
+    "FileBrowser.OfficeFiles.Open.IOTaskError.OneDrive.Move.MetricState";
+
 constexpr char kOneDriveCopyErrorMetricName[] =
     "FileBrowser.OfficeFiles.Open.IOTaskError.OneDrive.Copy";
+constexpr char kOneDriveCopyErrorMetricStateMetricName[] =
+    "FileBrowser.OfficeFiles.Open.IOTaskError.OneDrive.Copy.MetricState";
 
 constexpr char kDriveOpenSourceVolumeMetric[] =
     "FileBrowser.OfficeFiles.Open.SourceVolume.GoogleDrive";
+constexpr char kDriveOpenSourceVolumeMetricStateMetric[] =
+    "FileBrowser.OfficeFiles.Open.SourceVolume.GoogleDrive.MetricState";
+
 constexpr char kOneDriveOpenSourceVolumeMetric[] =
     "FileBrowser.OfficeFiles.Open.SourceVolume.MicrosoftOneDrive";
+constexpr char kOneDriveOpenSourceVolumeMetricStateMetric[] =
+    "FileBrowser.OfficeFiles.Open.SourceVolume.OneDrive.MetricState";
 
 constexpr char kOpenCloudProviderMetric[] =
     "FileBrowser.OfficeFiles.Open.CloudProvider";
 
 constexpr char kDriveTransferRequiredMetric[] =
     "FileBrowser.OfficeFiles.Open.TransferRequired.GoogleDrive";
+constexpr char kDriveTransferRequiredMetricStateMetric[] =
+    "FileBrowser.OfficeFiles.Open.TransferRequired.GoogleDrive.MetricState";
+
 constexpr char kOneDriveTransferRequiredMetric[] =
     "FileBrowser.OfficeFiles.Open.TransferRequired.OneDrive";
+constexpr char kOneDriveTransferRequiredMetricStateMetric[] =
+    "FileBrowser.OfficeFiles.Open.TransferRequired.OneDrive.MetricState";
 
 constexpr char kDriveErrorMetricName[] = "FileBrowser.OfficeFiles.Errors.Drive";
+constexpr char kDriveErrorMetricStateMetricName[] =
+    "FileBrowser.OfficeFiles.Errors.GoogleDrive.MetricState";
+
 constexpr char kOneDriveErrorMetricName[] =
     "FileBrowser.OfficeFiles.Errors.OneDrive";
+constexpr char kOneDriveErrorMetricStateMetricName[] =
+    "FileBrowser.OfficeFiles.Errors.OneDrive.MetricState";
 
 // Query actions for this path to get ODFS Metadata.
 const char kODFSMetadataQueryPath[] = "/";
diff --git a/chrome/browser/ui/webui/ash/settings/pages/a11y/accessibility_section.h b/chrome/browser/ui/webui/ash/settings/pages/a11y/accessibility_section.h
index cdd984d..0c90c87 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/a11y/accessibility_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/a11y/accessibility_section.h
@@ -7,7 +7,7 @@
 
 #include "base/memory/raw_ptr.h"
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "content/public/browser/tts_controller.h"
 #include "extensions/browser/extension_registry.h"
diff --git a/chrome/browser/ui/webui/ash/settings/pages/about/about_section.h b/chrome/browser/ui/webui/ash/settings/pages/about/about_section.h
index eb42b0f..1374ac6 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/about/about_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/about/about_section.h
@@ -9,7 +9,7 @@
 #include "base/values.h"
 #include "build/branding_buildflags.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/crostini/crostini_section.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/user_manager/user_manager.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/chrome/browser/ui/webui/ash/settings/pages/apps/apps_section.h b/chrome/browser/ui/webui/ash/settings/pages/apps/apps_section.h
index 979e713..dbcfa2f 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/apps/apps_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/apps/apps_section.h
@@ -10,8 +10,8 @@
 #include "base/values.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_forward.h"
 #include "chrome/browser/ash/app_list/arc/arc_app_list_prefs.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/system_preferences/startup_section.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
 #include "components/prefs/pref_change_registrar.h"
 
 class PrefService;
diff --git a/chrome/browser/ui/webui/ash/settings/pages/bluetooth/bluetooth_section.h b/chrome/browser/ui/webui/ash/settings/pages/bluetooth/bluetooth_section.h
index 46c555f..eed775f 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/bluetooth/bluetooth_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/bluetooth/bluetooth_section.h
@@ -9,7 +9,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "device/bluetooth/bluetooth_adapter.h"
 
 class PrefChangeRegistrar;
diff --git a/chrome/browser/ui/webui/ash/settings/pages/crostini/crostini_section.h b/chrome/browser/ui/webui/ash/settings/pages/crostini/crostini_section.h
index 34e3b6a..716fb31 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/crostini/crostini_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/crostini/crostini_section.h
@@ -7,7 +7,7 @@
 
 #include "base/memory/raw_ptr.h"
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "components/prefs/pref_change_registrar.h"
 
 namespace content {
diff --git a/chrome/browser/ui/webui/ash/settings/pages/date_time/date_time_section.h b/chrome/browser/ui/webui/ash/settings/pages/date_time/date_time_section.h
index 50a657c..86fdb8a 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/date_time/date_time_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/date_time/date_time_section.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_PAGES_DATE_TIME_DATE_TIME_SECTION_H_
 
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 
 namespace content {
 class WebUIDataSource;
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/device_section.cc b/chrome/browser/ui/webui/ash/settings/pages/device/device_section.cc
index 514ecd3..6aad7113 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/device_section.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/device_section.cc
@@ -1043,7 +1043,7 @@
   if (night_light_controller) {
     NightLightController::GetInstance()->AddObserver(this);
     OnNightLightEnabledChanged(
-        NightLightController::GetInstance()->GetEnabled());
+        NightLightController::GetInstance()->IsNightLightEnabled());
   }
 }
 
@@ -1557,7 +1557,7 @@
   }
 
   // Night Light on settings.
-  if (NightLightController::GetInstance()->GetEnabled()) {
+  if (NightLightController::GetInstance()->IsNightLightEnabled()) {
     updater.AddSearchTags(GetDisplayNightLightOnSearchConcepts());
   } else {
     updater.RemoveSearchTags(GetDisplayNightLightOnSearchConcepts());
@@ -1720,6 +1720,8 @@
        IDS_SETTINGS_CUSTOMIZE_BUTTONS_DIALOG_CANCEL},
       {"buttonRemappingDialogSaveLabel",
        IDS_SETTINGS_CUSTOMIZE_BUTTONS_DIALOG_SAVE},
+      {"buttonRenamingDialogInputCharCount",
+       IDS_SETTINGS_CUSTOMIZE_BUTTONS_RENAMING_DIALOG_INPUT_CHARACTER_COUNT},
       {"buttonRenamingDialogTitle",
        IDS_SETTINGS_CUSTOMIZE_BUTTONS_RENAMING_DIALOG_TITLE},
       {"customizeButtonSubpageDescription",
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/device_section.h b/chrome/browser/ui/webui/ash/settings/pages/device/device_section.h
index c7811ff..1de0458 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/device_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/device_section.h
@@ -11,10 +11,10 @@
 #include "base/values.h"
 #include "chrome/browser/ash/system/pointer_device_observer.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/power/power_section.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/printing/printing_section.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/storage/storage_section.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
 #include "chromeos/crosapi/mojom/cros_display_config.mojom.h"
 #include "mojo/public/cpp/bindings/associated_receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.cc b/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.cc
index 7988ebc7..efc984b 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.cc
@@ -55,12 +55,18 @@
     {"Play/Pause media", AcceleratorAction::kMediaPlayPause},
     {"Overview", AcceleratorAction::kToggleOverview},
     {"Screenshot", AcceleratorAction::kTakeScreenshot},
+    {"Previous page", ::ash::mojom::StaticShortcutAction::kPreviousPage},
+    {"Next page", ::ash::mojom::StaticShortcutAction::kNextPage},
     {"Emoji Picker", AcceleratorAction::kShowEmojiPicker},
     {"Turn on high contrast", AcceleratorAction::kToggleHighContrast},
     {"Turn on magnifier", AcceleratorAction::kToggleFullscreenMagnifier},
     {"Turn on dictation", AcceleratorAction::kEnableOrToggleDictation},
     {"Copy", ::ash::mojom::StaticShortcutAction::kCopy},
     {"Paste", ::ash::mojom::StaticShortcutAction::kPaste},
+    {"Undo", ::ash::mojom::StaticShortcutAction::kUndo},
+    {"Redo", ::ash::mojom::StaticShortcutAction::kRedo},
+    {"Zoom In", ::ash::mojom::StaticShortcutAction::kZoomIn},
+    {"Zoom Out", ::ash::mojom::StaticShortcutAction::kZoomOut},
 };
 
 mojom::ActionTypePtr GetActionType(AcceleratorAction accelerator_action) {
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.h b/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.h
index 91b0af8..6a66889c 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.h
@@ -8,7 +8,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/scoped_observation.h"
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "ui/base/ime/ash/input_method_manager.h"
 
diff --git a/chrome/browser/ui/webui/ash/settings/pages/files/files_section.h b/chrome/browser/ui/webui/ash/settings/pages/files/files_section.h
index 1b2d9a6..7fccbc9 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/files/files_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/files/files_section.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_PAGES_FILES_FILES_SECTION_H_
 
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 
 namespace content {
 class WebUIDataSource;
diff --git a/chrome/browser/ui/webui/ash/settings/pages/internet/internet_section.cc b/chrome/browser/ui/webui/ash/settings/pages/internet/internet_section.cc
index 176eed4..63640680 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/internet/internet_section.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/internet/internet_section.cc
@@ -434,16 +434,24 @@
 }
 
 const std::vector<SearchConcept>& GetInstantTetheringSearchConcepts() {
-  static const base::NoDestructor<std::vector<SearchConcept>> tags({
-      {IDS_OS_SETTINGS_TAG_INSTANT_MOBILE_NETWORKS,
-       mojom::kMobileDataNetworksSubpagePath,
-       mojom::SearchResultIcon::kInstantTethering,
-       mojom::SearchResultDefaultRank::kMedium,
-       mojom::SearchResultType::kSubpage,
-       {.subpage = mojom::Subpage::kMobileDataNetworks},
-       {IDS_OS_SETTINGS_TAG_INSTANT_MOBILE_NETWORKS_ALT1,
-        SearchConcept::kAltTagEnd}},
-  });
+  static const base::NoDestructor<std::vector<SearchConcept>> tags([] {
+    SearchConcept instant_tethering_concept{
+        IDS_OS_SETTINGS_TAG_INSTANT_MOBILE_NETWORKS,
+        mojom::kMobileDataNetworksSubpagePath,
+        mojom::SearchResultIcon::kInstantTethering,
+        mojom::SearchResultDefaultRank::kMedium,
+        mojom::SearchResultType::kSubpage,
+        {.subpage = mojom::Subpage::kMobileDataNetworks},
+    };
+
+    if (ash::features::IsInstantHotspotRebrandEnabled()) {
+      instant_tethering_concept.alt_tag_ids[0] =
+          IDS_OS_SETTINGS_TAG_INSTANT_MOBILE_NETWORKS_ALT1;
+      instant_tethering_concept.alt_tag_ids[1] = SearchConcept::kAltTagEnd;
+    }
+
+    return std::vector<SearchConcept>{instant_tethering_concept};
+  }());
   return *tags;
 }
 
diff --git a/chrome/browser/ui/webui/ash/settings/pages/internet/internet_section.h b/chrome/browser/ui/webui/ash/settings/pages/internet/internet_section.h
index e32c8d6..e09db1c 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/internet/internet_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/internet/internet_section.h
@@ -9,7 +9,7 @@
 #include <vector>
 
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "chromeos/ash/services/hotspot_config/public/cpp/cros_hotspot_config_observer.h"
 #include "chromeos/services/network_config/public/cpp/cros_network_config_observer.h"
 #include "mojo/public/cpp/bindings/receiver.h"
diff --git a/chrome/browser/ui/webui/ash/settings/pages/kerberos/kerberos_accounts_handler.cc b/chrome/browser/ui/webui/ash/settings/pages/kerberos/kerberos_accounts_handler.cc
index 234f541..4a458c18 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/kerberos/kerberos_accounts_handler.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/kerberos/kerberos_accounts_handler.cc
@@ -16,7 +16,7 @@
 #include "chrome/browser/ash/kerberos/kerberos_credentials_manager_factory.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "chrome/browser/ui/webui/webui_util.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/webui/ash/settings/pages/kerberos/kerberos_section.h b/chrome/browser/ui/webui/ash/settings/pages/kerberos/kerberos_section.h
index fe47dc5..dda2f64 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/kerberos/kerberos_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/kerberos/kerberos_section.h
@@ -8,7 +8,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/values.h"
 #include "chrome/browser/ash/kerberos/kerberos_credentials_manager.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 
 class Profile;
 
diff --git a/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.h b/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.h
index a695377..b3956d3 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.h
@@ -8,7 +8,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/values.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace content {
diff --git a/chrome/browser/ui/webui/ash/settings/pages/main/main_section.h b/chrome/browser/ui/webui/ash/settings/pages/main/main_section.h
index 73957dc5..e67c891b1 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/main/main_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/main/main_section.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_PAGES_MAIN_MAIN_SECTION_H_
 
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 
 class PluralStringHandler;
 
diff --git a/chrome/browser/ui/webui/ash/settings/pages/multidevice/multidevice_section.h b/chrome/browser/ui/webui/ash/settings/pages/multidevice/multidevice_section.h
index 404c8fcf..be4d717b 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/multidevice/multidevice_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/multidevice/multidevice_section.h
@@ -8,7 +8,7 @@
 #include "ash/webui/eche_app_ui/eche_app_manager.h"
 #include "base/memory/raw_ptr.h"
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "chromeos/ash/services/multidevice_setup/public/cpp/multidevice_setup_client.h"
 #include "chromeos/ash/services/nearby/public/mojom/nearby_share_settings.mojom.h"
 #include "components/prefs/pref_change_registrar.h"
diff --git a/chrome/browser/ui/webui/settings/ash/os_settings_section.cc b/chrome/browser/ui/webui/ash/settings/pages/os_settings_section.cc
similarity index 97%
rename from chrome/browser/ui/webui/settings/ash/os_settings_section.cc
rename to chrome/browser/ui/webui/ash/settings/pages/os_settings_section.cc
index 07cf7e02..7daca55 100644
--- a/chrome/browser/ui/webui/settings/ash/os_settings_section.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/os_settings_section.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 
 #include "ash/constants/ash_features.h"
 #include "base/check.h"
diff --git a/chrome/browser/ui/webui/settings/ash/os_settings_section.h b/chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h
similarity index 96%
rename from chrome/browser/ui/webui/settings/ash/os_settings_section.h
rename to chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h
index bba6760..3c977eae 100644
--- a/chrome/browser/ui/webui/settings/ash/os_settings_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_OS_SETTINGS_SECTION_H_
-#define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_OS_SETTINGS_SECTION_H_
+#ifndef CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_PAGES_OS_SETTINGS_SECTION_H_
+#define CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_PAGES_OS_SETTINGS_SECTION_H_
 
 #include <string>
 #include <vector>
@@ -189,4 +189,4 @@
 
 }  // namespace ash::settings
 
-#endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_OS_SETTINGS_SECTION_H_
+#endif  // CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_PAGES_OS_SETTINGS_SECTION_H_
diff --git a/chrome/browser/ui/webui/settings/ash/os_settings_section_unittest.cc b/chrome/browser/ui/webui/ash/settings/pages/os_settings_section_unittest.cc
similarity index 95%
rename from chrome/browser/ui/webui/settings/ash/os_settings_section_unittest.cc
rename to chrome/browser/ui/webui/ash/settings/pages/os_settings_section_unittest.cc
index a1ab6f1..4cb9874 100644
--- a/chrome/browser/ui/webui/settings/ash/os_settings_section_unittest.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/os_settings_section_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 
 #include "ash/webui/settings/public/constants/setting.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/ui/webui/settings/ash/os_settings_sections.cc b/chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.cc
similarity index 98%
rename from chrome/browser/ui/webui/settings/ash/os_settings_sections.cc
rename to chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.cc
index 15214c1..4bc86b8 100644
--- a/chrome/browser/ui/webui/settings/ash/os_settings_sections.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/webui/settings/ash/os_settings_sections.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.h"
 
 #include "ash/constants/ash_features.h"
 #include "base/containers/contains.h"
diff --git a/chrome/browser/ui/webui/settings/ash/os_settings_sections.h b/chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.h
similarity index 86%
rename from chrome/browser/ui/webui/settings/ash/os_settings_sections.h
rename to chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.h
index 5452526..2c6ff18 100644
--- a/chrome/browser/ui/webui/settings/ash/os_settings_sections.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_OS_SETTINGS_SECTIONS_H_
-#define CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_OS_SETTINGS_SECTIONS_H_
+#ifndef CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_PAGES_OS_SETTINGS_SECTIONS_H_
+#define CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_PAGES_OS_SETTINGS_SECTIONS_H_
 
 #include <unordered_map>
 #include <vector>
@@ -11,7 +11,7 @@
 #include "ash/webui/eche_app_ui/eche_app_manager.h"
 #include "ash/webui/settings/public/constants/routes.mojom.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_forward.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 
 class ArcAppListPrefs;
 class Profile;
@@ -77,4 +77,4 @@
 }  // namespace settings
 }  // namespace ash
 
-#endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_ASH_OS_SETTINGS_SECTIONS_H_
+#endif  // CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_PAGES_OS_SETTINGS_SECTIONS_H_
diff --git a/chrome/browser/ui/webui/ash/settings/pages/people/people_section.h b/chrome/browser/ui/webui/ash/settings/pages/people/people_section.h
index 4430d62..11be75f 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/people/people_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/people/people_section.h
@@ -10,8 +10,8 @@
 #include "base/scoped_observation.h"
 #include "base/values.h"
 #include "chrome/browser/ui/ash/auth/legacy_fingerprint_engine.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/privacy/sync_section.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
 #include "chromeos/ash/components/login/auth/auth_performer.h"
 #include "components/account_manager_core/account.h"
 #include "components/account_manager_core/account_manager_facade.h"
diff --git a/chrome/browser/ui/webui/ash/settings/pages/personalization/personalization_section.h b/chrome/browser/ui/webui/ash/settings/pages/personalization/personalization_section.h
index 3593aef..4d359bd 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/personalization/personalization_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/personalization/personalization_section.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_PAGES_PERSONALIZATION_PERSONALIZATION_SECTION_H_
 
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "components/prefs/pref_change_registrar.h"
 
 class PrefService;
diff --git a/chrome/browser/ui/webui/ash/settings/pages/power/power_section.h b/chrome/browser/ui/webui/ash/settings/pages/power/power_section.h
index 15b6af8d..cbab58ad 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/power/power_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/power/power_section.h
@@ -10,8 +10,8 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/values.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/power/device_power_handler.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
 #include "chromeos/dbus/power/power_manager_client.h"
 
 class PrefService;
diff --git a/chrome/browser/ui/webui/ash/settings/pages/printing/printing_section.h b/chrome/browser/ui/webui/ash/settings/pages/printing/printing_section.h
index f14b3fe0..ca9d142e 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/printing/printing_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/printing/printing_section.h
@@ -8,7 +8,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/values.h"
 #include "chrome/browser/ash/printing/cups_printers_manager.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 
 namespace content {
 class WebUIDataSource;
diff --git a/chrome/browser/ui/webui/ash/settings/pages/privacy/privacy_section.cc b/chrome/browser/ui/webui/ash/settings/pages/privacy/privacy_section.cc
index 6c3b00d..9efd4cf 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/privacy/privacy_section.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/privacy/privacy_section.cc
@@ -418,7 +418,11 @@
        kIsRevampEnabled
            ? IDS_OS_SETTINGS_REVAMP_DATA_ACCESS_PROTECTION_CONFIRM_DIALOG_ALLOW_BUTTON_LABEL
            : IDS_OS_SETTINGS_DATA_ACCESS_PROTECTION_CONFIRM_DIALOG_DISABLE_BUTTON_LABEL},
-      {"privacyPageTitle", IDS_SETTINGS_PRIVACY_V2},
+      {"privacyPageTitle", kIsRevampEnabled
+                               ? IDS_OS_SETTINGS_REVAMP_PRIVACY_TITLE
+                               : IDS_OS_SETTINGS_PRIVACY_TITLE},
+      {"privacyMenuItemDescription",
+       IDS_OS_SETTINGS_PRIVACY_MENU_ITEM_DESCRIPTION},
       {"smartPrivacyTitle", IDS_OS_SETTINGS_SMART_PRIVACY_TITLE},
       {"smartPrivacyQuickDimTitle",
        IDS_OS_SETTINGS_SMART_PRIVACY_QUICK_DIM_TITLE},
diff --git a/chrome/browser/ui/webui/ash/settings/pages/privacy/privacy_section.h b/chrome/browser/ui/webui/ash/settings/pages/privacy/privacy_section.h
index eb5ebff..1eead555 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/privacy/privacy_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/privacy/privacy_section.h
@@ -8,8 +8,8 @@
 #include "base/memory/raw_ptr.h"
 #include "base/values.h"
 #include "chrome/browser/ui/ash/auth/legacy_fingerprint_engine.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/privacy/sync_section.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
 #include "chromeos/ash/components/login/auth/auth_performer.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/chrome/browser/ui/webui/ash/settings/pages/privacy/sync_section.h b/chrome/browser/ui/webui/ash/settings/pages/privacy/sync_section.h
index 1de4c2fd..0f46f1842 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/privacy/sync_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/privacy/sync_section.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_PAGES_PRIVACY_SYNC_SECTION_H_
 
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 
 namespace content {
 class WebUIDataSource;
diff --git a/chrome/browser/ui/webui/ash/settings/pages/reset/reset_section.h b/chrome/browser/ui/webui/ash/settings/pages/reset/reset_section.h
index 42e4c5d..2cabbb2 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/reset/reset_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/reset/reset_section.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_PAGES_RESET_RESET_SECTION_H_
 
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 
 namespace content {
 class WebUIDataSource;
diff --git a/chrome/browser/ui/webui/ash/settings/pages/search/search_section.h b/chrome/browser/ui/webui/ash/settings/pages/search/search_section.h
index 7e00235..a7b0ae8f 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/search/search_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/search/search_section.h
@@ -7,7 +7,7 @@
 
 #include "ash/public/cpp/assistant/assistant_state_base.h"
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "chromeos/components/quick_answers/public/cpp/quick_answers_state.h"
 
 namespace content {
diff --git a/chrome/browser/ui/webui/ash/settings/pages/storage/storage_section.h b/chrome/browser/ui/webui/ash/settings/pages/storage/storage_section.h
index 4f37b71..6bebafc 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/storage/storage_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/storage/storage_section.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_PAGES_STORAGE_STORAGE_SECTION_H_
 
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 
 namespace content {
 class WebUIDataSource;
diff --git a/chrome/browser/ui/webui/ash/settings/pages/system_preferences/startup_section.h b/chrome/browser/ui/webui/ash/settings/pages/system_preferences/startup_section.h
index f744d35b..8938a545 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/system_preferences/startup_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/system_preferences/startup_section.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_PAGES_SYSTEM_PREFERENCES_STARTUP_SECTION_H_
 
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 
 namespace content {
 class WebUIDataSource;
diff --git a/chrome/browser/ui/webui/ash/settings/pages/system_preferences/system_preferences_section.h b/chrome/browser/ui/webui/ash/settings/pages/system_preferences/system_preferences_section.h
index f2bd61b2..8c64cb8 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/system_preferences/system_preferences_section.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/system_preferences/system_preferences_section.h
@@ -9,12 +9,12 @@
 #include "chrome/browser/ui/webui/ash/settings/pages/date_time/date_time_section.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/files/files_section.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/languages/languages_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/power/power_section.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/reset/reset_section.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/search/search_section.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/storage/storage_section.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/system_preferences/startup_section.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
 
 namespace content {
 class WebUIDataSource;
diff --git a/chrome/browser/ui/webui/ash/settings/search/hierarchy.cc b/chrome/browser/ui/webui/ash/settings/search/hierarchy.cc
index 0fad3c1..877147ac 100644
--- a/chrome/browser/ui/webui/ash/settings/search/hierarchy.cc
+++ b/chrome/browser/ui/webui/ash/settings/search/hierarchy.cc
@@ -10,8 +10,8 @@
 #include "base/containers/contains.h"
 #include "base/memory/raw_ptr.h"
 #include "chrome/browser/ui/webui/ash/settings/constants/constants_util.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_sections.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.h"
 #include "chrome/grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
diff --git a/chrome/browser/ui/webui/ash/settings/search/search_handler.cc b/chrome/browser/ui/webui/ash/settings/search/search_handler.cc
index eed5427..bc4cecb 100644
--- a/chrome/browser/ui/webui/ash/settings/search/search_handler.cc
+++ b/chrome/browser/ui/webui/ash/settings/search/search_handler.cc
@@ -6,10 +6,10 @@
 
 #include "base/ranges/algorithm.h"
 #include "base/strings/string_number_conversions.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.h"
 #include "chrome/browser/ui/webui/ash/settings/search/hierarchy.h"
 #include "chrome/browser/ui/webui/ash/settings/search/mojom/search_result_icon.mojom.h"
 #include "chrome/browser/ui/webui/ash/settings/search/search_concept.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_sections.h"
 #include "chrome/grit/generated_resources.h"
 #include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/ui/webui/ash/settings/search/search_tag_registry.h b/chrome/browser/ui/webui/ash/settings/search/search_tag_registry.h
index 8c00576..490101d 100644
--- a/chrome/browser/ui/webui/ash/settings/search/search_tag_registry.h
+++ b/chrome/browser/ui/webui/ash/settings/search/search_tag_registry.h
@@ -13,7 +13,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/observer_list.h"
 #include "base/observer_list_types.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.h"
 #include "chromeos/ash/components/local_search_service/public/mojom/index.mojom.h"
 #include "mojo/public/cpp/bindings/remote.h"
diff --git a/chrome/browser/ui/webui/ash/settings/test_support/fake_os_settings_section.h b/chrome/browser/ui/webui/ash/settings/test_support/fake_os_settings_section.h
index db626ea..7275fd7 100644
--- a/chrome/browser/ui/webui/ash/settings/test_support/fake_os_settings_section.h
+++ b/chrome/browser/ui/webui/ash/settings/test_support/fake_os_settings_section.h
@@ -10,7 +10,7 @@
 
 #include "ash/webui/settings/public/constants/setting.mojom-shared.h"
 #include "base/values.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_section.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_section.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash::settings {
diff --git a/chrome/browser/ui/webui/ash/settings/test_support/fake_os_settings_sections.h b/chrome/browser/ui/webui/ash/settings/test_support/fake_os_settings_sections.h
index e6a7ee9..0115835 100644
--- a/chrome/browser/ui/webui/ash/settings/test_support/fake_os_settings_sections.h
+++ b/chrome/browser/ui/webui/ash/settings/test_support/fake_os_settings_sections.h
@@ -5,7 +5,7 @@
 #ifndef CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_TEST_SUPPORT_FAKE_OS_SETTINGS_SECTIONS_H_
 #define CHROME_BROWSER_UI_WEBUI_ASH_SETTINGS_TEST_SUPPORT_FAKE_OS_SETTINGS_SECTIONS_H_
 
-#include "chrome/browser/ui/webui/settings/ash/os_settings_sections.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.h"
 
 namespace ash::settings {
 
diff --git a/chrome/browser/ui/webui/ash/web_app_install/BUILD.gn b/chrome/browser/ui/webui/ash/web_app_install/BUILD.gn
index f1d557f9..3cc9659 100644
--- a/chrome/browser/ui/webui/ash/web_app_install/BUILD.gn
+++ b/chrome/browser/ui/webui/ash/web_app_install/BUILD.gn
@@ -10,7 +10,10 @@
 mojom("mojo_bindings") {
   sources = [ "web_app_install.mojom" ]
 
-  public_deps = [ "//mojo/public/mojom/base" ]
+  public_deps = [
+    "//mojo/public/mojom/base",
+    "//url/mojom:url_mojom_gurl",
+  ]
   webui_module_path = "/"
   use_typescript_sources = true
 }
diff --git a/chrome/browser/ui/webui/ash/web_app_install/web_app_install.mojom b/chrome/browser/ui/webui/ash/web_app_install/web_app_install.mojom
index d12e420..7c37a1b4 100644
--- a/chrome/browser/ui/webui/ash/web_app_install/web_app_install.mojom
+++ b/chrome/browser/ui/webui/ash/web_app_install/web_app_install.mojom
@@ -4,6 +4,18 @@
 
 module ash.web_app_install.mojom;
 
+import "url/mojom/url.mojom";
+
+struct DialogArgs {
+  url.mojom.Url url;
+
+  string name;
+
+  string description;
+
+  // TODO(crbug.com/1488697): Add icons and screenshots.
+};
+
 // Lives in the browser process. A renderer uses this to create a page handler
 // that enables communication between a renderer and the browser process.
 interface PageHandlerFactory {
@@ -16,6 +28,9 @@
 interface PageHandler {
   // TODO(crbug.com/1488697): Add an InstallApp method.
 
+  // Returns arguments passed to the dialog on creation.
+  GetDialogArgs() => (DialogArgs args);
+
   // Closes the dialog.
   CloseDialog();
 };
diff --git a/chrome/browser/ui/webui/ash/web_app_install/web_app_install_dialog.cc b/chrome/browser/ui/webui/ash/web_app_install/web_app_install_dialog.cc
index 5ceffcc..0c62fda 100644
--- a/chrome/browser/ui/webui/ash/web_app_install/web_app_install_dialog.cc
+++ b/chrome/browser/ui/webui/ash/web_app_install/web_app_install_dialog.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/ui/webui/ash/web_app_install/web_app_install_dialog.h"
 
+#include "chrome/browser/ui/webui/ash/web_app_install/web_app_install.mojom.h"
+#include "chrome/browser/ui/webui/ash/web_app_install/web_app_install_ui.h"
 #include "chrome/common/webui_url_constants.h"
 #include "chromeos/constants/chromeos_features.h"
 
@@ -19,16 +21,26 @@
     return false;
   }
 
+  mojom::DialogArgsPtr args = mojom::DialogArgs::New();
+  // TODO(crbug.com/1488697): Get app data passed in and set the dialog args.
+
   // The pointer is managed by an instance of `views::WebDialogView` and removed
   // in `SystemWebDialogDelegate::OnDialogClosed`.
-  WebAppInstallDialog* dialog = new WebAppInstallDialog();
+  WebAppInstallDialog* dialog = new WebAppInstallDialog(std::move(args));
   dialog->ShowSystemDialog();
   return true;
 }
 
-WebAppInstallDialog::WebAppInstallDialog()
+void WebAppInstallDialog::OnDialogShown(content::WebUI* webui) {
+  DCHECK(dialog_args_);
+  static_cast<WebAppInstallDialogUI*>(webui->GetController())
+      ->SetDialogArgs(std::move(dialog_args_));
+}
+
+WebAppInstallDialog::WebAppInstallDialog(mojom::DialogArgsPtr args)
     : SystemWebDialogDelegate(GURL(chrome::kChromeUIWebAppInstallDialogURL),
-                              std::u16string() /* title */) {}
+                              std::u16string() /* title */),
+      dialog_args_(std::move(args)) {}
 
 WebAppInstallDialog::~WebAppInstallDialog() = default;
 
diff --git a/chrome/browser/ui/webui/ash/web_app_install/web_app_install_dialog.h b/chrome/browser/ui/webui/ash/web_app_install/web_app_install_dialog.h
index 89c3972..52e05024 100644
--- a/chrome/browser/ui/webui/ash/web_app_install/web_app_install_dialog.h
+++ b/chrome/browser/ui/webui/ash/web_app_install/web_app_install_dialog.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_UI_WEBUI_ASH_WEB_APP_INSTALL_WEB_APP_INSTALL_DIALOG_H_
 
 #include "chrome/browser/ui/webui/ash/system_web_dialog_delegate.h"
+#include "chrome/browser/ui/webui/ash/web_app_install/web_app_install.mojom.h"
 
 namespace ash::web_app_install {
 
@@ -19,10 +20,15 @@
   // if a new dialog has been effectively created.
   static bool Show();
 
+  void OnDialogShown(content::WebUI* webui) override;
+
  protected:
-  WebAppInstallDialog();
+  explicit WebAppInstallDialog(mojom::DialogArgsPtr args);
   ~WebAppInstallDialog() override;
   bool ShouldShowCloseButton() const override;
+
+ private:
+  mojom::DialogArgsPtr dialog_args_;
 };
 
 }  // namespace ash::web_app_install
diff --git a/chrome/browser/ui/webui/ash/web_app_install/web_app_install_page_handler.cc b/chrome/browser/ui/webui/ash/web_app_install/web_app_install_page_handler.cc
index 55b92b33..59bd618a 100644
--- a/chrome/browser/ui/webui/ash/web_app_install/web_app_install_page_handler.cc
+++ b/chrome/browser/ui/webui/ash/web_app_install/web_app_install_page_handler.cc
@@ -4,17 +4,26 @@
 
 #include "chrome/browser/ui/webui/ash/web_app_install/web_app_install_page_handler.h"
 
+#include "chrome/browser/ui/webui/ash/web_app_install/web_app_install.mojom.h"
+
 namespace ash::web_app_install {
 
 WebAppInstallPageHandler::WebAppInstallPageHandler(
+    mojom::DialogArgsPtr args,
     mojo::PendingReceiver<ash::web_app_install::mojom::PageHandler>
         pending_page_handler,
     CloseDialogCallback close_dialog_callback)
-    : receiver_{this, std::move(pending_page_handler)},
+    : dialog_args_{std::move(args)},
+      receiver_{this, std::move(pending_page_handler)},
       close_dialog_callback_{std::move(close_dialog_callback)} {}
 
 WebAppInstallPageHandler::~WebAppInstallPageHandler() = default;
 
+void WebAppInstallPageHandler::GetDialogArgs(GetDialogArgsCallback callback) {
+  std::move(callback).Run(dialog_args_ ? dialog_args_.Clone()
+                                       : mojom::DialogArgs::New());
+}
+
 void WebAppInstallPageHandler::CloseDialog() {
   // The callback could be null if the close button is clicked a second time
   // before the dialog closes.
diff --git a/chrome/browser/ui/webui/ash/web_app_install/web_app_install_page_handler.h b/chrome/browser/ui/webui/ash/web_app_install/web_app_install_page_handler.h
index eb60c52..cbab6d3 100644
--- a/chrome/browser/ui/webui/ash/web_app_install/web_app_install_page_handler.h
+++ b/chrome/browser/ui/webui/ash/web_app_install/web_app_install_page_handler.h
@@ -21,6 +21,7 @@
  public:
   using CloseDialogCallback = base::OnceCallback<void()>;
   explicit WebAppInstallPageHandler(
+      mojom::DialogArgsPtr args,
       mojo::PendingReceiver<mojom::PageHandler> pending_page_handler,
       CloseDialogCallback close_dialog_callback);
 
@@ -30,9 +31,11 @@
   ~WebAppInstallPageHandler() override;
 
   // mojom::PageHandler:
+  void GetDialogArgs(GetDialogArgsCallback callback) override;
   void CloseDialog() override;
 
  private:
+  mojom::DialogArgsPtr dialog_args_;
   mojo::Receiver<mojom::PageHandler> receiver_;
   CloseDialogCallback close_dialog_callback_;
 
diff --git a/chrome/browser/ui/webui/ash/web_app_install/web_app_install_ui.cc b/chrome/browser/ui/webui/ash/web_app_install/web_app_install_ui.cc
index 39de71e4..452ed24 100644
--- a/chrome/browser/ui/webui/ash/web_app_install/web_app_install_ui.cc
+++ b/chrome/browser/ui/webui/ash/web_app_install/web_app_install_ui.cc
@@ -39,6 +39,10 @@
 
 WebAppInstallDialogUI::~WebAppInstallDialogUI() = default;
 
+void WebAppInstallDialogUI::SetDialogArgs(mojom::DialogArgsPtr args) {
+  dialog_args_ = std::move(args);
+}
+
 void WebAppInstallDialogUI::BindInterface(
     mojo::PendingReceiver<mojom::PageHandlerFactory> pending_receiver) {
   if (factory_receiver_.is_bound()) {
@@ -50,8 +54,9 @@
 void WebAppInstallDialogUI::CreatePageHandler(
     mojo::PendingReceiver<mojom::PageHandler> receiver) {
   page_handler_ = std::make_unique<WebAppInstallPageHandler>(
-      std::move(receiver), base::BindOnce(&WebAppInstallDialogUI::CloseDialog,
-                                          base::Unretained(this)));
+      std::move(dialog_args_), std::move(receiver),
+      base::BindOnce(&WebAppInstallDialogUI::CloseDialog,
+                     base::Unretained(this)));
 }
 
 void WebAppInstallDialogUI::CloseDialog() {
diff --git a/chrome/browser/ui/webui/ash/web_app_install/web_app_install_ui.h b/chrome/browser/ui/webui/ash/web_app_install/web_app_install_ui.h
index 3725029..a8d3705 100644
--- a/chrome/browser/ui/webui/ash/web_app_install/web_app_install_ui.h
+++ b/chrome/browser/ui/webui/ash/web_app_install/web_app_install_ui.h
@@ -21,6 +21,8 @@
   WebAppInstallDialogUI& operator=(const WebAppInstallDialogUI&) = delete;
   ~WebAppInstallDialogUI() override;
 
+  void SetDialogArgs(mojom::DialogArgsPtr args);
+
   // Instantiates the implementor of the mojom::PageHandlerFactory mojo
   // interface passing the pending receiver that will be internally bound.
   void BindInterface(mojo::PendingReceiver<mojom::PageHandlerFactory> receiver);
@@ -32,6 +34,7 @@
  private:
   void CloseDialog();
 
+  mojom::DialogArgsPtr dialog_args_;
   std::unique_ptr<WebAppInstallPageHandler> page_handler_;
   mojo::Receiver<mojom::PageHandlerFactory> factory_receiver_{this};
 
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 122a3d93d..06bf28a 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -1170,6 +1170,7 @@
     GURL(chrome::kChromeUIBluetoothInternalsURL),
     GURL(chrome::kChromeUIBluetoothPairingURL),
     GURL(chrome::kChromeUIBorealisCreditsURL),
+    GURL(chrome::kChromeUIBorealisInstallerUrl),
     GURL(chrome::kChromeUICloudUploadURL),
     GURL(chrome::kChromeUIConnectivityDiagnosticsAppURL),
     GURL(chrome::kChromeUICrashesUrl),
diff --git a/chrome/browser/ui/webui/flags/flags_ui.cc b/chrome/browser/ui/webui/flags/flags_ui.cc
index e95f5c89..ea25114f 100644
--- a/chrome/browser/ui/webui/flags/flags_ui.cc
+++ b/chrome/browser/ui/webui/flags/flags_ui.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/flags/flags_ui_handler.h"
+#include "chrome/browser/ui/webui/webui_util.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 #include "components/flags_ui/flags_ui_constants.h"
@@ -36,7 +37,6 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "content/public/browser/web_ui_message_handler.h"
-#include "services/network/public/mojom/content_security_policy.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 
@@ -65,13 +65,6 @@
 content::WebUIDataSource* CreateAndAddFlagsUIHTMLSource(Profile* profile) {
   content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd(
       profile, chrome::kChromeUIFlagsHost);
-  source->EnableReplaceI18nInJS();
-  source->OverrideContentSecurityPolicy(
-      network::mojom::CSPDirectiveName::ScriptSrc,
-      "script-src chrome://resources 'self';");
-  source->OverrideContentSecurityPolicy(
-      network::mojom::CSPDirectiveName::TrustedTypes,
-      "trusted-types static-types;");
   source->AddString(flags_ui::kVersion,
                     std::string(version_info::GetVersionNumber()));
 
@@ -89,10 +82,9 @@
   }
 #endif
 
-  source->AddResourcePaths(
-      base::make_span(kFlagsUiResources, kFlagsUiResourcesSize));
-  source->SetDefaultResource(IDR_FLAGS_UI_FLAGS_HTML);
-  source->UseStringsJs();
+  webui::SetupWebUIDataSource(
+      source, base::make_span(kFlagsUiResources, kFlagsUiResourcesSize),
+      IDR_FLAGS_UI_FLAGS_HTML);
   return source;
 }
 
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
index 1f912b9..8c94bd9 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -415,11 +415,17 @@
       {"modulesCartLowerYour", IDS_NTP_MODULES_CART_LOWER_YOUR},
       {"modulesDisableToastMessage",
        IDS_NTP_MODULES_HISTORY_CLUSTERS_DISABLE_TOAST_MESSAGE},
+      {"modulesDriveDisableButtonText",
+       IDS_NTP_MODULES_DRIVE_DISABLE_BUTTON_TEXT},
+      {"modulesDriveDisableButtonTextV2",
+       IDS_NTP_MODULES_DRIVE_DISABLE_BUTTON_TEXT_V2},
+      {"modulesDriveDismissButtonText",
+       IDS_NTP_MODULES_DRIVE_DISMISS_BUTTON_TEXT},
+      {"modulesDriveMoreActionsButtonText",
+       IDS_NTP_MODULES_DRIVE_MORE_ACTIONS_BUTTON_TEXT},
       {"modulesDriveSentence", IDS_NTP_MODULES_DRIVE_SENTENCE},
-      {"modulesDriveSentenceV2", IDS_NTP_MODULES_DRIVE_SENTENCE_V2},
       {"modulesDriveSentence2", IDS_NTP_MODULES_DRIVE_SENTENCE2},
       {"modulesDriveFilesSentence", IDS_NTP_MODULES_DRIVE_FILES_SENTENCE},
-      {"modulesDriveFilesLower", IDS_NTP_MODULES_DRIVE_FILES_LOWER},
       {"modulesDummyLower", IDS_NTP_MODULES_DUMMY_LOWER},
       {"modulesDriveTitle", IDS_NTP_MODULES_DRIVE_TITLE},
       {"modulesDriveTitleV2", IDS_NTP_MODULES_DRIVE_TITLE_V2},
diff --git a/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc b/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc
index d339218..143e1b8 100644
--- a/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc
+++ b/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc
@@ -501,7 +501,14 @@
 
 void OmniboxPageHandler::GetMlModelVersion(GetMlModelVersionCallback callback) {
   if (auto* service = GetMlService()) {
-    std::move(callback).Run(service->GetModelVersion());
+    auto version = service->GetModelVersion();
+    if (version == -1) {
+      service->AddOnModelUpdatedCallback(
+          base::BindOnce(&OmniboxPageHandler::GetMlModelVersion,
+                         weak_factory_.GetWeakPtr(), std::move(callback)));
+    } else {
+      std::move(callback).Run(version);
+    }
   } else {
     std::move(callback).Run(-1);
   }
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
index de0d3296..2b52075 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -20,6 +20,7 @@
 #include "base/i18n/number_formatting.h"
 #include "base/json/json_reader.h"
 #include "base/lazy_instance.h"
+#include "base/time/time.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -607,7 +608,8 @@
       base::BindRepeating(&PrintPreviewHandler::OnAddedPrinters,
                           weak_factory_.GetWeakPtr(), printer_type),
       base::BindOnce(&PrintPreviewHandler::OnGetPrintersDone,
-                     weak_factory_.GetWeakPtr(), callback_id));
+                     weak_factory_.GetWeakPtr(), callback_id, printer_type,
+                     base::TimeTicks::Now()));
 }
 
 void PrintPreviewHandler::HandleGetPrinterCapabilities(
@@ -1222,7 +1224,10 @@
   }
 }
 
-void PrintPreviewHandler::OnGetPrintersDone(const std::string& callback_id) {
+void PrintPreviewHandler::OnGetPrintersDone(const std::string& callback_id,
+                                            mojom::PrinterType printer_type,
+                                            const base::TimeTicks& start_time) {
+  RecordGetPrintersTimeHistogram(printer_type, start_time);
   ResolveJavascriptCallback(base::Value(callback_id), base::Value());
 }
 
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.h b/chrome/browser/ui/webui/print_preview/print_preview_handler.h
index e6f90073..9890bb9 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler.h
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.h
@@ -30,6 +30,10 @@
 #include "printing/print_job_constants.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
+namespace base {
+class TimeTicks;
+}  // namespace base
+
 #if BUILDFLAG(IS_CHROMEOS)
 namespace crosapi {
 namespace mojom {
@@ -261,7 +265,9 @@
 
   // Called when printer search is done for some destination type.
   // |callback_id|: The javascript callback to call.
-  void OnGetPrintersDone(const std::string& callback_id);
+  void OnGetPrintersDone(const std::string& callback_id,
+                         mojom::PrinterType printer_type,
+                         const base::TimeTicks& start_time);
 
   // Called when an extension print job is completed.
   // |callback_id|: The javascript callback to run.
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
index fc87f6c..6d9d2bb 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
@@ -1167,6 +1167,7 @@
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
 TEST_F(PrintPreviewHandlerTest, GetPrinters) {
+  base::HistogramTester histogram_tester;
   Initialize();
 
   // Check all three printer types that implement
@@ -1189,6 +1190,10 @@
     const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
     CheckWebUIResponse(data, callback_id_in, true);
   }
+  histogram_tester.ExpectTotalCount("PrintPreview.GetPrintersTime.Extension",
+                                    1);
+  histogram_tester.ExpectTotalCount("PrintPreview.GetPrintersTime.Local", 1);
+  histogram_tester.ExpectTotalCount("PrintPreview.GetPrintersTime.PDF", 0);
 }
 
 // Validates the 'printing.printer_type_deny_list' pref by placing the extension
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_metrics.cc b/chrome/browser/ui/webui/print_preview/print_preview_metrics.cc
index a2fdb48a..12213c8 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_metrics.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_metrics.cc
@@ -8,6 +8,8 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/no_destructor.h"
+#include "base/strings/strcat.h"
+#include "base/time/time.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -177,4 +179,28 @@
   UMA_HISTOGRAM_ENUMERATION("PrintPreview.UserAction", event);
 }
 
+void RecordGetPrintersTimeHistogram(mojom::PrinterType printer_type,
+                                    const base::TimeTicks& start_time) {
+  std::string printer_type_metric;
+  switch (printer_type) {
+    case mojom::PrinterType::kExtension:
+      printer_type_metric = "Extension";
+      break;
+    case mojom::PrinterType::kPdf:
+      printer_type_metric = "PDF";
+      break;
+    case mojom::PrinterType::kLocal:
+      printer_type_metric = "Local";
+      break;
+    case mojom::PrinterType::kPrivetDeprecated:
+    case mojom::PrinterType::kCloudDeprecated:
+      NOTREACHED_NORETURN();
+  }
+  base::UmaHistogramCustomTimes(
+      base::StrCat({"PrintPreview.GetPrintersTime.", printer_type_metric}),
+      /*sample=*/base::TimeTicks::Now() - start_time,
+      /*min=*/base::Milliseconds(1),
+      /*max=*/base::Minutes(1), /*buckets=*/50);
+}
+
 }  // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_metrics.h b/chrome/browser/ui/webui/print_preview/print_preview_metrics.h
index 7baf331..8869728 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_metrics.h
+++ b/chrome/browser/ui/webui/print_preview/print_preview_metrics.h
@@ -8,6 +8,11 @@
 #include <cstddef>
 
 #include "base/values.h"
+#include "printing/mojom/print.mojom-forward.h"
+
+namespace base {
+class TimeTicks;
+}  // namespace base
 
 namespace printing {
 
@@ -84,6 +89,9 @@
 
 void ReportUserActionHistogram(UserActionBuckets event);
 
+void RecordGetPrintersTimeHistogram(mojom::PrinterType printer_type,
+                                    const base::TimeTicks& start_time);
+
 }  // namespace printing
 
 #endif  // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_METRICS_H_
diff --git a/chrome/browser/ui/webui/settings/ash/os_settings_manager.cc b/chrome/browser/ui/webui/settings/ash/os_settings_manager.cc
index c9c2c4b..bcbf43e1 100644
--- a/chrome/browser/ui/webui/settings/ash/os_settings_manager.cc
+++ b/chrome/browser/ui/webui/settings/ash/os_settings_manager.cc
@@ -9,11 +9,11 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/apps/app_notification_handler.h"
 #include "chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.h"
 #include "chrome/browser/ui/webui/ash/settings/search/hierarchy.h"
 #include "chrome/browser/ui/webui/ash/settings/search/search_handler.h"
 #include "chrome/browser/ui/webui/ash/settings/search/search_tag_registry.h"
 #include "chrome/browser/ui/webui/settings/ash/display_settings/display_settings_provider.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_sections.h"
 #include "chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.h"
 #include "chromeos/ash/components/phonehub/phone_hub_manager.h"
 #include "chromeos/constants/chromeos_features.h"
diff --git a/chrome/browser/ui/webui/settings/ash/os_settings_manager_unittest.cc b/chrome/browser/ui/webui/settings/ash/os_settings_manager_unittest.cc
index 063607f..16cc030 100644
--- a/chrome/browser/ui/webui/settings/ash/os_settings_manager_unittest.cc
+++ b/chrome/browser/ui/webui/settings/ash/os_settings_manager_unittest.cc
@@ -18,9 +18,9 @@
 #include "chrome/browser/ash/printing/cups_printers_manager_factory.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/ui/webui/ash/settings/constants/constants_util.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.h"
 #include "chrome/browser/ui/webui/ash/settings/search/hierarchy.h"
 #include "chrome/browser/ui/webui/settings/ash/os_settings_manager_factory.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_sections.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
diff --git a/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.cc b/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.cc
index 3c566ef2..f7d7c17 100644
--- a/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.cc
+++ b/chrome/browser/ui/webui/settings/ash/settings_user_action_tracker.cc
@@ -8,8 +8,8 @@
 #include <utility>
 
 #include "base/metrics/histogram_functions.h"
+#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.h"
 #include "chrome/browser/ui/webui/ash/settings/search/hierarchy.h"
-#include "chrome/browser/ui/webui/settings/ash/os_settings_sections.h"
 
 namespace ash::settings {
 
diff --git a/chrome/browser/ui/webui/settings/search_engines_handler.cc b/chrome/browser/ui/webui/settings/search_engines_handler.cc
index ad9fff2..5491c103 100644
--- a/chrome/browser/ui/webui/settings/search_engines_handler.cc
+++ b/chrome/browser/ui/webui/settings/search_engines_handler.cc
@@ -132,8 +132,7 @@
     defaults.Append(CreateDictionaryForEngine(i, i == default_index));
   }
 
-  // Build the second list (active search engines). This will not have any
-  // entries if the new Search Engines page is not enabled.
+  // Build the second list (active search engines).
   base::Value::List actives;
   size_t last_active_engine_index =
       list_controller_.table_model()->last_active_engine_index();
@@ -145,7 +144,7 @@
     actives.Append(CreateDictionaryForEngine(i, i == default_index));
   }
 
-  // Build the second list (other search engines).
+  // Build the third list (other search engines).
   base::Value::List others;
   size_t last_other_engine_index =
       list_controller_.table_model()->last_other_engine_index();
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome.mojom b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome.mojom
index b0894f4..e2c5321 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome.mojom
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome.mojom
@@ -176,9 +176,11 @@
   // Retrieves NTP descriptors.
   GetDescriptors() => (Descriptors? descriptors);
 
-  // Searches NTP wallpaper for `query`. Returns list of sanitized image data.
-  GetWallpaperSearchResults(string descriptor_a, string? descriptor_b,
-    string? descriptor_c) => (array<WallpaperSearchResult> results);
+  // Searches NTP wallpaper for descriptors.
+  // Returns list of sanitized image data.
+  GetWallpaperSearchResults(string descriptor_a,
+      string? descriptor_b, string? descriptor_c,
+      string? descriptor_d) => (array<WallpaperSearchResult> results);
 
   // Sets wallpaper search result of index to background image.
   SetBackgroundToWallpaperSearchResult(mojo_base.mojom.Token result_id);
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.cc b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.cc
index 03ec517..92a04dbf 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.cc
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.cc
@@ -476,6 +476,7 @@
     const std::string& descriptor_a,
     const absl::optional<std::string>& descriptor_b,
     const absl::optional<std::string>& descriptor_c,
+    const absl::optional<std::string>& descriptor_d,
     GetWallpaperSearchResultsCallback callback) {
   callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun(
       std::move(callback),
@@ -494,7 +495,8 @@
   chrome_intelligence_modelexecution_proto::WallpaperSearchRequest request;
   request.set_query(base::StrCat(
       {descriptor_a, descriptor_b ? " " : "", descriptor_b.value_or(""),
-       descriptor_c ? " " : "", descriptor_c.value_or("")}));
+       descriptor_c ? " " : "", descriptor_c.value_or(""),
+       descriptor_d ? " " : "", descriptor_d.value_or("")}));
   optimization_guide_keyed_service->ExecuteModel(
       optimization_guide::proto::ModelExecutionFeature::
           MODEL_EXECUTION_FEATURE_WALLPAPER_SEARCH,
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.h b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.h
index 3c4a166..1b4af62 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.h
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.h
@@ -114,6 +114,7 @@
       const std::string& descriptor_a,
       const absl::optional<std::string>& descriptor_b,
       const absl::optional<std::string>& descriptor_c,
+      const absl::optional<std::string>& descriptor_d,
       GetWallpaperSearchResultsCallback callback) override;
   void SetBackgroundToWallpaperSearchResult(
       const base::Token& result_id) override;
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler_unittest.cc b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler_unittest.cc
index af5540f..f5764e6 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler_unittest.cc
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler_unittest.cc
@@ -1027,8 +1027,9 @@
       CustomizeChromePageHandler::GetWallpaperSearchResultsCallback>
       callback;
 
-  handler().GetWallpaperSearchResults("foo", "bar", "baz", callback.Get());
-  EXPECT_EQ("foo bar baz", request.query());
+  handler().GetWallpaperSearchResults("foo", "bar", "baz", "qux",
+                                      callback.Get());
+  EXPECT_EQ("foo bar baz qux", request.query());
 
   chrome_intelligence_modelexecution_proto::WallpaperSearchResponse response;
 
@@ -1104,8 +1105,8 @@
   testing::NiceMock<base::MockCallback<
       CustomizeChromePageHandler::GetWallpaperSearchResultsCallback>>
       callback;
-  handler().GetWallpaperSearchResults("foo", absl::nullopt, "bar",
-                                      callback.Get());
+  handler().GetWallpaperSearchResults("foo", absl::nullopt, absl::nullopt,
+                                      "bar", callback.Get());
 
   EXPECT_EQ("foo bar", request.query());
 }
@@ -1133,7 +1134,7 @@
       callback;
 
   handler().GetWallpaperSearchResults("foo", absl::nullopt, absl::nullopt,
-                                      callback.Get());
+                                      absl::nullopt, callback.Get());
   EXPECT_EQ("foo", request.query());
 
   std::vector<side_panel::mojom::WallpaperSearchResultPtr> images;
@@ -1167,7 +1168,7 @@
       callback;
 
   handler().GetWallpaperSearchResults("foo", absl::nullopt, absl::nullopt,
-                                      callback.Get());
+                                      absl::nullopt, callback.Get());
   EXPECT_EQ("foo", request.query());
 
   chrome_intelligence_modelexecution_proto::WallpaperSearchResponse response;
@@ -1225,7 +1226,7 @@
       callback;
 
   handler().GetWallpaperSearchResults("foo", absl::nullopt, absl::nullopt,
-                                      callback.Get());
+                                      absl::nullopt, callback.Get());
   EXPECT_EQ("foo", request.query());
 
   chrome_intelligence_modelexecution_proto::WallpaperSearchResponse response;
diff --git a/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc b/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc
index b4ab8a72..ca568b5 100644
--- a/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc
+++ b/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc
@@ -80,6 +80,13 @@
       {"test_loader.js", IDR_WEBUI_JS_TEST_LOADER_JS},
       {"test_loader_util.js", IDR_WEBUI_JS_TEST_LOADER_UTIL_JS},
       {"test_loader.html", IDR_WEBUI_TEST_LOADER_HTML},
+      // Resources for the Chrome signin sub page: chrome_signin/.
+      {chrome::kChromeUIDiceWebSigninInterceptChromeSigninSubPage,
+       IDR_SIGNIN_DICE_WEB_SIGNIN_INTERCEPT_CHROME_SIGNIN_CHROME_SIGNIN_HTML},
+      {"chrome_signin/chrome_signin_app.js",
+       IDR_SIGNIN_DICE_WEB_SIGNIN_INTERCEPT_CHROME_SIGNIN_CHROME_SIGNIN_APP_JS},
+      {"chrome_signin/chrome_signin_app.html.js",
+       IDR_SIGNIN_DICE_WEB_SIGNIN_INTERCEPT_CHROME_SIGNIN_CHROME_SIGNIN_APP_HTML_JS},
   };
   source->AddResourcePaths(kResources);
 
@@ -109,8 +116,6 @@
     base::OnceCallback<void(int)> show_widget_with_height_callback,
     base::OnceCallback<void(SigninInterceptionUserChoice)>
         completion_callback) {
-  // TODO(b/301431278): Create a different handler for the Chrome Signin
-  // intercept UI.
   web_ui()->AddMessageHandler(std::make_unique<DiceWebSigninInterceptHandler>(
       bubble_parameters, std::move(show_widget_with_height_callback),
       std::move(completion_callback)));
diff --git a/chrome/browser/ui/webui/signin/inline_login_ui.cc b/chrome/browser/ui/webui/signin/inline_login_ui.cc
index e46f5fe1..3d0459f 100644
--- a/chrome/browser/ui/webui/signin/inline_login_ui.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_ui.cc
@@ -7,6 +7,7 @@
 #include <memory>
 
 #include "base/command_line.h"
+#include "base/containers/span.h"
 #include "base/functional/bind.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/branding_buildflags.h"
@@ -49,6 +50,8 @@
 #include "chrome/browser/ui/webui/signin/ash/inline_login_handler_impl.h"
 #include "chrome/grit/arc_account_picker_resources.h"
 #include "chrome/grit/arc_account_picker_resources_map.h"
+#include "chrome/grit/edu_coexistence_resources.h"
+#include "chrome/grit/edu_coexistence_resources_map.h"
 #include "chrome/grit/gaia_action_buttons_resources.h"
 #include "chrome/grit/gaia_action_buttons_resources_map.h"
 #include "chrome/grit/supervision_resources.h"
@@ -132,6 +135,8 @@
   source->AddResourcePaths(base::make_span(kGaiaActionButtonsResources,
                                            kGaiaActionButtonsResourcesSize));
   source->AddResourcePaths(
+      base::make_span(kEduCoexistenceResources, kEduCoexistenceResourcesSize));
+  source->AddResourcePaths(
       base::make_span(kSupervisionResources, kSupervisionResourcesSize));
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
@@ -152,20 +157,7 @@
     {"error_screen.js", IDR_ACCOUNT_MANAGER_COMPONENTS_ERROR_SCREEN_JS},
     // Resources for the server-based edu coexistence flow.
     {"edu-coexistence", IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_HTML},
-    {"edu_coexistence_app.js", IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_APP_JS},
-    {"edu_coexistence_ui.js", IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_UI_JS},
-    {"edu_coexistence_controller.js",
-     IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_CONTROLLER_JS},
-    {"edu_coexistence_browser_proxy.js",
-     IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_BROWSER_PROXY_JS},
-    {"edu_coexistence_button.js",
-     IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_BUTTON_JS},
-    {"edu_coexistence_offline.js",
-     IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_OFFLINE_JS},
-    {"edu_coexistence_error.js", IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_ERROR_JS},
-    {"edu_coexistence_template.js",
-     IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_TEMPLATE_JS},
-    {"edu_coexistence_css.js", IDR_EDU_COEXISTENCE_EDU_COEXISTENCE_CSS_JS},
+
     {"account_manager_signin_blocked_by_policy.svg",
      IDS_ACCOUNT_MANAGER_SIGNIN_BLOCKED_BY_POLICY_SVG},
 
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn
index 02b0f4a..868ce44 100644
--- a/chrome/browser/web_applications/BUILD.gn
+++ b/chrome/browser/web_applications/BUILD.gn
@@ -983,7 +983,7 @@
     sources += [ "chromeos_web_app_experiments_browsertest.cc" ]
   }
 
-  # On Lacros, this test is added to the lacros_chrome_browsertests_run_in_series target.
+  # On Lacros, this test is added to the lacros_chrome_browsertests target.
   if (!is_chromeos_lacros) {
     sources += [ "externally_managed_app_manager_browsertest.cc" ]
   }
diff --git a/chrome/browser/web_applications/app_service/browser_shortcuts.cc b/chrome/browser/web_applications/app_service/browser_shortcuts.cc
index f7e3122..f7ff072d 100644
--- a/chrome/browser/web_applications/app_service/browser_shortcuts.cc
+++ b/chrome/browser/web_applications/app_service/browser_shortcuts.cc
@@ -9,7 +9,6 @@
 
 #include "base/no_destructor.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/app_launch_params.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
@@ -23,6 +22,7 @@
 #include "components/app_constants/constants.h"
 #include "components/services/app_service/public/cpp/app_registry_cache.h"
 #include "components/services/app_service/public/cpp/app_types.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
 #include "components/services/app_service/public/cpp/shortcut/shortcut.h"
 #include "components/services/app_service/public/cpp/shortcut/shortcut_registry_cache.h"
diff --git a/chrome/browser/web_applications/app_service/browser_shortcuts_unittest.cc b/chrome/browser/web_applications/app_service/browser_shortcuts_unittest.cc
index f67c72f8..ca1b2c48 100644
--- a/chrome/browser/web_applications/app_service/browser_shortcuts_unittest.cc
+++ b/chrome/browser/web_applications/app_service/browser_shortcuts_unittest.cc
@@ -9,7 +9,6 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/test/test_future.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/app_service/app_service_test.h"
@@ -25,6 +24,7 @@
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/app_constants/constants.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "components/services/app_service/public/cpp/shortcut/shortcut.h"
 #include "components/services/app_service/public/cpp/shortcut/shortcut_registry_cache.h"
 #include "content/public/test/browser_task_environment.h"
diff --git a/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc b/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc
index 86538a9..c6de9e4 100644
--- a/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc
+++ b/chrome/browser/web_applications/app_service/lacros_web_apps_controller_browsertest.cc
@@ -28,7 +28,6 @@
 #include "base/test/test_future.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/time/time.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
 #include "chrome/browser/apps/app_service/browser_app_instance_tracker.h"
@@ -72,6 +71,7 @@
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/app_types.h"
 #include "components/services/app_service/public/cpp/capability_access.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
 #include "components/services/app_service/public/cpp/intent_filter.h"
 #include "components/services/app_service/public/cpp/intent_util.h"
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
index 95b1a04a0..b31c8de 100644
--- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
+++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
@@ -43,7 +43,6 @@
 #include "build/buildflag.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/app_launch_params.h"
 #include "chrome/browser/apps/app_service/intent_util.h"
 #include "chrome/browser/apps/app_service/launch_utils.h"
@@ -80,6 +79,7 @@
 #include "components/content_settings/core/common/content_settings_types.h"
 #include "components/services/app_service/public/cpp/app_launch_util.h"
 #include "components/services/app_service/public/cpp/file_handler.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 #include "components/services/app_service/public/cpp/intent_filter.h"
 #include "components/services/app_service/public/cpp/intent_filter_util.h"
 #include "components/services/app_service/public/cpp/intent_util.h"
diff --git a/chrome/browser/web_applications/app_service/web_apps.cc b/chrome/browser/web_applications/app_service/web_apps.cc
index 9f04e34..0079e82 100644
--- a/chrome/browser/web_applications/app_service/web_apps.cc
+++ b/chrome/browser/web_applications/app_service/web_apps.cc
@@ -10,7 +10,6 @@
 #include "base/memory/weak_ptr.h"
 #include "base/trace_event/trace_event.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
-#include "chrome/browser/apps/app_service/app_icon/icon_effects.h"
 #include "chrome/browser/apps/app_service/app_launch_params.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/profiles/profile.h"
@@ -20,6 +19,7 @@
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/browser/web_applications/web_app_registrar.h"
 #include "chrome/browser/web_applications/web_app_utils.h"
+#include "components/services/app_service/public/cpp/icon_effects.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/constants/ash_features.h"
diff --git a/chrome/browser/web_applications/test/fake_web_app_ui_manager.cc b/chrome/browser/web_applications/test/fake_web_app_ui_manager.cc
index 7db8cd8f..15edcbd79 100644
--- a/chrome/browser/web_applications/test/fake_web_app_ui_manager.cc
+++ b/chrome/browser/web_applications/test/fake_web_app_ui_manager.cc
@@ -209,4 +209,8 @@
 void FakeWebAppUiManager::LaunchIsolatedWebAppInstaller(
     const base::FilePath& bundle_path) {}
 
+void FakeWebAppUiManager::MaybeCreateEnableSupportedLinksInfobar(
+    content::WebContents* web_contents,
+    const std::string& launch_name) {}
+
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/test/fake_web_app_ui_manager.h b/chrome/browser/web_applications/test/fake_web_app_ui_manager.h
index 7fe28fc..c56165c 100644
--- a/chrome/browser/web_applications/test/fake_web_app_ui_manager.h
+++ b/chrome/browser/web_applications/test/fake_web_app_ui_manager.h
@@ -119,6 +119,10 @@
   void LaunchIsolatedWebAppInstaller(
       const base::FilePath& bundle_path) override;
 
+  void MaybeCreateEnableSupportedLinksInfobar(
+      content::WebContents* web_contents,
+      const std::string& launch_name) override;
+
  private:
   base::flat_map<webapps::AppId, size_t> app_id_to_num_windows_map_;
   // Closures waiting to be called when all windows for a given `webapps::AppId`
diff --git a/chrome/browser/web_applications/web_app_ui_manager.h b/chrome/browser/web_applications/web_app_ui_manager.h
index 4eb8ecd5..27dfe07 100644
--- a/chrome/browser/web_applications/web_app_ui_manager.h
+++ b/chrome/browser/web_applications/web_app_ui_manager.h
@@ -238,6 +238,12 @@
   virtual void LaunchIsolatedWebAppInstaller(
       const base::FilePath& bundle_path) = 0;
 
+  // Creates the EnableSupportedLinksInfobar in an app window when the app is
+  // launched via link capturing from a link.
+  virtual void MaybeCreateEnableSupportedLinksInfobar(
+      content::WebContents* web_contents,
+      const std::string& launch_name) = 0;
+
  private:
   base::ObserverList<WebAppUiManagerObserver, /*check_empty=*/true> observers_;
 
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt
index 095ddd9..d19b9680 100644
--- a/chrome/build/android-arm32.pgo.txt
+++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@
-chrome-android32-main-1697630396-a9607199ad8afd010c3cf045d6629276c14e8880.profdata
+chrome-android32-main-1697673542-f0af53ef790d495a0ebe4bb454d306375d6848b3.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt
index 3860baf..94102da 100644
--- a/chrome/build/android-arm64.pgo.txt
+++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@
-chrome-android64-main-1697630396-abb5c3305c6f412aff356fd4c4d93d5e653f48d7.profdata
+chrome-android64-main-1697673542-8ca8fc35bab94aa8f42d410a8a230f0d3fbdf4bd.profdata
diff --git a/chrome/build/lacros64.pgo.txt b/chrome/build/lacros64.pgo.txt
index 121e21d..c7dbe300 100644
--- a/chrome/build/lacros64.pgo.txt
+++ b/chrome/build/lacros64.pgo.txt
@@ -1 +1 @@
-chrome-chromeos-amd64-generic-main-1697630485-e1717a08e8e45f6c7b87fff3e8c9ecb921d81102.profdata
+chrome-chromeos-amd64-generic-main-1697673542-8a6a0cf443ab2ea1fe29fe94922d293961c740e8.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index f99e8f8..3792f69 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1697630396-04abd7870ded80eb74edc225bef03248c538986a.profdata
+chrome-linux-main-1697673542-07c2c922bf986e31aca322e6a21cc4e71ac892d2.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index a02e7ae..622cce6 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1697637597-01aa924e1b8bbef23ec89dc5f6eca119756bc62e.profdata
+chrome-mac-arm-main-1697680203-52f62c11a713b00f087c739ed842bd5f75fb8734.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 936f5acc..9153a0f 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1697630396-03b0f3ccca7685dabb16de3415fb05feda7a449b.profdata
+chrome-mac-main-1697673542-c908b6200ddccf5b0977ae94aac02030d560bde1.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt
index 2de3714..cc567f5f 100644
--- a/chrome/build/win-arm64.pgo.txt
+++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@
-chrome-win-arm64-main-1697630396-0f9ea6f438730702c30eb3aaad8175bd52ab7287.profdata
+chrome-win-arm64-main-1697673542-885b5b6800bd2ebe5af24eddc25b492727c8a40d.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 1981003..e4d1e90 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1697630396-9fd191e88a1090f75ee0058c51d23173bd67764a.profdata
+chrome-win32-main-1697662777-b4e5898d26a7deabc0dc6f7e577bacde17651258.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index a20410a3..a35af27e 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1697630396-b68b2722b9084b50611983c823171351429cb730.profdata
+chrome-win64-main-1697662777-d232c3fe2c1431b3eb33ab218623e6f8ecb073eb.profdata
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni
index 27d5b89..a9614a5 100644
--- a/chrome/chrome_paks.gni
+++ b/chrome/chrome_paks.gni
@@ -264,6 +264,7 @@
         "$root_gen_dir/chrome/cloud_upload_resources.pak",
         "$root_gen_dir/chrome/cros_styles_resources.pak",
         "$root_gen_dir/chrome/desk_api_resources.pak",
+        "$root_gen_dir/chrome/edu_coexistence_resources.pak",
         "$root_gen_dir/chrome/emoji_picker_resources.pak",
         "$root_gen_dir/chrome/enterprise_reporting_resources.pak",
         "$root_gen_dir/chrome/gaia_action_buttons_resources.pak",
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 89d18a3..74b7507 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -454,13 +454,6 @@
              base::FEATURE_ENABLED_BY_DEFAULT);
 #endif
 
-// If enabled, this feature's |kExternalInstallDefaultButtonKey| field trial
-// parameter value controls which |ExternalInstallBubbleAlert| button is the
-// default.
-BASE_FEATURE(kExternalExtensionDefaultButtonControl,
-             "ExternalExtensionDefaultButtonControl",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 BASE_FEATURE(kFileTransferEnterpriseConnector,
              "FileTransferEnterpriseConnector",
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 3297f4f..8099b89 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -263,9 +263,6 @@
 BASE_DECLARE_FEATURE(kEnterpriseReportingInChromeOS);
 #endif
 
-COMPONENT_EXPORT(CHROME_FEATURES)
-BASE_DECLARE_FEATURE(kExternalExtensionDefaultButtonControl);
-
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 COMPONENT_EXPORT(CHROME_FEATURES)
 BASE_DECLARE_FEATURE(kFileTransferEnterpriseConnector);
diff --git a/chrome/common/extensions/api/file_manager_private.idl b/chrome/common/extensions/api/file_manager_private.idl
index 8c6d4c9f..a71cc50 100644
--- a/chrome/common/extensions/api/file_manager_private.idl
+++ b/chrome/common/extensions/api/file_manager_private.idl
@@ -1263,7 +1263,7 @@
 };
 
 // The current progress of the bulk pinning manager. This is a subset of the
-// Progress struct in chromeos/ash/components/drivefs/drivefs_pin_manager.h
+// Progress struct in chromeos/ash/components/drivefs/drivefs_pinning_manager.h
 dictionary BulkPinProgress {
   // The stage the bulk pin manager is in.
   BulkPinStage stage;
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index e38f3f44..7f6c4d4 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -486,7 +486,7 @@
 
 // The URL for the Help Center page about User Bypass.
 inline constexpr char16_t kUserBypassHelpCenterURL[] =
-    u"https://support.google.com/chrome?p=user_bypass";
+    u"https://support.google.com/chrome?p=pause_protections";
 
 inline constexpr char kUpgradeHelpCenterBaseURL[] =
     "https://support.google.com/installer/?product="
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc
index dbe075da..aeb50f37 100644
--- a/chrome/common/webui_url_constants.cc
+++ b/chrome/common/webui_url_constants.cc
@@ -80,6 +80,10 @@
 const char kChromeUIDiceWebSigninInterceptHost[] = "signin-dice-web-intercept";
 const char kChromeUIDiceWebSigninInterceptURL[] =
     "chrome://signin-dice-web-intercept/";
+const char kChromeUIDiceWebSigninInterceptChromeSigninURL[] =
+    "chrome://signin-dice-web-intercept/chrome-signin";
+const char kChromeUIDiceWebSigninInterceptChromeSigninSubPage[] =
+    "chrome-signin";
 const char kChromeUIDownloadInternalsHost[] = "download-internals";
 const char kChromeUIDownloadsHost[] = "downloads";
 const char kChromeUIDownloadsURL[] = "chrome://downloads/";
@@ -440,6 +444,7 @@
     kChromeUIAssistantOptInHost,
     kChromeUIBluetoothPairingHost,
     kChromeUIBorealisCreditsHost,
+    kChromeUIBorealisInstallerHost,
     kChromeUICertificateManagerHost,
     kChromeUICloudUploadHost,
     kChromeUICrostiniCreditsHost,
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h
index c24d2b52b..695c47e9 100644
--- a/chrome/common/webui_url_constants.h
+++ b/chrome/common/webui_url_constants.h
@@ -77,6 +77,8 @@
 extern const char kChromeUIDevUiLoaderURL[];
 extern const char kChromeUIDiceWebSigninInterceptHost[];
 extern const char kChromeUIDiceWebSigninInterceptURL[];
+extern const char kChromeUIDiceWebSigninInterceptChromeSigninURL[];
+extern const char kChromeUIDiceWebSigninInterceptChromeSigninSubPage[];
 extern const char kChromeUIDownloadInternalsHost[];
 extern const char kChromeUIDownloadsHost[];
 extern const char kChromeUIDownloadsURL[];
diff --git a/chrome/services/sharing/nearby/nearby_presence_conversions.cc b/chrome/services/sharing/nearby/nearby_presence_conversions.cc
index 54dbbf31..9658715 100644
--- a/chrome/services/sharing/nearby/nearby_presence_conversions.cc
+++ b/chrome/services/sharing/nearby/nearby_presence_conversions.cc
@@ -241,10 +241,9 @@
   }
 
   // TODO(b/276642472): Properly plumb type and stable_device_id.
-  return mojom::PresenceDevice::New(
-      device.GetEndpointId(), device.GetMetadata().device_name(),
-      mojom::PresenceDeviceType::kPhone, std::move(actions),
-      /*stable_device_id=*/absl::nullopt);
+  return mojom::PresenceDevice::New(device.GetEndpointId(), std::move(actions),
+                                    /*stable_device_id=*/absl::nullopt,
+                                    MetadataToMojom(device.GetMetadata()));
 }
 
 }  // namespace ash::nearby::presence
diff --git a/chrome/services/sharing/nearby/nearby_presence_unittest.cc b/chrome/services/sharing/nearby/nearby_presence_unittest.cc
index 233ca60e..200e412 100644
--- a/chrome/services/sharing/nearby/nearby_presence_unittest.cc
+++ b/chrome/services/sharing/nearby/nearby_presence_unittest.cc
@@ -122,21 +122,21 @@
   void OnDeviceFound(
       ash::nearby::presence::mojom::PresenceDevicePtr device) override {
     num_devices_found_++;
-    last_device_found_name_ = device->device_name;
+    last_device_found_name_ = device->metadata->device_name;
     std::move(next_on_device_found_callback_).Run();
   }
 
   void OnDeviceChanged(
       ash::nearby::presence::mojom::PresenceDevicePtr device) override {
     num_devices_changed_++;
-    last_device_changed_name_ = device->device_name;
+    last_device_changed_name_ = device->metadata->device_name;
     std::move(next_on_device_changed_callback_).Run();
   }
 
   void OnDeviceLost(
       ash::nearby::presence::mojom::PresenceDevicePtr device) override {
     num_devices_lost_++;
-    last_device_lost_name_ = device->device_name;
+    last_device_lost_name_ = device->metadata->device_name;
     std::move(next_on_device_lost_callback_).Run();
   }
 
diff --git a/chrome/services/sharing/nearby/platform/credential_storage.cc b/chrome/services/sharing/nearby/platform/credential_storage.cc
index df8c5f3..238a958 100644
--- a/chrome/services/sharing/nearby/platform/credential_storage.cc
+++ b/chrome/services/sharing/nearby/platform/credential_storage.cc
@@ -53,10 +53,16 @@
     nearby::internal::LocalCredential credential,
     SaveCredentialsResultCallback callback) {}
 
-// TODO(b/287334225): Implement.
 void CredentialStorage::GetLocalCredentials(
     const CredentialSelector& credential_selector,
-    GetLocalCredentialsResultCallback callback) {}
+    GetLocalCredentialsResultCallback callback) {
+  // Because 'manager_app_id' and 'account_name' are consistent per user, and
+  // credentials are stored in the user's cryptohome, 'credential_selector' is
+  // redundant.
+  nearby_presence_credential_storage_->GetPrivateCredentials(
+      base::BindOnce(&CredentialStorage::OnLocalCredentialsRetrieved,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+}
 
 // TODO(b/287334335): Implement.
 void CredentialStorage::GetPublicCredentials(
@@ -114,4 +120,31 @@
       .credentials_fetched_cb(shared_credentials);
 }
 
+void CredentialStorage::OnLocalCredentialsRetrieved(
+    nearby::presence::GetLocalCredentialsResultCallback
+        on_local_credentials_retrieved_callback,
+    mojo_base::mojom::AbslStatusCode retrieved_status,
+    absl::optional<
+        std::vector<ash::nearby::presence::mojom::LocalCredentialPtr>>
+        local_credentials_mojom) {
+  if (retrieved_status != mojo_base::mojom::AbslStatusCode::kOk) {
+    std::move(on_local_credentials_retrieved_callback)
+        .credentials_fetched_cb(absl::Status(
+            absl::StatusCode::kAborted, "Failed to retrieve from database."));
+    return;
+  }
+
+  CHECK(local_credentials_mojom.has_value());
+
+  std::vector<LocalCredential> local_credentials;
+  for (const auto& local_credential_mojom : *local_credentials_mojom) {
+    local_credentials.push_back(
+        ash::nearby::presence::proto::LocalCredentialFromMojom(
+            local_credential_mojom.get()));
+  }
+
+  std::move(on_local_credentials_retrieved_callback)
+      .credentials_fetched_cb(local_credentials);
+}
+
 }  // namespace nearby::chrome
diff --git a/chrome/services/sharing/nearby/platform/credential_storage.h b/chrome/services/sharing/nearby/platform/credential_storage.h
index dfdef742..58fedba 100644
--- a/chrome/services/sharing/nearby/platform/credential_storage.h
+++ b/chrome/services/sharing/nearby/platform/credential_storage.h
@@ -58,6 +58,13 @@
       absl::optional<
           std::vector<ash::nearby::presence::mojom::SharedCredentialPtr>>
           shared_credentials_mojom);
+  void OnLocalCredentialsRetrieved(
+      nearby::presence::GetLocalCredentialsResultCallback
+          on_local_credentials_retrieved_callback,
+      mojo_base::mojom::AbslStatusCode retrieved_status,
+      absl::optional<
+          std::vector<ash::nearby::presence::mojom::LocalCredentialPtr>>
+          local_credentials_mojom);
 
   const mojo::SharedRemote<
       ash::nearby::presence::mojom::NearbyPresenceCredentialStorage>
diff --git a/chrome/services/sharing/nearby/platform/credential_storage_unittest.cc b/chrome/services/sharing/nearby/platform/credential_storage_unittest.cc
index 83663f3b..fbb222b 100644
--- a/chrome/services/sharing/nearby/platform/credential_storage_unittest.cc
+++ b/chrome/services/sharing/nearby/platform/credential_storage_unittest.cc
@@ -18,6 +18,7 @@
 const char kAccountName[] = "test_account_name";
 
 const unsigned int kPublicCredentialInStorageCount = 1u;
+const unsigned int kPrivateCredentialInStorageCount = 1u;
 
 const std::vector<uint8_t> kSecretId_Local = {0x11, 0x12, 0x13,
                                               0x14, 0x15, 0x16};
@@ -153,6 +154,42 @@
       advertisement_signature_verification_key, identity_type, version);
 }
 
+ash::nearby::presence::mojom::LocalCredentialPtr CreateLocalCredential(
+    const std::vector<uint8_t>& secret_id,
+    const std::vector<uint8_t>& key_seed,
+    const int64_t start_time_millis,
+    const std::vector<uint8_t>& metadata_encryption_key_v0,
+    const std::string& advertisement_signing_key_certificate_alias,
+    const std::vector<uint8_t>& advertisement_signing_key_data,
+    const std::string& connection_signing_key_certificate_alias,
+    const std::vector<uint8_t>& connection_signing_key_data,
+    const ash::nearby::presence::mojom::IdentityType identity_type,
+    const base::flat_map<uint32_t, bool>& consumed_salts,
+    const std::vector<uint8_t>& metadata_encryption_key_v1) {
+  auto local_credential = ash::nearby::presence::mojom::LocalCredential::New();
+
+  local_credential->secret_id = secret_id;
+  local_credential->key_seed = key_seed;
+  local_credential->start_time_millis = start_time_millis;
+  local_credential->metadata_encryption_key_v0 = metadata_encryption_key_v0;
+  local_credential->identity_type = identity_type;
+  local_credential->consumed_salts = consumed_salts;
+  local_credential->metadata_encryption_key_v1 = metadata_encryption_key_v1;
+
+  auto advertisement_key = ash::nearby::presence::mojom::PrivateKey::New();
+  advertisement_key->certificate_alias =
+      advertisement_signing_key_certificate_alias;
+  advertisement_key->key = advertisement_signing_key_data;
+  local_credential->advertisement_signing_key = std::move(advertisement_key);
+
+  auto connection_key = ash::nearby::presence::mojom::PrivateKey::New();
+  connection_key->certificate_alias = connection_signing_key_certificate_alias;
+  connection_key->key = connection_signing_key_data;
+  local_credential->connection_signing_key = std::move(connection_key);
+
+  return local_credential;
+}
+
 void PopulateTestData(
     std::vector<::nearby::internal::LocalCredential>& local_credentials,
     std::vector<::nearby::internal::SharedCredential>& shared_credentials) {
@@ -218,7 +255,6 @@
         kAdvertisementSignatureVerificationKey,
         ash::nearby::presence::mojom::IdentityType::kIdentityTypePrivate,
         kVersion));
-
     // The constant must be changed if more shared credentials are added to
     // the vector.
     ASSERT_EQ(kPublicCredentialInStorageCount, shared_credentials.size());
@@ -227,6 +263,29 @@
                             std::move(shared_credentials));
   }
 
+  void GetPrivateCredentials(GetPrivateCredentialsCallback callback) override {
+    if (!should_private_credentials_successfully_retrieve_) {
+      std::move(callback).Run(mojo_base::mojom::AbslStatusCode::kUnknown,
+                              absl::nullopt);
+      return;
+    }
+
+    std::vector<ash::nearby::presence::mojom::LocalCredentialPtr>
+        local_credentials;
+    local_credentials.emplace_back(CreateLocalCredential(
+        kSecretId_Local, kKeySeed, kStartTimeMillis, kMetadataEncryptionKeyV0,
+        AdvertisementSigningKeyCertificateAlias, kAdvertisementPrivateKey,
+        ConnectionSigningKeyCertificateAlias, kConnectionPrivateKey,
+        ash::nearby::presence::mojom::IdentityType::kIdentityTypePrivate,
+        kConsumedSalts, kMetadataEncryptionKeyV1));
+    // The constant must be changed if more local credentials are added to
+    // the vector.
+    ASSERT_EQ(kPrivateCredentialInStorageCount, local_credentials.size());
+
+    std::move(callback).Run(mojo_base::mojom::AbslStatusCode::kOk,
+                            std::move(local_credentials));
+  }
+
   void SetShouldCredentialsSuccessfullySave(bool should_succeed) {
     should_credentials_successfully_save_ = should_succeed;
   }
@@ -235,9 +294,14 @@
     should_public_credentials_successfully_retrieve_ = should_succed;
   }
 
+  void SetShouldPrivateCredentialsSuccessfullyRetrieve(bool should_succed) {
+    should_private_credentials_successfully_retrieve_ = should_succed;
+  }
+
  private:
   bool should_credentials_successfully_save_ = true;
   bool should_public_credentials_successfully_retrieve_ = true;
+  bool should_private_credentials_successfully_retrieve_ = true;
 };
 
 }  // namespace
@@ -453,4 +517,36 @@
   run_loop.Run();
 }
 
+TEST_F(CredentialStorageTest, GetLocalCredentials_Success) {
+  base::RunLoop run_loop;
+
+  credential_storage_->GetLocalCredentials(
+      CreateCredentialSelector(),
+      {.credentials_fetched_cb = [&](auto status_or_creds) {
+        ASSERT_TRUE(status_or_creds.ok());
+
+        auto& creds = *status_or_creds;
+        EXPECT_EQ(creds.size(), kPrivateCredentialInStorageCount);
+
+        run_loop.Quit();
+      }});
+
+  run_loop.Run();
+}
+
+TEST_F(CredentialStorageTest, GetLocalCredentials_Fail) {
+  base::RunLoop run_loop;
+
+  fake_credential_storage_->SetShouldPrivateCredentialsSuccessfullyRetrieve(
+      /*should_succeed=*/false);
+  credential_storage_->GetLocalCredentials(
+      CreateCredentialSelector(),
+      {.credentials_fetched_cb = [&](auto status_or_creds) {
+        EXPECT_FALSE(status_or_creds.ok());
+        run_loop.Quit();
+      }});
+
+  run_loop.Run();
+}
+
 }  // namespace nearby::chrome
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 786086a..b12a2e3 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -386,6 +386,7 @@
     "//components/network_time:network_time_test_support",
     "//components/omnibox/browser:test_support",
     "//components/optimization_guide/content/browser:test_support",
+    "//components/os_crypt/async/browser:test_support",
     "//components/os_crypt/sync",
     "//components/password_manager/core/browser:test_support",
     "//components/password_manager/core/browser/features:password_features",
@@ -2210,6 +2211,7 @@
       "../browser/media/webrtc/region_capture_browsertest.cc",
       "../browser/media/webrtc/same_origin_observer_browsertest.cc",
       "../browser/media/webrtc/test_stats_dictionary_unittest.cc",
+      "../browser/tpcd/metadata/devtools_observer_browsertest.cc",
       "../browser/tpcd/metadata/updater_service_browsertest.cc",
       "../browser/tpcd/support/tpcd_support_browsertest.cc",
 
@@ -2310,6 +2312,7 @@
       "../browser/optimization_guide/page_content_annotations_service_browsertest.cc",
       "../browser/optimization_guide/page_text_observer_browsertest.cc",
       "../browser/origin_trials/origin_trials_browsertest.cc",
+      "../browser/os_crypt/os_crypt_async_browsertest.cc",
       "../browser/page_load_metrics/observers/ad_metrics/ad_density_intervention_browsertest.cc",
       "../browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc",
       "../browser/page_load_metrics/observers/ad_metrics/large_sticky_ad_intervention_browsertest.cc",
@@ -6090,6 +6093,7 @@
     "../browser/policy/messaging_layer/public/report_client_test_util.cc",
     "../browser/policy/messaging_layer/public/report_client_test_util.h",
     "../browser/policy/messaging_layer/public/report_client_unittest.cc",
+    "../browser/policy/messaging_layer/upload/configuration_file_controller_unittest.cc",
     "../browser/policy/messaging_layer/upload/dm_server_uploader_unittest.cc",
     "../browser/policy/messaging_layer/upload/encrypted_reporting_client_unittest.cc",
     "../browser/policy/messaging_layer/upload/event_upload_size_controller_unittest.cc",
@@ -6682,6 +6686,7 @@
     "//components/reporting/encryption:test_support",
     "//components/reporting/encryption:testing_primitives",
     "//components/reporting/encryption:verification",
+    "//components/reporting/proto:configuration_file_proto",
     "//components/reporting/proto:upload_tracker_proto",
     "//components/reporting/resources:resource_manager",
     "//components/reporting/storage:storage_uploader_interface",
@@ -8719,7 +8724,6 @@
       "../browser/extensions/extension_user_script_loader_unittest.cc",
       "../browser/extensions/extension_util_unittest.cc",
       "../browser/extensions/extension_web_ui_unittest.cc",
-      "../browser/extensions/external_install_error_unittest.cc",
       "../browser/extensions/external_policy_loader_unittest.cc",
       "../browser/extensions/external_provider_impl_unittest.cc",
       "../browser/extensions/forced_extensions/force_installed_metrics_unittest.cc",
diff --git a/chrome/test/DEPS b/chrome/test/DEPS
index bd2069e..3920104db 100644
--- a/chrome/test/DEPS
+++ b/chrome/test/DEPS
@@ -59,6 +59,7 @@
   "+components/optimization_guide",
   "+components/optimization_guide/content",
   "+components/optimization_guide/core",
+  "+components/os_crypt/async",
   "+components/os_crypt/sync",
   "+components/password_manager/content/browser",
   "+components/password_manager/content/common",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/batch/BlankCTATabInitialStateRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/batch/BlankCTATabInitialStateRule.java
index d3af67c4..d072cd0 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/batch/BlankCTATabInitialStateRule.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/batch/BlankCTATabInitialStateRule.java
@@ -53,8 +53,12 @@
             public void evaluate() throws Throwable {
                 if (sActivity == null) {
                     TestThreadUtils.runOnUiThreadBlocking(
-                            () -> { FirstRunStatus.setFirstRunFlowComplete(true); });
-                    mActivityTestRule.startMainActivityOnBlankPage();
+                            () -> {
+                                FirstRunStatus.setFirstRunFlowComplete(true);
+                            });
+                    if (mActivityTestRule.getActivity() == null) {
+                        mActivityTestRule.startMainActivityOnBlankPage();
+                    }
                     sActivity = mActivityTestRule.getActivity();
 
                     // Previous tests may have left tabs open and finished the Activity.
diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc
index 36a1db0..697c7778 100644
--- a/chrome/test/base/testing_browser_process.cc
+++ b/chrome/test/base/testing_browser_process.cc
@@ -32,6 +32,7 @@
 #include "components/embedder_support/origin_trials/origin_trials_settings_storage.h"
 #include "components/metrics/metrics_service.h"
 #include "components/network_time/network_time_tracker.h"
+#include "components/os_crypt/async/browser/test_utils.h"
 #include "components/permissions/permissions_client.h"
 #include "components/policy/core/browser/browser_policy_connector.h"
 #include "components/prefs/pref_service.h"
@@ -140,7 +141,8 @@
 
 TestingBrowserProcess::TestingBrowserProcess()
     : app_locale_("en"),
-      platform_part_(std::make_unique<TestingBrowserProcessPlatformPart>()) {
+      platform_part_(std::make_unique<TestingBrowserProcessPlatformPart>()),
+      os_crypt_async_(os_crypt_async::GetTestOSCryptAsyncForTesting()) {
   // TestingBrowserProcess is used in unit_tests which sets this up through
   // content::UnitTestTestSuite but also through other test binaries which don't
   // use that test suite in which case we have to set it up.
@@ -516,6 +518,10 @@
 }
 #endif
 
+os_crypt_async::OSCryptAsync* TestingBrowserProcess::os_crypt_async() {
+  return os_crypt_async_.get();
+}
+
 BuildState* TestingBrowserProcess::GetBuildState() {
 #if !BUILDFLAG(IS_ANDROID)
   return &build_state_;
diff --git a/chrome/test/base/testing_browser_process.h b/chrome/test/base/testing_browser_process.h
index c8e6471..445052f 100644
--- a/chrome/test/base/testing_browser_process.h
+++ b/chrome/test/base/testing_browser_process.h
@@ -58,6 +58,10 @@
 class TestNetworkQualityTracker;
 }
 
+namespace os_crypt_async {
+class OSCryptAsync;
+}
+
 namespace policy {
 class PolicyService;
 }
@@ -157,6 +161,7 @@
   HidSystemTrayIcon* hid_system_tray_icon() override;
   UsbSystemTrayIcon* usb_system_tray_icon() override;
 #endif
+  os_crypt_async::OSCryptAsync* os_crypt_async() override;
   BuildState* GetBuildState() override;
 
   // Set the local state for tests. Consumer is responsible for cleaning it up
@@ -262,6 +267,7 @@
 #endif
 
   std::unique_ptr<StatusTray> status_tray_;
+  std::unique_ptr<os_crypt_async::OSCryptAsync> os_crypt_async_;
 };
 
 // RAII (resource acquisition is initialization) for TestingBrowserProcess.
diff --git a/chrome/test/data/extensions/api_test/preference/lacros/test.js b/chrome/test/data/extensions/api_test/preference/lacros/test.js
index 823af71..083cb28 100644
--- a/chrome/test/data/extensions/api_test/preference/lacros/test.js
+++ b/chrome/test/data/extensions/api_test/preference/lacros/test.js
@@ -5,7 +5,7 @@
 // Preferences API test for extension controlled prefs where the underlying
 // feature lives in ash. These tests make use of the crosapi to set the value
 // in ash. Thus, they run as lacros_chrome_browsertests.
-// Run with lacros_chrome_browsertests_run_in_series \
+// Run with lacros_chrome_browsertests \
 //     --gtest_filter=ExtensionPreferenceLacrosBrowserTest.Lacros
 // Based on the "standard" extension test.
 
diff --git a/chrome/test/data/extensions/api_test/preference/lacros_secondary_profile/test.js b/chrome/test/data/extensions/api_test/preference/lacros_secondary_profile/test.js
index 95501aa3..6a3b130 100644
--- a/chrome/test/data/extensions/api_test/preference/lacros_secondary_profile/test.js
+++ b/chrome/test/data/extensions/api_test/preference/lacros_secondary_profile/test.js
@@ -5,7 +5,7 @@
 // Preferences API test for extension controlled prefs where the main profile
 // controls the underlying feature in ash, but secondary profile can still set
 // the preference in the browser instance.
-// Run with lacros_chrome_browsertests_run_in_series \
+// Run with lacros_chrome_browsertests \
 //     --gtest_filter=ExtensionPreferenceLacrosBrowserTest.SecondaryProfilePrefs
 // Based on the "standard" extension test.
 
diff --git a/chrome/test/data/extensions/api_test/preference/lacros_secondary_profile_read/test.js b/chrome/test/data/extensions/api_test/preference/lacros_secondary_profile_read/test.js
index e280618..1a408c22 100644
--- a/chrome/test/data/extensions/api_test/preference/lacros_secondary_profile_read/test.js
+++ b/chrome/test/data/extensions/api_test/preference/lacros_secondary_profile_read/test.js
@@ -5,7 +5,7 @@
 // Preferences API test for extension controlled prefs where the underlying
 // feature lives in ash. These tests verify that prefs can be read by
 // extensions running in Lacros secondary profile.
-// Run with lacros_chrome_browsertests_run_in_series \
+// Run with lacros_chrome_browsertests \
 //     --ash-chrome-path {path_to_ash_build}/test_ash_chrome
 //     --gtest_filter= \
 //         ExtensionPreferenceLacrosBrowserTest.LacrosSecondaryProfile
diff --git a/chrome/test/data/extensions/api_test/preference/onchange_lacros/test.js b/chrome/test/data/extensions/api_test/preference/onchange_lacros/test.js
index 2fe3130..439377df 100644
--- a/chrome/test/data/extensions/api_test/preference/onchange_lacros/test.js
+++ b/chrome/test/data/extensions/api_test/preference/onchange_lacros/test.js
@@ -6,7 +6,7 @@
 // feature lives in ash. These tests make use of the crosapi to set the value
 // in ash. Thus, they run as lacros_chrome_browsertests. This test verifies the
 // hehavior of the onChange callback.
-// Run with lacros_chrome_browsertests_run_in_series \
+// Run with lacros_chrome_browsertests \
 //     --gtest_filter=ExtensionPreferenceLacrosBrowserTest.Lacros
 
 // Listen until |event| has fired with the |expected| value.
diff --git a/chrome/test/data/extensions/api_test/preference/unsupported_in_ash/test.js b/chrome/test/data/extensions/api_test/preference/unsupported_in_ash/test.js
index 69db9f7..912f91a2 100644
--- a/chrome/test/data/extensions/api_test/preference/unsupported_in_ash/test.js
+++ b/chrome/test/data/extensions/api_test/preference/unsupported_in_ash/test.js
@@ -6,7 +6,7 @@
 // prefs should live in Ash but are not supported in the current Ash version due
 // to version skew. These tests make use of the crosapi to set the value in Ash.
 // Thus, they run as lacros_chrome_browsertests.
-// Run with lacros_chrome_browsertests_run_in_series \
+// Run with lacros_chrome_browsertests \
 //     --gtest_filter=*/ExtensionPreferenceApiUnsupportedInAshBrowserTest.*/*
 // Based on the "standard" extension test.
 chrome.test.runTests([
diff --git a/chrome/test/data/extensions/api_test/tts/is_speaking/test.js b/chrome/test/data/extensions/api_test/tts/is_speaking/test.js
index 7acd30f..a122f4d 100644
--- a/chrome/test/data/extensions/api_test/tts/is_speaking/test.js
+++ b/chrome/test/data/extensions/api_test/tts/is_speaking/test.js
@@ -4,7 +4,7 @@
 
 // TTS api test running from Lacros with Ash.
 // build/lacros/test_runner.py test
-//     {path_to_lacros_build}/lacros_chrome_browsertests_run_in_series
+//     {path_to_lacros_build}/lacros_chrome_browsertests
 //     --gtest_filter=LacrosTtsApiTest.IsSpeaking
 //     --ash-chrome-path {path_to_ash_build}/test_ash_chrome
 // and TTS api test running from Ash with Lacros.
diff --git a/chrome/test/data/extensions/api_test/tts_engine/lacros_register_engine/test.js b/chrome/test/data/extensions/api_test/tts_engine/lacros_register_engine/test.js
index 690bedd..e337b91e 100644
--- a/chrome/test/data/extensions/api_test/tts_engine/lacros_register_engine/test.js
+++ b/chrome/test/data/extensions/api_test/tts_engine/lacros_register_engine/test.js
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 // TTS api test for Lacros Chrome.
-// lacros_chrome_browsertests_run_in_series --gtest_filter="LacrosTtsApiTest.*"
+// lacros_chrome_browsertests --gtest_filter="LacrosTtsApiTest.*"
 
 chrome.test.runTests([
   function testGetVoices() {
diff --git a/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/register_lacros_tts_engine/test.js b/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/register_lacros_tts_engine/test.js
index 190cb58..68bdbff0 100644
--- a/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/register_lacros_tts_engine/test.js
+++ b/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/register_lacros_tts_engine/test.js
@@ -4,7 +4,7 @@
 
 // TTS api test running from Lacros with Ash.
 // build/lacros/test_runner.py test
-//     {path_to_lacros_build}/lacros_chrome_browsertests_run_in_series
+//     {path_to_lacros_build}/lacros_chrome_browsertests
 //     --gtest_filter=LacrosTtsApiTest.SpeakAshUtteranceWithLacrosSpeechEngine
 //     --ash-chrome-path {path_to_ash_build}/test_ash_chrome
 
diff --git a/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_pause_before_speak_lacros_engine/test.js b/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_pause_before_speak_lacros_engine/test.js
index 562368c..bc3f947 100644
--- a/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_pause_before_speak_lacros_engine/test.js
+++ b/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_pause_before_speak_lacros_engine/test.js
@@ -4,7 +4,7 @@
 
 // TTS api test running from Lacros with Ash.
 // build/lacros/test_runner.py test
-//     {path_to_lacros_build}/lacros_chrome_browsertests_run_in_series
+//     {path_to_lacros_build}/lacros_chrome_browsertests
 //     --gtest_filter=LacrosTtsApiTest.PauseBeforeSpeakWithLacrosTtsEngine
 //     --ash-chrome-path {path_to_ash_build}/test_ash_chrome
 
diff --git a/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_pause_during_speak_lacros_engine/test.js b/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_pause_during_speak_lacros_engine/test.js
index 25e6597..fabcd7ec 100644
--- a/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_pause_during_speak_lacros_engine/test.js
+++ b/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_pause_during_speak_lacros_engine/test.js
@@ -4,7 +4,7 @@
 
 // TTS api test running from Lacros with Ash.
 // build/lacros/test_runner.py test
-//     {path_to_lacros_build}/lacros_chrome_browsertests_run_in_series
+//     {path_to_lacros_build}/lacros_chrome_browsertests
 //     --gtest_filter=LacrosTtsApiTest.PauseDuringSpeakWithLacrosTtsEngine
 //     --ash-chrome-path {path_to_ash_build}/test_ash_chrome
 
diff --git a/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_speak_lacros_utterance_with_lacros_engine/test.js b/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_speak_lacros_utterance_with_lacros_engine/test.js
index 7a420aa5..3ca8ad1 100644
--- a/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_speak_lacros_utterance_with_lacros_engine/test.js
+++ b/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_speak_lacros_utterance_with_lacros_engine/test.js
@@ -4,7 +4,7 @@
 
 // TTS api test running from Lacros with Ash.
 // build/lacros/test_runner.py test
-//     {path_to_lacros_build}/lacros_chrome_browsertests_run_in_series
+//     {path_to_lacros_build}/lacros_chrome_browsertests
 //     --gtest_filter=LacrosTtsApiTest.SpeakLacrosUtteranceWithLacrosTtsEngine
 //     --ash-chrome-path {path_to_ash_build}/test_ash_chrome
 
diff --git a/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_stop_lacros_engine/test.js b/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_stop_lacros_engine/test.js
index 378eb9a..bec9c7cb 100644
--- a/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_stop_lacros_engine/test.js
+++ b/chrome/test/data/extensions/api_test/tts_engine/lacros_tts_support/tts_stop_lacros_engine/test.js
@@ -4,7 +4,7 @@
 
 // TTS api test running from Lacros with Ash.
 // build/lacros/test_runner.py test
-//     {path_to_lacros_build}/lacros_chrome_browsertests_run_in_series
+//     {path_to_lacros_build}/lacros_chrome_browsertests
 //     --gtest_filter=LacrosTtsApiTest.StopLacrosUtteranceWithLacrosTtsEngine
 //     --ash-chrome-path {path_to_ash_build}/test_ash_chrome
 
diff --git a/chrome/test/data/pdf/test_util.ts b/chrome/test/data/pdf/test_util.ts
index e8873862..4ced1a8 100644
--- a/chrome/test/data/pdf/test_util.ts
+++ b/chrome/test/data/pdf/test_util.ts
@@ -160,7 +160,7 @@
   }
 }
 
-export class MockUnseasonedPdfPluginElement extends HTMLEmbedElement {
+export class MockPdfPluginElement extends HTMLEmbedElement {
   private messages_: any[] = [];
 
   get messages(): any[] {
@@ -180,16 +180,14 @@
   }
 }
 customElements.define(
-    'mock-unseasoned-pdf-plugin', MockUnseasonedPdfPluginElement,
-    {extends: 'embed'});
+    'mock-pdf-plugin', MockPdfPluginElement, {extends: 'embed'});
 
 /**
- * Creates a fake element simulating the unseasoned PDF plugin.
+ * Creates a fake element simulating the PDF plugin.
  */
-export function createMockUnseasonedPdfPluginForTest():
-    MockUnseasonedPdfPluginElement {
-  return document.createElement('embed', {is: 'mock-unseasoned-pdf-plugin'}) as
-      MockUnseasonedPdfPluginElement;
+export function createMockPdfPluginForTest(): MockPdfPluginElement {
+  return document.createElement('embed', {is: 'mock-pdf-plugin'}) as
+      MockPdfPluginElement;
 }
 
 class TestBookmarksElement extends PolymerElement {
diff --git a/chrome/test/data/pdf/viewport_test.ts b/chrome/test/data/pdf/viewport_test.ts
index 28cba52..aa559b60 100644
--- a/chrome/test/data/pdf/viewport_test.ts
+++ b/chrome/test/data/pdf/viewport_test.ts
@@ -5,7 +5,7 @@
 import {FittingType, PAGE_SHADOW, Point, Rect, SwipeDirection, Viewport} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js';
 import {isMac} from 'chrome://resources/js/platform.js';
 
-import {createMockUnseasonedPdfPluginForTest, getZoomableViewport, MockDocumentDimensions, MockElement, MockSizer, MockUnseasonedPdfPluginElement, MockViewportChangedCallback} from './test_util.js';
+import {createMockPdfPluginForTest, getZoomableViewport, MockDocumentDimensions, MockElement, MockPdfPluginElement, MockSizer, MockViewportChangedCallback} from './test_util.js';
 
 const SCROLLBAR_WIDTH: number = 15;
 
@@ -21,7 +21,7 @@
  * Simulates acknowledgements to all "syncScrollToRemote" messages.
  */
 function ackAllScrollToRemoteMessages(
-    viewport: Viewport, plugin: MockUnseasonedPdfPluginElement) {
+    viewport: Viewport, plugin: MockPdfPluginElement) {
   for (const message of plugin.messages) {
     if (message.type === 'syncScrollToRemote') {
       viewport.ackScrollToRemote(message);
@@ -67,7 +67,7 @@
   function testOverlayScrollbarWidth_remote() {
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), 43, 1);
-    viewport.setRemoteContent(createMockUnseasonedPdfPluginForTest());
+    viewport.setRemoteContent(createMockPdfPluginForTest());
 
     chrome.test.assertEq(isMac ? 16 : 43, viewport.overlayScrollbarWidth);
     chrome.test.succeed();
@@ -1752,7 +1752,7 @@
     const mockSizer = new MockSizer();
     const viewport =
         getZoomableViewport(new MockElement(100, 100, null), mockSizer, 0, 1);
-    viewport.setRemoteContent(createMockUnseasonedPdfPluginForTest());
+    viewport.setRemoteContent(createMockPdfPluginForTest());
 
     const dummyPlugin = document.body.querySelector('#plugin');
     viewport.setContent(dummyPlugin);
@@ -1765,7 +1765,7 @@
     const mockSizer = new MockSizer();
     const viewport =
         getZoomableViewport(new MockElement(100, 100, null), mockSizer, 0, 1);
-    viewport.setRemoteContent(createMockUnseasonedPdfPluginForTest());
+    viewport.setRemoteContent(createMockPdfPluginForTest());
     viewport.setDocumentDimensions(new MockDocumentDimensions(20, 30));
     chrome.test.assertEq('0px', mockSizer.style.width);
     chrome.test.assertEq('0px', mockSizer.style.height);
@@ -1781,7 +1781,7 @@
   function testSetContent_scrollToLocal() {
     const mockWindow = new MockElement(100, 100, null);
     const viewport = getZoomableViewport(mockWindow, new MockSizer(), 0, 1);
-    viewport.setRemoteContent(createMockUnseasonedPdfPluginForTest());
+    viewport.setRemoteContent(createMockPdfPluginForTest());
     viewport.setDocumentDimensions(new MockDocumentDimensions(200, 200));
     viewport.setZoom(1);
     viewport.setPosition({x: 20, y: 30});
@@ -1800,7 +1800,7 @@
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), 0, 1);
 
-    const mockPlugin = createMockUnseasonedPdfPluginForTest();
+    const mockPlugin = createMockPdfPluginForTest();
     viewport.setRemoteContent(mockPlugin);
 
     const dummyContent = document.body.querySelector('div');
@@ -1813,7 +1813,7 @@
     const viewport =
         getZoomableViewport(new MockElement(100, 100, null), mockSizer, 0, 1);
 
-    viewport.setRemoteContent(createMockUnseasonedPdfPluginForTest());
+    viewport.setRemoteContent(createMockPdfPluginForTest());
 
     chrome.test.assertEq('none', mockSizer.style.display);
     chrome.test.succeed();
@@ -1824,7 +1824,7 @@
         new MockElement(100, 100, null), new MockSizer(), 0, 1);
     viewport.setDocumentDimensions(new MockDocumentDimensions(20, 30));
 
-    const mockPlugin = createMockUnseasonedPdfPluginForTest();
+    const mockPlugin = createMockPdfPluginForTest();
     viewport.setRemoteContent(mockPlugin);
 
     const {width, height} = mockPlugin.findMessage('updateSize');
@@ -1840,7 +1840,7 @@
     viewport.setZoom(1);
     viewport.setPosition({x: 20, y: 30});
 
-    const mockPlugin = createMockUnseasonedPdfPluginForTest();
+    const mockPlugin = createMockPdfPluginForTest();
     viewport.setRemoteContent(mockPlugin);
 
     const {x, y} = mockPlugin.findMessage('syncScrollToRemote');
@@ -1852,7 +1852,7 @@
   function testSetDocumentDimensions_remote() {
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), 0, 1);
-    const mockPlugin = createMockUnseasonedPdfPluginForTest();
+    const mockPlugin = createMockPdfPluginForTest();
     viewport.setRemoteContent(mockPlugin);
     mockPlugin.clearMessages();
 
@@ -1869,7 +1869,7 @@
   function testSetPosition_remote() {
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), 0, 1);
-    const mockPlugin = createMockUnseasonedPdfPluginForTest();
+    const mockPlugin = createMockPdfPluginForTest();
     viewport.setRemoteContent(mockPlugin);
     viewport.setDocumentDimensions(new MockDocumentDimensions(200, 200));
     viewport.setZoom(1);
@@ -1888,7 +1888,7 @@
   function testSetPosition_remote_modifiedByAck() {
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), 0, 1);
-    const mockPlugin = createMockUnseasonedPdfPluginForTest();
+    const mockPlugin = createMockPdfPluginForTest();
     viewport.setRemoteContent(mockPlugin);
     viewport.setDocumentDimensions(new MockDocumentDimensions(200, 200));
     viewport.setZoom(1);
@@ -1907,7 +1907,7 @@
   function testSetPosition_remote_modifiedByAck_ignoreOverlapping() {
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), 0, 1);
-    const mockPlugin = createMockUnseasonedPdfPluginForTest();
+    const mockPlugin = createMockPdfPluginForTest();
     viewport.setRemoteContent(mockPlugin);
     viewport.setDocumentDimensions(new MockDocumentDimensions(200, 200));
     viewport.setZoom(1);
@@ -1927,7 +1927,7 @@
   function testSetPosition_remote_modifiedByAck_multiple() {
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), 0, 1);
-    const mockPlugin = createMockUnseasonedPdfPluginForTest();
+    const mockPlugin = createMockPdfPluginForTest();
     viewport.setRemoteContent(mockPlugin);
     viewport.setDocumentDimensions(new MockDocumentDimensions(200, 200));
     viewport.setZoom(1);
@@ -1948,7 +1948,7 @@
   function testSetPosition_remote_NaN() {
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), 0, 1);
-    viewport.setRemoteContent(createMockUnseasonedPdfPluginForTest());
+    viewport.setRemoteContent(createMockPdfPluginForTest());
 
     viewport.setPosition({x: NaN, y: NaN});
 
@@ -1960,7 +1960,7 @@
   function testSetPosition_remote_underflow_leftAndTop() {
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), SCROLLBAR_WIDTH, 1);
-    viewport.setRemoteContent(createMockUnseasonedPdfPluginForTest());
+    viewport.setRemoteContent(createMockPdfPluginForTest());
     viewport.setDocumentDimensions(new MockDocumentDimensions(200, 200));
     viewport.setZoom(1);
 
@@ -1976,7 +1976,7 @@
     mockWindow.dir = 'rtl';
     const viewport =
         getZoomableViewport(mockWindow, new MockSizer(), SCROLLBAR_WIDTH, 1);
-    viewport.setRemoteContent(createMockUnseasonedPdfPluginForTest());
+    viewport.setRemoteContent(createMockPdfPluginForTest());
     viewport.setDocumentDimensions(new MockDocumentDimensions(200, 200));
     viewport.setZoom(1);
 
@@ -1990,7 +1990,7 @@
   function testSetPosition_remote_overflow_rightAndBottom() {
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), SCROLLBAR_WIDTH, 1);
-    viewport.setRemoteContent(createMockUnseasonedPdfPluginForTest());
+    viewport.setRemoteContent(createMockPdfPluginForTest());
     viewport.setDocumentDimensions(new MockDocumentDimensions(200, 300));
     viewport.setZoom(1);
 
@@ -2006,7 +2006,7 @@
     mockWindow.dir = 'rtl';
     const viewport =
         getZoomableViewport(mockWindow, new MockSizer(), SCROLLBAR_WIDTH, 1);
-    viewport.setRemoteContent(createMockUnseasonedPdfPluginForTest());
+    viewport.setRemoteContent(createMockPdfPluginForTest());
     viewport.setDocumentDimensions(new MockDocumentDimensions(200, 300));
     viewport.setZoom(1);
 
@@ -2020,7 +2020,7 @@
   function testSetPosition_remote_overflowWithoutVerticalScrollbar_right() {
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), SCROLLBAR_WIDTH, 1);
-    viewport.setRemoteContent(createMockUnseasonedPdfPluginForTest());
+    viewport.setRemoteContent(createMockPdfPluginForTest());
     viewport.setDocumentDimensions(new MockDocumentDimensions(200, 85));
     viewport.setZoom(1);
 
@@ -2036,7 +2036,7 @@
     mockWindow.dir = 'rtl';
     const viewport =
         getZoomableViewport(mockWindow, new MockSizer(), SCROLLBAR_WIDTH, 1);
-    viewport.setRemoteContent(createMockUnseasonedPdfPluginForTest());
+    viewport.setRemoteContent(createMockPdfPluginForTest());
     viewport.setDocumentDimensions(new MockDocumentDimensions(200, 85));
     viewport.setZoom(1);
 
@@ -2050,7 +2050,7 @@
   function testSetPosition_remote_overflowWithoutHorizontalScrollbar_bottom() {
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), SCROLLBAR_WIDTH, 1);
-    viewport.setRemoteContent(createMockUnseasonedPdfPluginForTest());
+    viewport.setRemoteContent(createMockPdfPluginForTest());
     viewport.setDocumentDimensions(new MockDocumentDimensions(85, 300));
     viewport.setZoom(1);
 
@@ -2064,7 +2064,7 @@
   function testSyncScrollFromRemote() {
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), 0, 1);
-    const mockPlugin = createMockUnseasonedPdfPluginForTest();
+    const mockPlugin = createMockPdfPluginForTest();
     viewport.setRemoteContent(mockPlugin);
     ackAllScrollToRemoteMessages(viewport, mockPlugin);
 
@@ -2080,7 +2080,7 @@
   function testSyncScrollFromRemote_duplicateScroll() {
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), 0, 1);
-    const mockPlugin = createMockUnseasonedPdfPluginForTest();
+    const mockPlugin = createMockPdfPluginForTest();
     viewport.setRemoteContent(mockPlugin);
     ackAllScrollToRemoteMessages(viewport, mockPlugin);
     viewport.syncScrollFromRemote({x: 30, y: 20});
@@ -2097,7 +2097,7 @@
   function testSyncScrollFromRemote_scrollToRemoteUnacked() {
     const viewport = getZoomableViewport(
         new MockElement(100, 100, null), new MockSizer(), 0, 1);
-    const mockPlugin = createMockUnseasonedPdfPluginForTest();
+    const mockPlugin = createMockPdfPluginForTest();
     viewport.setRemoteContent(mockPlugin);
     chrome.test.assertTrue(!!mockPlugin.findMessage('syncScrollToRemote'));
 
diff --git a/chrome/test/data/printing/embedded_images_ps_level3.emf b/chrome/test/data/printing/embedded_images_ps_level3.emf
index b723823..255ba0f 100644
--- a/chrome/test/data/printing/embedded_images_ps_level3.emf
+++ b/chrome/test/data/printing/embedded_images_ps_level3.emf
Binary files differ
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn
index 3decaf3b..ad6d68ad 100644
--- a/chrome/test/data/webui/BUILD.gn
+++ b/chrome/test/data/webui/BUILD.gn
@@ -41,6 +41,7 @@
     "css/css_browsertest.cc",
     "downloads/downloads_browsertest.cc",
     "engagement/site_engagement_browsertest.cc",
+    "flags/flags_browsertest.cc",
     "histograms/histograms_internals_browsertest.cc",
     "history/history_supervised_user_browsertest.cc",
     "history/history_ui_browsertest.cc",
@@ -495,6 +496,7 @@
     "discards:build_grdp",
     "downloads:build_grdp",
     "engagement:build_grdp",
+    "flags:build_grdp",
     "histograms:build_grdp",
     "history:build_grdp",
     "history_clusters_internals:build_grdp",
@@ -535,6 +537,7 @@
     "$target_gen_dir/discards/resources.grdp",
     "$target_gen_dir/downloads/resources.grdp",
     "$target_gen_dir/engagement/resources.grdp",
+    "$target_gen_dir/flags/resources.grdp",
     "$target_gen_dir/histograms/resources.grdp",
     "$target_gen_dir/history/resources.grdp",
     "$target_gen_dir/history_clusters_internals/resources.grdp",
@@ -621,6 +624,7 @@
       "chromeos/borealis_installer:build_grdp",
       "chromeos/cloud_upload:build_grdp",
       "chromeos/diagnostics:build_grdp",
+      "chromeos/edu_coexistence:build_grdp",
       "chromeos/emoji_picker:build_grdp",
       "chromeos/enterprise_reporting:build_grdp",
       "chromeos/firmware_update:build_grdp",
@@ -641,12 +645,13 @@
       "$target_gen_dir/chromeos/ash_common/resources.grdp",
       "$target_gen_dir/chromeos/borealis_installer/resources.grdp",
       "$target_gen_dir/chromeos/cloud_upload/resources.grdp",
-      "$target_gen_dir/chromeos/parent_access/resources.grdp",
       "$target_gen_dir/chromeos/diagnostics/resources.grdp",
+      "$target_gen_dir/chromeos/edu_coexistence/resources.grdp",
       "$target_gen_dir/chromeos/emoji_picker/resources.grdp",
       "$target_gen_dir/chromeos/enterprise_reporting/resources.grdp",
       "$target_gen_dir/chromeos/firmware_update/resources.grdp",
       "$target_gen_dir/chromeos/office_fallback/resources.grdp",
+      "$target_gen_dir/chromeos/parent_access/resources.grdp",
       "$target_gen_dir/chromeos/personalization_app/resources.grdp",
       "$target_gen_dir/chromeos/shortcut_customization/resources.grdp",
       "$target_gen_dir/chromeos/print_management/resources.grdp",
diff --git a/chrome/test/data/webui/chromeos/edu_coexistence/BUILD.gn b/chrome/test/data/webui/chromeos/edu_coexistence/BUILD.gn
new file mode 100644
index 0000000..3d83764
--- /dev/null
+++ b/chrome/test/data/webui/chromeos/edu_coexistence/BUILD.gn
@@ -0,0 +1,51 @@
+# Copyright 2023 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("../../build_webui_tests.gni")
+
+build_webui_tests("build") {
+  files = [
+    "edu_coexistence_app_test.ts",
+    "edu_coexistence_app_with_arc_picker_test.ts",
+    "edu_coexistence_controller_test.ts",
+    "edu_coexistence_test_browser_proxy.ts",
+    "edu_coexistence_ui_test.ts",
+  ]
+
+  ts_path_mappings = [
+    "chrome://chrome-signin/edu_coexistence/*|" + rebase_path(
+            "$root_gen_dir/chrome/browser/resources/chromeos/edu_coexistence/tsc/*",
+            target_gen_dir),
+    "chrome://chrome-signin/gaia_auth_host/*|" +
+        rebase_path("//chrome/browser/resources/gaia_auth_host/*",
+                    target_gen_dir),
+    "chrome://chrome-signin/arc_account_picker/*|" +
+        rebase_path("//chrome/browser/resources/chromeos/arc_account_picker/*",
+                    target_gen_dir),
+    "chrome://webui-test/chromeos/arc_account_picker/*|" +
+        rebase_path("//chrome/test/data/webui/chromeos/arc_account_picker/*",
+                    target_gen_dir),
+    "chrome://webui-test/*|" +
+        rebase_path("$root_gen_dir/chrome/test/data/webui/tsc/*",
+                    target_gen_dir),
+  ]
+
+  ts_deps = [
+    "//ash/webui/common/resources:build_ts",
+    "//chrome/browser/resources/chromeos/edu_coexistence:build_ts",
+    "//third_party/polymer/v3_0:library",
+    "//ui/webui/resources/cr_elements:build_ts",
+    "//ui/webui/resources/js:build_ts",
+    "//ui/webui/resources/mojo:build_ts",
+  ]
+
+  ts_definitions = [
+    "//tools/typescript/definitions/webview_tag.d.ts",
+    "//tools/typescript/definitions/web_request.d.ts",
+    "//tools/typescript/definitions/context_menus.d.ts",
+    "//tools/typescript/definitions/tabs.d.ts",
+    "//tools/typescript/definitions/extension_types.d.ts",
+    "//tools/typescript/definitions/chrome_test.d.ts",
+  ]
+}
diff --git a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_app_test.js b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_app_test.js
deleted file mode 100644
index 3095833..0000000
--- a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_app_test.js
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'chrome://chrome-signin/edu_coexistence_app.js';
-
-import {Screens} from 'chrome://chrome-signin/edu_coexistence_app.js';
-import {EduCoexistenceBrowserProxyImpl} from 'chrome://chrome-signin/edu_coexistence_browser_proxy.js';
-import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {assertEquals} from 'chrome://webui-test/chai_assert.js';
-
-import {TestEduCoexistenceBrowserProxy} from './edu_coexistence_test_browser_proxy.js';
-
-suite('EduCoexistenceAppTest', function() {
-  let appComponent;
-  let testBrowserProxy;
-
-  setup(function() {
-    testBrowserProxy = new TestEduCoexistenceBrowserProxy();
-    EduCoexistenceBrowserProxyImpl.setInstance(testBrowserProxy);
-    testBrowserProxy.setDialogArguments(
-        {isAvailableInArc: true, showArcAvailabilityPicker: false});
-    testBrowserProxy.setInitializeEduArgsResponse(async function() {
-      return {
-        url: 'https://foo.example.com/supervision/coexistence/intro',
-        hl: 'en-US',
-        sourceUi: 'oobe',
-        clientId: 'test-client-id',
-        clientVersion: ' test-client-version',
-        eduCoexistenceId: ' test-edu-coexistence-id',
-        platformVersion: ' test-platform-version',
-        releaseChannel: 'test-release-channel',
-        deviceId: 'test-device-id',
-      };
-    });
-
-    document.body.innerHTML = window.trustedTypes.emptyHTML;
-    appComponent = document.createElement('edu-coexistence-app');
-    document.body.appendChild(appComponent);
-    flush();
-  });
-
-  test('InitOnline', function() {
-    window.dispatchEvent(new Event('online'));
-    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ONLINE_FLOW);
-  });
-
-  test('InitOffline', function() {
-    window.dispatchEvent(new Event('offline'));
-    assertEquals(appComponent.getCurrentScreenForTest(), Screens.OFFLINE);
-
-    const offlineScreen =
-        appComponent.shadowRoot.querySelector('edu-coexistence-offline');
-    const nextButton =
-        offlineScreen.shadowRoot.querySelector('edu-coexistence-button')
-            .shadowRoot.querySelector('cr-button');
-    nextButton.click();
-
-    assertEquals(testBrowserProxy.getCallCount('dialogClose'), 1);
-  });
-
-  test('ShowOffline', function() {
-    window.dispatchEvent(new Event('online'));
-    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ONLINE_FLOW);
-
-    window.dispatchEvent(new Event('offline'));
-    assertEquals(appComponent.getCurrentScreenForTest(), Screens.OFFLINE);
-  });
-
-  test('ShowOnline', function() {
-    window.dispatchEvent(new Event('offline'));
-    assertEquals(appComponent.getCurrentScreenForTest(), Screens.OFFLINE);
-
-    window.dispatchEvent(new Event('online'));
-    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ONLINE_FLOW);
-  });
-
-  test('ShowError', function() {
-    window.dispatchEvent(new Event('online'));
-    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ONLINE_FLOW);
-
-    appComponent.dispatchEvent(new CustomEvent('go-error'));
-    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ERROR);
-
-    const errorScreen =
-        appComponent.shadowRoot.querySelector('edu-coexistence-error');
-    const nextButton =
-        errorScreen.shadowRoot.querySelector('edu-coexistence-button')
-            .shadowRoot.querySelector('cr-button');
-    nextButton.click();
-
-    assertEquals(testBrowserProxy.getCallCount('dialogClose'), 1);
-  });
-
-  test('DontSwitchViewIfDisplayingError', function() {
-    appComponent.dispatchEvent(new CustomEvent('go-error'));
-    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ERROR);
-
-    window.dispatchEvent(new Event('offline'));
-    // Should still show error screen.
-    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ERROR);
-
-    window.dispatchEvent(new Event('online'));
-    // Should still show error screen.
-    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ERROR);
-  });
-
-  test(
-      'ShowErrorScreenImmediatelyOnLoadAbort', function() {
-        assertEquals(
-            appComponent.getCurrentScreenForTest(), Screens.ONLINE_FLOW);
-        const coexistenceUi =
-            appComponent.shadowRoot.querySelector('edu-coexistence-ui');
-        coexistenceUi.shadowRoot.querySelector('webview').dispatchEvent(
-            new CustomEvent('loadabort'));
-
-        // Should show error screen.
-        assertEquals(appComponent.getCurrentScreenForTest(), Screens.ERROR);
-      });
-});
diff --git a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_app_test.ts b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_app_test.ts
new file mode 100644
index 0000000..829c7c3
--- /dev/null
+++ b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_app_test.ts
@@ -0,0 +1,104 @@
+// Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://chrome-signin/edu_coexistence/edu_coexistence_app.js';
+
+import {EduCoexistenceApp, Screens} from 'chrome://chrome-signin/edu_coexistence/edu_coexistence_app.js';
+import {EduCoexistenceBrowserProxyImpl} from 'chrome://chrome-signin/edu_coexistence/edu_coexistence_browser_proxy.js';
+import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {assertEquals} from 'chrome://webui-test/chai_assert.js';
+
+import {TestEduCoexistenceBrowserProxy} from './edu_coexistence_test_browser_proxy.js';
+
+
+suite('EduCoexistenceAppTest', function() {
+  let appComponent: EduCoexistenceApp;
+  let testBrowserProxy: TestEduCoexistenceBrowserProxy;
+
+  setup(function() {
+    testBrowserProxy = new TestEduCoexistenceBrowserProxy();
+    EduCoexistenceBrowserProxyImpl.setInstance(testBrowserProxy);
+
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    appComponent = new EduCoexistenceApp();
+    document.body.appendChild(appComponent);
+    flush();
+  });
+
+  test('InitOnline', function() {
+    window.dispatchEvent(new Event('online'));
+    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ONLINE_FLOW);
+  });
+
+  test('InitOffline', function() {
+    window.dispatchEvent(new Event('offline'));
+    assertEquals(appComponent.getCurrentScreenForTest(), Screens.OFFLINE);
+
+    const offlineScreen =
+        appComponent.shadowRoot!.querySelector('edu-coexistence-offline')!;
+    const nextButton =
+        offlineScreen.shadowRoot!.querySelector('edu-coexistence-button')!
+            .shadowRoot!.querySelector('cr-button')!;
+    nextButton.click();
+
+    assertEquals(testBrowserProxy.getCallCount('dialogClose'), 1);
+  });
+
+  test('ShowOffline', function() {
+    window.dispatchEvent(new Event('online'));
+    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ONLINE_FLOW);
+
+    window.dispatchEvent(new Event('offline'));
+    assertEquals(appComponent.getCurrentScreenForTest(), Screens.OFFLINE);
+  });
+
+  test('ShowOnline', function() {
+    window.dispatchEvent(new Event('offline'));
+    assertEquals(appComponent.getCurrentScreenForTest(), Screens.OFFLINE);
+
+    window.dispatchEvent(new Event('online'));
+    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ONLINE_FLOW);
+  });
+
+  test('ShowError', function() {
+    window.dispatchEvent(new Event('online'));
+    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ONLINE_FLOW);
+
+    appComponent.dispatchEvent(new CustomEvent('go-error'));
+    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ERROR);
+
+    const errorScreen =
+        appComponent.shadowRoot!.querySelector('edu-coexistence-error')!;
+    const nextButton =
+        errorScreen.shadowRoot!.querySelector('edu-coexistence-button')!
+            .shadowRoot!.querySelector('cr-button')!;
+    nextButton.click();
+
+    assertEquals(testBrowserProxy.getCallCount('dialogClose'), 1);
+  });
+
+  test('DontSwitchViewIfDisplayingError', function() {
+    appComponent.dispatchEvent(new CustomEvent('go-error'));
+    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ERROR);
+
+    window.dispatchEvent(new Event('offline'));
+    // Should still show error screen.
+    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ERROR);
+
+    window.dispatchEvent(new Event('online'));
+    // Should still show error screen.
+    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ERROR);
+  });
+
+  test('ShowErrorScreenImmediatelyOnLoadAbort', function() {
+    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ONLINE_FLOW);
+    const coexistenceUi =
+        appComponent.shadowRoot!.querySelector('edu-coexistence-ui')!;
+    coexistenceUi.shadowRoot!.querySelector('webview')!.dispatchEvent(
+        new CustomEvent('loadabort'));
+
+    // Should show error screen.
+    assertEquals(appComponent.getCurrentScreenForTest(), Screens.ERROR);
+  });
+});
diff --git a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_app_with_arc_picker_test.js b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_app_with_arc_picker_test.ts
similarity index 64%
rename from chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_app_with_arc_picker_test.js
rename to chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_app_with_arc_picker_test.ts
index 8d0e2c2..8add993 100644
--- a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_app_with_arc_picker_test.js
+++ b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_app_with_arc_picker_test.ts
@@ -2,26 +2,25 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'chrome://chrome-signin/edu_coexistence_app.js';
+import 'chrome://chrome-signin/edu_coexistence/edu_coexistence_app.js';
 
-import {Screens} from 'chrome://chrome-signin/edu_coexistence_app.js';
-import {EduCoexistenceBrowserProxyImpl} from 'chrome://chrome-signin/edu_coexistence_browser_proxy.js';
+import {EduCoexistenceApp, Screens} from 'chrome://chrome-signin/edu_coexistence/edu_coexistence_app.js';
+import {EduCoexistenceBrowserProxyImpl} from 'chrome://chrome-signin/edu_coexistence/edu_coexistence_browser_proxy.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assertEquals} from 'chrome://webui-test/chai_assert.js';
-
-import {getFakeAccountsNotAvailableInArcList, setTestArcAccountPickerBrowserProxy, TestArcAccountPickerBrowserProxy} from '../arc_account_picker/test_util.js';
+import {getFakeAccountsNotAvailableInArcList, setTestArcAccountPickerBrowserProxy, TestArcAccountPickerBrowserProxy} from 'chrome://webui-test/chromeos/arc_account_picker/test_util.js';
 
 import {TestEduCoexistenceBrowserProxy} from './edu_coexistence_test_browser_proxy.js';
 
 suite('EduCoexistenceAppWithArcPickerTest', function() {
-  let appComponent;
-  let testBrowserProxy;
-  let testArcBrowserProxy;
+  let appComponent: EduCoexistenceApp;
+  let testBrowserProxy: TestEduCoexistenceBrowserProxy;
+  let testArcBrowserProxy: TestArcAccountPickerBrowserProxy;
 
   async function waitForSwitchViewPromise() {
     return new Promise(
-        resolve => appComponent.addEventListener(
-            'switch-view-notify-for-testing', () => resolve()));
+        (resolve) => appComponent.addEventListener(
+            'switch-view-notify-for-testing', () => resolve(true)));
   }
 
   setup(function() {
@@ -29,27 +28,14 @@
     EduCoexistenceBrowserProxyImpl.setInstance(testBrowserProxy);
     testBrowserProxy.setDialogArguments(
         {isAvailableInArc: true, showArcAvailabilityPicker: true});
-    testBrowserProxy.setInitializeEduArgsResponse(async function() {
-      return {
-        url: 'https://foo.example.com/supervision/coexistence/intro',
-        hl: 'en-US',
-        sourceUi: 'oobe',
-        clientId: 'test-client-id',
-        clientVersion: ' test-client-version',
-        eduCoexistenceId: ' test-edu-coexistence-id',
-        platformVersion: ' test-platform-version',
-        releaseChannel: 'test-release-channel',
-        deviceId: 'test-device-id',
-      };
-    });
 
     testArcBrowserProxy = new TestArcAccountPickerBrowserProxy();
     testArcBrowserProxy.setAccountsNotAvailableInArc(
         getFakeAccountsNotAvailableInArcList());
     setTestArcAccountPickerBrowserProxy(testArcBrowserProxy);
 
-    document.body.innerHTML = window.trustedTypes.emptyHTML;
-    appComponent = document.createElement('edu-coexistence-app');
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    appComponent = new EduCoexistenceApp();
     document.body.appendChild(appComponent);
     flush();
   });
@@ -81,10 +67,9 @@
         appComponent.getCurrentScreenForTest(), Screens.ARC_ACCOUNT_PICKER);
 
     const arcAccountPickerComponent =
-        /** @type {ArcAccountPickerAppElement} */ (
-            appComponent.shadowRoot.querySelector('arc-account-picker-app'));
-    arcAccountPickerComponent.shadowRoot.querySelector('#addAccountButton')
-        .click();
+        appComponent.shadowRoot!.querySelector('arc-account-picker-app')!;
+    arcAccountPickerComponent.shadowRoot!
+        .querySelector<HTMLElement>('#addAccountButton')!.click();
     assertEquals(appComponent.getCurrentScreenForTest(), Screens.ONLINE_FLOW);
   });
-});
+});
\ No newline at end of file
diff --git a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_browsertest.js b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_browsertest.js
index 12aba0363..b339fb8 100644
--- a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_browsertest.js
+++ b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_browsertest.js
@@ -31,7 +31,7 @@
     /** @override */
     get browsePreload() {
       return `chrome://chrome-signin/test_loader.html` +
-          `?module=chromeos/edu_coexistence/${module}&host=test`;
+          `?module=chromeos/edu_coexistence/${module}`;
     }
   };
   TEST_F(className, caseName || 'All', () => mocha.run());
diff --git a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_controller_test.js b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_controller_test.js
deleted file mode 100644
index 9b3b158..0000000
--- a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_controller_test.js
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {EduCoexistenceBrowserProxyImpl} from 'chrome://chrome-signin/edu_coexistence_browser_proxy.js';
-import {EduCoexistenceController} from 'chrome://chrome-signin/edu_coexistence_controller.js';
-import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {assertEquals} from 'chrome://webui-test/chai_assert.js';
-
-import {TestEduCoexistenceBrowserProxy} from './edu_coexistence_test_browser_proxy.js';
-
-const FAKE_NOW_MILLISECONDS = 100000;
-const FAKE_SIGNIN_TIME_MILLISECONDS = 50000;
-
-suite('EduCoexistenceControllerTest', function() {
-  let appComponent;
-  let testBrowserProxy;
-  let eduCoexistenceController;
-
-  setup(function() {
-    testBrowserProxy = new TestEduCoexistenceBrowserProxy();
-    EduCoexistenceBrowserProxyImpl.setInstance(testBrowserProxy);
-    testBrowserProxy.setInitializeEduArgsResponse(async function() {
-      return {
-        url: 'https://foo.example.com/supervision/coexistence/intro',
-        hl: 'en-US',
-        sourceUi: 'oobe',
-        clientId: 'test-client-id',
-        clientVersion: ' test-client-version',
-        eduCoexistenceId: ' test-edu-coexistence-id',
-        platformVersion: ' test-platform-version',
-        releaseChannel: 'test-release-channel',
-        deviceId: 'test-device-id',
-        signinTime: FAKE_SIGNIN_TIME_MILLISECONDS,
-      };
-    });
-
-    document.body.innerHTML = window.trustedTypes.emptyHTML;
-    // The controller wants an edu-coexistence-ui Polymer component
-    // as a parameter.
-    appComponent = document.createElement('edu-coexistence-ui');
-    document.body.appendChild(appComponent);
-    flush();
-
-    eduCoexistenceController = new EduCoexistenceController(
-        appComponent, document.createElement('webview'),
-        getEduCoexistenceParams());
-  });
-
-  test(
-      'GetSigninTimeDelta', function() {
-        // Fake Date.now()
-        const realDateNow = Date.now;
-        Date.now = () => {
-          return FAKE_NOW_MILLISECONDS;
-        };
-        const expectedDeltaSeconds =
-            (FAKE_NOW_MILLISECONDS - FAKE_SIGNIN_TIME_MILLISECONDS) / 1000;
-        assertEquals(
-            eduCoexistenceController.getTimeDeltaSinceSigninSeconds(),
-            expectedDeltaSeconds);
-
-        // Restore original Date.now()
-        Date.now = realDateNow;
-      });
-});
-
-
-function getEduCoexistenceParams() {
-  return {
-    url: 'https://foo.example.com/supervision/coexistence/intro',
-    hl: 'en-US',
-    sourceUi: 'oobe',
-    clientId: 'test-client-id',
-    clientVersion: ' test-client-version',
-    eduCoexistenceId: ' test-edu-coexistence-id',
-    platformVersion: ' test-platform-version',
-    releaseChannel: 'test-release-channel',
-    deviceId: 'test-device-id',
-    signinTime: FAKE_SIGNIN_TIME_MILLISECONDS,
-  };
-}
diff --git a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_controller_test.ts b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_controller_test.ts
new file mode 100644
index 0000000..fb99536
--- /dev/null
+++ b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_controller_test.ts
@@ -0,0 +1,69 @@
+// Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {EduCoexistenceBrowserProxyImpl} from 'chrome://chrome-signin/edu_coexistence/edu_coexistence_browser_proxy.js';
+import {EduCoexistenceController} from 'chrome://chrome-signin/edu_coexistence/edu_coexistence_controller.js';
+import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {assertEquals} from 'chrome://webui-test/chai_assert.js';
+
+import {TestEduCoexistenceBrowserProxy} from './edu_coexistence_test_browser_proxy.js';
+
+const FAKE_NOW_MILLISECONDS = 100000;
+const FAKE_SIGNIN_TIME_MILLISECONDS = 50000;
+
+suite('EduCoexistenceControllerTest', function() {
+  let appComponent;
+  let testBrowserProxy;
+  let eduCoexistenceController: EduCoexistenceController;
+
+  setup(function() {
+    testBrowserProxy = new TestEduCoexistenceBrowserProxy();
+    EduCoexistenceBrowserProxyImpl.setInstance(testBrowserProxy);
+    testBrowserProxy.setCoexistenceParams(getEduCoexistenceParams());
+
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    // The controller wants an edu-coexistence-ui Polymer component
+    // as a parameter.
+    appComponent = document.createElement('edu-coexistence-ui');
+    document.body.appendChild(appComponent);
+    flush();
+
+    eduCoexistenceController = new EduCoexistenceController(
+        appComponent, document.createElement('webview'),
+        getEduCoexistenceParams());
+  });
+
+  test('GetSigninTimeDelta', function() {
+    // Fake Date.now()
+    const realDateNow = Date.now;
+    Date.now = () => {
+      return FAKE_NOW_MILLISECONDS;
+    };
+    const expectedDeltaSeconds =
+        (FAKE_NOW_MILLISECONDS - FAKE_SIGNIN_TIME_MILLISECONDS) / 1000;
+    assertEquals(
+        eduCoexistenceController.getTimeDeltaSinceSigninSeconds(),
+        expectedDeltaSeconds);
+
+    // Restore original Date.now()
+    Date.now = realDateNow;
+  });
+});
+
+
+function getEduCoexistenceParams() {
+  return {
+    url: 'https://foo.example.com/supervision/coexistence/intro',
+    hl: 'en-US',
+    sourceUi: 'oobe',
+    clientId: 'test-client-id',
+    clientVersion: ' test-client-version',
+    eduCoexistenceId: ' test-edu-coexistence-id',
+    platformVersion: ' test-platform-version',
+    releaseChannel: 'test-release-channel',
+    deviceId: 'test-device-id',
+    signinTime: FAKE_SIGNIN_TIME_MILLISECONDS,
+    eduCoexistenceAccessToken: 'token',
+  };
+}
diff --git a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_test_browser_proxy.js b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_test_browser_proxy.js
deleted file mode 100644
index 2ae7576f..0000000
--- a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_test_browser_proxy.js
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {TestBrowserProxy} from 'chrome://webui-test/chromeos/test_browser_proxy.js';
-
-/** @implements {EduCoexistenceBrowserProxy} */
-export class TestEduCoexistenceBrowserProxy extends TestBrowserProxy {
-  constructor() {
-    super([
-      'initializeLogin',
-      'initializeEduArgs',
-      'completeLogin',
-      'getAccounts',
-      'consentValid',
-      'consentLogged',
-      'dialogClose',
-      'error',
-    ]);
-
-    /**
-     * @private {?AccountAdditionOptions}
-     */
-    this.dialogArguments_ = null;
-  }
-
-  /** @override */
-  initializeLogin() {
-    this.methodCalled('initializeLogin');
-  }
-
-  /** @override */
-  initializeEduArgs() {
-    this.methodCalled('initializeEduArgs');
-    return this.initializeEduArgsResponse_ ? this.initializeEduArgsResponse_() :
-                                             Promise.resolve({});
-  }
-
-  /** @param {function} initializeEduArgsResponse */
-  setInitializeEduArgsResponse(initializeEduArgsResponse) {
-    this.initializeEduArgsResponse_ = initializeEduArgsResponse;
-  }
-
-  /**
-   * @param {?AccountAdditionOptions} dialogArguments
-   */
-  setDialogArguments(dialogArguments) {
-    this.dialogArguments_ = dialogArguments;
-  }
-
-  /** @override */
-  completeLogin(credentials, eduLoginParams) {
-    this.methodCalled('completeLogin', [credentials, eduLoginParams]);
-  }
-
-  /** @override */
-  getAccounts() {
-    this.methodCalled('getAccounts');
-    return Promise.resolve(
-      ['test@gmail.com', 'test2@gmail.com', 'test3@gmail.com']);
-  }
-
-  /** @override */
-  consentLogged(account, eduCoexistenceTosVersion) {
-    this.methodCalled('consentLogged', account, eduCoexistenceTosVersion);
-    return this.consentLoggedResponse_();
-  }
-
-  /** @param {function} consentLoggedResponse */
-  setConsentLoggedResponse(consentLoggedResponse) {
-    this.consentLoggedResponse_ = consentLoggedResponse;
-  }
-
-  /** @override */
-  dialogClose() {
-    this.methodCalled('dialogClose');
-  }
-
-  /** @override */
-  error() {
-    this.methodCalled('error');
-  }
-
-  /** @override */
-  getDialogArguments() {
-    return JSON.stringify(this.dialogArguments_);
-  }
-}
diff --git a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_test_browser_proxy.ts b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_test_browser_proxy.ts
new file mode 100644
index 0000000..606cef47
--- /dev/null
+++ b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_test_browser_proxy.ts
@@ -0,0 +1,112 @@
+// Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {AccountAdditionOptions} from 'chrome://chrome-signin/arc_account_picker/arc_util.js';
+import {EduCoexistenceBrowserProxy} from 'chrome://chrome-signin/edu_coexistence/edu_coexistence_browser_proxy.js';
+import {EduCoexistenceParams} from 'chrome://chrome-signin/edu_coexistence/edu_coexistence_controller.js';
+import {AuthCompletedCredentials} from 'chrome://chrome-signin/gaia_auth_host/authenticator.js';
+import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
+
+const DEFAULT_COEXISTENCE_PARAMS = {
+  url: 'https://foo.example.com/supervision/coexistence/intro',
+  hl: 'en-US',
+  sourceUi: 'oobe',
+  clientId: 'test-client-id',
+  clientVersion: ' test-client-version',
+  eduCoexistenceId: ' test-edu-coexistence-id',
+  platformVersion: ' test-platform-version',
+  releaseChannel: 'test-release-channel',
+  deviceId: 'test-device-id',
+  eduCoexistenceAccessToken: 'token',
+  signinTime: 10000,
+};
+
+const DEFAULT_DIALOG_ARGUMENTS = {
+  isAvailableInArc: true,
+  showArcAvailabilityPicker: false,
+};
+
+export class TestEduCoexistenceBrowserProxy extends TestBrowserProxy implements
+    EduCoexistenceBrowserProxy {
+  private dialogArguments: AccountAdditionOptions;
+  private coexistenceParams: EduCoexistenceParams;
+
+  constructor() {
+    super([
+      'initializeLogin',
+      'initializeEduArgs',
+      'authExtensionReady',
+      'completeLogin',
+      'getAccounts',
+      'consentValid',
+      'consentLogged',
+      'dialogClose',
+      'onError',
+    ]);
+
+    this.dialogArguments = DEFAULT_DIALOG_ARGUMENTS;
+    this.coexistenceParams = DEFAULT_COEXISTENCE_PARAMS;
+  }
+
+  initializeLogin() {
+    this.methodCalled('initializeLogin');
+  }
+
+  initializeEduArgs(): Promise<EduCoexistenceParams> {
+    this.methodCalled('initializeEduArgs');
+    return Promise.resolve(this.coexistenceParams);
+  }
+
+  authExtensionReady() {
+    this.methodCalled('authExtensionReady');
+  }
+
+  completeLogin(credentials: AuthCompletedCredentials) {
+    this.methodCalled('completeLogin', credentials);
+  }
+
+  getAccounts(): Promise<string[]> {
+    this.methodCalled('getAccounts');
+    return Promise.resolve(
+        ['test@gmail.com', 'test2@gmail.com', 'test3@gmail.com']);
+  }
+
+  consentValid() {
+    this.methodCalled('consentValid');
+  }
+
+  consentLogged(account: string, eduCoexistenceTosVersion: string):
+      Promise<boolean> {
+    this.methodCalled('consentLogged', account, eduCoexistenceTosVersion);
+    return Promise.resolve(true);
+  }
+
+  dialogClose() {
+    this.methodCalled('dialogClose');
+  }
+
+  onError() {
+    this.methodCalled('error');
+  }
+
+  getDialogArguments(): string {
+    return JSON.stringify(this.dialogArguments);
+  }
+
+  /**
+   * The passed in params override DEFAULT_COEXISTENCE_PARAMS for this instance
+   * of TestEduCoexistenceBrowserProxy.
+   */
+  setCoexistenceParams(coexistenceParams: EduCoexistenceParams) {
+    this.coexistenceParams = coexistenceParams;
+  }
+
+  /**
+   * The passed in dialogArguments override DEFAULT_DIALOG_ARGUMENTS for this
+   * instance of TestEduCoexistenceBrowserProxy.
+   */
+  setDialogArguments(dialogArguments: AccountAdditionOptions) {
+    this.dialogArguments = dialogArguments;
+  }
+}
diff --git a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_ui_test.js b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_ui_test.js
deleted file mode 100644
index a5f6d3d..0000000
--- a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_ui_test.js
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'chrome://chrome-signin/edu_coexistence_ui.js';
-
-import {EduCoexistenceBrowserProxyImpl} from 'chrome://chrome-signin/edu_coexistence_browser_proxy.js';
-import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
-
-import {TestEduCoexistenceBrowserProxy} from './edu_coexistence_test_browser_proxy.js';
-
-suite('EduCoexistenceUiTest', function() {
-  let coexistenceUi;
-  let testBrowserProxy;
-  let webview;
-  setup(function() {
-    testBrowserProxy = new TestEduCoexistenceBrowserProxy();
-    EduCoexistenceBrowserProxyImpl.setInstance(testBrowserProxy);
-    testBrowserProxy.setInitializeEduArgsResponse(async function() {
-      return {
-        url: 'https://foo.example.com/supervision/coexistence/intro',
-        hl: 'en-US',
-        sourceUi: 'oobe',
-        clientId: 'test-client-id',
-        clientVersion: ' test-client-version',
-        eduCoexistenceId: ' test-edu-coexistence-id',
-        platformVersion: ' test-platform-version',
-        releaseChannel: 'test-release-channel',
-        deviceId: 'test-device-id',
-      };
-    });
-
-
-    document.body.innerHTML = window.trustedTypes.emptyHTML;
-    coexistenceUi = document.createElement('edu-coexistence-ui');
-    document.body.appendChild(coexistenceUi);
-    // The webview needs to be set explicitly in for the test because
-    // the component itself doesn't initialize the webview until
-    // too late.  This is OK because we just need a webview in there
-    // to access the back() and focus() methods.
-    webview = document.createElement('webview');
-    coexistenceUi.setWebviewForTest(webview);
-    flush();
-  });
-
-  test(
-      'DisableGaiaBackButtonAfterClick', function() {
-        // Fake out the relevant webview methods.
-        let backCalled = false;
-        webview.back = (success) => {
-          backCalled = true;
-        };
-
-        const backButton =
-            coexistenceUi.shadowRoot.querySelector('#gaia-back-button');
-        // Simulate being on the Gaia signin page by enabling the
-        // Gaia back button
-        backButton.disabled = false;
-
-        // Call the back button action.
-        backButton.dispatchEvent(new CustomEvent('go-back'));
-
-        // Should have called webview_.back() and disabled the button.
-        assertTrue(backCalled);
-        assertTrue(backButton.disabled);
-
-        // Reset the signal in the fake.
-        backCalled = false;
-
-        // Simulate a rapid double-click by immediately calling
-        // the action again.
-        backButton.dispatchEvent(new CustomEvent('go-back'));
-
-        // The webview_.back() method should not be called again.
-        assertFalse(backCalled);
-      });
-});
diff --git a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_ui_test.ts b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_ui_test.ts
new file mode 100644
index 0000000..41936e4
--- /dev/null
+++ b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_ui_test.ts
@@ -0,0 +1,66 @@
+// Copyright 2020 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://chrome-signin/edu_coexistence/edu_coexistence_ui.js';
+
+import {EduCoexistenceBrowserProxyImpl} from 'chrome://chrome-signin/edu_coexistence/edu_coexistence_browser_proxy.js';
+import {EduCoexistenceButton} from 'chrome://chrome-signin/edu_coexistence/edu_coexistence_button.js';
+import {EduCoexistenceUi} from 'chrome://chrome-signin/edu_coexistence/edu_coexistence_ui.js';
+import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+
+import {TestEduCoexistenceBrowserProxy} from './edu_coexistence_test_browser_proxy.js';
+
+suite('EduCoexistenceUiTest', function() {
+  let coexistenceUi: EduCoexistenceUi;
+  let testBrowserProxy: TestEduCoexistenceBrowserProxy;
+  let webview: chrome.webviewTag.WebView;
+
+  setup(function() {
+    testBrowserProxy = new TestEduCoexistenceBrowserProxy();
+    EduCoexistenceBrowserProxyImpl.setInstance(testBrowserProxy);
+
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    coexistenceUi = new EduCoexistenceUi();
+    document.body.appendChild(coexistenceUi);
+    // The webview needs to be set explicitly in for the test because
+    // the component itself doesn't initialize the webview until
+    // too late.  This is OK because we just need a webview in there
+    // to access the back() and focus() methods.
+    webview = document.createElement('webview') as chrome.webviewTag.WebView;
+    coexistenceUi.setWebviewForTest(webview);
+    flush();
+  });
+
+  test('DisableGaiaBackButtonAfterClick', function() {
+    // Fake out the relevant webview methods.
+    let backCalled = false;
+    webview.back = () => {
+      backCalled = true;
+    };
+
+    const backButton = coexistenceUi.shadowRoot!.querySelector(
+                           '#gaia-back-button')! as EduCoexistenceButton;
+    // Simulate being on the Gaia signin page by enabling the
+    // Gaia back button
+    backButton.disabled = false;
+
+    // Call the back button action.
+    backButton.dispatchEvent(new CustomEvent('go-back'));
+
+    // Should have called webview_.back() and disabled the button.
+    assertTrue(backCalled);
+    assertTrue(backButton.disabled);
+
+    // Reset the signal in the fake.
+    backCalled = false;
+
+    // Simulate a rapid double-click by immediately calling
+    // the action again.
+    backButton.dispatchEvent(new CustomEvent('go-back'));
+
+    // The webview_.back() method should not be called again.
+    assertFalse(backCalled);
+  });
+});
diff --git a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_with_arc_restrictions_browsertest.js b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_with_arc_restrictions_browsertest.js
index f804afa..5e96bf7 100644
--- a/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_with_arc_restrictions_browsertest.js
+++ b/chrome/test/data/webui/chromeos/edu_coexistence/edu_coexistence_with_arc_restrictions_browsertest.js
@@ -38,7 +38,7 @@
     /** @override */
     get browsePreload() {
       return `chrome://chrome-signin/test_loader.html` +
-          `?module=chromeos/edu_coexistence/${module}&host=test`;
+          `?module=chromeos/edu_coexistence/${module}`;
     }
   };
   TEST_F(className, caseName || 'All', () => mocha.run());
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js
index 3d577ba..44bd831 100644
--- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js
+++ b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/esim_flow_ui_test.js
@@ -158,29 +158,20 @@
   }
 
   /**
-   * Simulates navigating forward to trigger a profile install.
-   * Asserts that the button_bar and page state is enabled and not busy before
-   * navigating forward. Asserts that the button_bar and page state is
-   * disabled and busy during the install.
+   * Simulates navigating forward to trigger a profile install. Asserts that the
+   * button_bar and page state is enabled before navigating forward. Asserts
+   * that the button_bar and page state is disabled during the install.
    * @param {HTMLElement} page
-   * @param {ButtonState} previousBackButtonState
    */
-  async function navigateForwardForInstall(page, previousBackButtonState) {
+  async function navigateForwardForInstall(page) {
     assertEquals(eSimPage.buttonState.forward, ButtonState.ENABLED);
-    assertEquals(eSimPage.buttonState.backward, previousBackButtonState);
+    assertEquals(eSimPage.buttonState.backward, ButtonState.HIDDEN);
 
-    // If back button is hidden before installation began, the new back button
-    // state should also be hidden, if it was enabled new back button state
-    // should be disabled while installation is taking place.
-    let newBackButtonState = ButtonState.HIDDEN;
-    if (previousBackButtonState === ButtonState.ENABLED) {
-      newBackButtonState = ButtonState.DISABLED;
-    }
     eSimPage.navigateForward();
 
     assertEquals(eSimPage.buttonState.forward, ButtonState.DISABLED);
+    assertEquals(eSimPage.buttonState.backward, ButtonState.HIDDEN);
     assertEquals(eSimPage.buttonState.cancel, ButtonState.DISABLED);
-    assertEquals(eSimPage.buttonState.backward, newBackButtonState);
 
     if (page !== profileLoadingPage && page !== profileDiscoveryConsentPage &&
         page !== finalPage) {
@@ -227,9 +218,9 @@
    * @param {boolean} forwardButtonShouldBeEnabled
    * @param {ButtonState} backButtonState
    */
-  function assertButtonState(forwardButtonShouldBeEnabled, backButtonState) {
+  function assertButtonState(forwardButtonShouldBeEnabled) {
     const buttonState = eSimPage.buttonState;
-    assertEquals(buttonState.backward, backButtonState);
+    assertEquals(buttonState.backward, ButtonState.HIDDEN);
     assertEquals(buttonState.cancel, ButtonState.ENABLED);
     assertEquals(
         buttonState.forward,
@@ -259,8 +250,7 @@
     assertSelectedPage(
         ESimPageName.PROFILE_DISCOVERY_CONSENT, profileDiscoveryConsentPage);
     assertButtonState(
-        /*forwardButtonShouldBeEnabled=*/ true,
-        /*backButtonState=*/ ButtonState.HIDDEN);
+        /*forwardButtonShouldBeEnabled=*/ true);
 
     // When the user clicks the "manually" link, they opt out of profile
     // discovery.
@@ -273,8 +263,7 @@
   async function assertProfileLoadingPageAndContinue() {
     assertSelectedPage(ESimPageName.PROFILE_LOADING, profileLoadingPage);
     assertButtonState(
-        /*forwardButtonShouldBeEnabled=*/ false,
-        /*backButtonState=*/ ButtonState.HIDDEN);
+        /*forwardButtonShouldBeEnabled=*/ false);
     assertEquals(eSimPage.header, eSimPage.i18n('profileLoadingPageTitle'));
     assertEquals(
         profileLoadingPage.loadingMessage,
@@ -285,8 +274,7 @@
   function assertProfileDiscoveryPage() {
     assertSelectedPage(ESimPageName.PROFILE_DISCOVERY, profileDiscoveryPage);
     assertButtonState(
-        /*forwardButtonShouldBeEnabled*/ true,
-        /*backButtonState*/ ButtonState.HIDDEN);
+        /*forwardButtonShouldBeEnabled*/ true);
     assertEquals(eSimPage.header, eSimPage.i18n('profileDiscoveryPageTitle'));
   }
 
@@ -297,7 +285,7 @@
       assertEquals(activationCodePage.$$('#activationCode').value, '');
     }
     assertSelectedPage(ESimPageName.ACTIVATION_CODE, activationCodePage);
-    assertButtonState(forwardButtonShouldBeEnabled, backButtonState);
+    assertButtonState(forwardButtonShouldBeEnabled);
   }
 
   function assertConfirmationCodePage(
@@ -307,7 +295,7 @@
       assertEquals(confirmationCodePage.$$('#confirmationCode').value, '');
     }
     assertSelectedPage(ESimPageName.CONFIRMATION_CODE, confirmationCodePage);
-    assertButtonState(forwardButtonShouldBeEnabled, backButtonState);
+    assertButtonState(forwardButtonShouldBeEnabled);
     assertEquals(eSimPage.header, eSimPage.i18n('confimationCodePageTitle'));
   }
 
diff --git a/chrome/test/data/webui/cr_elements/BUILD.gn b/chrome/test/data/webui/cr_elements/BUILD.gn
index c0a91cc..2686f17f 100644
--- a/chrome/test/data/webui/cr_elements/BUILD.gn
+++ b/chrome/test/data/webui/cr_elements/BUILD.gn
@@ -26,6 +26,7 @@
     "cr_input_test.ts",
     "cr_lazy_render_test.ts",
     "cr_link_row_test.ts",
+    "cr_loading_gradient_test.ts",
     "cr_lottie_test.ts",
     "cr_menu_selector_focus_test.ts",
     "cr_policy_indicator_mixin_test.ts",
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.cc b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.cc
index 95b7e35..071a64e 100644
--- a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.cc
+++ b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.cc
@@ -147,6 +147,10 @@
   RunTest("cr_elements/store_client_test.js", "mocha.run()");
 }
 
+IN_PROC_BROWSER_TEST_F(CrElementsTest, CrLoadingGradient) {
+  RunTest("cr_elements/cr_loading_gradient_test.js", "mocha.run()");
+}
+
 // Test with --enable-pixel-output-in-tests enabled, required by a few test
 // cases using HTML canvas.
 class CrElementsWithPixelOutputTest : public WebUIMochaBrowserTest {
diff --git a/chrome/test/data/webui/cr_elements/cr_loading_gradient_test.ts b/chrome/test/data/webui/cr_elements/cr_loading_gradient_test.ts
new file mode 100644
index 0000000..f6053adf
--- /dev/null
+++ b/chrome/test/data/webui/cr_elements/cr_loading_gradient_test.ts
@@ -0,0 +1,41 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://resources/cr_elements/cr_loading_gradient/cr_loading_gradient.js';
+
+import {getTrustedHTML} from 'chrome://resources/js/static_types.js';
+import {assertEquals} from 'chrome://webui-test/chai_assert.js';
+import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
+
+suite('CrLoadingGradientElement', () => {
+  test('AssignsUniqueIds', async () => {
+    document.body.innerHTML = getTrustedHTML`
+      <cr-loading-gradient>
+        <svg width="100" height="100">
+          <clipPath><circle cx="100" cy="100" r="100"></circle></clipPath>
+        </svg>
+      </cr-loading-gradient>
+      <cr-loading-gradient>
+        <svg width="100" height="100">
+          <clipPath>
+            <rect x="0" y="0" width="100%" height="100" rx="5"></rect>
+          </clipPath>
+        </svg>
+      </cr-loading-gradient>
+    `;
+    await flushTasks();
+
+    const gradients = document.querySelectorAll('cr-loading-gradient');
+    assertEquals(
+        'crLoadingGradient0', gradients[0]!.querySelector('clipPath')!.id);
+    assertEquals(
+        'url("#crLoadingGradient0")',
+        gradients[0]!.style.getPropertyValue('clip-path'));
+    assertEquals(
+        'crLoadingGradient1', gradients[1]!.querySelector('clipPath')!.id);
+    assertEquals(
+        'url("#crLoadingGradient1")',
+        gradients[1]!.style.getPropertyValue('clip-path'));
+  });
+});
diff --git a/chrome/test/data/webui/flags/BUILD.gn b/chrome/test/data/webui/flags/BUILD.gn
new file mode 100644
index 0000000..b979ed1
--- /dev/null
+++ b/chrome/test/data/webui/flags/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright 2023 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("../build_webui_tests.gni")
+
+build_webui_tests("build") {
+  files = [
+    "app_test.ts",
+    "test_flags_browser_proxy.ts",
+  ]
+
+  ts_path_mappings = [ "chrome://flags/*|" + rebase_path(
+                           "$root_gen_dir/components/flags_ui/resources/tsc/*",
+                           target_gen_dir) ]
+
+  ts_deps = [
+    "//components/flags_ui/resources:build_ts",
+    "//ui/webui/resources/js:build_ts",
+  ]
+}
diff --git a/chrome/test/data/webui/flags/DIR_METADATA b/chrome/test/data/webui/flags/DIR_METADATA
new file mode 100644
index 0000000..75be1aea
--- /dev/null
+++ b/chrome/test/data/webui/flags/DIR_METADATA
@@ -0,0 +1 @@
+mixins: "//components/flags_ui/COMMON_METADATA"
diff --git a/chrome/test/data/webui/flags/app_test.ts b/chrome/test/data/webui/flags/app_test.ts
new file mode 100644
index 0000000..3995895
--- /dev/null
+++ b/chrome/test/data/webui/flags/app_test.ts
@@ -0,0 +1,163 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://flags/app.js';
+
+import {FlagsAppElement} from 'chrome://flags/app.js';
+import {ExperimentalFeaturesData, Feature, FlagsBrowserProxyImpl} from 'chrome://flags/flags_browser_proxy.js';
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {eventToPromise, isVisible} from 'chrome://webui-test/test_util.js';
+
+import {TestFlagsBrowserProxy} from './test_flags_browser_proxy.js';
+
+suite('FlagsAppTest', function() {
+  const supportedFeatures: Feature[] = [
+    {
+      'description': 'available_feature_1',
+      'internal_name': 'available_feature_1',
+      'is_default': true,
+      'name': 'available_feature_1',
+      'enabled': true,
+      'options': [
+        {
+          'description': 'Default',
+          'internal_name': 'available_feature_1',
+          'selected': false,
+        },
+        {
+          'description': 'Enabled',
+          'internal_name': 'available_feature_1',
+          'selected': false,
+        },
+        {
+          'description': 'Disabled',
+          'internal_name': 'available_feature_1',
+          'selected': false,
+        },
+      ],
+      'supported_platforms': ['Windows'],
+    },
+  ];
+  const unsupportedFeatures: Feature[] = [
+    {
+      'description': 'unavailable_feature_1',
+      'enabled': false,
+      'internal_name': 'unavailable_feature_1',
+      'is_default': true,
+      'name': 'unavailable_feature_1',
+      'supported_platforms': ['ChromeOS', 'Android'],
+    },
+  ];
+  const experimentalFeaturesData: ExperimentalFeaturesData = {
+    'supportedFeatures': supportedFeatures,
+    'unsupportedFeatures': unsupportedFeatures,
+    'needsRestart': false,
+    'showBetaChannelPromotion': false,
+    'showDevChannelPromotion': false,
+    'showOwnerWarning': false,
+    'showSystemFlagsLink': true,
+  };
+
+  let app: FlagsAppElement;
+  let searchTextArea: HTMLInputElement;
+  let clearSearch: HTMLInputElement;
+  let resetAllButton: HTMLButtonElement;
+  let browserProxy: TestFlagsBrowserProxy;
+
+  setup(async function() {
+    browserProxy = new TestFlagsBrowserProxy();
+    browserProxy.setFeatureData(experimentalFeaturesData);
+    FlagsBrowserProxyImpl.setInstance(browserProxy);
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    app = document.createElement('flags-app');
+    document.body.appendChild(app);
+    app.setAnnounceStatusDelayMsForTesting(0);
+    app.setSearchDebounceDelayMsForTesting(0);
+    await app.experimentalFeaturesReadyForTesting();
+    searchTextArea = app.getRequiredElement<HTMLInputElement>('#search');
+    clearSearch = app.getRequiredElement<HTMLInputElement>('.clear-search');
+    resetAllButton =
+        app.getRequiredElement<HTMLButtonElement>('#experiment-reset-all');
+  });
+
+  function searchBoxInput(text: string) {
+    searchTextArea.value = text;
+    searchTextArea.dispatchEvent(
+        new CustomEvent('input', {composed: true, bubbles: true}));
+  }
+
+  test('clear search button shown/hidden', async function() {
+    // The clear search button is hidden initially.
+    assertFalse(isVisible(clearSearch));
+
+    // The clear search button is shown when an input event fired.
+    const searchEventPromise =
+        eventToPromise('search-finished-for-testing', app);
+    searchBoxInput('test');
+    await searchEventPromise;
+    assertTrue(isVisible(clearSearch));
+
+    // The clear search button is hidden after button clicked.
+    clearSearch.click();
+    assertEquals('', searchTextArea.value);
+    assertFalse(isVisible(clearSearch));
+  });
+
+  test('restart toast shown and relaunch event fired', function() {
+    const restartToast = app.getRequiredElement('#needs-restart');
+
+    // The restart toast is not visible initially.
+    assertFalse(restartToast.classList.contains('show'));
+
+    // The reset all button is clicked and restart toast becomes visible.
+    resetAllButton.click();
+    assertTrue(restartToast.classList.contains('show'));
+
+    // The restart button is clicked and a browserRestart event fired.
+    const restartButton =
+        app.getRequiredElement<HTMLButtonElement>('#experiment-restart-button');
+    restartButton.click();
+    return browserProxy.whenCalled('restartBrowser');
+  });
+
+  test('search and found match', function() {
+    const promise = eventToPromise('search-finished-for-testing', app);
+    searchBoxInput('available');
+    return promise.then(() => {
+      assertFalse(isVisible(app.getRequiredElement('.no-match')));
+      const noMatchMsg: NodeListOf<HTMLElement> =
+          app.$all('.tab-content .no-match');
+      assertTrue(!!noMatchMsg[0]);
+      assertEquals(
+          1,
+          app.$all(`#tab-content-available flags-experiment:not(.hidden)`)
+              .length);
+      assertTrue(!!noMatchMsg[1]);
+      assertEquals(
+          1,
+          app.$all(`#tab-content-unavailable flags-experiment:not(.hidden)`)
+              .length);
+    });
+  });
+
+  test('search and match not found', function() {
+    const promise = eventToPromise('search-finished-for-testing', app);
+    searchBoxInput('none');
+    return promise.then(() => {
+      assertTrue(isVisible(app.getRequiredElement('.no-match')));
+      const noMatchMsg: NodeListOf<HTMLElement> =
+          app.$all('.tab-content .no-match');
+      assertTrue(!!noMatchMsg[0]);
+      assertEquals(
+          0,
+          app.$all(`#tab-content-available flags-experiment:not(.hidden)`)
+              .length);
+      assertTrue(!!noMatchMsg[1]);
+      assertEquals(
+          0,
+          app.$all(`#tab-content-unavailable flags-experiment:not(.hidden)`)
+              .length);
+    });
+  });
+});
diff --git a/chrome/test/data/webui/flags/flags_browsertest.cc b/chrome/test/data/webui/flags/flags_browsertest.cc
new file mode 100644
index 0000000..e5f27f1
--- /dev/null
+++ b/chrome/test/data/webui/flags/flags_browsertest.cc
@@ -0,0 +1,16 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/webui_url_constants.h"
+#include "chrome/test/base/web_ui_mocha_browser_test.h"
+#include "content/public/test/browser_test.h"
+
+class FlagsUiBrowserTest : public WebUIMochaBrowserTest {
+ protected:
+  FlagsUiBrowserTest() { set_test_loader_host(chrome::kChromeUIFlagsHost); }
+};
+
+IN_PROC_BROWSER_TEST_F(FlagsUiBrowserTest, App) {
+  RunTest("flags/app_test.js", "mocha.run()");
+}
diff --git a/chrome/test/data/webui/flags/test_flags_browser_proxy.ts b/chrome/test/data/webui/flags/test_flags_browser_proxy.ts
new file mode 100644
index 0000000..c707b8aa
--- /dev/null
+++ b/chrome/test/data/webui/flags/test_flags_browser_proxy.ts
@@ -0,0 +1,74 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {ExperimentalFeaturesData, FlagsBrowserProxy} from 'chrome://flags/flags_browser_proxy.js';
+import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
+
+export class TestFlagsBrowserProxy extends TestBrowserProxy implements
+    FlagsBrowserProxy {
+  private featureData: ExperimentalFeaturesData = {
+    // Default feature data
+    'supportedFeatures': [],
+    'unsupportedFeatures': [],
+    'needsRestart': false,
+    'showBetaChannelPromotion': false,
+    'showDevChannelPromotion': false,
+    'showOwnerWarning': false,
+    'showSystemFlagsLink': true,
+  };
+
+  constructor() {
+    super([
+      'restartBrowser',
+      // <if expr="is_chromeos">
+      'crosUrlFlagsRedirect',
+      // </if>
+      'resetAllFlags',
+      'requestExperimentalFeatures',
+      'enableExperimentalFeature',
+      'selectExperimentalFeature',
+      'setOriginListFlag',
+      'setStringFlag',
+    ]);
+  }
+
+  setFeatureData(data: ExperimentalFeaturesData) {
+    this.featureData = data;
+  }
+
+  restartBrowser() {
+    this.methodCalled('restartBrowser');
+  }
+
+  // <if expr="is_chromeos">
+  crosUrlFlagsRedirect() {
+    this.methodCalled('crosUrlFlagsRedirect');
+  }
+  // </if>
+
+  resetAllFlags() {
+    this.methodCalled('resetAllFlags');
+  }
+
+  requestExperimentalFeatures() {
+    this.methodCalled('requestExperimentalFeatures');
+    return Promise.resolve(structuredClone(this.featureData));
+  }
+
+  enableExperimentalFeature(internalName: string, enable: boolean) {
+    this.methodCalled('enableExperimentalFeature', internalName, enable);
+  }
+
+  selectExperimentalFeature(internalName: string, index: number) {
+    this.methodCalled('selectExperimentalFeature', internalName, index);
+  }
+
+  setOriginListFlag(internalName: string, value: string) {
+    this.methodCalled('setOriginListFlag', internalName, value);
+  }
+
+  setStringFlag(internalName: string, value: string) {
+    this.methodCalled('setStringFlag', internalName, value);
+  }
+}
diff --git a/chrome/test/data/webui/settings/chromeos/apn_detail_dialog_test.ts b/chrome/test/data/webui/settings/chromeos/apn_detail_dialog_test.ts
index 2458f4de..dc0bd7f6 100644
--- a/chrome/test/data/webui/settings/chromeos/apn_detail_dialog_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/apn_detail_dialog_test.ts
@@ -98,6 +98,7 @@
     assertEquals(
         apnDetailDialog.i18n('apnDetailAddApnDialogTitle'),
         apnDetailDialogTitle.innerText);
+    assertEquals('polite', apnDetailDialogTitle.ariaLive);
     assertTrue(!!apnDetailDialog.shadowRoot!.querySelector('#apnInput'));
     assertTrue(!!apnDetailDialog.shadowRoot!.querySelector('#usernameInput'));
     assertTrue(!!apnDetailDialog.shadowRoot!.querySelector('#passwordInput'));
@@ -441,10 +442,18 @@
           assertTrue(!!apnDefaultTypeCheckbox);
           apnDefaultTypeCheckbox.checked = defaultType;
 
+          assertEquals(
+              'apnDetailApnTypesLabel',
+              apnDefaultTypeCheckbox.getAttribute('aria-describedby'));
+
           const apnAttachTypeCheckbox =
               apnDetailDialog.shadowRoot!.querySelector<CrCheckboxElement>(
                   '#apnAttachTypeCheckbox');
           assertTrue(!!apnAttachTypeCheckbox);
+          assertEquals(
+              'apnDetailApnTypesLabel',
+              apnAttachTypeCheckbox.getAttribute('aria-describedby'));
+
           apnAttachTypeCheckbox.checked = attachType;
         };
 
diff --git a/chrome/test/data/webui/settings/chromeos/device_page/customize_buttons_subsection_test.ts b/chrome/test/data/webui/settings/chromeos/device_page/customize_buttons_subsection_test.ts
index d25d830..d7b5dba8 100644
--- a/chrome/test/data/webui/settings/chromeos/device_page/customize_buttons_subsection_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/device_page/customize_buttons_subsection_test.ts
@@ -68,10 +68,23 @@
             '#renamingDialogInput');
     assertTrue(!!buttonLabelInput);
     assertEquals(buttonRemappingChangedEventCount, 0);
-    buttonLabelInput.value = 'New Button Name';
+
+    // Verify that if the new button is too long, it will cause invalid and be
+    // truncated.
+    buttonLabelInput.value =
+        'Button name which exceeds 64 character is too long and is invalid.';
     const saveButton: CrButtonElement|null =
         customizeButtonsSubsection.shadowRoot!.querySelector('#saveButton');
+    assertTrue(customizeButtonsSubsection.get('buttonNameInvalid_'));
+    assertEquals(buttonLabelInput.value.length, 64);
+    const inputCountText: HTMLDivElement|null =
+        customizeButtonsSubsection.shadowRoot!.querySelector('#inputCount');
+    assertEquals(inputCountText!.textContent!.trim(), '64/64');
     assertTrue(!!saveButton);
+
+    buttonLabelInput.value = 'New Button Name';
+    assertEquals(inputCountText!.textContent!.trim(), '15/64');
+    assertFalse(customizeButtonsSubsection.get('buttonNameInvalid_'));
     saveButton.click();
     await flushTasks();
     assertEquals(buttonRemappingChangedEventCount, 1);
diff --git a/chrome/test/data/webui/settings/chromeos/internet_page/hotspot_subpage_test.ts b/chrome/test/data/webui/settings/chromeos/internet_page/hotspot_subpage_test.ts
index 8cdd3ada..78c0ad0 100644
--- a/chrome/test/data/webui/settings/chromeos/internet_page/hotspot_subpage_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/internet_page/hotspot_subpage_test.ts
@@ -147,20 +147,27 @@
     const enableToggle = queryEnableHotspotToggle();
     const hotspotNameElement =
         hotspotSubpage.shadowRoot!.querySelector('#hotspotSSID');
+    const connectedClientCountRow =
+        hotspotSubpage.shadowRoot!.querySelector<HTMLElement>(
+            '#connectedDeviceCountRow');
     const connectedClientCount =
         hotspotSubpage.shadowRoot!.querySelector('#connectedDeviceCount');
 
     assertTrue(!!hotspotOnOffLabel);
     assertTrue(!!enableToggle);
     assertTrue(!!hotspotNameElement);
+    assertTrue(!!connectedClientCountRow);
     assertTrue(!!connectedClientCount);
 
     assertEquals(
         hotspotSubpage.i18n('hotspotSummaryStateOff'),
         hotspotOnOffLabel.textContent!.trim());
     assertEquals('test_ssid', hotspotNameElement.textContent!.trim());
-    assertEquals('0', connectedClientCount.textContent!.trim());
-    assertFalse(enableToggle.checked);
+    assertFalse(
+        enableToggle.checked, 'Enable hotspot toggle should not be checked');
+    assertTrue(
+        connectedClientCountRow.hidden,
+        'Connected device count row should be hidden');
 
     // Simulate turning on hotspot.
     hotspotConfig.setFakeEnableHotspotResult(HotspotControlResult.kSuccess);
@@ -169,7 +176,10 @@
     assertEquals(
         hotspotSubpage.i18n('hotspotSummaryStateOn'),
         hotspotOnOffLabel.textContent!.trim());
-    assertTrue(enableToggle.checked);
+    assertTrue(enableToggle.checked, 'Enable hotspot toggle should be checked');
+    assertFalse(
+        connectedClientCountRow.hidden,
+        'Connected device count row should not be hidden');
 
     // Simulate turning off hotspot.
     hotspotConfig.setFakeDisableHotspotResult(HotspotControlResult.kSuccess);
@@ -178,7 +188,11 @@
     assertEquals(
         hotspotSubpage.i18n('hotspotSummaryStateOff'),
         hotspotOnOffLabel.textContent!.trim());
-    assertFalse(enableToggle.checked);
+    assertFalse(
+        enableToggle.checked, 'Enable hotspot toggle should not be checked');
+    assertTrue(
+        connectedClientCountRow.hidden,
+        'Connected device count row should be hidden');
 
     // Verify toggle is able to turn on/off by CrosHotspotConfig even when it is
     // disabled by policy.
@@ -186,35 +200,58 @@
         HotspotAllowStatus.kDisallowedByPolicy);
     await flushAsync();
     // Toggle should be disabled.
-    assertTrue(enableToggle.disabled);
+    assertTrue(
+        enableToggle.disabled, 'Enable hotspot toggle should be disabled');
 
     hotspotConfig.setFakeHotspotState(HotspotState.kEnabling);
     await flushAsync();
     assertEquals(
         hotspotSubpage.i18n('hotspotSummaryStateTurningOn'),
         hotspotOnOffLabel.textContent!.trim());
-    assertTrue(enableToggle.checked);
+    assertTrue(
+        enableToggle.checked,
+        'Enable hotspot toggle should not checked when hotspot enabling');
+    assertTrue(
+        connectedClientCountRow.hidden,
+        'Connected device count row should be hidden when hotspot enabling');
 
     hotspotConfig.setFakeHotspotState(HotspotState.kEnabled);
     await flushAsync();
     assertEquals(
         hotspotSubpage.i18n('hotspotSummaryStateOn'),
         hotspotOnOffLabel.textContent!.trim());
-    assertTrue(enableToggle.checked);
+    assertTrue(
+        enableToggle.checked,
+        'Enable hotspot toggle should be checked when hotspot enabled');
+    assertFalse(
+        connectedClientCountRow.hidden,
+        'Connected device count row should be not hidden when hotspot enabled');
+    assertEquals('0', connectedClientCount.textContent!.trim());
 
     hotspotConfig.setFakeHotspotState(HotspotState.kDisabling);
     await flushAsync();
     assertEquals(
         hotspotSubpage.i18n('hotspotSummaryStateTurningOff'),
         hotspotOnOffLabel.textContent!.trim());
-    assertFalse(enableToggle.checked);
+    assertFalse(
+        enableToggle.checked,
+        'Enable hotspot toggle should not be checked when hotspot disabling');
+    assertFalse(
+        connectedClientCountRow.hidden,
+        'Connected device count row should be shown when hotspot disabling');
+    assertEquals('0', connectedClientCount.textContent!.trim());
 
     hotspotConfig.setFakeHotspotState(HotspotState.kDisabled);
     await flushAsync();
     assertEquals(
         hotspotSubpage.i18n('hotspotSummaryStateOff'),
         hotspotOnOffLabel.textContent!.trim());
-    assertFalse(enableToggle.checked);
+    assertFalse(
+        enableToggle.checked,
+        'Enable hotspot toggle should not be checked when hotspot disabled');
+    assertTrue(
+        connectedClientCountRow.hidden,
+        'Connected device count row should be hidden when hotspot disabled');
 
     hotspotConfig.setFakeHotspotActiveClientCount(6);
     await flushAsync();
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_menu/os_settings_menu_revamp_test.ts b/chrome/test/data/webui/settings/chromeos/os_settings_menu/os_settings_menu_revamp_test.ts
index 595dc8e..b4bc3d8 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_menu/os_settings_menu_revamp_test.ts
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_menu/os_settings_menu_revamp_test.ts
@@ -425,4 +425,16 @@
       assertEquals('Touchpad, print, display', deviceMenuItem.sublabel);
     });
   });
+
+  suite('Privacy menu item', () => {
+    test('Privacy menu item description', async () => {
+      await createMenu();
+
+      const privacyMenuItem = queryMenuItemByPath(
+          `/${routesMojom.PRIVACY_AND_SECURITY_SECTION_PATH}`);
+      assertTrue(!!privacyMenuItem);
+
+      assertEquals('Lock screen, controls', privacyMenuItem.sublabel);
+    });
+  });
 });
diff --git a/chrome/test/data/webui/settings/route_test.ts b/chrome/test/data/webui/settings/route_test.ts
index 2f1a349..3d51540b 100644
--- a/chrome/test/data/webui/settings/route_test.ts
+++ b/chrome/test/data/webui/settings/route_test.ts
@@ -384,7 +384,7 @@
 
     // Assert that the route is changed to safety hub.
     path = Router.getInstance().getCurrentRoute().path;
-    assertEquals('/safetyHub', path);
+    assertEquals('/safetyCheck', path);
   });
 
   test('SafetyCheckRouteNotReachable', async function() {
diff --git a/chrome/test/data/webui/side_panel/customize_chrome/wallpaper_search_test.ts b/chrome/test/data/webui/side_panel/customize_chrome/wallpaper_search_test.ts
index d328d67..d51f3a2 100644
--- a/chrome/test/data/webui/side_panel/customize_chrome/wallpaper_search_test.ts
+++ b/chrome/test/data/webui/side_panel/customize_chrome/wallpaper_search_test.ts
@@ -6,7 +6,7 @@
 
 import {CustomizeChromePageCallbackRouter, CustomizeChromePageHandlerRemote, Descriptors} from 'chrome://customize-chrome-side-panel.top-chrome/customize_chrome.mojom-webui.js';
 import {CustomizeChromeApiProxy} from 'chrome://customize-chrome-side-panel.top-chrome/customize_chrome_api_proxy.js';
-import {WallpaperSearchElement} from 'chrome://customize-chrome-side-panel.top-chrome/wallpaper_search.js';
+import {DESCRIPTOR_C_VALUE, WallpaperSearchElement} from 'chrome://customize-chrome-side-panel.top-chrome/wallpaper_search.js';
 import {assertEquals, assertFalse, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
 import {TestMock} from 'chrome://webui-test/test_mock.js';
@@ -100,6 +100,11 @@
           wallpaperSearchElement.shadowRoot!
               .querySelectorAll('#descriptorMenuC .dropdown-item')
               .length);
+      assertEquals(
+          5,
+          wallpaperSearchElement.shadowRoot!
+              .querySelectorAll('#descriptorMenuD cr-button')
+              .length);
     });
 
     test('descriptor menus open and close', async () => {
@@ -145,12 +150,17 @@
           wallpaperSearchElement, '#descriptorMenuB .dropdown-item')!.click();
       $$<HTMLElement>(
           wallpaperSearchElement, '#descriptorMenuC .dropdown-item')!.click();
+      $$<HTMLElement>(
+          wallpaperSearchElement, '#descriptorMenuD cr-button')!.click();
       wallpaperSearchElement.$.submitButton.click();
 
       assertEquals(1, handler.getCallCount('getWallpaperSearchResults'));
       assertEquals('bar', handler.getArgs('getWallpaperSearchResults')[0][0]);
       assertEquals('foo', handler.getArgs('getWallpaperSearchResults')[0][1]);
       assertEquals('baz', handler.getArgs('getWallpaperSearchResults')[0][2]);
+      assertEquals(
+          DESCRIPTOR_C_VALUE[0],
+          handler.getArgs('getWallpaperSearchResults')[0][3]);
     });
 
     test('selects random descriptor', async () => {
@@ -191,6 +201,8 @@
           undefined, handler.getArgs('getWallpaperSearchResults')[0][1]);
       assertEquals(
           undefined, handler.getArgs('getWallpaperSearchResults')[0][2]);
+      assertEquals(
+          undefined, handler.getArgs('getWallpaperSearchResults')[0][3]);
     });
 
     test('empty result shows no tiles', async () => {
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc
index 5d9cce6..6f68068 100644
--- a/chrome/updater/test/integration_tests.cc
+++ b/chrome/updater/test/integration_tests.cc
@@ -1785,6 +1785,14 @@
   ~IntegrationTestDeviceManagement() override = default;
 
  protected:
+  struct TestApp {
+    std::string appid;
+    base::Version v1;
+    std::string v1_crx;
+    base::Version v2;
+    std::string v2_crx;
+  };
+
   void SetUp() override {
     IntegrationTest::SetUp();
     test_server_ = std::make_unique<ScopedServer>(test_commands_);
@@ -1809,23 +1817,25 @@
                               to_version.GetString().c_str());
   }
 
-  void InstallAppWithVersion(const std::string& app_id,
-                             const base::Version& version) {
-    InstallApp(app_id, version, [&]() {
+  void InstallTestApp(const TestApp& app, bool install_v1 = true) {
+    const base::Version version = install_v1 ? app.v1 : app.v2;
+    const base::FilePath& installer_path =
+        GetInstallerPath(install_v1 ? app.v1_crx : app.v2_crx);
+    InstallApp(app.appid, version, [&]() {
       base::FilePath exe_path;
       ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &exe_path));
 #if BUILDFLAG(IS_WIN)
       // Run test app installer to set app `pv` value to its initial
       // version.
-      const std::wstring command(base::StrCat(
-          {base::CommandLine::QuoteForCommandLineToArgvW(
-               exe_path
-                   .Append(GetInstallerPath(kAppCRX).ReplaceExtension(
-                       FILE_PATH_LITERAL(".exe")))
-                   .value()),
-           L" ",
-           base::ASCIIToWide(
-               BuildCommandLineArgs(GetTestScope(), app_id, version))}));
+      const std::wstring command(
+          base::StrCat({base::CommandLine::QuoteForCommandLineToArgvW(
+                            exe_path
+                                .Append(installer_path.ReplaceExtension(
+                                    FILE_PATH_LITERAL(".exe")))
+                                .value()),
+                        L" ",
+                        base::ASCIIToWide(BuildCommandLineArgs(
+                            GetTestScope(), app.appid, version))}));
       VLOG(2) << "Launch app setup command: " << command;
       base::Process process = base::LaunchProcess(command, {});
       if (!process.IsValid()) {
@@ -1838,9 +1848,9 @@
 #else
       // Run test app installer to set app initial version artifacts.
       base::CommandLine command(exe_path
-                   .Append(GetInstallerPath(kAppCRX).DirName().AppendASCII(
+                   .Append(installer_path.DirName().AppendASCII(
                        "test_app_setup.sh")));
-      command.AppendSwitchASCII("--appid", app_id);
+      command.AppendSwitchASCII("--appid", app.appid);
       command.AppendSwitchASCII("--company", COMPANY_SHORTNAME_STRING);
       command.AppendSwitchASCII("--product_version", version.GetString());
       VLOG(2) << "Launch app setup command: " << command.GetCommandLineString();
@@ -1852,13 +1862,13 @@
       EXPECT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_timeout(),
                                                  &exit_code));
       EXPECT_EQ(0, exit_code);
-      SetExistenceCheckerPath(app_id,
+      SetExistenceCheckerPath(app.appid,
           GetInstallDirectory(
-              UpdaterScope::kSystem)->DirName().AppendASCII(app_id));
+              UpdaterScope::kSystem)->DirName().AppendASCII(app.appid));
 #endif
     });
 
-    ExpectAppInstalled(app_id, version);
+    ExpectAppInstalled(app.appid, version);
   }
 
   void SetCloudPolicyOverridesPlatformPolicy() {
@@ -1874,13 +1884,28 @@
   std::unique_ptr<ScopedServer> test_server_;
   static constexpr char kEnrollmentToken[] = "integration-enrollment-token";
   static constexpr char kDMToken[] = "integration-dm-token";
-  static constexpr char kAppId1[] = "test1";
-  static constexpr char kAppId2[] = "test2";
-  static constexpr char kAppId3[] = "test3";
+
 #if BUILDFLAG(IS_WIN)
-  static constexpr char kAppCRX[] = "Testapp2Setup.crx3";
+  static constexpr char kGlobalPolicyKey[] = "";
+  const TestApp kApp1 = {"test1", base::Version("1.0.0.0"),
+                         "Testapp2Setup.crx3", base::Version("2.0.0.0"),
+                         "Testapp2Setup.crx3"};
+  const TestApp kApp2 = {"test2", base::Version("100.0.0.0"),
+                         "Testapp2Setup.crx3", base::Version("101.0.0.0"),
+                         "Testapp2Setup.crx3"};
+  const TestApp kApp3 = {"test3", base::Version("1.0"), "Testapp2Setup.crx3",
+                         base::Version("1.1"), "Testapp2Setup.crx3"};
 #else
-  static constexpr char kAppCRX[] = "test_installer_test1_v1.crx3";
+  static constexpr char kGlobalPolicyKey[] = "global";
+  const TestApp kApp1 = {
+      "test1", base::Version("1.0.0.0"), "test_installer_test1_v1.crx3",
+      base::Version("2.0.0.0"), "test_installer_test1_v2.crx3"};
+  const TestApp kApp2 = {
+      "test2", base::Version("100.0.0.0"), "test_installer_test2_v1.crx3",
+      base::Version("101.0.0.0"), "test_installer_test2_v2.crx3"};
+  const TestApp kApp3 = {"test3", base::Version("1.0"),
+                         "test_installer_test3_v1.crx3", base::Version("1.1"),
+                         "test_installer_test3_v2.crx3"};
 #endif  // BUILDFLAG(IS_WIN)
 };
 
@@ -1895,7 +1920,7 @@
   omaha_settings.set_proxy_mode("system");
   omaha_settings.set_proxy_server("test.proxy.server");
   ApplicationSettings app;
-  app.set_app_guid(kAppId1);
+  app.set_app_guid(kApp1.appid);
   app.set_update(enterprise_management::AUTOMATIC_UPDATES_ONLY);
   app.set_target_version_prefix("0.1");
   app.set_rollback_to_target_version(
@@ -1922,7 +1947,7 @@
   ASSERT_GT(omaha_policy->application_settings_size(), 0);
   const ApplicationSettings& app_policy =
       omaha_policy->application_settings()[0];
-  EXPECT_EQ(app_policy.app_guid(), kAppId1);
+  EXPECT_EQ(app_policy.app_guid(), kApp1.appid);
   EXPECT_EQ(app_policy.update(), enterprise_management::AUTOMATIC_UPDATES_ONLY);
   EXPECT_EQ(app_policy.target_version_prefix(), "0.1");
   EXPECT_EQ(app_policy.rollback_to_target_version(),
@@ -1939,7 +1964,7 @@
   omaha_settings.set_install_default(
       enterprise_management::INSTALL_DEFAULT_DISABLED);
   ApplicationSettings app;
-  app.set_app_guid(kAppId1);
+  app.set_app_guid(kApp1.appid);
   app.set_install(enterprise_management::INSTALL_ENABLED);
   omaha_settings.mutable_application_settings()->Add(std::move(app));
 
@@ -1951,22 +1976,22 @@
   ASSERT_NO_FATAL_FAILURE(Install());
   ASSERT_NO_FATAL_FAILURE(ExpectInstalled());
 
-  const base::FilePath crx_path = GetInstallerPath(kAppCRX);
   ASSERT_NO_FATAL_FAILURE(ExpectAppsUpdateSequence(
       UpdaterScope::kSystem, test_server_.get(),
       /*request_attributes=*/{},
       {
           AppUpdateExpectation(
-              BuildCommandLineArgs(GetTestScope(), kAppId1, kApp1Version),
-              kAppId1, base::Version({0, 0, 0, 0}), kApp1Version,
+              BuildCommandLineArgs(GetTestScope(), kApp1.appid, kApp1.v1),
+              kApp1.appid, base::Version({0, 0, 0, 0}), kApp1.v1,
               /*is_install=*/true,
-              /*should_update=*/true, false, "", "", crx_path),
+              /*should_update=*/true, false, "", "",
+              GetInstallerPath(kApp1.v1_crx)),
       }));
 
-  ASSERT_NO_FATAL_FAILURE(InstallAppViaService(kAppId1));
-  ASSERT_NO_FATAL_FAILURE(InstallAppViaService(kAppId2));
-  ExpectAppInstalled(kAppId1, kApp1Version);
-  ASSERT_NO_FATAL_FAILURE(ExpectNotRegistered(kAppId2));
+  ASSERT_NO_FATAL_FAILURE(InstallAppViaService(kApp1.appid));
+  ASSERT_NO_FATAL_FAILURE(InstallAppViaService(kApp2.appid));
+  ExpectAppInstalled(kApp1.appid, kApp1.v1);
+  ASSERT_NO_FATAL_FAILURE(ExpectNotRegistered(kApp2.appid));
 
   ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get()));
   ASSERT_NO_FATAL_FAILURE(Uninstall());
@@ -1983,11 +2008,11 @@
   omaha_settings.set_install_default(
       enterprise_management::INSTALL_DEFAULT_DISABLED);
   ApplicationSettings app1;
-  app1.set_app_guid(kAppId1);
+  app1.set_app_guid(kApp1.appid);
   app1.set_install(enterprise_management::INSTALL_FORCED);
   omaha_settings.mutable_application_settings()->Add(std::move(app1));
   ApplicationSettings app2;
-  app2.set_app_guid(kAppId2);
+  app2.set_app_guid(kApp2.appid);
   app2.set_install(enterprise_management::INSTALL_ENABLED);
   omaha_settings.mutable_application_settings()->Add(std::move(app2));
 
@@ -1996,23 +2021,23 @@
                                             kEnrollmentToken, kDMToken);
   ExpectDeviceManagementPolicyFetchRequest(test_server_.get(), kDMToken,
                                            omaha_settings);
-  const base::FilePath crx_path = GetInstallerPath(kAppCRX);
   ExpectAppsUpdateSequence(
       UpdaterScope::kSystem, test_server_.get(),
       /*request_attributes=*/{},
       {
           AppUpdateExpectation(
-              BuildCommandLineArgs(GetTestScope(), kAppId1, kApp1Version),
-              kAppId1, base::Version({0, 0, 0, 0}), kApp1Version,
+              BuildCommandLineArgs(GetTestScope(), kApp1.appid, kApp1.v1),
+              kApp1.appid, base::Version({0, 0, 0, 0}), kApp1.v1,
               /*is_install=*/true,
-              /*should_update=*/true, false, "", "", crx_path),
+              /*should_update=*/true, false, "", "",
+              GetInstallerPath(kApp1.v1_crx)),
       });
   ExpectUpdateCheckRequest(test_server_.get());
 
   ASSERT_NO_FATAL_FAILURE(RunWake(0));
   ASSERT_TRUE(WaitForUpdaterExit());
-  ExpectAppInstalled(kAppId1, kApp1Version);
-  ASSERT_NO_FATAL_FAILURE(ExpectNotRegistered(kAppId2));
+  ExpectAppInstalled(kApp1.appid, kApp1.v1);
+  ASSERT_NO_FATAL_FAILURE(ExpectNotRegistered(kApp2.appid));
 
   ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get()));
   ASSERT_NO_FATAL_FAILURE(Uninstall());
@@ -2022,21 +2047,14 @@
 // the default on POSIX. Therefore, this test is Windows only.
 #if BUILDFLAG(IS_WIN)
 TEST_F(IntegrationTestDeviceManagement, AppUpdateConflictPolicies) {
-  const base::Version kApp1InitialVersion = base::Version("1.0.0.0");
-  const base::Version kApp1UpdatedVersion = base::Version("2.0.0.0");
-  const base::Version kApp2InitialVersion = base::Version("100.0.0.0");
-  const base::Version kApp2UpdatedVersion = base::Version("101.0.0.0");
-  const base::Version kApp3InitialVersion = base::Version("1.0");
-  const base::Version kApp3UpdatedVersion = base::Version("1.1");
-
   ASSERT_NO_FATAL_FAILURE(Install());
   ASSERT_NO_FATAL_FAILURE(ExpectInstalled());
-  ASSERT_NO_FATAL_FAILURE(InstallAppWithVersion(kAppId1, kApp1InitialVersion));
-  ASSERT_NO_FATAL_FAILURE(InstallAppWithVersion(kAppId2, kApp2InitialVersion));
-  ASSERT_NO_FATAL_FAILURE(InstallAppWithVersion(kAppId3, kApp3InitialVersion));
+  ASSERT_NO_FATAL_FAILURE(InstallTestApp(kApp1, /*install_v1=*/true));
+  ASSERT_NO_FATAL_FAILURE(InstallTestApp(kApp2, /*install_v1=*/true));
+  ASSERT_NO_FATAL_FAILURE(InstallTestApp(kApp3, /*install_v1=*/true));
 
   base::Value::Dict policies;
-  policies.Set(kAppId2, base::Value::Dict().Set("Update", kPolicyEnabled));
+  policies.Set(kApp2.appid, base::Value::Dict().Set("Update", kPolicyEnabled));
   ASSERT_NO_FATAL_FAILURE(SetPlatformPolicies(policies));
 
   // Cloud policy sets update default to disabled, app1 to auto-update, and
@@ -2047,83 +2065,71 @@
   OmahaSettingsClientProto omaha_settings;
   omaha_settings.set_update_default(enterprise_management::UPDATES_DISABLED);
   ApplicationSettings app1;
-  app1.set_app_guid(kAppId1);
+  app1.set_app_guid(kApp1.appid);
   app1.set_update(enterprise_management::AUTOMATIC_UPDATES_ONLY);
   omaha_settings.mutable_application_settings()->Add(std::move(app1));
   ApplicationSettings app2;
-  app2.set_app_guid(kAppId2);
+  app2.set_app_guid(kApp2.appid);
   app2.set_update(enterprise_management::MANUAL_UPDATES_ONLY);
   omaha_settings.mutable_application_settings()->Add(std::move(app2));
   ExpectDeviceManagementPolicyFetchRequest(test_server_.get(), kDMToken,
                                            omaha_settings);
 
-  const base::FilePath crx_path = GetInstallerPath(kAppCRX);
   ExpectAppsUpdateSequence(
       UpdaterScope::kSystem, test_server_.get(),
       /*request_attributes=*/{},
       {
-          AppUpdateExpectation(BuildCommandLineArgs(GetTestScope(), kAppId1,
-                                                    kApp1UpdatedVersion),
-                               kAppId1, kApp1InitialVersion,
-                               kApp1UpdatedVersion,
-                               /*is_install=*/false,
-                               /*should_update=*/true, false, "", "", crx_path),
-          AppUpdateExpectation(BuildCommandLineArgs(GetTestScope(), kAppId2,
-                                                    kApp2UpdatedVersion),
-                               kAppId2, kApp2InitialVersion,
-                               kApp2UpdatedVersion,
-                               /*is_install=*/false,
-                               /*should_update=*/true, false, "", "", crx_path),
           AppUpdateExpectation(
-              BuildCommandLineArgs(GetTestScope(), kAppId3,
-                                   kApp3UpdatedVersion),
-              kAppId3, kApp3InitialVersion, kApp3UpdatedVersion,
+              BuildCommandLineArgs(GetTestScope(), kApp1.appid, kApp1.v2),
+              kApp1.appid, kApp1.v1, kApp1.v2,
               /*is_install=*/false,
-              /*should_update=*/false, false, "", "", crx_path),
+              /*should_update=*/true, false, "", "",
+              GetInstallerPath(kApp1.v2_crx)),
+          AppUpdateExpectation(
+              BuildCommandLineArgs(GetTestScope(), kApp2.appid, kApp2.v2),
+              kApp2.appid, kApp2.v1, kApp2.v2,
+              /*is_install=*/false,
+              /*should_update=*/true, false, "", "",
+              GetInstallerPath(kApp2.v2_crx)),
+          AppUpdateExpectation(
+              BuildCommandLineArgs(GetTestScope(), kApp3.appid, kApp3.v2),
+              kApp3.appid, kApp3.v1, kApp3.v2,
+              /*is_install=*/false,
+              /*should_update=*/false, false, "", "",
+              GetInstallerPath(kApp3.v2_crx)),
       });
   ASSERT_NO_FATAL_FAILURE(RunWake(0));
   ASSERT_TRUE(WaitForUpdaterExit());
-  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId1, kApp1UpdatedVersion));
-  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId2, kApp2UpdatedVersion));
-  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId3, kApp3InitialVersion));
+  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kApp1.appid, kApp1.v2));
+  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kApp2.appid, kApp2.v2));
+  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kApp3.appid, kApp3.v1));
   ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get()));
-  ASSERT_NO_FATAL_FAILURE(UninstallApp(kAppId1));
-  ASSERT_NO_FATAL_FAILURE(UninstallApp(kAppId2));
-  ASSERT_NO_FATAL_FAILURE(UninstallApp(kAppId3));
+  ASSERT_NO_FATAL_FAILURE(UninstallApp(kApp1.appid));
+  ASSERT_NO_FATAL_FAILURE(UninstallApp(kApp2.appid));
+  ASSERT_NO_FATAL_FAILURE(UninstallApp(kApp3.appid));
   ASSERT_NO_FATAL_FAILURE(Uninstall());
 }
 #endif  // BUILDFLAG(IS_WIN)
 
-// This test depends on setting platform policy from the test, which does not
-// work on POSIX. Therefore, this test is Windows only.
-#if BUILDFLAG(IS_WIN)
 TEST_F(IntegrationTestDeviceManagement, CloudPolicyOverridesPlatformPolicy) {
   ASSERT_NO_FATAL_FAILURE(SetCloudPolicyOverridesPlatformPolicy());
-
-  const base::Version kApp1InitialVersion = base::Version("1.0.0.0");
-  const base::Version kApp1UpdatedVersion = base::Version("2.0.0.0");
-  const base::Version kApp2InitialVersion = base::Version("100.0.0.0");
-  const base::Version kApp2UpdatedVersion = base::Version("101.0.0.0");
-  const base::Version kApp3InitialVersion = base::Version("1.0");
-  const base::Version kApp3UpdatedVersion = base::Version("1.1");
-
   ASSERT_NO_FATAL_FAILURE(Install());
   ASSERT_NO_FATAL_FAILURE(ExpectInstalled());
-  ASSERT_NO_FATAL_FAILURE(InstallAppWithVersion(kAppId1, kApp1InitialVersion));
-  ASSERT_NO_FATAL_FAILURE(InstallAppWithVersion(kAppId2, kApp2InitialVersion));
-  ASSERT_NO_FATAL_FAILURE(InstallAppWithVersion(kAppId3, kApp3InitialVersion));
+  ASSERT_NO_FATAL_FAILURE(InstallTestApp(kApp1, /*install_v1=*/true));
+  ASSERT_NO_FATAL_FAILURE(InstallTestApp(kApp2, /*install_v1=*/true));
+  ASSERT_NO_FATAL_FAILURE(InstallTestApp(kApp3, /*install_v1=*/true));
 
   base::Value::Dict policies;
-  policies.Set("", base::Value::Dict()
-                       .Set("UpdateDefault", kPolicyDisabled)
-                       .Set("DownloadPreference", "cacheable"));
-  policies.Set(kAppId1, base::Value::Dict()
-                            .Set("Update", kPolicyDisabled)
-                            .Set("TargetChannel", "beta"));
-  policies.Set(kAppId2, base::Value::Dict().Set("Update", kPolicyEnabled));
-  policies.Set(kAppId3, base::Value::Dict()
-                            .Set("Update", kPolicyEnabled)
-                            .Set("TargetChannel", "canary"));
+  policies.Set(kGlobalPolicyKey, base::Value::Dict()
+                                     .Set("UpdateDefault", kPolicyDisabled)
+                                     .Set("DownloadPreference", "cacheable"));
+  policies.Set(kApp1.appid, base::Value::Dict()
+                                .Set("Update", kPolicyDisabled)
+                                .Set("TargetChannel", "beta"));
+  policies.Set(kApp2.appid, base::Value::Dict().Set("Update", kPolicyEnabled));
+  policies.Set(kApp3.appid, base::Value::Dict()
+                                .Set("Update", kPolicyEnabled)
+                                .Set("TargetChannel", "canary"));
   ASSERT_NO_FATAL_FAILURE(SetPlatformPolicies(policies));
 
   // Overrides app1 to auto-update, app2 to manual-update with cloud policy.
@@ -2132,71 +2138,67 @@
                                             kEnrollmentToken, kDMToken);
   OmahaSettingsClientProto omaha_settings;
   ApplicationSettings app1;
-  app1.set_app_guid(kAppId1);
+  app1.set_app_guid(kApp1.appid);
   app1.set_update(enterprise_management::AUTOMATIC_UPDATES_ONLY);
   app1.set_target_channel("beta_canary");
   omaha_settings.mutable_application_settings()->Add(std::move(app1));
   ApplicationSettings app2;
-  app2.set_app_guid(kAppId2);
+  app2.set_app_guid(kApp2.appid);
   app2.set_update(enterprise_management::MANUAL_UPDATES_ONLY);
   omaha_settings.mutable_application_settings()->Add(std::move(app2));
   ExpectDeviceManagementPolicyFetchRequest(test_server_.get(), kDMToken,
                                            omaha_settings);
 
-  const base::FilePath crx_path = GetInstallerPath(kAppCRX);
   ExpectAppsUpdateSequence(
       UpdaterScope::kSystem, test_server_.get(),
       /*request_attributes=*/base::Value::Dict().Set("dlpref", "cacheable"),
       {
           AppUpdateExpectation(
-              BuildCommandLineArgs(GetTestScope(), kAppId1,
-                                   kApp1UpdatedVersion),
-              kAppId1, kApp1InitialVersion, kApp1UpdatedVersion,
+              BuildCommandLineArgs(GetTestScope(), kApp1.appid, kApp1.v2),
+              kApp1.appid, kApp1.v1, kApp1.v2,
               /*is_install=*/false,
-              /*should_update=*/true, false, "", "beta_canary", crx_path),
+              /*should_update=*/true, false, "", "beta_canary",
+              GetInstallerPath(kApp1.v2_crx)),
           AppUpdateExpectation(
-              BuildCommandLineArgs(GetTestScope(), kAppId2,
-                                   kApp2UpdatedVersion),
-              kAppId2, kApp2InitialVersion, kApp2InitialVersion,
+              BuildCommandLineArgs(GetTestScope(), kApp2.appid, kApp2.v2),
+              kApp2.appid, kApp2.v1, kApp2.v1,
               /*is_install=*/false,
-              /*should_update=*/false, false, "", "", crx_path),
+              /*should_update=*/false, false, "", "",
+              GetInstallerPath(kApp2.v2_crx)),
           AppUpdateExpectation(
-              BuildCommandLineArgs(GetTestScope(), kAppId3,
-                                   kApp3UpdatedVersion),
-              kAppId3, kApp3InitialVersion, kApp3UpdatedVersion,
+              BuildCommandLineArgs(GetTestScope(), kApp3.appid, kApp3.v2),
+              kApp3.appid, kApp3.v1, kApp3.v2,
               /*is_install=*/false,
-              /*should_update=*/true, false, "", "canary", crx_path),
+              /*should_update=*/true, false, "", "canary",
+              GetInstallerPath(kApp3.v2_crx)),
       });
   ASSERT_NO_FATAL_FAILURE(RunWake(0));
   ASSERT_TRUE(WaitForUpdaterExit());
-  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId1, kApp1UpdatedVersion));
-  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId2, kApp2InitialVersion));
-  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId3, kApp3UpdatedVersion));
+  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kApp1.appid, kApp1.v2));
+  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kApp2.appid, kApp2.v1));
+  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kApp3.appid, kApp3.v2));
   ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get()));
-  ASSERT_NO_FATAL_FAILURE(UninstallApp(kAppId1));
-  ASSERT_NO_FATAL_FAILURE(UninstallApp(kAppId2));
-  ASSERT_NO_FATAL_FAILURE(UninstallApp(kAppId3));
+  ASSERT_NO_FATAL_FAILURE(UninstallApp(kApp1.appid));
+  ASSERT_NO_FATAL_FAILURE(UninstallApp(kApp2.appid));
+  ASSERT_NO_FATAL_FAILURE(UninstallApp(kApp3.appid));
   ASSERT_NO_FATAL_FAILURE(Uninstall());
 }
-#endif  // BUILDFLAG(IS_WIN)
 
 TEST_F(IntegrationTestDeviceManagement, RollbackToTargetVersion) {
   constexpr char kTargetVersionPrefix[] = "1.0.";
-  const base::Version kAppInitialVersion = base::Version("2.0.0.0");
-  const base::Version kAppRollbackVersion = base::Version("1.0.0.0");
 
   ASSERT_NO_FATAL_FAILURE(Install());
-  ASSERT_NO_FATAL_FAILURE(InstallAppWithVersion(kAppId1, kAppInitialVersion));
+  ASSERT_NO_FATAL_FAILURE(InstallTestApp(kApp1, /*install_v1=*/false));
 
   ASSERT_NO_FATAL_FAILURE(ExpectInstalled());
-  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId1, kAppInitialVersion));
+  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kApp1.appid, kApp1.v2));
 
   DMPushEnrollmentToken(kEnrollmentToken);
   ExpectDeviceManagementRegistrationRequest(test_server_.get(),
                                             kEnrollmentToken, kDMToken);
   OmahaSettingsClientProto omaha_settings;
   ApplicationSettings app;
-  app.set_app_guid(kAppId1);
+  app.set_app_guid(kApp1.appid);
   app.set_target_version_prefix(kTargetVersionPrefix);
   app.set_rollback_to_target_version(
       enterprise_management::ROLLBACK_TO_TARGET_VERSION_ENABLED);
@@ -2208,17 +2210,17 @@
       UpdaterScope::kSystem, test_server_.get(),
       /*request_attributes=*/{},
       {AppUpdateExpectation(
-          BuildCommandLineArgs(GetTestScope(), kAppId1, kAppRollbackVersion),
-          kAppId1, kAppInitialVersion, kAppRollbackVersion,
+          BuildCommandLineArgs(GetTestScope(), kApp1.appid, kApp1.v1),
+          kApp1.appid, kApp1.v2, kApp1.v1,
           /*is_install=*/false,
           /*should_update=*/true, /*allow_rollback=*/true, kTargetVersionPrefix,
-          "", GetInstallerPath(kAppCRX))});
+          "", GetInstallerPath(kApp1.v1_crx))});
   ASSERT_NO_FATAL_FAILURE(RunWake(0));
   ASSERT_TRUE(WaitForUpdaterExit());
-  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kAppId1, kAppRollbackVersion));
+  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kApp1.appid, kApp1.v1));
 
   ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get()));
-  ASSERT_NO_FATAL_FAILURE(UninstallApp(kAppId1));
+  ASSERT_NO_FATAL_FAILURE(UninstallApp(kApp1.appid));
   ASSERT_NO_FATAL_FAILURE(Uninstall());
 }
 #endif  // !defined(COMPONENT_BUILD)
diff --git a/chrome/updater/test/integration_tests_mac.mm b/chrome/updater/test/integration_tests_mac.mm
index 95bfc48..248cd51 100644
--- a/chrome/updater/test/integration_tests_mac.mm
+++ b/chrome/updater/test/integration_tests_mac.mm
@@ -383,13 +383,29 @@
       }
     }
     all_policies[base::SysUTF8ToNSString(app_id)] = app_policies;
-  }
 
-  CFPreferencesSetValue(CFSTR("updatePolicies"),
-                        base::apple::NSToCFPtrCast(all_policies), domain,
-                        kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
+    NSURL* const managed_preferences_url = base::apple::FilePathToNSURL(
+        GetLibraryFolderPath(UpdaterScope::kSystem)
+            ->AppendASCII("Managed Preferences")
+            .AppendASCII("com.google.Keystone.plist"));
+    ASSERT_TRUE([[NSDictionary dictionaryWithObject:all_policies
+                                             forKey:@"updatePolicies"]
+        writeToURL:managed_preferences_url
+        atomically:YES])
+        << "Failed to write " << managed_preferences_url;
+  }
   ASSERT_TRUE(CFPreferencesSynchronize(domain, kCFPreferencesAnyUser,
                                        kCFPreferencesCurrentHost));
+
+  // Force flushing preferences cache by killing the defaults server.
+  base::Process process = base::LaunchProcess({"killall", "cfprefsd"}, {});
+  if (!process.IsValid()) {
+    VLOG(2) << "Failed to launch the process to refresh preferences.";
+  }
+  int exit_code = -1;
+  EXPECT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_timeout(),
+                                             &exit_code));
+  EXPECT_EQ(0, exit_code);
 }
 
 }  // namespace updater::test
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc
index 6e91d0f..6f264bcc 100644
--- a/chrome/updater/test/integration_tests_win.cc
+++ b/chrome/updater/test/integration_tests_win.cc
@@ -1901,28 +1901,27 @@
                        bool is_legacy_install,
                        bool is_silent_install) {
   static constexpr char kManifestFormat[] =
-      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-      "<response protocol=\"3.0\">\n"
-      "  <systemrequirements platform=\"win\"/>\n"
-      "  <app appid=\"%ls\" status=\"ok\">\n"
-      "    <updatecheck status=\"ok\">\n"
-      "      <manifest version=\"%s\">\n"
-      "        <packages>\n"
-      "          <package hash_sha256=\"sha256hash_foobar\"\n"
-      "            name=\"%s\" required=\"true\" size=\"%" PRId64
-      "\"/>\n"
-      "        </packages>\n"
-      "        <actions>\n"
-      "          <action event=\"install\"\n"
-      "            run=\"%s\"/>\n"
-      "        </actions>\n"
-      "      </manifest>\n"
-      "    </updatecheck>\n"
-      "    <data index=\"verboselogging\" name=\"install\" status=\"ok\">\n"
-      "      {\"distribution\": { \"verbose_logging\": true}}\n"
-      "    </data>\n"
-      "  </app>\n"
-      "</response>\n";
+      R"(<?xml version="1.0" encoding="UTF-8"?>
+<response protocol="3.0">
+  <systemrequirements platform="win"/>
+  <app appid="%ls" status="ok">
+    <updatecheck status="ok">
+      <manifest version="%s">
+        <packages>
+          <package hash_sha256="sha256hash_foobar"
+            name="%s" required="true" size="%)" PRId64 R"("/>
+        </packages>
+        <actions>
+          <action event="install"
+            run="%s"/>
+        </actions>
+      </manifest>
+    </updatecheck>
+    <data index="verboselogging" name="install" status="ok">
+      {"distribution": { "verbose_logging": true}}
+    </data>
+  </app>
+</response>)";
   RunOfflineInstallWithManifest(scope, is_legacy_install, is_silent_install,
                                 kManifestFormat,
                                 IDS_BUNDLE_INSTALLED_SUCCESSFULLY_BASE, true);
@@ -1932,28 +1931,27 @@
                                      bool is_legacy_install,
                                      bool is_silent_install) {
   static constexpr char kManifestFormat[] =
-      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-      "<response protocol=\"3.0\">\n"
-      "  <systemrequirements platform=\"minix\"/>\n"
-      "  <app appid=\"%ls\" status=\"ok\">\n"
-      "    <updatecheck status=\"ok\">\n"
-      "      <manifest version=\"%s\">\n"
-      "        <packages>\n"
-      "          <package hash_sha256=\"sha256hash_foobar\"\n"
-      "            name=\"%s\" required=\"true\" size=\"%" PRId64
-      "\"/>\n"
-      "        </packages>\n"
-      "        <actions>\n"
-      "          <action event=\"install\"\n"
-      "            run=\"%s\"/>\n"
-      "        </actions>\n"
-      "      </manifest>\n"
-      "    </updatecheck>\n"
-      "    <data index=\"verboselogging\" name=\"install\" status=\"ok\">\n"
-      "      {\"distribution\": { \"verbose_logging\": true}}\n"
-      "    </data>\n"
-      "  </app>\n"
-      "</response>\n";
+      R"(<?xml version="1.0" encoding="UTF-8"?>
+<response protocol="3.0">
+  <systemrequirements platform="minix"/>
+  <app appid="%ls" status="ok">
+    <updatecheck status="ok">
+      <manifest version="%s">
+        <packages>
+          <package hash_sha256="sha256hash_foobar"
+            name="%s" required="true" size="%)" PRId64 R"("/>
+        </packages>
+        <actions>
+          <action event="install"
+            run="%s"/>
+        </actions>
+      </manifest>
+    </updatecheck>
+    <data index="verboselogging" name="install" status="ok">
+      {"distribution": { "verbose_logging": true}}
+    </data>
+  </app>
+</response>)";
   RunOfflineInstallWithManifest(scope, is_legacy_install, is_silent_install,
                                 kManifestFormat,
                                 IDS_INSTALL_OS_NOT_SUPPORTED_BASE, false);
diff --git a/chrome/updater/update_service_impl.cc b/chrome/updater/update_service_impl.cc
index 0dca5d7..4a82c77 100644
--- a/chrome/updater/update_service_impl.cc
+++ b/chrome/updater/update_service_impl.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/updater/update_service_impl.h"
 
+#include <algorithm>
 #include <map>
 #include <string>
 #include <utility>
@@ -89,6 +90,92 @@
       return UpdateService::Result::kInvalidArgument;
   }
 }
+
+void GetComponents(
+    scoped_refptr<Configurator> config,
+    scoped_refptr<PersistedData> persisted_data,
+    const AppClientInstallData& app_client_install_data,
+    const AppInstallDataIndex& app_install_data_index,
+    UpdateService::Priority priority,
+    bool update_blocked,
+    UpdateService::PolicySameVersionUpdate policy_same_version_update,
+    const std::vector<std::string>& ids,
+    base::OnceCallback<
+        void(const std::vector<absl::optional<update_client::CrxComponent>>&)>
+        callback) {
+  VLOG(1) << __func__
+          << ". Same version update: " << policy_same_version_update;
+  const bool is_foreground = priority == UpdateService::Priority::kForeground;
+  auto barrier_callback =
+      base::BarrierCallback<absl::optional<update_client::CrxComponent>>(
+          ids.size(),
+          base::BindOnce(
+              [](const std::vector<std::string>& ids,
+                 const std::vector<absl::optional<update_client::CrxComponent>>&
+                     unordered) {
+                // Re-order the vector to match the order of `ids`.
+                std::vector<absl::optional<update_client::CrxComponent>>
+                    ordered;
+                for (const auto& id : ids) {
+                  auto it = std::find_if(
+                      unordered.begin(), unordered.end(),
+                      [&id](absl::optional<update_client::CrxComponent> v) {
+                        return v && v->app_id == id;
+                      });
+                  ordered.push_back(it != unordered.end() ? *it
+                                                          : absl::nullopt);
+                }
+                return ordered;
+              },
+              ids)
+              .Then(std::move(callback)));
+  for (const auto& id : ids) {
+    base::MakeRefCounted<Installer>(
+        id,
+        [&app_client_install_data, &id]() {
+          auto it = app_client_install_data.find(id);
+          return it != app_client_install_data.end() ? it->second : "";
+        }(),
+        [&app_install_data_index, &id]() {
+          auto it = app_install_data_index.find(id);
+          return it != app_install_data_index.end() ? it->second : "";
+        }(),
+        [&config, &id]() {
+          return config->GetPolicyService()->GetTargetChannel(id).policy_or(
+              std::string());
+        }(),
+        [&config, &id]() {
+          return config->GetPolicyService()
+              ->GetTargetVersionPrefix(id)
+              .policy_or(std::string());
+        }(),
+        [&config, &id]() {
+          return config->GetPolicyService()
+              ->IsRollbackToTargetVersionAllowed(id)
+              .policy_or(false);
+        }(),
+        [&config, &id, &is_foreground, update_blocked]() {
+          if (update_blocked) {
+            return true;
+          }
+          PolicyStatus<int> app_updates =
+              config->GetPolicyService()->GetPolicyForAppUpdates(id);
+          return app_updates &&
+                 (app_updates.policy() == kPolicyDisabled ||
+                  (!is_foreground &&
+                   app_updates.policy() == kPolicyManualUpdatesOnly) ||
+                  (is_foreground &&
+                   app_updates.policy() == kPolicyAutomaticUpdatesOnly));
+        }(),
+        policy_same_version_update, persisted_data,
+        config->GetCrxVerifierFormat())
+        ->MakeCrxComponent(
+            base::BindOnce([](update_client::CrxComponent component) {
+              return component;
+            }).Then(barrier_callback));
+  }
+}
+
 }  // namespace internal
 
 namespace {
@@ -217,71 +304,6 @@
       config, persisted_data, new_install, callback);
 }
 
-void GetComponents(
-    scoped_refptr<Configurator> config,
-    scoped_refptr<PersistedData> persisted_data,
-    const AppClientInstallData& app_client_install_data,
-    const AppInstallDataIndex& app_install_data_index,
-    UpdateService::Priority priority,
-    bool update_blocked,
-    UpdateService::PolicySameVersionUpdate policy_same_version_update,
-    const std::vector<std::string>& ids,
-    base::OnceCallback<
-        void(const std::vector<absl::optional<update_client::CrxComponent>>&)>
-        callback) {
-  VLOG(1) << __func__
-          << ". Same version update: " << policy_same_version_update;
-  const bool is_foreground = priority == UpdateService::Priority::kForeground;
-  auto barrier_callback =
-      base::BarrierCallback<absl::optional<update_client::CrxComponent>>(
-          ids.size(), std::move(callback));
-  for (const auto& id : ids) {
-    base::MakeRefCounted<Installer>(
-        id,
-        [&app_client_install_data, &id]() {
-          auto it = app_client_install_data.find(id);
-          return it != app_client_install_data.end() ? it->second : "";
-        }(),
-        [&app_install_data_index, &id]() {
-          auto it = app_install_data_index.find(id);
-          return it != app_install_data_index.end() ? it->second : "";
-        }(),
-        [&config, &id]() {
-          return config->GetPolicyService()->GetTargetChannel(id).policy_or(
-              std::string());
-        }(),
-        [&config, &id]() {
-          return config->GetPolicyService()
-              ->GetTargetVersionPrefix(id)
-              .policy_or(std::string());
-        }(),
-        [&config, &id]() {
-          return config->GetPolicyService()
-              ->IsRollbackToTargetVersionAllowed(id)
-              .policy_or(false);
-        }(),
-        [&config, &id, &is_foreground, update_blocked]() {
-          if (update_blocked) {
-            return true;
-          }
-          PolicyStatus<int> app_updates =
-              config->GetPolicyService()->GetPolicyForAppUpdates(id);
-          return app_updates &&
-                 (app_updates.policy() == kPolicyDisabled ||
-                  (!is_foreground &&
-                   app_updates.policy() == kPolicyManualUpdatesOnly) ||
-                  (is_foreground &&
-                   app_updates.policy() == kPolicyAutomaticUpdatesOnly));
-        }(),
-        policy_same_version_update, persisted_data,
-        config->GetCrxVerifierFormat())
-        ->MakeCrxComponent(
-            base::BindOnce([](update_client::CrxComponent component) {
-              return component;
-            }).Then(barrier_callback));
-  }
-}
-
 }  // namespace
 
 UpdateServiceImpl::UpdateServiceImpl(scoped_refptr<Configurator> config)
@@ -595,7 +617,7 @@
   pos->second = update_client_->Install(
       registration.app_id,
       base::BindOnce(
-          &GetComponents, config_, persisted_data_,
+          &internal::GetComponents, config_, persisted_data_,
           AppClientInstallData(
               {std::make_pair(registration.app_id, client_install_data)}),
           AppInstallDataIndex(
@@ -826,7 +848,7 @@
       FROM_HERE,
       base::BindOnce(
           &update_client::UpdateClient::CheckForUpdate, update_client_, app_id,
-          base::BindOnce(&GetComponents, config_, persisted_data_,
+          base::BindOnce(&internal::GetComponents, config_, persisted_data_,
                          AppClientInstallData(), AppInstallDataIndex(),
                          priority, update_blocked, policy_same_version_update),
           MakeUpdateClientCrxStateChangeCallback(config_, persisted_data_,
@@ -850,7 +872,7 @@
       FROM_HERE,
       base::BindOnce(
           &update_client::UpdateClient::Update, update_client_, app_ids,
-          base::BindOnce(&GetComponents, config_, persisted_data_,
+          base::BindOnce(&internal::GetComponents, config_, persisted_data_,
                          app_client_install_data, app_install_data_index,
                          priority, update_blocked, policy_same_version_update),
           MakeUpdateClientCrxStateChangeCallback(config_, persisted_data_,
@@ -886,7 +908,7 @@
         base::BindOnce(
             base::IgnoreResult(&update_client::UpdateClient::Install),
             update_client_, id,
-            base::BindOnce(&GetComponents, config_, persisted_data_,
+            base::BindOnce(&internal::GetComponents, config_, persisted_data_,
                            app_client_install_data, app_install_data_index,
                            Priority::kBackground, update_blocked,
                            policy_same_version_update),
diff --git a/chrome/updater/update_service_impl.h b/chrome/updater/update_service_impl.h
index 41dfd1f2..9cd279bb 100644
--- a/chrome/updater/update_service_impl.h
+++ b/chrome/updater/update_service_impl.h
@@ -142,6 +142,19 @@
 
 namespace internal {
 UpdateService::Result ToResult(update_client::Error error);
+
+void GetComponents(
+    scoped_refptr<Configurator> config,
+    scoped_refptr<PersistedData> persisted_data,
+    const AppClientInstallData& app_client_install_data,
+    const AppInstallDataIndex& app_install_data_index,
+    UpdateService::Priority priority,
+    bool update_blocked,
+    UpdateService::PolicySameVersionUpdate policy_same_version_update,
+    const std::vector<std::string>& ids,
+    base::OnceCallback<
+        void(const std::vector<absl::optional<update_client::CrxComponent>>&)>
+        callback);
 }  // namespace internal
 
 }  // namespace updater
diff --git a/chrome/updater/update_service_impl_unittest.cc b/chrome/updater/update_service_impl_unittest.cc
index 795b70c..a8ff643 100644
--- a/chrome/updater/update_service_impl_unittest.cc
+++ b/chrome/updater/update_service_impl_unittest.cc
@@ -6,7 +6,19 @@
 
 #include <string>
 
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/test/bind.h"
+#include "base/test/task_environment.h"
+#include "chrome/updater/configurator.h"
+#include "chrome/updater/external_constants.h"
+#include "chrome/updater/persisted_data.h"
+#include "chrome/updater/prefs.h"
+#include "chrome/updater/test_scope.h"
 #include "chrome/updater/update_service.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/testing_pref_service.h"
 #include "components/update_client/update_client_errors.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -33,4 +45,50 @@
             UpdateService::Result::kInvalidArgument);
 }
 
+TEST(UpdateServiceImplTest, TestGetComponentsInOrder) {
+  base::test::TaskEnvironment environment_{
+      base::test::TaskEnvironment::MainThreadType::UI};
+
+  base::ScopedTempDir temp_dir;
+  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
+  base::FilePath plist_path = temp_dir.GetPath().Append(
+      FILE_PATH_LITERAL("InstallerTest.LoadFromPath.plist"));
+  base::WriteFile(plist_path, "<dict></dict>");
+
+  auto pref = std::make_unique<TestingPrefServiceSimple>();
+  update_client::RegisterPrefs(pref->registry());
+  RegisterPersistedDataPrefs(pref->registry());
+  auto metadata =
+      base::MakeRefCounted<PersistedData>(GetTestScope(), pref.get());
+  metadata->SetProductVersion("id1", base::Version("1.2.3.4"));
+  metadata->SetProductVersionKey("id1", "pv_key");
+  metadata->SetAP("id1", "ap");
+  metadata->SetAPPath("id1", plist_path);
+  metadata->SetProductVersionPath("id1", plist_path);
+  metadata->SetBrandPath("id1", plist_path);
+  metadata->SetAPKey("id1", "brand_key");
+  metadata->SetBrandCode("id1", "BRND");
+
+  std::vector<absl::optional<update_client::CrxComponent>> crxs;
+  base::RunLoop loop;
+  internal::GetComponents(
+      base::MakeRefCounted<Configurator>(nullptr, CreateExternalConstants()),
+      metadata, {}, {}, UpdateService::Priority::kForeground, false,
+      UpdateService::PolicySameVersionUpdate::kNotAllowed,
+      {"id1", "id2", "id3", "id4"},
+      base::BindLambdaForTesting(
+          [&](const std::vector<absl::optional<update_client::CrxComponent>>&
+                  out) {
+            crxs = out;
+            loop.Quit();
+          }));
+  loop.Run();
+
+  ASSERT_EQ(crxs.size(), 4u);
+  EXPECT_EQ(crxs[0]->app_id, "id1");
+  EXPECT_EQ(crxs[1]->app_id, "id2");
+  EXPECT_EQ(crxs[2]->app_id, "id3");
+  EXPECT_EQ(crxs[3]->app_id, "id4");
+}
+
 }  // namespace updater::internal
diff --git a/chrome/updater/updater.cc b/chrome/updater/updater.cc
index 7ac1353f..b71d42ac 100644
--- a/chrome/updater/updater.cc
+++ b/chrome/updater/updater.cc
@@ -17,6 +17,7 @@
 #include "base/process/memory.h"
 #include "base/process/process_handle.h"
 #include "base/ranges/algorithm.h"
+#include "base/strings/stringprintf.h"
 #include "base/system/sys_info.h"
 #include "base/task/single_thread_task_executor.h"
 #include "base/task/thread_pool/thread_pool_instance.h"
@@ -49,6 +50,7 @@
 #if BUILDFLAG(IS_WIN)
 #include "base/win/process_startup_helper.h"
 #include "base/win/scoped_com_initializer.h"
+#include "base/win/windows_version.h"
 #include "chrome/updater/app/server/win/service_main.h"
 #include "chrome/updater/util/win_util.h"
 #endif
@@ -253,6 +255,16 @@
 #endif
 }
 
+std::string OperatingSystemVersion() {
+#if BUILDFLAG(IS_WIN)
+  const base::win::OSInfo::VersionNumber v =
+      base::win::OSInfo::GetInstance()->version_number();
+  return base::StringPrintf("%u.%u.%u.%u", v.major, v.minor, v.build, v.patch);
+#else
+  return base::SysInfo().OperatingSystemVersion();
+#endif
+}
+
 base::CommandLine::StringType GetCommandLineString() {
 #if BUILDFLAG(IS_WIN)
   // Gets the raw command line on Windows, because
@@ -283,10 +295,11 @@
 
   const UpdaterScope updater_scope = GetUpdaterScope();
   InitLogging(updater_scope);
-  VLOG(1) << "Version " << kUpdaterVersion << ", " << BuildFlavor() << ", "
+  VLOG(1) << "Version: " << kUpdaterVersion << ", " << BuildFlavor() << ", "
           << BuildArch() << ", command line: " << GetCommandLineString();
-  VLOG(1) << "System uptime (seconds): " << base::SysInfo::Uptime().InSeconds()
-          << ", parent pid: "
+  VLOG(1) << "OS version: " << OperatingSystemVersion()
+          << ", System uptime (seconds): "
+          << base::SysInfo::Uptime().InSeconds() << ", parent pid: "
           << base::GetParentProcessId(base::GetCurrentProcessHandle());
   const int retval = HandleUpdaterCommands(updater_scope, command_line);
   VLOG(1) << __func__ << " (--" << GetUpdaterCommand(command_line) << ")"
diff --git a/chrome/updater/util/util.cc b/chrome/updater/util/util.cc
index c0e590c..c886381 100644
--- a/chrome/updater/util/util.cc
+++ b/chrome/updater/util/util.cc
@@ -284,15 +284,6 @@
       {0xa1, 0x88, 0x21, 0x36, 0xab, 0x85, 0xf5, 0xf1}};
   logging::LogEventProvider::Initialize(kUpdaterETWProviderName);
 #endif
-
-  VLOG(1) << "Log initialized for " <<
-      [] {
-        base::FilePath file_exe;
-        return base::PathService::Get(base::FILE_EXE, &file_exe)
-                   ? file_exe
-                   : base::FilePath();
-      }() << " -> "
-          << settings.log_file_path;
 }
 
 std::string GetUpdaterUserAgent() {
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 6292e87..3bffb586 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-15649.0.0
\ No newline at end of file
+15650.0.0
\ No newline at end of file
diff --git a/chromeos/ash/components/nearby/presence/nearby_presence_service.cc b/chromeos/ash/components/nearby/presence/nearby_presence_service.cc
index 1308c2d..1b8298fa 100644
--- a/chromeos/ash/components/nearby/presence/nearby_presence_service.cc
+++ b/chromeos/ash/components/nearby/presence/nearby_presence_service.cc
@@ -25,16 +25,14 @@
 NearbyPresenceService::ScanDelegate::~ScanDelegate() = default;
 
 NearbyPresenceService::PresenceDevice::PresenceDevice(
-    ::nearby::internal::DeviceType device_type,
+    ::nearby::internal::Metadata metadata,
     absl::optional<std::string> stable_device_id,
     std::string endpoint_id,
-    std::string device_name,
     std::vector<Action> actions,
     int rssi)
-    : device_type_(device_type),
+    : metadata_(metadata),
       stable_device_id_(stable_device_id),
       endpoint_id_(endpoint_id),
-      device_name_(device_name),
       actions_(actions),
       rssi_(rssi) {}
 
diff --git a/chromeos/ash/components/nearby/presence/nearby_presence_service.h b/chromeos/ash/components/nearby/presence/nearby_presence_service.h
index 952729e..9c6d1321 100644
--- a/chromeos/ash/components/nearby/presence/nearby_presence_service.h
+++ b/chromeos/ash/components/nearby/presence/nearby_presence_service.h
@@ -75,31 +75,32 @@
   // inherit from the upcoming Nearby Connections Device class.
   class PresenceDevice {
    public:
-    PresenceDevice(::nearby::internal::DeviceType device_type,
+    PresenceDevice(::nearby::internal::Metadata metadata,
                    absl::optional<std::string> stable_device_id,
                    std::string endpoint_id,
-                   std::string device_name,
                    std::vector<Action> actions,
                    int rssi);
+
     PresenceDevice(const PresenceDevice&) = delete;
     PresenceDevice& operator=(const PresenceDevice&) = delete;
     ~PresenceDevice();
 
-    ::nearby::internal::DeviceType GetType() const { return device_type_; }
+    ::nearby::internal::DeviceType GetType() const {
+      return metadata_.device_type();
+    }
 
     const absl::optional<std::string> GetStableId() const {
       return stable_device_id_;
     }
     const std::string& GetEndpointId() const { return endpoint_id_; }
-    const std::string& GetName() const { return device_name_; }
+    const std::string& GetName() const { return metadata_.device_name(); }
     const std::vector<Action> GetActions() const { return actions_; }
     int GetRssi() const { return rssi_; }
 
    private:
-    ::nearby::internal::DeviceType device_type_;
+    ::nearby::internal::Metadata metadata_;
     absl::optional<std::string> stable_device_id_;
     std::string endpoint_id_;
-    std::string device_name_;
     std::vector<Action> actions_;
     int rssi_;
   };
diff --git a/chromeos/ash/components/nearby/presence/nearby_presence_service_impl.cc b/chromeos/ash/components/nearby/presence/nearby_presence_service_impl.cc
index 4e7aaf31..da77d85 100644
--- a/chromeos/ash/components/nearby/presence/nearby_presence_service_impl.cc
+++ b/chromeos/ash/components/nearby/presence/nearby_presence_service_impl.cc
@@ -42,6 +42,22 @@
   }
 }
 
+::nearby::internal::Metadata ConvertMetadataFromMojom(
+    ash::nearby::presence::mojom::Metadata* metadata) {
+  ::nearby::internal::Metadata proto;
+
+  proto.set_device_type(ConvertMojomDeviceType(metadata->device_type));
+  proto.set_account_name(metadata->account_name);
+  proto.set_user_name(metadata->user_name);
+  proto.set_device_name(metadata->device_name);
+  proto.set_user_name(metadata->user_name);
+  proto.set_device_profile_url(metadata->device_profile_url);
+  proto.set_bluetooth_mac_address(
+      std::string(metadata->bluetooth_mac_address.begin(),
+                  metadata->bluetooth_mac_address.end()));
+  return proto;
+}
+
 ash::nearby::presence::NearbyPresenceService::Action ConvertActionToActionType(
     ash::nearby::presence::mojom::ActionType action_type) {
   switch (action_type) {
@@ -80,9 +96,8 @@
 
   // TODO(b/276642472): Populate actions and rssi fields.
   return ash::nearby::presence::NearbyPresenceService::PresenceDevice(
-      ConvertMojomDeviceType(device->device_type), device->stable_device_id,
-      device->endpoint_id, device->device_name, actions,
-      /*rssi_=*/-65);
+      ConvertMetadataFromMojom(device->metadata.get()),
+      device->stable_device_id, device->endpoint_id, actions, /*rssi_=*/-65);
 }
 
 }  // namespace
diff --git a/chromeos/ash/components/nearby/presence/nearby_presence_service_impl_unittest.cc b/chromeos/ash/components/nearby/presence/nearby_presence_service_impl_unittest.cc
index 9215fa17..31ea942 100644
--- a/chromeos/ash/components/nearby/presence/nearby_presence_service_impl_unittest.cc
+++ b/chromeos/ash/components/nearby/presence/nearby_presence_service_impl_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "chromeos/ash/components/nearby/presence/nearby_presence_service_impl.h"
 
+#include <memory>
+
 #include "base/run_loop.h"
 #include "base/test/mock_callback.h"
 #include "chromeos/ash/components/nearby/presence/credentials/fake_nearby_presence_credential_manager.h"
@@ -21,13 +23,15 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-#include <memory>
-
 namespace ash::nearby::presence {
 
+const char kAccountName[] = "Pepper@gmail.com";
 const char kDeviceName[] = "Pepper's Request";
+const char kDeviceProfileUrl[] = "some_url";
 const char kEndpointId[] = "00000001";
 const char kStableDeviceId[] = "00000002";
+const char kUserName[] = "Pepper";
+const std::vector<uint8_t> kMacAddress = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11};
 const mojom::ActionType kAction1 = mojom::ActionType::kInstantTetheringAction;
 const mojom::ActionType kAction2 = mojom::ActionType::kActiveUnlockAction;
 const mojom::ActionType kAction3 = mojom::ActionType::kPhoneHubAction;
@@ -138,10 +142,13 @@
       actions.push_back(kAction1);
       actions.push_back(kAction2);
       actions.push_back(kAction3);
+
       fake_nearby_presence_.ReturnScanObserver()->OnDeviceFound(
-          mojom::PresenceDevice::New(kEndpointId, kDeviceName,
-                                     mojom::PresenceDeviceType::kPhone, actions,
-                                     kStableDeviceId));
+          mojom::PresenceDevice::New(
+              kEndpointId, actions, kStableDeviceId,
+              mojom::Metadata::New(mojom::PresenceDeviceType::kPhone,
+                                   kAccountName, kDeviceName, kUserName,
+                                   kDeviceProfileUrl, kMacAddress)));
       run_loop.Run();
     }
 
@@ -218,13 +225,15 @@
     scan_delegate.SetNextScanDelegateCallback(run_loop.QuitClosure());
 
     std::vector<mojom::ActionType> actions;
-    ;
     actions.push_back(kAction1);
     actions.push_back(kAction2);
+
     fake_nearby_presence_.ReturnScanObserver()->OnDeviceChanged(
-        mojom::PresenceDevice::New(kEndpointId, kDeviceName,
-                                   mojom::PresenceDeviceType::kPhone, actions,
-                                   kStableDeviceId));
+        mojom::PresenceDevice::New(
+            kEndpointId, actions, kStableDeviceId,
+            mojom::Metadata::New(mojom::PresenceDeviceType::kPhone,
+                                 kAccountName, kDeviceName, kUserName,
+                                 kDeviceProfileUrl, kMacAddress)));
     run_loop.Run();
   }
 
@@ -255,11 +264,12 @@
     scan_delegate.SetNextScanDelegateCallback(run_loop.QuitClosure());
 
     std::vector<mojom::ActionType> actions;
-    ;
     fake_nearby_presence_.ReturnScanObserver()->OnDeviceLost(
-        mojom::PresenceDevice::New(kEndpointId, kDeviceName,
-                                   mojom::PresenceDeviceType::kPhone, actions,
-                                   kStableDeviceId));
+        mojom::PresenceDevice::New(
+            kEndpointId, actions, kStableDeviceId,
+            mojom::Metadata::New(mojom::PresenceDeviceType::kPhone,
+                                 kAccountName, kDeviceName, kUserName,
+                                 kDeviceProfileUrl, kMacAddress)));
     run_loop.Run();
   }
 
@@ -293,9 +303,11 @@
     std::vector<mojom::ActionType> actions;
     actions.push_back(kAction1);
     fake_nearby_presence_.ReturnScanObserver()->OnDeviceFound(
-        mojom::PresenceDevice::New(kEndpointId, kDeviceName,
-                                   mojom::PresenceDeviceType::kPhone, actions,
-                                   kStableDeviceId));
+        mojom::PresenceDevice::New(
+            kEndpointId, actions, kStableDeviceId,
+            mojom::Metadata::New(mojom::PresenceDeviceType::kPhone,
+                                 kAccountName, kDeviceName, kUserName,
+                                 kDeviceProfileUrl, kMacAddress)));
 
     // Allow the ScanObserver function to finish before checking EXPECTs.
     run_loop.Run();
diff --git a/chromeos/ash/services/nearby/public/mojom/nearby_presence.mojom b/chromeos/ash/services/nearby/public/mojom/nearby_presence.mojom
index 3a35719..71ec41e4 100644
--- a/chromeos/ash/services/nearby/public/mojom/nearby_presence.mojom
+++ b/chromeos/ash/services/nearby/public/mojom/nearby_presence.mojom
@@ -69,7 +69,6 @@
   kLastAction,
 };
 
-
 // A mojo conversion of the PublicCredentialType which is defined in
 // //third_party/nearby/src/internal/platform/implementation/credential_callbacks.h.
 // This definition should be kept consistent with the afformentioned file.
@@ -78,17 +77,7 @@
   kRemotePublicCredential = 2,
 };
 
-// Presence Device information to specify the device information when a device
-// is found/lost/changed during a scan.
-struct PresenceDevice {
-  string endpoint_id;
-  string device_name;
-  PresenceDeviceType device_type;
-  array<ActionType> actions;
-  string? stable_device_id;
-};
-
-// The metadata of a device. This struct represents
+// The metadata of a device. This struct should always match
 // //third_party/nearby/src/internal/proto/metadata.proto.
 struct Metadata {
   // The type of the device.
@@ -105,6 +94,16 @@
   array<uint8> bluetooth_mac_address;
 };
 
+// Presence Device information to specify the device information when a device
+// is found/lost/changed during a scan. This loosely represents
+// //third_party/nearby/src/presence/presence_device.h.
+struct PresenceDevice {
+  string endpoint_id;
+  array<ActionType> actions;
+  string? stable_device_id;
+  Metadata metadata;
+};
+
 // The Nearby Presence library is responsible for generating and storing Shared
 // Credentials for the local device and remote devices. These credentials
 // are generated using information provided by ChromeOS. ChromeOS is responsible
diff --git a/chromeos/ash/services/nearby/public/mojom/nearby_presence_credential_storage.mojom b/chromeos/ash/services/nearby/public/mojom/nearby_presence_credential_storage.mojom
index b47b243..056e707 100644
--- a/chromeos/ash/services/nearby/public/mojom/nearby_presence_credential_storage.mojom
+++ b/chromeos/ash/services/nearby/public/mojom/nearby_presence_credential_storage.mojom
@@ -28,4 +28,10 @@
   GetPublicCredentials(PublicCredentialType public_credential_type)
       => (mojo_base.mojom.AbslStatusCode status,
           array<SharedCredential>? shared_credentials);
+
+  // GetPrivateCredentials returns Nearby Presence private credentials
+  // stored in the database. If retrieving the credentials fails,
+  // local_credentials will be null.
+  GetPrivateCredentials() => (mojo_base.mojom.AbslStatusCode status,
+          array<LocalCredential>? local_credentials);
 };
\ No newline at end of file
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd
index 157c24c..cbf9823 100644
--- a/chromeos/chromeos_strings.grd
+++ b/chromeos/chromeos_strings.grd
@@ -2601,10 +2601,10 @@
         <message name="IDS_PERSONALIZATION_APP_AMBIENT_MODE_ALBUMS_SUBPAGE_ALBUM_UNSELECTED" desc="A11y label of an unselected album in ambient mode.">
           Select album <ph name="TITLE">$1<ex>Recent highlights</ex></ph> <ph name="DESC">$2<ex>Your best auto selected photos</ex></ph>
         </message>
-        <message name="IDS_PERONSONALIZATION_APP_AMBIENT_MODE_LAST_ART_ALBUM_MESSAGE" desc="A message shown when deselecting the last art album.">
+        <message name="IDS_PERSONALIZATION_APP_AMBIENT_MODE_LAST_ART_ALBUM_MESSAGE" desc="A message shown when deselecting the last art album.">
           A minimum of one Art gallery album needs to be selected
         </message>
-        <message name="IDS_PERONSONALIZATION_APP_AMBIENT_MODE_ART_ALBUM_DIALOG_CLOSE_BUTTON_LABEL" desc="Label on the close button in the art album dialog.">
+        <message name="IDS_PERSONALIZATION_APP_AMBIENT_MODE_ART_ALBUM_DIALOG_CLOSE_BUTTON_LABEL" desc="Label on the close button in the art album dialog.">
           Got it
         </message>
         <message name="IDS_PERSONALIZATION_APP_AMBIENT_MODE_ANIMATION_TITLE" desc="Label for the ambient mode animation section.">
diff --git a/chromeos/chromeos_strings_grd/IDS_PERONSONALIZATION_APP_AMBIENT_MODE_ART_ALBUM_DIALOG_CLOSE_BUTTON_LABEL.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_AMBIENT_MODE_ART_ALBUM_DIALOG_CLOSE_BUTTON_LABEL.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_PERONSONALIZATION_APP_AMBIENT_MODE_ART_ALBUM_DIALOG_CLOSE_BUTTON_LABEL.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_AMBIENT_MODE_ART_ALBUM_DIALOG_CLOSE_BUTTON_LABEL.png.sha1
diff --git a/chromeos/chromeos_strings_grd/IDS_PERONSONALIZATION_APP_AMBIENT_MODE_LAST_ART_ALBUM_MESSAGE.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_AMBIENT_MODE_LAST_ART_ALBUM_MESSAGE.png.sha1
similarity index 100%
rename from chromeos/chromeos_strings_grd/IDS_PERONSONALIZATION_APP_AMBIENT_MODE_LAST_ART_ALBUM_MESSAGE.png.sha1
rename to chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_AMBIENT_MODE_LAST_ART_ALBUM_MESSAGE.png.sha1
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc
index ab4155e..9d6c775 100644
--- a/chromeos/constants/chromeos_features.cc
+++ b/chromeos/constants/chromeos_features.cc
@@ -59,6 +59,9 @@
              "CrosWebAppInstallDialog",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+// Enables the desk profiles feature.
+BASE_FEATURE(kDeskProfiles, "DeskProfiles", base::FEATURE_DISABLED_BY_DEFAULT);
+
 // Disable idle sockets closing on memory pressure for NetworkContexts that
 // belong to Profiles. It only applies to Profiles because the goal is to
 // improve perceived performance of web browsing within the ChromeOS user
@@ -173,6 +176,14 @@
   return base::FeatureList::IsEnabled(kCrosComponents) && IsJellyEnabled();
 }
 
+bool IsDeskProfilesEnabled() {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  return chromeos::BrowserParamsProxy::Get()->IsDeskProfilesEnabled();
+#else
+  return base::FeatureList::IsEnabled(kDeskProfiles);
+#endif
+}
+
 bool IsIWAForTelemetryExtensionAPIEnabled() {
   return base::FeatureList::IsEnabled(kIWAForTelemetryExtensionAPI);
 }
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h
index 30b1d91..6b89e62fd 100644
--- a/chromeos/constants/chromeos_features.h
+++ b/chromeos/constants/chromeos_features.h
@@ -34,6 +34,7 @@
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) BASE_DECLARE_FEATURE(kCrosComponents);
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 BASE_DECLARE_FEATURE(kCrosWebAppInstallDialog);
+COMPONENT_EXPORT(CHROMEOS_CONSTANTS) BASE_DECLARE_FEATURE(kDeskProfiles);
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 BASE_DECLARE_FEATURE(kDisableIdleSocketsCloseOnMemoryPressure);
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
@@ -70,6 +71,8 @@
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsBlinkExtensionDiagnosticsEnabled();
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsCrosComponentsEnabled();
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
+bool IsDeskProfilesEnabled();
+COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 bool IsIWAForTelemetryExtensionAPIEnabled();
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsJellyEnabled();
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsJellyrollEnabled();
diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom
index f5f7fa4..9bdcae8 100644
--- a/chromeos/crosapi/mojom/crosapi.mojom
+++ b/chromeos/crosapi/mojom/crosapi.mojom
@@ -1039,8 +1039,8 @@
 // parameters here. If a new parameter is added and its value is only known
 // after the user has logged in, please update BrowserPostLoginParams as well.
 //
-// Next version: 71
-// Next id: 71
+// Next version: 72
+// Next id: 72
 [Stable, RenamedFrom="crosapi.mojom.LacrosInitParams"]
 struct BrowserInitParams {
   // This is ash-chrome's version of the Crosapi interface. This is used by
@@ -1469,6 +1469,10 @@
   // Tells lacros whether the app install service URI is enabled.
   [MinVersion=70]
   bool is_app_install_service_uri_enabled@70;
+
+  // Tells if the desk profiles feature is enabled.
+  [MinVersion=71]
+  bool is_desk_profiles_enabled@71;
 };
 
 // BrowserPostLoginParams is the subset of parameters in BrowserInitParams
diff --git a/chromeos/profiles/arm-exp.afdo.newest.txt b/chromeos/profiles/arm-exp.afdo.newest.txt
index 2460285da..62de72d 100644
--- a/chromeos/profiles/arm-exp.afdo.newest.txt
+++ b/chromeos/profiles/arm-exp.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-arm-exp-120-6045.16-1697449393-benchmark-120.0.6070.0-r1-redacted.afdo.xz
+chromeos-chrome-arm-exp-120-6045.16-1697449393-benchmark-120.0.6073.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/arm.afdo.newest.txt b/chromeos/profiles/arm.afdo.newest.txt
index 5fe05fa..7fedb792 100644
--- a/chromeos/profiles/arm.afdo.newest.txt
+++ b/chromeos/profiles/arm.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-arm-none-120-6036.0-1697456259-benchmark-120.0.6073.0-r1-redacted.afdo.xz
+chromeos-chrome-arm-none-120-6036.0-1697456259-benchmark-120.0.6074.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt
index e8350dea5..b451bf1 100644
--- a/chromeos/profiles/atom.afdo.newest.txt
+++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-atom-120-6045.16-1697449393-benchmark-120.0.6070.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-atom-120-6045.16-1697449393-benchmark-120.0.6073.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt
index 39025794..b970e9d 100644
--- a/chromeos/profiles/bigcore.afdo.newest.txt
+++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-bigcore-120-6045.16-1697450635-benchmark-120.0.6070.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-bigcore-120-6045.16-1697450635-benchmark-120.0.6073.0-r1-redacted.afdo.xz
diff --git a/chromeos/services/network_config/public/mojom/BUILD.gn b/chromeos/services/network_config/public/mojom/BUILD.gn
index 3bc4a8f..11f02668 100644
--- a/chromeos/services/network_config/public/mojom/BUILD.gn
+++ b/chromeos/services/network_config/public/mojom/BUILD.gn
@@ -12,12 +12,15 @@
     "cros_network_config.mojom",
   ]
 
-  webui_module_path =
-      "chrome://resources/mojo/chromeos/services/network_config/public/mojom"
+  # WebUI bindings are only needed on ChromeOS Ash.
+  if (is_chromeos_ash) {
+    webui_module_path =
+        "chrome://resources/mojo/chromeos/services/network_config/public/mojom"
 
-  # Used by ash/webui/common/resources/network_health, which is still using
-  # JS + Closure.
-  use_typescript_sources = false
+    # Used by ash/webui/common/resources/network_health, which is still using
+    # JS + Closure.
+    use_typescript_sources = false
+  }
 
   public_deps = [
     ":network_types",
@@ -44,6 +47,13 @@
 mojom("network_types") {
   sources = [ "network_types.mojom" ]
 
-  webui_module_path =
-      "chrome://resources/mojo/chromeos/services/network_config/public/mojom"
+  # WebUI bindings are only needed on Ash.
+  if (is_chromeos_ash) {
+    webui_module_path =
+        "chrome://resources/mojo/chromeos/services/network_config/public/mojom"
+
+    # Used by ash/webui/common/resources/network_health, which is still using
+    # JS + Closure.
+    use_typescript_sources = false
+  }
 }
diff --git a/chromeos/services/network_health/public/mojom/BUILD.gn b/chromeos/services/network_health/public/mojom/BUILD.gn
index e68684226..17a672c1 100644
--- a/chromeos/services/network_health/public/mojom/BUILD.gn
+++ b/chromeos/services/network_health/public/mojom/BUILD.gn
@@ -38,6 +38,14 @@
     "//url/mojom:url_mojom_gurl",
   ]
 
-  webui_module_path =
-      "chrome://resources/mojo/chromeos/services/network_health/public/mojom"
+  # WebUI bindings only needed on ChromeOS Ash (dependency of the mojom target
+  # above). Only build them on that platform since they're using deprecated JS.
+  if (is_chromeos_ash) {
+    webui_module_path =
+        "chrome://resources/mojo/chromeos/services/network_health/public/mojom"
+
+    # Used by ash/webui/common/resources/network_health, which is still using
+    # JS + Closure.
+    use_typescript_sources = false
+  }
 }
diff --git a/chromeos/startup/browser_params_proxy.cc b/chromeos/startup/browser_params_proxy.cc
index 54fa138..f8e813a2 100644
--- a/chromeos/startup/browser_params_proxy.cc
+++ b/chromeos/startup/browser_params_proxy.cc
@@ -343,4 +343,8 @@
   return BrowserInitParams::Get()->is_app_install_service_uri_enabled;
 }
 
+bool BrowserParamsProxy::IsDeskProfilesEnabled() const {
+  return BrowserInitParams::Get()->is_desk_profiles_enabled;
+}
+
 }  // namespace chromeos
diff --git a/chromeos/startup/browser_params_proxy.h b/chromeos/startup/browser_params_proxy.h
index 516674e8..07b4111 100644
--- a/chromeos/startup/browser_params_proxy.h
+++ b/chromeos/startup/browser_params_proxy.h
@@ -152,6 +152,8 @@
 
   bool IsAppInstallServiceUriEnabled() const;
 
+  bool IsDeskProfilesEnabled() const;
+
  private:
   friend base::NoDestructor<BrowserParamsProxy>;
 
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni
index 2647264..41da410 100644
--- a/chromeos/tast_control.gni
+++ b/chromeos/tast_control.gni
@@ -66,9 +66,6 @@
   # https://crbug.com/1307940
   "policy.URLCheck.blocklist",
 
-  # https://crbug.com/1309466
-  "arc.StartStop.vm",
-
   # https://crbug.com/1309492
   "arc.DragDrop.chrome_to_android",
 
diff --git a/clank b/clank
index 3550ec3..6df998f 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit 3550ec36b687fc1d983b858dadd2016af443b8de
+Subproject commit 6df998f988f76d25861fc7aeea8fa55bcc6c98b8
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 5a01b5a9..e3ddf940 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -1026,6 +1026,7 @@
     if (enable_screen_ai_service) {
       deps += [
         "//components/services/screen_ai",
+        "//components/services/screen_ai:test_support",
         "//components/services/screen_ai/public/mojom",
         "//skia",
       ]
diff --git a/components/autofill/core/browser/autofill_data_util.cc b/components/autofill/core/browser/autofill_data_util.cc
index 3b9a7c8..0d5e46c69 100644
--- a/components/autofill/core/browser/autofill_data_util.cc
+++ b/components/autofill/core/browser/autofill_data_util.cc
@@ -9,6 +9,7 @@
 
 #include "base/containers/contains.h"
 #include "base/i18n/char_iterator.h"
+#include "base/no_destructor.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
@@ -546,7 +547,8 @@
   if (country_code.size() != 2)
     return false;
 
-  return re2::RE2::FullMatch(country_code, "^[A-Z]{2}$");
+  static const base::NoDestructor<re2::RE2> country_code_regex("^[A-Z]{2}$");
+  return re2::RE2::FullMatch(country_code, *country_code_regex.get());
 }
 
 bool IsValidCountryCode(const std::u16string& country_code) {
diff --git a/components/autofill/core/browser/data_model/autofill_structured_address_component.cc b/components/autofill/core/browser/data_model/autofill_structured_address_component.cc
index ccfcda2f..862e2a9 100644
--- a/components/autofill/core/browser/data_model/autofill_structured_address_component.cc
+++ b/components/autofill/core/browser/data_model/autofill_structured_address_component.cc
@@ -103,7 +103,7 @@
 }
 
 void AddressComponent::CopyFrom(const AddressComponent& other) {
-  CHECK(GetStorageType() == other.GetStorageType());
+  CHECK_EQ(GetStorageType(), other.GetStorageType());
   if (this == &other) {
     return;
   }
@@ -116,7 +116,8 @@
     UnsetValue();
   }
 
-  CHECK(other.subcomponents_.size() == subcomponents_.size());
+  CHECK_EQ(other.subcomponents_.size(), subcomponents_.size())
+      << GetStorageTypeName();
   for (size_t i = 0; i < other.subcomponents_.size(); i++)
     subcomponents_[i]->CopyFrom(*other.subcomponents_[i]);
 
@@ -134,7 +135,8 @@
       value_verification_status_ != other.value_verification_status_) {
     return false;
   }
-  CHECK(other.subcomponents_.size() == subcomponents_.size());
+  CHECK_EQ(other.subcomponents_.size(), subcomponents_.size())
+      << GetStorageTypeName();
   for (size_t i = 0; i < other.subcomponents_.size(); i++) {
     if (!(subcomponents_[i]->SameAs(*other.subcomponents_[i]))) {
       return false;
@@ -823,7 +825,8 @@
       HasNewerValuePrecedenceInMerging(newer_component)) {
     value_verification_status_ = newer_component.GetVerificationStatus();
   }
-  CHECK(newer_component.subcomponents_.size() == subcomponents_.size());
+  CHECK_EQ(newer_component.subcomponents_.size(), subcomponents_.size())
+      << GetStorageTypeName();
   for (size_t i = 0; i < newer_component.subcomponents_.size(); i++) {
     subcomponents_[i]->MergeVerificationStatuses(
         *newer_component.subcomponents_.at(i));
@@ -935,7 +938,8 @@
   // Checks if all child nodes are mergeable.
   if (merge_mode_ & kMergeChildrenAndReformatIfNeeded) {
     bool is_mergeable = true;
-    CHECK(newer_component.subcomponents_.size() == subcomponents_.size());
+    CHECK_EQ(newer_component.subcomponents_.size(), subcomponents_.size())
+        << GetStorageTypeName();
     for (size_t i = 0; i < newer_component.subcomponents_.size(); i++) {
       if (!subcomponents_[i]->IsMergeableWithComponent(
               *newer_component.subcomponents_[i])) {
@@ -1134,7 +1138,7 @@
   // If the corresponding mode is active, ignore this mode and pair-wise merge
   // the child tokens. Reformat this nodes from its children after the merge.
   if (merge_mode_ & kMergeChildrenAndReformatIfNeeded) {
-    CHECK(newer_component.subcomponents_.size() == subcomponents_.size());
+    CHECK_EQ(newer_component.subcomponents_.size(), subcomponents_.size());
     for (size_t i = 0; i < newer_component.subcomponents_.size(); i++) {
       if (!subcomponents_[i]->MergeWithComponent(
               *newer_component.subcomponents_[i],
@@ -1211,7 +1215,8 @@
 
   const SubcomponentsList& other_subcomponents =
       newer_component.Subcomponents();
-  CHECK(subcomponents_.size() == other_subcomponents.size());
+  CHECK_EQ(subcomponents_.size(), other_subcomponents.size())
+      << GetStorageTypeName();
   if (HasNewerValuePrecedenceInMerging(newer_component)) {
     SetValue(newer_component.GetValue(),
              newer_component.GetVerificationStatus());
@@ -1262,8 +1267,8 @@
   unmerged_indices.reserve(subcomponents_.size());
 
   for (size_t i = 0; i < subcomponents_.size(); i++) {
-    CHECK(subcomponents_[i]->GetStorageType() ==
-          other_subcomponents.at(i)->GetStorageType());
+    CHECK_EQ(subcomponents_[i]->GetStorageType(),
+             other_subcomponents.at(i)->GetStorageType());
     // If the components can't be merged directly, store the unmerged index and
     // sum the verification scores to decide which component's substructure to
     // use.
@@ -1317,7 +1322,7 @@
     const AddressComponent& subset_component,
     const SortedTokenComparisonResult& token_comparison_result) {
   CHECK(token_comparison_result.IsSingleTokenSuperset());
-  CHECK(token_comparison_result.additional_tokens.size() == 1);
+  CHECK_EQ(token_comparison_result.additional_tokens.size(), 1u);
   std::u16string token_to_consume =
       token_comparison_result.additional_tokens.back().value;
 
@@ -1334,8 +1339,8 @@
   unmerged_indices.reserve(subcomponents_.size());
 
   for (size_t i = 0; i < subcomponents_.size(); i++) {
-    CHECK(subcomponents_[i]->GetStorageType() ==
-          subset_subcomponents.at(i)->GetStorageType());
+    CHECK_EQ(subcomponents_[i]->GetStorageType(),
+             subset_subcomponents.at(i)->GetStorageType());
     std::unique_ptr<AddressComponent>& subcomponent = subcomponents_[i];
     const auto& subset_subcomponent = subset_subcomponents.at(i);
 
diff --git a/components/background_task_scheduler/internal/android/junit/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskJobServiceTest.java b/components/background_task_scheduler/internal/android/junit/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskJobServiceTest.java
index c1fc7d47..70bd61f 100644
--- a/components/background_task_scheduler/internal/android/junit/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskJobServiceTest.java
+++ b/components/background_task_scheduler/internal/android/junit/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskJobServiceTest.java
@@ -8,8 +8,10 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.app.job.JobParameters;
 import android.content.Context;
@@ -185,6 +187,13 @@
         verify(mBackgroundTaskSchedulerUma, times(0)).reportTaskStarted(eq(TaskIds.TEST));
     }
 
+    private static JobParameters newJobParameters(int jobId, PersistableBundle extras) {
+        JobParameters ret = mock(JobParameters.class);
+        when(ret.getJobId()).thenReturn(jobId);
+        when(ret.getExtras()).thenReturn(extras);
+        return ret;
+    }
+
     private static JobParameters buildOneOffJobParameters(
             int taskId, Long schedulingTimeMs, Long windowEndTimeForDeadlineMs) {
         PersistableBundle extras = new PersistableBundle();
@@ -202,18 +211,7 @@
         extras.putPersistableBundle(
                 BackgroundTaskSchedulerDelegate.BACKGROUND_TASK_EXTRAS_KEY, taskExtras);
 
-        return new JobParameters(
-                null /* callback */,
-                taskId,
-                extras,
-                null /* transientExtras */,
-                null /* clipData */,
-                0 /* clipGrantFlags */,
-                false /* overrideDeadlineExpired */,
-                false /* isExpedited */,
-                null /* triggeredContentUris */,
-                null /* triggeredContentAuthorities */,
-                null /* network */);
+        return newJobParameters(taskId, extras);
     }
 
     private static JobParameters buildPeriodicJobParameters(
@@ -236,18 +234,7 @@
         extras.putPersistableBundle(
                 BackgroundTaskSchedulerDelegate.BACKGROUND_TASK_EXTRAS_KEY, taskExtras);
 
-        return new JobParameters(
-                null /* callback */,
-                taskId,
-                extras,
-                null /* transientExtras */,
-                null /* clipData */,
-                0 /* clipGrantFlags */,
-                false /* overrideDeadlineExpired */,
-                false /* isExpedited */,
-                null /* triggeredContentUris */,
-                null /* triggeredContentAuthorities */,
-                null /* network */);
+        return newJobParameters(taskId, extras);
     }
 
     @Test
diff --git a/components/browser_ui/display_cutout/android/java/src/org/chromium/components/browser_ui/display_cutout/DisplayCutoutController.java b/components/browser_ui/display_cutout/android/java/src/org/chromium/components/browser_ui/display_cutout/DisplayCutoutController.java
index a15ecc5..7724a3e 100644
--- a/components/browser_ui/display_cutout/android/java/src/org/chromium/components/browser_ui/display_cutout/DisplayCutoutController.java
+++ b/components/browser_ui/display_cutout/android/java/src/org/chromium/components/browser_ui/display_cutout/DisplayCutoutController.java
@@ -35,6 +35,8 @@
  * Activity's window only in P+, and only when the associated WebContents is fullscreen.
  */
 public class DisplayCutoutController implements InsetObserverView.WindowInsetObserver, UserData {
+    private static final String TAG = "E2E_DCController";
+
     private static final Class<DisplayCutoutController> USER_DATA_KEY =
             DisplayCutoutController.class;
 
@@ -123,6 +125,9 @@
 
         /** Whether the activity is in browser (not-HTML) fullscreen. */
         boolean isInBrowserFullscreen();
+
+        /** Whether the basic Feature for drawing Edge To Edge is enabled. */
+        boolean isDrawEdgeToEdgeEnabled();
     }
 
     private final Delegate mDelegate;
@@ -228,7 +233,8 @@
 
         // TODO(crbug.com/1480477): Investigate whether if() can be turned into assert.
         if (!mDelegate.getWebContents().isFullscreenForCurrentTab()
-                && !mDelegate.isInBrowserFullscreen()) {
+                && !mDelegate.isInBrowserFullscreen()
+                && !mDelegate.isDrawEdgeToEdgeEnabled()) {
             value = ViewportFit.AUTO;
         }
 
diff --git a/components/browser_ui/modaldialog/android/java/res/layout/permission_dialog.xml b/components/browser_ui/modaldialog/android/java/res/layout/permission_dialog.xml
index 67b5855..d76b871e 100644
--- a/components/browser_ui/modaldialog/android/java/res/layout/permission_dialog.xml
+++ b/components/browser_ui/modaldialog/android/java/res/layout/permission_dialog.xml
@@ -20,14 +20,4 @@
         android:drawablePadding="8dp"
         android:textAppearance="@style/TextAppearance.TextMedium.Secondary"
         app:chromeDrawableTint="@macro/default_icon_color_accent1" />
-
-    <TextView
-        android:id="@+id/secondary"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center_vertical"
-        android:textDirection="locale"
-        android:paddingBottom="12dp"
-        android:visibility="gone"
-        android:textAppearance="@style/TextAppearance.TextSmall.Secondary"/>
 </LinearLayout>
diff --git a/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/PaddedItemDecorationWithDivider.java b/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/PaddedItemDecorationWithDivider.java
index 84896b0..a7681ce 100644
--- a/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/PaddedItemDecorationWithDivider.java
+++ b/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/PaddedItemDecorationWithDivider.java
@@ -7,7 +7,6 @@
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.util.Pair;
 import android.view.View;
 
 import androidx.annotation.NonNull;
@@ -34,17 +33,17 @@
     private boolean mAllowDividerAfterLastItem;
     private @NonNull Supplier<Integer> mDividerPaddingStartSupplier;
     private @NonNull Supplier<Integer> mDividerPaddingEndSupplier;
-    private @NonNull Pair<Integer, Integer> mItemOffsets;
+    private @NonNull Supplier<Integer> mItemOffsetSupplier;
 
     /**
      * Create the item decoration with padding.
      *
-     * @param itemOffsets Offsets to apply to start and end of each item.
+     * @param itemOffsetSupplier Supplier for offset to apply to start and end of each item.
      */
-    public PaddedItemDecorationWithDivider(@NonNull Pair<Integer, Integer> itemOffsets) {
+    public PaddedItemDecorationWithDivider(Supplier<Integer> itemOffsetSupplier) {
         mDividerPaddingStartSupplier = () -> 0;
         mDividerPaddingEndSupplier = () -> 0;
-        setItemOffsets(itemOffsets);
+        mItemOffsetSupplier = itemOffsetSupplier;
     }
 
     /** Set whether drawing divider after the last item is allowed. */
@@ -75,14 +74,15 @@
         final int width = parent.getWidth();
         int dividerStartPadding = getDividerPaddingStart();
         int dividerEndPadding = getDividerPaddingEnd();
+        int itemOffset = mItemOffsetSupplier.get();
         for (int childViewIndex = 0; childViewIndex < childCount; childViewIndex++) {
             final View view = parent.getChildAt(childViewIndex);
             if (shouldDrawDividerBelow(view, parent)) {
                 int top = (int) view.getY() + view.getHeight();
                 mDividerDrawable.setBounds(
-                        mItemOffsets.first + dividerStartPadding,
+                        itemOffset + dividerStartPadding,
                         top,
-                        width - (mItemOffsets.second + dividerEndPadding),
+                        width - (itemOffset + dividerEndPadding),
                         top + mDividerHeight);
                 mDividerDrawable.draw(c);
             }
@@ -95,8 +95,9 @@
             @NonNull View view,
             @NonNull RecyclerView parent,
             @NonNull State state) {
-        outRect.left = mItemOffsets.first;
-        outRect.right = mItemOffsets.second;
+        int itemOffset = mItemOffsetSupplier.get();
+        outRect.left = itemOffset;
+        outRect.right = itemOffset;
         if (shouldDrawDividerBelow(view, parent)) {
             outRect.bottom = mDividerHeight;
         }
@@ -133,11 +134,7 @@
         return mDividerPaddingEndSupplier.get() != null ? mDividerPaddingEndSupplier.get() : 0;
     }
 
-    public void setItemOffsets(@NonNull Pair<Integer, Integer> itemOffsets) {
-        mItemOffsets = itemOffsets;
-    }
-
-    public Pair<Integer, Integer> getItemOffsetsForTesting() {
-        return mItemOffsets;
+    public int getItemOffsetForTesting() {
+        return mItemOffsetSupplier.get();
     }
 }
diff --git a/components/browser_ui/widget/android/BUILD.gn b/components/browser_ui/widget/android/BUILD.gn
index 9376251..d0d373e 100644
--- a/components/browser_ui/widget/android/BUILD.gn
+++ b/components/browser_ui/widget/android/BUILD.gn
@@ -42,6 +42,7 @@
     "java/src/org/chromium/components/browser_ui/widget/SurfaceColorDrawable.java",
     "java/src/org/chromium/components/browser_ui/widget/TintedDrawable.java",
     "java/src/org/chromium/components/browser_ui/widget/TouchEventObserver.java",
+    "java/src/org/chromium/components/browser_ui/widget/TouchEventProvider.java",
     "java/src/org/chromium/components/browser_ui/widget/ViewResourceFrameLayout.java",
     "java/src/org/chromium/components/browser_ui/widget/WrappingLayout.java",
     "java/src/org/chromium/components/browser_ui/widget/animation/CancelAwareAnimatorListener.java",
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RoundedCornerOutlineProvider.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RoundedCornerOutlineProvider.java
index f7597f5..5f44c8e 100644
--- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RoundedCornerOutlineProvider.java
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RoundedCornerOutlineProvider.java
@@ -8,25 +8,30 @@
 import android.view.View;
 import android.view.ViewOutlineProvider;
 
+import androidx.annotation.VisibleForTesting;
+
 /**
- * A custom {@link ViewOutlineProvider} that is able to render content with rounded off corners.
- * The instance guarantees that only the actual bounds of the view are rounded,
- * ie. if the content does not stretch into the corners, it won't be rounded.
- * This class can be applied to any view, including containers.
+ * A custom {@link ViewOutlineProvider} that is able to render content with rounded off corners. The
+ * instance guarantees that only the actual bounds of the view are rounded, ie. if the content does
+ * not stretch into the corners, it won't be rounded. This class can be applied to any view,
+ * including containers.
  *
- * Affect background/foreground colors alike, as well as select/focus states etc.
+ * <p>Affect background/foreground colors alike, as well as select/focus states etc.
  *
- * To apply:
+ * <p>To apply: <code>
  *     myView.setOutlineProvider(new RoundedCornerOutlineProvider(r));
  *     myView.setClipToOutline(true);
+ * </code>
  */
 public class RoundedCornerOutlineProvider extends ViewOutlineProvider {
     /** Radius of each corner. */
     private int mRadius;
+
     private boolean mRoundLeftEdge;
     private boolean mRoundTopEdge;
     private boolean mRoundRightEdge;
     private boolean mRoundBottomEdge;
+    private boolean mClipPaddedArea;
 
     public RoundedCornerOutlineProvider() {
         this(0);
@@ -42,10 +47,17 @@
 
     @Override
     public void getOutline(View view, Outline outline) {
-        var left = view.getPaddingLeft();
-        var top = view.getPaddingTop();
-        var right = view.getWidth() - view.getPaddingRight();
-        var bottom = view.getHeight() - view.getPaddingBottom();
+        var left = 0;
+        var top = 0;
+        var right = view.getWidth();
+        var bottom = view.getHeight();
+
+        if (mClipPaddedArea) {
+            left += view.getPaddingLeft();
+            top += view.getPaddingTop();
+            right -= view.getPaddingRight();
+            bottom -= view.getPaddingBottom();
+        }
 
         // Grow the rounded area size in the direction where the rounding is not desired.
         if (!mRoundLeftEdge) left -= mRadius;
@@ -59,6 +71,7 @@
 
     /**
      * Set the rounding radius.
+     *
      * @param radius The radius to apply to round rectangle corners.
      */
     public void setRadius(int radius) {
@@ -66,8 +79,16 @@
     }
 
     /**
-     * Override edges that receive rounding.
+     * Specify which region of view to clip.
+     *
+     * @param clipPaddedArea when true, area within the view will be clipped, otherwise the entire
+     *     view will be clipped.
      */
+    public void setClipPaddedArea(boolean clipPaddedArea) {
+        mClipPaddedArea = clipPaddedArea;
+    }
+
+    /** Override edges that receive rounding. */
     public void setRoundingEdges(
             boolean leftEdge, boolean topEdge, boolean rightEdge, boolean bottomEdge) {
         mRoundLeftEdge = leftEdge;
@@ -77,14 +98,19 @@
     }
 
     /** Returns the radius used to round the view. */
+    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
     public int getRadiusForTesting() {
         return mRadius;
     }
 
+    /** Returns whether the corners around the top edge are rounded. */
+    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
     public boolean isTopEdgeRoundedForTesting() {
         return mRoundTopEdge;
     }
 
+    /** Returns whether the corners around the bottom edge are rounded. */
+    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
     public boolean isBottomEdgeRoundedForTesting() {
         return mRoundBottomEdge;
     }
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RoundedCornerOutlineProviderUnitTest.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RoundedCornerOutlineProviderUnitTest.java
index 2cc5a9d..72244d8 100644
--- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RoundedCornerOutlineProviderUnitTest.java
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/RoundedCornerOutlineProviderUnitTest.java
@@ -94,6 +94,17 @@
     public void verifyRespectsPaddings() {
         mView.setPaddingRelative(15, 10, 25, 20);
         mProvider.getOutline(mView, mOutline);
+
+        // Default: no clipping padded area.
+        mProvider.getOutline(mView, mOutline);
+        mOutline.getRect(mRect);
+        Assert.assertEquals(new Rect(0, 0, VIEW_WIDTH, VIEW_HEIGHT), mRect);
+        Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
+        Assert.assertTrue(mOutline.canClip());
+
+        // Variant: clip padded area.
+        mProvider.setClipPaddedArea(true);
+        mProvider.getOutline(mView, mOutline);
         mOutline.getRect(mRect);
         Assert.assertEquals(new Rect(15, 10, VIEW_WIDTH - 25, VIEW_HEIGHT - 20), mRect);
         Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
@@ -110,6 +121,16 @@
                 mView.getLayoutDirection());
 
         mView.setPaddingRelative(15, 10, 25, 20);
+
+        // Default: no clipping padded area.
+        mProvider.getOutline(mView, mOutline);
+        mOutline.getRect(mRect);
+        Assert.assertEquals(new Rect(0, 0, VIEW_WIDTH, VIEW_HEIGHT), mRect);
+        Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
+        Assert.assertTrue(mOutline.canClip());
+
+        // Variant: clip padded area.
+        mProvider.setClipPaddedArea(true);
         mProvider.getOutline(mView, mOutline);
         mOutline.getRect(mRect);
         Assert.assertEquals(new Rect(25, 10, VIEW_WIDTH - 15, VIEW_HEIGHT - 20), mRect);
@@ -122,6 +143,16 @@
     public void verifyViewOriginDoesNotImpactOutline() {
         mView.layout(10, 15, 10 + VIEW_WIDTH, 15 + VIEW_HEIGHT);
         mView.setPaddingRelative(15, 10, 25, 20);
+
+        // Default: no clipping padded area.
+        mProvider.getOutline(mView, mOutline);
+        mOutline.getRect(mRect);
+        Assert.assertEquals(new Rect(0, 0, VIEW_WIDTH, VIEW_HEIGHT), mRect);
+        Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
+        Assert.assertTrue(mOutline.canClip());
+
+        // Variant: clip padded area.
+        mProvider.setClipPaddedArea(true);
         mProvider.getOutline(mView, mOutline);
         mOutline.getRect(mRect);
         Assert.assertEquals(new Rect(15, 10, VIEW_WIDTH - 25, VIEW_HEIGHT - 20), mRect);
@@ -137,9 +168,17 @@
         mProvider.setRoundingEdges(
                 /* left= */ false, /* top= */ true, /* right= */ true, /* bottom= */ true);
 
+        // Default: no clipping padded area.
         mProvider.getOutline(mView, mOutline);
         mOutline.getRect(mRect);
+        Assert.assertEquals(new Rect(-RADIUS, 0, VIEW_WIDTH, VIEW_HEIGHT), mRect);
+        Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
+        Assert.assertTrue(mOutline.canClip());
 
+        // Variant: clip padded area.
+        mProvider.setClipPaddedArea(true);
+        mProvider.getOutline(mView, mOutline);
+        mOutline.getRect(mRect);
         Assert.assertEquals(new Rect(15 - RADIUS, 10, VIEW_WIDTH - 25, VIEW_HEIGHT - 20), mRect);
         Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
         Assert.assertTrue(mOutline.canClip());
@@ -153,9 +192,17 @@
         mProvider.setRoundingEdges(
                 /* left= */ true, /* top= */ false, /* right= */ true, /* bottom= */ true);
 
+        // Default: no clipping padded area.
         mProvider.getOutline(mView, mOutline);
         mOutline.getRect(mRect);
+        Assert.assertEquals(new Rect(0, -RADIUS, VIEW_WIDTH, VIEW_HEIGHT), mRect);
+        Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
+        Assert.assertTrue(mOutline.canClip());
 
+        // Variant: clip padded area.
+        mProvider.setClipPaddedArea(true);
+        mProvider.getOutline(mView, mOutline);
+        mOutline.getRect(mRect);
         Assert.assertEquals(new Rect(15, 10 - RADIUS, VIEW_WIDTH - 25, VIEW_HEIGHT - 20), mRect);
         Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
         Assert.assertTrue(mOutline.canClip());
@@ -169,9 +216,17 @@
         mProvider.setRoundingEdges(
                 /* left= */ true, /* top= */ true, /* right= */ false, /* bottom= */ true);
 
+        // Default: no clipping padded area.
         mProvider.getOutline(mView, mOutline);
         mOutline.getRect(mRect);
+        Assert.assertEquals(new Rect(0, 0, VIEW_WIDTH + RADIUS, VIEW_HEIGHT), mRect);
+        Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
+        Assert.assertTrue(mOutline.canClip());
 
+        // Variant: clip padded area.
+        mProvider.setClipPaddedArea(true);
+        mProvider.getOutline(mView, mOutline);
+        mOutline.getRect(mRect);
         Assert.assertEquals(new Rect(15, 10, VIEW_WIDTH - 25 + RADIUS, VIEW_HEIGHT - 20), mRect);
         Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
         Assert.assertTrue(mOutline.canClip());
@@ -185,9 +240,17 @@
         mProvider.setRoundingEdges(
                 /* left= */ true, /* top= */ true, /* right= */ true, /* bottom= */ false);
 
+        // Default: no clipping padded area.
         mProvider.getOutline(mView, mOutline);
         mOutline.getRect(mRect);
+        Assert.assertEquals(new Rect(0, 0, VIEW_WIDTH, VIEW_HEIGHT + RADIUS), mRect);
+        Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
+        Assert.assertTrue(mOutline.canClip());
 
+        // Variant: clip padded area.
+        mProvider.setClipPaddedArea(true);
+        mProvider.getOutline(mView, mOutline);
+        mOutline.getRect(mRect);
         Assert.assertEquals(new Rect(15, 10, VIEW_WIDTH - 25, VIEW_HEIGHT - 20 + RADIUS), mRect);
         Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
         Assert.assertTrue(mOutline.canClip());
@@ -203,9 +266,17 @@
         mProvider.setRoundingEdges(
                 /* left= */ true, /* top= */ true, /* right= */ false, /* bottom= */ false);
 
+        // Default: no clipping padded area.
         mProvider.getOutline(mView, mOutline);
         mOutline.getRect(mRect);
+        Assert.assertEquals(new Rect(0, 0, VIEW_WIDTH + RADIUS, VIEW_HEIGHT + RADIUS), mRect);
+        Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
+        Assert.assertTrue(mOutline.canClip());
 
+        // Variant: clip padded area.
+        mProvider.setClipPaddedArea(true);
+        mProvider.getOutline(mView, mOutline);
+        mOutline.getRect(mRect);
         Assert.assertEquals(
                 new Rect(15, 10, VIEW_WIDTH - 25 + RADIUS, VIEW_HEIGHT - 20 + RADIUS), mRect);
         Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
@@ -222,9 +293,17 @@
         mProvider.setRoundingEdges(
                 /* left= */ true, /* top= */ false, /* right= */ true, /* bottom= */ false);
 
+        // Default: no clipping padded area.
         mProvider.getOutline(mView, mOutline);
         mOutline.getRect(mRect);
+        Assert.assertEquals(new Rect(0, -RADIUS, VIEW_WIDTH, VIEW_HEIGHT + RADIUS), mRect);
+        Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
+        Assert.assertTrue(mOutline.canClip());
 
+        // Variant: clip padded area.
+        mProvider.setClipPaddedArea(true);
+        mProvider.getOutline(mView, mOutline);
+        mOutline.getRect(mRect);
         Assert.assertEquals(
                 new Rect(15, 10 - RADIUS, VIEW_WIDTH - 25, VIEW_HEIGHT - 20 + RADIUS), mRect);
         Assert.assertEquals(RADIUS, mOutline.getRadius(), 0.001);
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/TouchEventObserver.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/TouchEventObserver.java
index 3669ada0..363dc71 100644
--- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/TouchEventObserver.java
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/TouchEventObserver.java
@@ -11,16 +11,27 @@
  */
 public interface TouchEventObserver {
     /**
-     * Determine if touch events should be forwarded to the observing object.
-     * Should return {@link true} if the object decided to consume the events.
+     * Determine if touch events should be forwarded to the observing object. Should return {@link
+     * true} if the object decided to consume the events.
+     *
      * @param e {@link MotionEvent} object to process.
      * @return {@code true} if the observer will process touch events going forward.
      */
-    boolean shouldInterceptTouchEvent(MotionEvent e);
+    boolean onInterceptTouchEvent(MotionEvent e);
 
     /**
-     * Handle touch events.
+     * @see {@link android.view.View#onTouchEvent()}
      * @param e {@link MotionEvent} object to process.
      */
-    void handleTouchEvent(MotionEvent e);
+    default boolean onTouchEvent(MotionEvent e) {
+        return false;
+    }
+
+    /**
+     * @see {@link android.view.View#dispatchTouchEvent()}
+     * @param e {@link MotionEvent} object to process.
+     */
+    default boolean dispatchTouchEvent(MotionEvent e) {
+        return false;
+    }
 }
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/TouchEventProvider.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/TouchEventProvider.java
new file mode 100644
index 0000000..d59fbc7
--- /dev/null
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/TouchEventProvider.java
@@ -0,0 +1,23 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.browser_ui.widget;
+
+/**
+ * Observer interface for any object that needs to process touch events. This is useful when
+ * ordinary Android view events processing hierarchy cannot be easily applied.
+ */
+public interface TouchEventProvider {
+    /**
+     * @param obs {@link TouchEventObserver} object to process.
+     */
+    void addTouchEventObserver(TouchEventObserver obs);
+
+    /**
+     * Removes the registered {@link TouchEventObserver}.
+     *
+     * @param obs {@link TouchEventObserver} object to process.
+     */
+    void removeTouchEventObserver(TouchEventObserver obs);
+}
diff --git a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/tile/TileView.java b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/tile/TileView.java
index 1ca418e..eba4b5c 100644
--- a/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/tile/TileView.java
+++ b/components/browser_ui/widget/android/java/src/org/chromium/components/browser_ui/widget/tile/TileView.java
@@ -113,6 +113,7 @@
     }
 
     /** Retrieves the radius used to round the image content. */
+    @VisibleForTesting(otherwise = VisibleForTesting.NONE)
     int getRoundingRadiusForTesting() {
         return mRoundingOutline.getRadiusForTesting();
     }
diff --git a/components/content_settings/core/browser/cookie_settings.cc b/components/content_settings/core/browser/cookie_settings.cc
index 14e25f1c..70f13c6 100644
--- a/components/content_settings/core/browser/cookie_settings.cc
+++ b/components/content_settings/core/browser/cookie_settings.cc
@@ -95,6 +95,25 @@
       primary_url, GURL(), ContentSettingsType::COOKIES, setting);
 }
 
+bool CookieSettings::IsAllowedByTpcdMetadataGrant(
+    const GURL& url,
+    const GURL& first_party_url) const {
+  if (!ShouldConsider3pcdMetadataGrantsSettings()) {
+    return false;
+  }
+
+  base::AutoLock lock(tpcd_lock_);
+  const auto& entry = base::ranges::find_if(
+      settings_for_3pcd_metadata_grants_,
+      [&](const ContentSettingPatternSource& entry) {
+        CHECK(IsAllowed(
+            content_settings::ValueToContentSetting(entry.setting_value)));
+        return entry.primary_pattern.Matches(url) &&
+               entry.secondary_pattern.Matches(first_party_url);
+      });
+  return entry != settings_for_3pcd_metadata_grants_.end();
+}
+
 void CookieSettings::SetTemporaryCookieGrantForHeuristic(
     const GURL& url,
     const GURL& first_party_url,
@@ -264,16 +283,7 @@
     ContentSettingsType content_type,
     content_settings::SettingInfo* info) const {
   if (content_type == ContentSettingsType::TPCD_METADATA_GRANTS) {
-    base::AutoLock lock(tpcd_lock_);
-    const auto& entry = base::ranges::find_if(
-        settings_for_3pcd_metadata_grants_,
-        [&](const ContentSettingPatternSource& entry) {
-          CHECK(IsAllowed(
-              content_settings::ValueToContentSetting(entry.setting_value)));
-          return entry.primary_pattern.Matches(primary_url) &&
-                 entry.secondary_pattern.Matches(secondary_url);
-        });
-    return entry != settings_for_3pcd_metadata_grants_.end()
+    return IsAllowedByTpcdMetadataGrant(primary_url, secondary_url)
                ? CONTENT_SETTING_ALLOW
                : CONTENT_SETTING_BLOCK;
   }
diff --git a/components/content_settings/core/browser/cookie_settings.h b/components/content_settings/core/browser/cookie_settings.h
index 56b38d8..af9bdfc 100644
--- a/components/content_settings/core/browser/cookie_settings.h
+++ b/components/content_settings/core/browser/cookie_settings.h
@@ -102,6 +102,13 @@
   // This should only be called on the UI thread.
   void SetCookieSetting(const GURL& primary_url, ContentSetting setting);
 
+  // Returns whether a cookie access is allowed for the `TPCD_METADATA_GRANTS`
+  // content settings type, scoped on the provided `url` and `first_party_url`.
+  //
+  // This may be called on any thread.
+  bool IsAllowedByTpcdMetadataGrant(const GURL& url,
+                                    const GURL& first_party_url) const;
+
   // Sets the `TPCD_HEURISTICS_GRANTS` setting for the given (`url`,
   // `first_party_url`) pair, for the provided `ttl`.
   //
diff --git a/components/content_settings/core/browser/cookie_settings_unittest.cc b/components/content_settings/core/browser/cookie_settings_unittest.cc
index 97b0509..663a0ce 100644
--- a/components/content_settings/core/browser/cookie_settings_unittest.cc
+++ b/components/content_settings/core/browser/cookie_settings_unittest.cc
@@ -1523,6 +1523,7 @@
   EXPECT_EQ(cookie_settings_->GetCookieSetting(
                 url, top_level_url, GetCookieSettingOverrides(), nullptr),
             SettingWith3pcdMetadataGrantEligibleOverride());
+
   histogram_tester.ExpectTotalCount(kAllowedRequestsHistogram, 1);
   histogram_tester.ExpectBucketCount(
       kAllowedRequestsHistogram,
@@ -1535,14 +1536,20 @@
   EXPECT_EQ(cookie_settings_->GetCookieSetting(
                 top_level_url, url, GetCookieSettingOverrides(), nullptr),
             CONTENT_SETTING_BLOCK);
+  EXPECT_FALSE(
+      cookie_settings_->IsAllowedByTpcdMetadataGrant(top_level_url, url));
 
   // Invalid pairs where a |third_url| is used.
   EXPECT_EQ(cookie_settings_->GetCookieSetting(
                 url, third_url, GetCookieSettingOverrides(), nullptr),
             CONTENT_SETTING_BLOCK);
+  EXPECT_FALSE(cookie_settings_->IsAllowedByTpcdMetadataGrant(third_url, url));
+
   EXPECT_EQ(cookie_settings_->GetCookieSetting(
                 third_url, top_level_url, GetCookieSettingOverrides(), nullptr),
             CONTENT_SETTING_BLOCK);
+  EXPECT_FALSE(
+      cookie_settings_->IsAllowedByTpcdMetadataGrant(top_level_url, third_url));
 }
 
 TEST_P(CookieSettingsTest, GetCookieSetting3pcdHeuristicsGrants) {
diff --git a/components/content_settings/core/common/cookie_settings_base.h b/components/content_settings/core/common/cookie_settings_base.h
index a5f1161..faba523 100644
--- a/components/content_settings/core/common/cookie_settings_base.h
+++ b/components/content_settings/core/common/cookie_settings_base.h
@@ -256,6 +256,10 @@
       net::CookieSettingOverrides overrides,
       SettingInfo* info) const;
 
+  // Returns true iff the query for third-party cookie access should consider
+  // grants awarded by the global allowlist.
+  bool ShouldConsider3pcdMetadataGrantsSettings() const;
+
  private:
   // Returns a content setting for the requested parameters and populates |info|
   // if not null. Implementations might only implement a subset of all
@@ -273,8 +277,6 @@
 
   bool ShouldConsider3pcdSupportSettings() const;
 
-  bool ShouldConsider3pcdMetadataGrantsSettings() const;
-
   bool ShouldConsider3pcdHeuristicsGrantsSettings() const;
 
   // Returns true iff the query should consider Storage Access API permission
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index 4e2b202..a4870df 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -437,7 +437,7 @@
   ":flags_java_proto",
   ":request_context_config_java_proto",
   "//base:base_java",
-  "//base:jni_java",
+  "//third_party/jni_zero:jni_zero_java",
   "//build/android:build_java",
   "//net/android:net_java",
   "//url:url_java",
@@ -467,11 +467,11 @@
   deps = [
     ":cronet_api_java",
     ":cronet_impl_common_base_java",
-    "//base:jni_java",
     "//build/android:build_java",
     "//third_party/android_deps:com_google_code_findbugs_jsr305_java",
     "//third_party/android_deps:protobuf_lite_runtime_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
+    "//third_party/jni_zero:jni_zero_java",
   ]
   deps += cronet_impl_native_java_deps_to_package
 
@@ -508,10 +508,10 @@
     ":cronet_api_java",
     ":cronet_impl_common_base_java",
     "//base:base_java",
-    "//base:jni_java",
     "//build/android:build_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_core_core_java",
+    "//third_party/jni_zero:jni_zero_java",
   ]
 }
 
@@ -1027,12 +1027,12 @@
     ":cronet_impl_all_java",
     "//base:base_java",
     "//base:base_java_test_support",
-    "//base:jni_java",
     "//build/android:build_java",
     "//net/android:net_java_test_support",
     "//third_party/android_sdk:android_test_base_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/google-truth:google_truth_java",
+    "//third_party/jni_zero:jni_zero_java",
     "//third_party/junit",
     "//third_party/netty4:netty_all_java",
   ]
@@ -1079,10 +1079,10 @@
            ":flags_java_proto",
            "//base:base_java",
            "//base:base_java_test_support",
-           "//base:jni_java",
            "//build/android:build_java",
            "//third_party/android_sdk:android_test_base_java",
            "//third_party/google-truth:google_truth_java",
+           "//third_party/jni_zero:jni_zero_java",
            "//third_party/junit",
          ] + cronet_tests_androidx_common_srcs
 }
@@ -1121,7 +1121,7 @@
   ":cronet_test_apk_java",
   ":flags_java_proto",
   "//base:base_java",
-  "//base:jni_java",
+  "//third_party/jni_zero:jni_zero_java",
   "//base:base_java_test_support",
 
   "//net/android:embedded_test_server_aidl_java",
@@ -1247,7 +1247,6 @@
            ":cronet_test_apk_resources",
            "//base:base_java",
            "//base:base_java_test_support",
-           "//base:jni_java",
            "//build/android:build_java",
            "//net/android:net_java",
            "//net/android:net_java_test_support",
@@ -1255,6 +1254,7 @@
            "//third_party/android_sdk:android_test_mock_java",
            "//third_party/google-truth:google_truth_java",
            "//third_party/hamcrest:hamcrest_core_java",
+           "//third_party/jni_zero:jni_zero_java",
            "//third_party/junit",
            "//third_party/netty-tcnative:netty-tcnative-so",
            "//third_party/netty4:netty_all_java",
@@ -1342,11 +1342,11 @@
            ":cronet_test_apk_resources",
            "//base:base_java",
            "//base:base_java_test_support",
-           "//base:jni_java",
            "//build/android:build_java",
            "//third_party/android_sdk:android_test_base_java",
            "//third_party/android_sdk:android_test_mock_java",
            "//third_party/google-truth:google_truth_java",
+           "//third_party/jni_zero:jni_zero_java",
            "//third_party/junit",
            "//third_party/netty4:netty_all_java",
          ] + cronet_tests_androidx_common_srcs
@@ -1385,9 +1385,9 @@
     ":cronet_javatests",
     ":cronet_test_apk_java",
     "//base:base_java",
-    "//base:jni_java",
     "//build/android:build_java",
     "//third_party/android_sdk:android_test_mock_java",
+    "//third_party/jni_zero:jni_zero_java",
     "//third_party/junit",
   ]
 
@@ -1554,13 +1554,14 @@
     "//components/cronet/android/java/src",
     "//net/android/java/src",
     "//url/android/java/src",
+    "//third_party/jni_zero/java/src",
   ]
   source_deps = [
     ":cronet_impl_native_base_java",
     "//base:base_java",
-    "//base:jni_java",
     "//build/android:build_java",
     "//net/android:net_java",
+    "//third_party/jni_zero:jni_zero_java",
     "//url:url_java",
   ]
 
diff --git a/components/cronet/android/cronet_impl_native_proguard.cfg b/components/cronet/android/cronet_impl_native_proguard.cfg
index c303e53..5fca055 100644
--- a/components/cronet/android/cronet_impl_native_proguard.cfg
+++ b/components/cronet/android/cronet_impl_native_proguard.cfg
@@ -8,9 +8,6 @@
 # While Chrome doesn't need to keep these with their version of R8, some cronet
 # users may be on other optimizers which still require the annotation to be
 # kept in order for the keep rules to work.
--keep @interface org.chromium.base.annotations.AccessedByNative
--keep @interface org.chromium.base.annotations.CalledByNative
--keep @interface org.chromium.base.annotations.CalledByNativeUnchecked
 -keep @interface org.chromium.build.annotations.DoNotInline
 -keep @interface org.chromium.build.annotations.UsedByReflection
 -keep @interface org.chromium.build.annotations.IdentifierNameString
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetBidirectionalStream.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetBidirectionalStream.java
index 32955684..60b8d96 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/CronetBidirectionalStream.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetBidirectionalStream.java
@@ -7,11 +7,12 @@
 import androidx.annotation.IntDef;
 import androidx.annotation.VisibleForTesting;
 
+import org.jni_zero.CalledByNative;
+import org.jni_zero.JNINamespace;
+import org.jni_zero.NativeClassQualifiedName;
+import org.jni_zero.NativeMethods;
+
 import org.chromium.base.Log;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeClassQualifiedName;
-import org.chromium.base.annotations.NativeMethods;
 import org.chromium.net.BidirectionalStream;
 import org.chromium.net.CallbackException;
 import org.chromium.net.CronetException;
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetLibraryLoader.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetLibraryLoader.java
index b4efc5e..458b1436 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/CronetLibraryLoader.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetLibraryLoader.java
@@ -13,11 +13,12 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import org.jni_zero.CalledByNative;
+import org.jni_zero.JNINamespace;
+import org.jni_zero.NativeMethods;
+
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
 import org.chromium.net.NetworkChangeNotifier;
 import org.chromium.net.httpflags.BaseFeature;
 import org.chromium.net.httpflags.Flags;
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetUploadDataStream.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetUploadDataStream.java
index 32e59858..bb27299 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/CronetUploadDataStream.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetUploadDataStream.java
@@ -9,11 +9,12 @@
 import androidx.annotation.IntDef;
 import androidx.annotation.VisibleForTesting;
 
+import org.jni_zero.CalledByNative;
+import org.jni_zero.JNINamespace;
+import org.jni_zero.NativeClassQualifiedName;
+import org.jni_zero.NativeMethods;
+
 import org.chromium.base.Log;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeClassQualifiedName;
-import org.chromium.base.annotations.NativeMethods;
 import org.chromium.net.UploadDataProvider;
 import org.chromium.net.UploadDataSink;
 
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequest.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequest.java
index 2819bfa3..d5f14dc 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequest.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequest.java
@@ -11,11 +11,12 @@
 import androidx.annotation.RequiresApi;
 import androidx.annotation.VisibleForTesting;
 
+import org.jni_zero.CalledByNative;
+import org.jni_zero.JNINamespace;
+import org.jni_zero.NativeClassQualifiedName;
+import org.jni_zero.NativeMethods;
+
 import org.chromium.base.Log;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeClassQualifiedName;
-import org.chromium.base.annotations.NativeMethods;
 import org.chromium.net.CallbackException;
 import org.chromium.net.CronetException;
 import org.chromium.net.Idempotency;
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java
index e34bc0a..e623ce5 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java
@@ -10,12 +10,13 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import org.jni_zero.CalledByNative;
+import org.jni_zero.JNINamespace;
+import org.jni_zero.NativeClassQualifiedName;
+import org.jni_zero.NativeMethods;
+
 import org.chromium.base.Log;
 import org.chromium.base.ObserverList;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeClassQualifiedName;
-import org.chromium.base.annotations.NativeMethods;
 import org.chromium.build.annotations.UsedByReflection;
 import org.chromium.net.BidirectionalStream;
 import org.chromium.net.CronetEngine;
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
index c9c4d46..64e009c 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
@@ -24,6 +24,8 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import org.jni_zero.JNINamespace;
+import org.jni_zero.NativeMethods;
 import org.json.JSONObject;
 import org.junit.After;
 import org.junit.Before;
@@ -33,8 +35,6 @@
 
 import org.chromium.base.Log;
 import org.chromium.base.PathUtils;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.test.util.DoNotBatch;
 import org.chromium.net.CronetTestRule.CronetImplementation;
 import org.chromium.net.CronetTestRule.DisableAutomaticNetLog;
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java
index a82b7d3..704c58c 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java
@@ -22,6 +22,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import org.jni_zero.NativeMethods;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -29,7 +30,6 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.Log;
-import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.test.util.DoNotBatch;
 import org.chromium.net.CronetTestRule.CronetImplementation;
 import org.chromium.net.CronetTestRule.IgnoreFor;
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java
index 929976d..1b3eac2 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTest.java
@@ -19,6 +19,8 @@
 import androidx.test.filters.LargeTest;
 import androidx.test.filters.MediumTest;
 
+import org.jni_zero.JNINamespace;
+import org.jni_zero.NativeMethods;
 import org.json.JSONObject;
 import org.junit.After;
 import org.junit.Before;
@@ -29,8 +31,6 @@
 
 import org.chromium.base.Log;
 import org.chromium.base.PathUtils;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.DoNotBatch;
 import org.chromium.net.CronetTestRule.CronetImplementation;
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTranslationTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTranslationTest.java
index d32ebe9f..0f46ba1 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTranslationTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/ExperimentalOptionsTranslationTest.java
@@ -13,12 +13,12 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.MediumTest;
 
+import org.jni_zero.JNINamespace;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.test.util.DoNotBatch;
 import org.chromium.net.DnsOptions.StaleDnsOptions;
 
diff --git a/components/cronet/android/test/src/org/chromium/net/CronetTestUtil.java b/components/cronet/android/test/src/org/chromium/net/CronetTestUtil.java
index ccbd5616..c85e3a3 100644
--- a/components/cronet/android/test/src/org/chromium/net/CronetTestUtil.java
+++ b/components/cronet/android/test/src/org/chromium/net/CronetTestUtil.java
@@ -6,11 +6,11 @@
 
 import android.net.Network;
 
+import org.jni_zero.JNINamespace;
+import org.jni_zero.NativeMethods;
 import org.json.JSONException;
 import org.json.JSONObject;
 
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
 import org.chromium.net.impl.CronetEngineBuilderImpl;
 import org.chromium.net.impl.CronetUrlRequest;
 import org.chromium.net.impl.CronetUrlRequestContext;
diff --git a/components/cronet/android/test/src/org/chromium/net/MockCertVerifier.java b/components/cronet/android/test/src/org/chromium/net/MockCertVerifier.java
index d2e732e..307ec81a 100644
--- a/components/cronet/android/test/src/org/chromium/net/MockCertVerifier.java
+++ b/components/cronet/android/test/src/org/chromium/net/MockCertVerifier.java
@@ -4,8 +4,9 @@
 
 package org.chromium.net;
 
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
+import org.jni_zero.JNINamespace;
+import org.jni_zero.NativeMethods;
+
 import org.chromium.base.test.util.UrlUtils;
 
 /**
diff --git a/components/cronet/android/test/src/org/chromium/net/MockUrlRequestJobFactory.java b/components/cronet/android/test/src/org/chromium/net/MockUrlRequestJobFactory.java
index bfa106f..935ece4 100644
--- a/components/cronet/android/test/src/org/chromium/net/MockUrlRequestJobFactory.java
+++ b/components/cronet/android/test/src/org/chromium/net/MockUrlRequestJobFactory.java
@@ -6,8 +6,9 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
+import org.jni_zero.JNINamespace;
+import org.jni_zero.NativeMethods;
+
 import org.chromium.net.impl.CronetUrlRequestContext;
 import org.chromium.net.test.FailurePhase;
 
diff --git a/components/cronet/android/test/src/org/chromium/net/NativeTestServer.java b/components/cronet/android/test/src/org/chromium/net/NativeTestServer.java
index fb0e0cb..3da1188 100644
--- a/components/cronet/android/test/src/org/chromium/net/NativeTestServer.java
+++ b/components/cronet/android/test/src/org/chromium/net/NativeTestServer.java
@@ -6,8 +6,9 @@
 
 import android.content.Context;
 
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
+import org.jni_zero.JNINamespace;
+import org.jni_zero.NativeMethods;
+
 import org.chromium.base.test.util.UrlUtils;
 
 /**
diff --git a/components/cronet/android/test/src/org/chromium/net/QuicTestServer.java b/components/cronet/android/test/src/org/chromium/net/QuicTestServer.java
index 4566e9a1..fd6e6fe 100644
--- a/components/cronet/android/test/src/org/chromium/net/QuicTestServer.java
+++ b/components/cronet/android/test/src/org/chromium/net/QuicTestServer.java
@@ -6,9 +6,10 @@
 
 import android.content.Context;
 
+import org.jni_zero.JNINamespace;
+import org.jni_zero.NativeMethods;
+
 import org.chromium.base.ContextUtils;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.test.util.UrlUtils;
 
 /**
diff --git a/components/cronet/android/test/src/org/chromium/net/TestUploadDataStreamHandler.java b/components/cronet/android/test/src/org/chromium/net/TestUploadDataStreamHandler.java
index 0335056..5010d4c 100644
--- a/components/cronet/android/test/src/org/chromium/net/TestUploadDataStreamHandler.java
+++ b/components/cronet/android/test/src/org/chromium/net/TestUploadDataStreamHandler.java
@@ -9,10 +9,11 @@
 import android.content.Context;
 import android.os.ConditionVariable;
 
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeClassQualifiedName;
-import org.chromium.base.annotations.NativeMethods;
+import org.jni_zero.CalledByNative;
+import org.jni_zero.JNINamespace;
+import org.jni_zero.NativeClassQualifiedName;
+import org.jni_zero.NativeMethods;
+
 import org.chromium.net.impl.CronetUrlRequestContext;
 
 /**
diff --git a/components/cronet/tools/jar_src.py b/components/cronet/tools/jar_src.py
index 66fe18b..adb7ddc 100755
--- a/components/cronet/tools/jar_src.py
+++ b/components/cronet/tools/jar_src.py
@@ -22,6 +22,7 @@
 # pylint: enable=wrong-import-position
 
 JAVA_PACKAGE_PREFIX = 'org/chromium/'
+JNI_ZERO_PACKAGE_PREFIX = 'org/jni_zero/'
 
 
 def main():
@@ -69,6 +70,8 @@
   # the Java package name.
   for i, s in enumerate(src_files):
     prefix_position = s.find(JAVA_PACKAGE_PREFIX)
+    if prefix_position == -1:
+      prefix_position = s.find(JNI_ZERO_PACKAGE_PREFIX)
     if prefix_position != -1:
       src_files[i] = s[prefix_position:]
 
diff --git a/components/exo/data_source.h b/components/exo/data_source.h
index 96eb615b..592a714 100644
--- a/components/exo/data_source.h
+++ b/components/exo/data_source.h
@@ -131,7 +131,7 @@
   // This can be a dangling pointer with AutoclickBrowserTest.ClickAndDrag
   // when run in browser_tests_require_lacros.
   const raw_ptr<DataSourceDelegate, DanglingUntriaged> delegate_;
-  base::ObserverList<DataSourceObserver>::Unchecked observers_;
+  base::ObserverList<DataSourceObserver> observers_;
 
   // Mime types which has been offered.
   std::set<std::string> mime_types_;
diff --git a/components/exo/data_source_observer.h b/components/exo/data_source_observer.h
index e8eb90f..cfaf548b 100644
--- a/components/exo/data_source_observer.h
+++ b/components/exo/data_source_observer.h
@@ -5,19 +5,21 @@
 #ifndef COMPONENTS_EXO_DATA_SOURCE_OBSERVER_H_
 #define COMPONENTS_EXO_DATA_SOURCE_OBSERVER_H_
 
+#include "base/observer_list_types.h"
+
 namespace exo {
 
 class DataSource;
 
 // Handles events on data devices in context-specific ways.
-class DataSourceObserver {
+class DataSourceObserver : public base::CheckedObserver {
  public:
   // Called at the top of the data device's destructor, to give observers a
   // chance to remove themselves.
   virtual void OnDataSourceDestroying(DataSource* source) = 0;
 
  protected:
-  virtual ~DataSourceObserver() {}
+  ~DataSourceObserver() override = default;
 };
 
 }  // namespace exo
diff --git a/components/feature_engagement/public/feature_configurations.cc b/components/feature_engagement/public/feature_configurations.cc
index f4f7b13..e73fcfc 100644
--- a/components/feature_engagement/public/feature_configurations.cc
+++ b/components/feature_engagement/public/feature_configurations.cc
@@ -200,6 +200,19 @@
     return config;
   }
 
+  if (kIPHTrackingProtectionOffboardingFeature.name == feature->name) {
+    absl::optional<FeatureConfig> config = FeatureConfig();
+    config->valid = true;
+    config->availability = Comparator(ANY, 0);
+    config->session_rate = Comparator(ANY, 0);
+    config->trigger =
+        EventConfig("iph_tracking_protection_offboarding_triggered",
+                    Comparator(GREATER_THAN_OR_EQUAL, 0), 0, 0);
+    config->used = EventConfig("iph_tracking_protection_offboarding_used",
+                               Comparator(ANY, 0), 0, 0);
+    return config;
+  }
+
   if (kIPHTrackingProtectionOnboardingFeature.name == feature->name) {
     absl::optional<FeatureConfig> config = FeatureConfig();
     config->valid = true;
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc
index 859d7ca..31e6121 100644
--- a/components/feature_engagement/public/feature_constants.cc
+++ b/components/feature_engagement/public/feature_constants.cc
@@ -130,6 +130,9 @@
 BASE_FEATURE(kIPHTabSearchFeature,
              "IPH_TabSearch",
              base::FEATURE_DISABLED_BY_DEFAULT);
+BASE_FEATURE(kIPHTrackingProtectionOffboardingFeature,
+             "IPH_TrackingProtectionOffboarding",
+             base::FEATURE_ENABLED_BY_DEFAULT);
 BASE_FEATURE(kIPHTrackingProtectionOnboardingFeature,
              "IPH_TrackingProtectionOnboarding",
              base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h
index fff75ae..3e890f0e 100644
--- a/components/feature_engagement/public/feature_constants.h
+++ b/components/feature_engagement/public/feature_constants.h
@@ -61,6 +61,7 @@
 BASE_DECLARE_FEATURE(kIPHSideSearchFeature);
 BASE_DECLARE_FEATURE(kIPHSideSearchPageActionLabelFeature);
 BASE_DECLARE_FEATURE(kIPHTabSearchFeature);
+BASE_DECLARE_FEATURE(kIPHTrackingProtectionOffboardingFeature);
 BASE_DECLARE_FEATURE(kIPHTrackingProtectionOnboardingFeature);
 BASE_DECLARE_FEATURE(kIPHWebUITabStripFeature);
 BASE_DECLARE_FEATURE(kIPHDesktopSnoozeFeature);
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc
index ff172e5..a923ec2 100644
--- a/components/feature_engagement/public/feature_list.cc
+++ b/components/feature_engagement/public/feature_list.cc
@@ -180,6 +180,7 @@
     &kIPHSideSearchFeature,
     &kIPHSideSearchPageActionLabelFeature,
     &kIPHTabSearchFeature,
+    &kIPHTrackingProtectionOffboardingFeature,
     &kIPHTrackingProtectionOnboardingFeature,
     &kIPHWebUITabStripFeature,
     &kIPHDesktopPwaInstallFeature,
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h
index b6959602..c8d9da1 100644
--- a/components/feature_engagement/public/feature_list.h
+++ b/components/feature_engagement/public/feature_list.h
@@ -328,6 +328,8 @@
                        "IPH_SideSearchPageActionLabel");
 DEFINE_VARIATION_PARAM(kIPHTabAudioMutingFeature, "IPH_TabAudioMuting");
 DEFINE_VARIATION_PARAM(kIPHTabSearchFeature, "IPH_TabSearch");
+DEFINE_VARIATION_PARAM(kIPHTrackingProtectionOffboardingFeature,
+                       "IPH_TrackingProtectionOffboarding");
 DEFINE_VARIATION_PARAM(kIPHTrackingProtectionOnboardingFeature,
                        "IPH_TrackingProtectionOnboarding");
 DEFINE_VARIATION_PARAM(kIPHWebUITabStripFeature, "IPH_WebUITabStrip");
diff --git a/components/flags_ui/COMMON_METADATA b/components/flags_ui/COMMON_METADATA
new file mode 100644
index 0000000..8325efa
--- /dev/null
+++ b/components/flags_ui/COMMON_METADATA
@@ -0,0 +1,3 @@
+monorail {
+  component: "UI>Browser>WebUI"
+}
diff --git a/components/flags_ui/DIR_METADATA b/components/flags_ui/DIR_METADATA
index 8325efa..75be1aea 100644
--- a/components/flags_ui/DIR_METADATA
+++ b/components/flags_ui/DIR_METADATA
@@ -1,3 +1 @@
-monorail {
-  component: "UI>Browser>WebUI"
-}
+mixins: "//components/flags_ui/COMMON_METADATA"
diff --git a/components/flags_ui/resources/BUILD.gn b/components/flags_ui/resources/BUILD.gn
index 6e678685f..280f2395 100644
--- a/components/flags_ui/resources/BUILD.gn
+++ b/components/flags_ui/resources/BUILD.gn
@@ -17,6 +17,7 @@
 
   non_web_component_files = [ "flags_browser_proxy.ts" ]
 
+  ts_composite = true
   ts_definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ]
   ts_deps = [ "//ui/webui/resources/js:build_ts" ]
 
diff --git a/components/flags_ui/resources/app.html b/components/flags_ui/resources/app.html
index eac33f5..27dccbe 100644
--- a/components/flags_ui/resources/app.html
+++ b/components/flags_ui/resources/app.html
@@ -565,7 +565,7 @@
       </div>
 </if>
     </div>
-    <div id="needs-restart" jsvalues="class:needsRestart ? 'show' : ''">
+    <div id="needs-restart">
       <div class="flex-container">
         <div class="flex restart-notice">$i18n{flagsRestartNotice}</div>
         <div class="flex">
diff --git a/components/flags_ui/resources/app.ts b/components/flags_ui/resources/app.ts
index 167ebd42..521e79e 100644
--- a/components/flags_ui/resources/app.ts
+++ b/components/flags_ui/resources/app.ts
@@ -25,19 +25,18 @@
   panelEl: HTMLElement;
 }
 
-// Delay in ms following a keypress, before a search is made.
-const SEARCH_DEBOUNCE_TIME_MS: number = 150;
 
 /**
  * Handles in page searching. Matches against the experiment flag name.
  */
-class FlagSearch {
+export class FlagSearch {
   private flagsAppElement: FlagsAppElement;
   private initialized: boolean = false;
   private noMatchMsg: NodeListOf<HTMLElement>;
   private searchIntervalId: number|null = null;
   private searchBox: HTMLInputElement;
-
+  // Delay in ms following a keypress, before a search is made.
+  private searchDebounceDelayMs: number = 150;
 
   constructor(el: FlagsAppElement) {
     this.flagsAppElement = el;
@@ -111,7 +110,7 @@
   /**
    * Performs a search against the experiment title, description, permalink.
    */
-  private doSearch() {
+  async doSearch() {
     const searchTerm = this.searchBox.value.trim().toLowerCase();
 
     if (searchTerm || searchTerm === '') {
@@ -136,16 +135,21 @@
           'hidden',
           this.highlightAllMatches(unavailableExperiments, searchTerm) > 0);
       // </if>
-      this.announceSearchResults();
+      await this.announceSearchResults();
+      this.flagsAppElement.dispatchEvent(
+          new Event('search-finished-for-testing', {
+            bubbles: true,
+            composed: true,
+          }));
     }
 
     this.searchIntervalId = null;
   }
 
-  private announceSearchResults() {
+  private announceSearchResults(): Promise<void> {
     const searchTerm = this.searchBox.value.trim().toLowerCase();
     if (!searchTerm) {
-      return;
+      return Promise.resolve();
     }
 
     const selectedTab = this.flagsAppElement.tabs.find(
@@ -154,24 +158,29 @@
     const queryString = `#${selectedTabId} flags-experiment:not(.hidden)`;
     const total = this.flagsAppElement.$all(queryString).length;
     if (total) {
-      this.flagsAppElement.announceStatus(
+      return this.flagsAppElement.announceStatus(
           total === 1 ?
               loadTimeData.getStringF('searchResultsSingular', searchTerm) :
               loadTimeData.getStringF(
                   'searchResultsPlural', total, searchTerm));
     }
+    return Promise.resolve();
   }
 
   /**
    * Debounces the search to improve performance and prevent too many searches
    * from being initiated.
    */
-  private debounceSearch() {
+  debounceSearch() {
     if (this.searchIntervalId) {
       clearTimeout(this.searchIntervalId);
     }
     this.searchIntervalId =
-        setTimeout(this.doSearch.bind(this), SEARCH_DEBOUNCE_TIME_MS);
+        setTimeout(this.doSearch.bind(this), this.searchDebounceDelayMs);
+  }
+
+  setSearchDebounceDelayMsForTesting(delay: number) {
+    this.searchDebounceDelayMs = delay;
   }
 }
 
@@ -184,6 +193,7 @@
     return getTemplate();
   }
 
+  private announceStatusDelayMs: number = 100;
   private featuresResolver: PromiseResolver<void> = new PromiseResolver();
   private flagSearch: FlagSearch = new FlagSearch(this);
   private lastChanged: HTMLElement|null = null;
@@ -214,26 +224,35 @@
     this.setupRestartButton();
     // </if>
     FocusOutlineManager.forDocument(document);
-
-    // Exported on |window| since this is needed by tests.
-    Object.assign(
-        window,
-        {experimentalFeaturesReadyForTest: this.featuresResolver.promise});
-
     // Update the highlighted flag when the hash changes.
     window.addEventListener('hashchange', () => this.highlightReferencedFlag);
   }
 
+  setAnnounceStatusDelayMsForTesting(delay: number) {
+    this.announceStatusDelayMs = delay;
+  }
+
+  setSearchDebounceDelayMsForTesting(delay: number) {
+    this.flagSearch.setSearchDebounceDelayMsForTesting(delay);
+  }
+
+  experimentalFeaturesReadyForTesting() {
+    return this.featuresResolver.promise;
+  }
+
   /**
    * Cause a text string to be announced by screen readers
    * @param text The text that should be announced.
    */
-  announceStatus(text: string) {
-    this.getRequiredElement('#screen-reader-status-message').textContent = '';
-    setTimeout(() => {
-      this.getRequiredElement('#screen-reader-status-message').textContent =
-          text;
-    }, 100);
+  announceStatus(text: string): Promise<void> {
+    return new Promise((resolve) => {
+      this.getRequiredElement('#screen-reader-status-message').textContent = '';
+      setTimeout(() => {
+        this.getRequiredElement('#screen-reader-status-message').textContent =
+            text;
+        resolve();
+      }, this.announceStatusDelayMs);
+    });
   }
 
   /**
diff --git a/components/media_router/common/providers/cast/certificate/cast_cert_validator.cc b/components/media_router/common/providers/cast/certificate/cast_cert_validator.cc
index df93378..7b343534 100644
--- a/components/media_router/common/providers/cast/certificate/cast_cert_validator.cc
+++ b/components/media_router/common/providers/cast/certificate/cast_cert_validator.cc
@@ -428,8 +428,9 @@
   }
 
   // Check for revocation.
-  if (crl && !crl->CheckRevocation(result.GetBestValidPath()->certs, time))
+  if (crl && !crl->CheckRevocation(result.GetBestValidPath()->certs, time)) {
     return CastCertError::ERR_CERTS_REVOKED;
+  }
 
   return CastCertError::OK;
 }
diff --git a/components/media_router/common/providers/cast/certificate/cast_crl.cc b/components/media_router/common/providers/cast/certificate/cast_crl.cc
index 68afdc78..deab5b4 100644
--- a/components/media_router/common/providers/cast/certificate/cast_crl.cc
+++ b/components/media_router/common/providers/cast/certificate/cast_crl.cc
@@ -13,6 +13,7 @@
 #include "base/containers/span.h"
 #include "base/logging.h"
 #include "base/memory/singleton.h"
+#include "base/time/time.h"
 #include "components/media_router/common/providers/cast/certificate/cast_fallback_crl.h"
 #include "crypto/sha2.h"
 #include "net/cert/pki/cert_errors.h"
@@ -117,11 +118,14 @@
 // at |time|. The validity period of the CRL is adjusted to be the earliest
 // of the issuer certificate chain's expiration and the CRL's expiration and
 // the result is stored in |overall_not_after|.
+// |is_fallback_crl| states whether a fallback CRL is used. When true,
+// ignore the validity range of the fallback CRL's issuer certificate.
 bool VerifyCRL(const Crl& crl,
                const TbsCrl& tbs_crl,
                const base::Time& time,
                net::TrustStore* trust_store,
-               net::der::GeneralizedTime* overall_not_after) {
+               net::der::GeneralizedTime* overall_not_after,
+               bool is_fallback_crl) {
   if (!crl.has_signature() || !crl.has_signer_cert()) {
     VLOG(2) << "CRL - Missing fields";
     return false;
@@ -167,9 +171,17 @@
   }
 
   // Verify the issuer certificate.
-  net::der::GeneralizedTime verification_time;
-  if (!net::EncodeTimeAsGeneralizedTime(time, &verification_time)) {
-    VLOG(2) << "CRL - Unable to parse verification time.";
+  net::der::GeneralizedTime issuer_verification_time;
+  base::Time time_issuer_check = time;
+  if (is_fallback_crl) {
+    time_issuer_check = base::Time::FromTimeT(kCastFallbackCRLTimestamp);
+    VLOG(2) << "CRL - Issuer certifcate's verification time overridden for the "
+               "fallback CRL.";
+  }
+  if (!net::EncodeTimeAsGeneralizedTime(time_issuer_check,
+                                        &issuer_verification_time)) {
+    VLOG(2) << "CRL - Unable to parse verification time for issuer certificate "
+               "check.";
     return false;
   }
 
@@ -180,9 +192,9 @@
 
   // Verify the trust of the CRL authority.
   net::CertPathBuilder path_builder(
-      parsed_cert, trust_store, &path_builder_delegate, verification_time,
-      net::KeyPurpose::ANY_EKU, net::InitialExplicitPolicy::kFalse,
-      {net::der::Input(net::kAnyPolicyOid)},
+      parsed_cert, trust_store, &path_builder_delegate,
+      issuer_verification_time, net::KeyPurpose::ANY_EKU,
+      net::InitialExplicitPolicy::kFalse, {net::der::Input(net::kAnyPolicyOid)},
       net::InitialPolicyMappingInhibit::kFalse,
       net::InitialAnyPolicyInhibit::kFalse);
   net::CertPathBuilder::Result result = path_builder.Run();
@@ -197,6 +209,12 @@
   // particular KeyUsages. Leaf certificate checks are bypassed.
 
   // Verify the CRL is still valid.
+  net::der::GeneralizedTime crl_verification_time;
+  if (!net::EncodeTimeAsGeneralizedTime(time, &crl_verification_time)) {
+    VLOG(2)
+        << "CRL - Unable to parse verification time for CRL validity check.";
+    return false;
+  }
   net::der::GeneralizedTime not_before;
   if (!ConvertTimeSeconds(tbs_crl.not_before_seconds(), &not_before)) {
     VLOG(2) << "CRL - Unable to parse not_before.";
@@ -207,7 +225,8 @@
     VLOG(2) << "CRL - Unable to parse not_after.";
     return false;
   }
-  if ((verification_time < not_before) || (verification_time > not_after)) {
+  if ((crl_verification_time < not_before) ||
+      (crl_verification_time > not_after)) {
     VLOG(2) << "CRL - Not time-valid.";
 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
     return false;
@@ -227,10 +246,13 @@
   const net::ParsedCertificateList& path_certs =
       result.GetBestValidPath()->certs;
 #endif
-  for (const auto& cert : path_certs) {
-    net::der::GeneralizedTime cert_not_after = cert->tbs().validity_not_after;
-    if (cert_not_after < *overall_not_after)
-      *overall_not_after = cert_not_after;
+  if (!is_fallback_crl) {
+    for (const auto& cert : path_certs) {
+      net::der::GeneralizedTime cert_not_after = cert->tbs().validity_not_after;
+      if (cert_not_after < *overall_not_after) {
+        *overall_not_after = cert_not_after;
+      }
+    }
   }
 
   // Perform sanity check on serial numbers.
@@ -414,7 +436,8 @@
     }
 
     net::der::GeneralizedTime overall_not_after;
-    if (!VerifyCRL(crl, tbs_crl, time, trust_store, &overall_not_after)) {
+    if (!VerifyCRL(crl, tbs_crl, time, trust_store, &overall_not_after,
+                   is_fallback_crl)) {
       LOG(ERROR) << "CRL - Verification failed.";
       return nullptr;
     }
@@ -430,7 +453,6 @@
   std::string fallback_serialized_crl(
       kCastFallbackCRLs, kCastFallbackCRLs + sizeof kCastFallbackCRLs /
                                                  sizeof kCastFallbackCRLs[0]);
-
   return ParseAndVerifyCRLUsingCustomTrustStore(
       fallback_serialized_crl, time, trust_store, true /* is_fallback_crl */);
 }
diff --git a/components/media_router/common/providers/cast/certificate/cast_fallback_crl.h b/components/media_router/common/providers/cast/certificate/cast_fallback_crl.h
index f130e96..fb69f0df 100644
--- a/components/media_router/common/providers/cast/certificate/cast_fallback_crl.h
+++ b/components/media_router/common/providers/cast/certificate/cast_fallback_crl.h
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 // no-include-guard-because-pch-file
+
+#include <time.h>
+
 // fallback CRL:
 const unsigned char kCastFallbackCRLs[] = {
     0x0a, 0xfc, 0x0d, 0x0a, 0xa8, 0x04, 0x08, 0x00, 0x10, 0x90, 0xbe, 0xb5,
@@ -155,3 +158,6 @@
     0x4b, 0x36, 0xcd, 0xc6, 0x14, 0x3a, 0x55, 0xfc, 0xa9, 0x98, 0x01, 0x43,
     0x6c, 0x51, 0x42,
 };
+
+// A valid time for the fallback CRL:
+const time_t kCastFallbackCRLTimestamp = 1692255600;
diff --git a/components/media_router/common/providers/cast/channel/cast_auth_util_unittest.cc b/components/media_router/common/providers/cast/channel/cast_auth_util_unittest.cc
index cd3d8b8..91c24a8 100644
--- a/components/media_router/common/providers/cast/channel/cast_auth_util_unittest.cc
+++ b/components/media_router/common/providers/cast/channel/cast_auth_util_unittest.cc
@@ -169,8 +169,7 @@
   EXPECT_EQ(kFlagsSHA1AndCRLMissing, result.flags);
 }
 
-// TODO(crbug.com/1485349): Re-enable this test
-TEST_F(CastAuthUtilTest, DISABLED_VerifyCrlRequiredWithFallback) {
+TEST_F(CastAuthUtilTest, VerifyCrlRequiredWithFallback) {
   std::string signed_data;
   AuthResponse auth_response = CreateAuthResponse(&signed_data, SHA256);
   base::Time now = base::Time::Now();
@@ -196,8 +195,7 @@
   EXPECT_EQ(kFlagsExpiredFallbackCRL, result.flags);
 }
 
-// TODO(crbug.com/1485349): Re-enable this test
-TEST_F(CastAuthUtilTest, DISABLED_VerifyCrlRequiredWithNotExpiredFallback) {
+TEST_F(CastAuthUtilTest, VerifyCrlRequiredWithNotExpiredFallback) {
   std::string signed_data;
   AuthResponse auth_response = CreateAuthResponse(&signed_data, SHA256);
   base::Time now = base::Time::Now() + base::Seconds(10);
@@ -210,8 +208,7 @@
   EXPECT_EQ(kFlagsAcceptedByFallbackCRL, result.flags);
 }
 
-// TODO(crbug.com/1485349): Re-enable this test
-TEST_F(CastAuthUtilTest, DISABLED_FeatureFlagVerifyCrlRequiredWithFallbackCRL) {
+TEST_F(CastAuthUtilTest, FeatureFlagVerifyCrlRequiredWithFallbackCRL) {
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(
       kEnforceFallbackCRLRevocationChecking);
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageDispatcherUnitTest.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageDispatcherUnitTest.java
index 6bb55e3..984e29bd 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageDispatcherUnitTest.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageDispatcherUnitTest.java
@@ -13,6 +13,7 @@
 import androidx.test.filters.SmallTest;
 
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -22,9 +23,12 @@
 import org.mockito.junit.MockitoRule;
 import org.robolectric.annotation.LooperMode;
 
+import org.chromium.base.FeatureList;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.ui.modelutil.PropertyModel;
 
+import java.util.HashMap;
+
 /** Unit tests for {@link MessageDispatcherImpl}. */
 @SmallTest
 @RunWith(BaseRobolectricTestRunner.class)
@@ -35,6 +39,14 @@
     @Mock private MessageQueueManager mQueueManager;
     @Mock private MessageAnimationCoordinator mAnimationCoordinator;
 
+    @Before
+    public void setUp() {
+        var map = new HashMap<String, Boolean>();
+        map.put(MessageFeatureList.MESSAGES_FOR_ANDROID_FULLY_VISIBLE_CALLBACK, true);
+        map.put(MessageFeatureList.MESSAGES_FOR_ANDROID_STACKING_ANIMATION, false);
+        FeatureList.setTestFeatures(map);
+    }
+
     @Test
     public void testEnqueueWindowScopedMessage() {
         doReturn(mAnimationCoordinator).when(mQueueManager).getAnimationCoordinator();
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessage.java b/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessage.java
index 1b01618..cd8998c 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessage.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessage.java
@@ -42,6 +42,7 @@
     private final Supplier<Integer> mTopOffsetSupplier;
     private final Supplier<Integer> mMaxTranslationSupplier;
     private final SwipeAnimationHandler mSwipeAnimationHandler;
+    private final boolean mIsFullyVisibileCallbackEnabled;
     private boolean mMessageDismissed;
 
     // The timestamp when the message was shown. Used for reproting visible duration.
@@ -71,6 +72,7 @@
         mTopOffsetSupplier = topOffsetSupplier;
         mMaxTranslationSupplier = maxTranslationSupplier;
         mSwipeAnimationHandler = swipeAnimationHandler;
+        mIsFullyVisibileCallbackEnabled = MessageFeatureList.isFullyVisibleCallbackEnabled();
 
         long dismissalDuration =
                 mModel.getAllSetProperties().contains(MessageBannerProperties.DISMISSAL_DURATION)
@@ -118,8 +120,10 @@
 
         if (toIndex == Position.FRONT) {
             mContainer.setA11yDelegate(this);
+            notifyVisibilityChange(true);
+        } else {
+            notifyVisibilityChange(false);
         }
-
         mMessageShownTime = MessagesMetrics.now();
         return mMessageBanner.show(fromIndex, toIndex, () -> MessageDimens.from(mContainer, mView));
     }
@@ -134,6 +138,7 @@
     @Nullable
     @Override
     public Animator hide(int fromIndex, int toIndex, boolean animate) {
+        notifyVisibilityChange(false);
         return mMessageBanner.hide(
                 fromIndex, toIndex, animate, () -> mContainer.removeMessage(mView));
     }
@@ -202,6 +207,18 @@
         mModel.get(MessageBannerProperties.ON_SECONDARY_ACTION).run();
     }
 
+    private void notifyVisibilityChange(boolean fullyVisible) {
+        if (!mIsFullyVisibileCallbackEnabled) return;
+        if (!mModel.containsKey(MessageBannerProperties.ON_FULLY_VISIBLE)) return;
+
+        var callback = mModel.get(MessageBannerProperties.ON_FULLY_VISIBLE);
+        if (callback == null) return;
+        if (fullyVisible == mModel.get(MessageBannerProperties.IS_FULLY_VISIBLE)) return;
+
+        mModel.set(MessageBannerProperties.IS_FULLY_VISIBLE, fullyVisible);
+        callback.onResult(fullyVisible);
+    }
+
     @VisibleForTesting
     long getAutoDismissDuration() {
         return mAutodismissDurationMs.get();
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessageTest.java b/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessageTest.java
index 9041ed51..7335686 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessageTest.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/SingleActionMessageTest.java
@@ -6,6 +6,7 @@
 
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
 import android.app.Activity;
@@ -23,10 +24,12 @@
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
 import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.base.Callback;
 import org.chromium.base.FeatureList;
 import org.chromium.base.test.BaseActivityTestRule;
 import org.chromium.base.test.BaseJUnit4ClassRunner;
@@ -39,7 +42,8 @@
 import org.chromium.ui.test.util.BlankUiTestActivity;
 import org.chromium.ui.test.util.DisableAnimationsTestRule;
 
-import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 
 /** Tests for {@link SingleActionMessage}. */
 @RunWith(BaseJUnit4ClassRunner.class)
@@ -77,6 +81,7 @@
     private CallbackHelper mDismissCallback;
     private SingleActionMessage.DismissCallback mEmptyDismissCallback =
             (model, dismissReason) -> {};
+    private Map<String, Boolean> mFeatureMap = new HashMap<>();
 
     @BeforeClass
     public static void setupSuite() {
@@ -92,9 +97,9 @@
         mDismissCallback = new CallbackHelper();
         mPrimaryActionCallback = new CallbackHelper();
         mSecondaryActionCallback = new CallbackHelper();
-        FeatureList.setTestFeatures(
-                Collections.singletonMap(
-                        MessageFeatureList.MESSAGES_FOR_ANDROID_STACKING_ANIMATION, false));
+        mFeatureMap.put(MessageFeatureList.MESSAGES_FOR_ANDROID_FULLY_VISIBLE_CALLBACK, true);
+        mFeatureMap.put(MessageFeatureList.MESSAGES_FOR_ANDROID_STACKING_ANIMATION, false);
+        FeatureList.setTestFeatures(mFeatureMap);
     }
 
     @Test
@@ -200,9 +205,8 @@
     @Test
     @MediumTest
     public void testAddAndRemoveSingleActionMessage_withStacking() {
-        FeatureList.setTestFeatures(
-                Collections.singletonMap(
-                        MessageFeatureList.MESSAGES_FOR_ANDROID_STACKING_ANIMATION, true));
+        mFeatureMap.put(MessageFeatureList.MESSAGES_FOR_ANDROID_STACKING_ANIMATION, true);
+        FeatureList.setTestFeatures(mFeatureMap);
         MessageContainer container = new MessageContainer(sActivity, null);
         PropertyModel m1 = createBasicSingleActionMessageModel();
         PropertyModel m2 = createBasicSingleActionMessageModel();
@@ -232,9 +236,8 @@
     @Test(expected = IllegalStateException.class)
     @MediumTest
     public void testAddMultipleSingleActionMessage_withStacking() {
-        FeatureList.setTestFeatures(
-                Collections.singletonMap(
-                        MessageFeatureList.MESSAGES_FOR_ANDROID_STACKING_ANIMATION, true));
+        mFeatureMap.put(MessageFeatureList.MESSAGES_FOR_ANDROID_STACKING_ANIMATION, true);
+        FeatureList.setTestFeatures(mFeatureMap);
         MessageContainer container = new MessageContainer(sActivity, null);
         PropertyModel m1 = createBasicSingleActionMessageModel();
         PropertyModel m2 = createBasicSingleActionMessageModel();
@@ -268,6 +271,38 @@
     }
 
     @Test
+    @MediumTest
+    public void testOnFullyVisible() {
+        mFeatureMap.put(MessageFeatureList.MESSAGES_FOR_ANDROID_STACKING_ANIMATION, true);
+        FeatureList.setTestFeatures(mFeatureMap);
+        MessageContainer container = new MessageContainer(sActivity, null);
+        PropertyModel m1 = createBasicSingleActionMessageModel();
+        PropertyModel m2 = createBasicSingleActionMessageModel();
+        Callback<Boolean> callback1 = Mockito.mock(Callback.class);
+        m1.set(MessageBannerProperties.ON_FULLY_VISIBLE, callback1);
+        Callback<Boolean> callback2 = Mockito.mock(Callback.class);
+        m2.set(MessageBannerProperties.ON_FULLY_VISIBLE, callback2);
+
+        final MessageBannerView view1 = createMessageBannerView(container);
+        final MessageBannerView view2 = createMessageBannerView(container);
+        var sam1 =
+                createAndShowSingleActionMessage(
+                        container, m1, view1, Position.INVISIBLE, Position.FRONT);
+        var sam2 =
+                createAndShowSingleActionMessage(
+                        container, m2, view2, Position.FRONT, Position.BACK);
+
+        verify(callback1).onResult(true);
+        verify(callback2, never()).onResult(anyBoolean());
+
+        sam1.hide(Position.FRONT, Position.INVISIBLE, false);
+        verify(callback1).onResult(false);
+
+        sam2.show(Position.BACK, Position.FRONT);
+        verify(callback2).onResult(true);
+    }
+
+    @Test
     @SmallTest
     public void testMessageShouldShowDefault() {
         MessageContainer container = new MessageContainer(sActivity, null);
diff --git a/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java b/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java
index 68cf7a42..3874f3c 100644
--- a/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java
+++ b/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java
@@ -115,10 +115,20 @@
     public static final WritableObjectPropertyKey<BooleanSupplier> ON_STARTED_SHOWING =
             new WritableObjectPropertyKey<>();
 
+    /**
+     * Whether the current message is in the foreground. True if the message is shown AND is in the
+     * foreground when stacked. False if the message is hidden OR is in the background when stacked.
+     */
+    public static final WritableObjectPropertyKey<Callback<Boolean>> ON_FULLY_VISIBLE =
+            new WritableObjectPropertyKey<>();
+
     // Following properties should only be accessed by the message banner component.
     static final WritableFloatPropertyKey TRANSLATION_X = new WritableFloatPropertyKey();
     static final WritableFloatPropertyKey TRANSLATION_Y = new WritableFloatPropertyKey();
 
+    // Internal tracker of whether the message is in the foreground.
+    static final WritableBooleanPropertyKey IS_FULLY_VISIBLE = new WritableBooleanPropertyKey();
+
     static final WritableIntPropertyKey MARGIN_TOP = new WritableIntPropertyKey();
     // ALPHA value of the content, i.e. every thing other than the background and shadow.
     static final WritableFloatPropertyKey CONTENT_ALPHA = new WritableFloatPropertyKey();
@@ -136,14 +146,43 @@
     static final WritableObjectPropertyKey<Runnable> ON_SECONDARY_BUTTON_CLICK =
             new WritableObjectPropertyKey<>();
 
-    public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {MESSAGE_IDENTIFIER,
-            PRIMARY_BUTTON_TEXT, PRIMARY_BUTTON_CLICK_LISTENER, TITLE, TITLE_CONTENT_DESCRIPTION,
-            DESCRIPTION, DESCRIPTION_ICON, RESIZE_DESCRIPTION_ICON, DESCRIPTION_MAX_LINES, ICON,
-            ICON_RESOURCE_ID, ICON_TINT_COLOR, LARGE_ICON, ICON_ROUNDED_CORNER_RADIUS_PX,
-            SECONDARY_ICON, SECONDARY_ICON_RESOURCE_ID, SECONDARY_BUTTON_MENU_TEXT,
-            ON_SECONDARY_BUTTON_CLICK, SECONDARY_ICON_CONTENT_DESCRIPTION, DISMISSAL_DURATION,
-            TRANSLATION_X, TRANSLATION_Y, CONTENT_ALPHA, ON_TOUCH_RUNNABLE, ON_PRIMARY_ACTION,
-            ON_SECONDARY_ACTION, ON_DISMISSED, ON_STARTED_SHOWING, SECONDARY_MENU_BUTTON_DELEGATE,
-            SECONDARY_MENU_MAX_SIZE, PRIMARY_WIDGET_APPEARANCE, ELEVATION, MARGIN_TOP,
-            VISUAL_HEIGHT};
+    public static final PropertyKey[] ALL_KEYS =
+            new PropertyKey[] {
+                MESSAGE_IDENTIFIER,
+                PRIMARY_BUTTON_TEXT,
+                PRIMARY_BUTTON_CLICK_LISTENER,
+                TITLE,
+                TITLE_CONTENT_DESCRIPTION,
+                DESCRIPTION,
+                DESCRIPTION_ICON,
+                RESIZE_DESCRIPTION_ICON,
+                DESCRIPTION_MAX_LINES,
+                ICON,
+                ICON_RESOURCE_ID,
+                ICON_TINT_COLOR,
+                LARGE_ICON,
+                ICON_ROUNDED_CORNER_RADIUS_PX,
+                SECONDARY_ICON,
+                SECONDARY_ICON_RESOURCE_ID,
+                SECONDARY_BUTTON_MENU_TEXT,
+                ON_SECONDARY_BUTTON_CLICK,
+                SECONDARY_ICON_CONTENT_DESCRIPTION,
+                DISMISSAL_DURATION,
+                TRANSLATION_X,
+                TRANSLATION_Y,
+                CONTENT_ALPHA,
+                ON_TOUCH_RUNNABLE,
+                ON_PRIMARY_ACTION,
+                ON_SECONDARY_ACTION,
+                ON_DISMISSED,
+                ON_STARTED_SHOWING,
+                ON_FULLY_VISIBLE,
+                IS_FULLY_VISIBLE,
+                SECONDARY_MENU_BUTTON_DELEGATE,
+                SECONDARY_MENU_MAX_SIZE,
+                PRIMARY_WIDGET_APPEARANCE,
+                ELEVATION,
+                MARGIN_TOP,
+                VISUAL_HEIGHT
+            };
 }
diff --git a/components/messages/android/java/src/org/chromium/components/messages/MessageFeatureList.java b/components/messages/android/java/src/org/chromium/components/messages/MessageFeatureList.java
index 3bdd876..8584035 100644
--- a/components/messages/android/java/src/org/chromium/components/messages/MessageFeatureList.java
+++ b/components/messages/android/java/src/org/chromium/components/messages/MessageFeatureList.java
@@ -13,8 +13,14 @@
 public abstract class MessageFeatureList {
     public static final String MESSAGES_FOR_ANDROID_STACKING_ANIMATION =
             "MessagesForAndroidStackingAnimation";
+    public static final String MESSAGES_FOR_ANDROID_FULLY_VISIBLE_CALLBACK =
+            "MessagesForAndroidFullyVisibleCallback";
 
     public static boolean isStackAnimationEnabled() {
         return MessageFeatureMap.isEnabled(MESSAGES_FOR_ANDROID_STACKING_ANIMATION);
     }
+
+    public static boolean isFullyVisibleCallbackEnabled() {
+        return MessageFeatureMap.isEnabled(MESSAGES_FOR_ANDROID_FULLY_VISIBLE_CALLBACK);
+    }
 }
diff --git a/components/messages/android/messages_feature.cc b/components/messages/android/messages_feature.cc
index d903a9b..93e2d6e8a 100644
--- a/components/messages/android/messages_feature.cc
+++ b/components/messages/android/messages_feature.cc
@@ -16,6 +16,7 @@
 
 const base::Feature* kFeaturesExposedToJava[] = {
     &kMessagesForAndroidStackingAnimation,
+    &kMessagesForAndroidFullyVisibleCallback,
 };
 
 // static
@@ -55,6 +56,10 @@
              "MessagesForAndroidStackingAnimation",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+BASE_FEATURE(kMessagesForAndroidFullyVisibleCallback,
+             "MessagesForAndroidFullyVisibleCallback",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
 bool IsAdsBlockedMessagesUiEnabled() {
   return base::FeatureList::IsEnabled(kMessagesForAndroidInfrastructure) &&
          base::FeatureList::IsEnabled(kMessagesForAndroidAdsBlocked);
@@ -85,6 +90,11 @@
          base::FeatureList::IsEnabled(kMessagesForAndroidStackingAnimation);
 }
 
+bool ISdFullyVisibleCallbackEnabled() {
+  return base::FeatureList::IsEnabled(kMessagesForAndroidInfrastructure) &&
+         base::FeatureList::IsEnabled(kMessagesForAndroidFullyVisibleCallback);
+}
+
 static jlong JNI_MessageFeatureMap_GetNativeMap(JNIEnv* env) {
   return reinterpret_cast<jlong>(GetFeatureMap());
 }
diff --git a/components/messages/android/messages_feature.h b/components/messages/android/messages_feature.h
index 2bba9d9..02f06c1 100644
--- a/components/messages/android/messages_feature.h
+++ b/components/messages/android/messages_feature.h
@@ -38,6 +38,10 @@
 // new Stacking Animation.
 BASE_DECLARE_FEATURE(kMessagesForAndroidStackingAnimation);
 
+// Feature that exposes a listener to notify whether the current message
+// is fully visible.
+BASE_DECLARE_FEATURE(kMessagesForAndroidFullyVisibleCallback);
+
 bool IsAdsBlockedMessagesUiEnabled();
 
 bool IsOfferNotificationMessagesUiEnabled();
diff --git a/components/mirroring/browser/single_client_video_capture_host_unittest.cc b/components/mirroring/browser/single_client_video_capture_host_unittest.cc
index 3838ff5..27fdd98 100644
--- a/components/mirroring/browser/single_client_video_capture_host_unittest.cc
+++ b/components/mirroring/browser/single_client_video_capture_host_unittest.cc
@@ -49,10 +49,12 @@
                                       base::OnceClosure done_cb) override {}
   MOCK_METHOD0(MaybeSuspendDevice, void());
   MOCK_METHOD0(ResumeDevice, void());
-  MOCK_METHOD3(Crop,
-               void(const base::Token&,
-                    uint32_t,
-                    base::OnceCallback<void(media::mojom::CropRequestResult)>));
+  MOCK_METHOD3(
+      Crop,
+      void(
+          const base::Token&,
+          uint32_t,
+          base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>));
   MOCK_METHOD0(RequestRefreshFrame, void());
   MOCK_METHOD1(OnUtilizationReport, void(media::VideoCaptureFeedback));
 };
diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc
index 52b9352..da7e5f9 100644
--- a/components/omnibox/browser/autocomplete_controller.cc
+++ b/components/omnibox/browser/autocomplete_controller.cc
@@ -212,6 +212,11 @@
         subtypes->emplace(omnibox::SUBTYPE_ZERO_PREFIX_LOCAL_FREQUENT_QUERIES);
       }
     } else if (match.provider->type() ==
+               AutocompleteProvider::TYPE_QUERY_TILE) {
+      DCHECK(is_android);
+      // QueryTiles are now shown in zero-prefix context on Android.
+      subtypes->emplace(omnibox::SUBTYPE_ZERO_PREFIX_QUERY_TILE);
+    } else if (match.provider->type() ==
                AutocompleteProvider::TYPE_ON_DEVICE_HEAD) {
       // This subtype indicates a match from an on-device head provider.
       subtypes->emplace(omnibox::SUBTYPE_SUGGEST_2G_LITE);
@@ -1303,7 +1308,8 @@
         subtypes.contains(omnibox::SUBTYPE_ZERO_PREFIX_LOCAL_FREQUENT_URLS) ||
         subtypes.contains(
             omnibox::SUBTYPE_ZERO_PREFIX_LOCAL_FREQUENT_QUERIES) ||
-        subtypes.contains(omnibox::SUBTYPE_ZERO_PREFIX)) {
+        subtypes.contains(omnibox::SUBTYPE_ZERO_PREFIX) ||
+        subtypes.contains(omnibox::SUBTYPE_ZERO_PREFIX_QUERY_TILE)) {
       num_zero_prefix_suggestions_shown++;
     }
 
diff --git a/components/omnibox/browser/autocomplete_scoring_model_service.cc b/components/omnibox/browser/autocomplete_scoring_model_service.cc
index df6b555..6be90ab8 100644
--- a/components/omnibox/browser/autocomplete_scoring_model_service.cc
+++ b/components/omnibox/browser/autocomplete_scoring_model_service.cc
@@ -41,6 +41,11 @@
 
 AutocompleteScoringModelService::~AutocompleteScoringModelService() = default;
 
+void AutocompleteScoringModelService::AddOnModelUpdatedCallback(
+    base::OnceClosure callback) {
+  url_scoring_model_handler_->AddOnModelUpdatedCallback(std::move(callback));
+}
+
 int AutocompleteScoringModelService::GetModelVersion() const {
   auto info = url_scoring_model_handler_->GetModelInfo();
   return info.has_value() ? info->GetVersion() : -1;
diff --git a/components/omnibox/browser/autocomplete_scoring_model_service.h b/components/omnibox/browser/autocomplete_scoring_model_service.h
index 5df48af..469dc52 100644
--- a/components/omnibox/browser/autocomplete_scoring_model_service.h
+++ b/components/omnibox/browser/autocomplete_scoring_model_service.h
@@ -40,6 +40,10 @@
   AutocompleteScoringModelService& operator=(
       const AutocompleteScoringModelService&) = delete;
 
+  // Passthrough to
+  // `AutocompleteScoringModelHandler::AddOnModelUpdatedCallback()`.
+  void AddOnModelUpdatedCallback(base::OnceClosure callback);
+
   // Returns the version from the model info.
   int GetModelVersion() const;
 
diff --git a/components/omnibox/browser/history_scoring_signals_annotator.cc b/components/omnibox/browser/history_scoring_signals_annotator.cc
index 21ab16d..57c0c7c 100644
--- a/components/omnibox/browser/history_scoring_signals_annotator.cc
+++ b/components/omnibox/browser/history_scoring_signals_annotator.cc
@@ -70,9 +70,9 @@
     }
 
     history::URLRow row;
-    // Return if no URL row found.
+    // Skip this match if no URL row found.
     if (url_db->GetRowForURL(match.destination_url, &row) == 0) {
-      return;
+      continue;
     }
 
     // Populate scoring signals.
diff --git a/components/omnibox/browser/history_scoring_signals_annotator_unittest.cc b/components/omnibox/browser/history_scoring_signals_annotator_unittest.cc
index 394500b8..305da05 100644
--- a/components/omnibox/browser/history_scoring_signals_annotator_unittest.cc
+++ b/components/omnibox/browser/history_scoring_signals_annotator_unittest.cc
@@ -85,6 +85,10 @@
 }
 
 void HistoryScoringSignalsAnnotatorTest::CreateAutocompleteResult() {
+  AutocompleteMatch url_match_not_in_db;
+  url_match_not_in_db.destination_url = GURL("http://test1.com/");
+  url_match_not_in_db.type = AutocompleteMatchType::HISTORY_URL;
+
   AutocompleteMatch url_match;
   url_match.destination_url = GURL("http://test.com/");
   url_match.type = AutocompleteMatchType::HISTORY_URL;
@@ -93,7 +97,8 @@
   AutocompleteMatch search_match;
   search_match.type = AutocompleteMatchType::SEARCH_HISTORY;
 
-  std::vector<AutocompleteMatch> matches{url_match, search_match};
+  std::vector<AutocompleteMatch> matches{url_match_not_in_db, url_match,
+                                         search_match};
   result_ = std::make_unique<AutocompleteResult>();
   result_->AppendMatches(matches);
 }
@@ -108,16 +113,26 @@
                           TestSchemeClassifier());
 
   annotator()->AnnotateResult(input, result());
-  EXPECT_EQ(result()->match_at(0)->scoring_signals->typed_count(), 2);
-  EXPECT_EQ(result()->match_at(0)->scoring_signals->visit_count(), 5);
+
+  // First match is not in the History DB, signals cannot be annotated.
+  EXPECT_FALSE(result()->match_at(0)->scoring_signals->has_typed_count());
+
+  // Match is a history URL and available in the history DB, ensure signals are
+  // annotated.
+  EXPECT_TRUE(result()->match_at(1)->scoring_signals.has_value());
+  EXPECT_TRUE(result()->match_at(1)->scoring_signals->has_typed_count());
+  EXPECT_EQ(result()->match_at(1)->scoring_signals->typed_count(), 2);
+  EXPECT_EQ(result()->match_at(1)->scoring_signals->visit_count(), 5);
   EXPECT_TRUE(
-      result()->match_at(0)->scoring_signals->elapsed_time_last_visit_secs() >
+      result()->match_at(1)->scoring_signals->elapsed_time_last_visit_secs() >
       0);
-  EXPECT_EQ(result()->match_at(0)->scoring_signals->total_title_match_length(),
+  EXPECT_EQ(result()->match_at(1)->scoring_signals->total_title_match_length(),
             3);
   EXPECT_EQ(result()
-                ->match_at(0)
+                ->match_at(1)
                 ->scoring_signals->num_input_terms_matched_by_title(),
             2);
-  EXPECT_FALSE(result()->match_at(1)->scoring_signals.has_value());
+
+  // Search results are skipped for annotation.
+  EXPECT_FALSE(result()->match_at(2)->scoring_signals.has_value());
 }
diff --git a/components/payments/content/android/java/src/org/chromium/components/payments/JourneyLogger.java b/components/payments/content/android/java/src/org/chromium/components/payments/JourneyLogger.java
index 3042e0d..b964bbd 100644
--- a/components/payments/content/android/java/src/org/chromium/components/payments/JourneyLogger.java
+++ b/components/payments/content/android/java/src/org/chromium/components/payments/JourneyLogger.java
@@ -180,8 +180,8 @@
     }
 
     /**
-     * Records that the Payment Request was aborted and for what reason. Also starts the logging of
-     * all the journey logger metrics.
+     * Records that the Payment Request was aborted. This counts as a completion, starting the
+     * logging of all the journey metrics.
      *
      * @param reason An int indicating why the payment request was aborted.
      */
diff --git a/components/payments/core/journey_logger.cc b/components/payments/core/journey_logger.cc
index 83e5f7f..e1edcf1 100644
--- a/components/payments/core/journey_logger.cc
+++ b/components/payments/core/journey_logger.cc
@@ -281,11 +281,6 @@
 }
 
 void JourneyLogger::SetAborted(AbortReason reason) {
-  // Always record the first abort reason regardless of whether the
-  // PaymentRequest.show() was triggered or not.
-  base::UmaHistogramEnumeration("PaymentRequest.CheckoutFunnel.Aborted", reason,
-                                ABORT_REASON_MAX);
-
   if (reason == ABORT_REASON_ABORTED_BY_USER ||
       reason == ABORT_REASON_USER_NAVIGATION)
     RecordJourneyStatsHistograms(COMPLETION_STATUS_USER_ABORTED);
diff --git a/components/payments/core/journey_logger.h b/components/payments/core/journey_logger.h
index 62add774..95541d2e 100644
--- a/components/payments/core/journey_logger.h
+++ b/components/payments/core/journey_logger.h
@@ -318,8 +318,8 @@
   // logging of all the journey metrics.
   void SetCompleted();
 
-  // Records that the Payment Request was aborted along with the reason. Also
-  // starts the logging of all the journey metrics.
+  // Records that the Payment Request was aborted. This counts as a completion,
+  // starting the logging of all the journey metrics.
   void SetAborted(AbortReason reason);
 
   // Records that the Payment Request was not shown to the user, along with the
diff --git a/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc b/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc
index 78c707f..be3a62ef 100644
--- a/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc
+++ b/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc
@@ -43,6 +43,7 @@
 #include "base/containers/queue.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "components/services/screen_ai/public/mojom/screen_ai_service.mojom.h"  // nogncheck crbug.com/1125897
+#include "components/services/screen_ai/public/test/fake_screen_ai_annotator.h"
 #include "components/services/screen_ai/screen_ai_ax_tree_serializer.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -236,59 +237,6 @@
   run_loop.Run();
 }
 
-#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
-class FakeScreenAIAnnotator : public screen_ai::mojom::ScreenAIAnnotator {
- public:
-  explicit FakeScreenAIAnnotator(bool create_empty_result)
-      : create_empty_result_(create_empty_result) {}
-  FakeScreenAIAnnotator(const FakeScreenAIAnnotator&) = delete;
-  FakeScreenAIAnnotator& operator=(const FakeScreenAIAnnotator&) = delete;
-  ~FakeScreenAIAnnotator() override = default;
-
-  void PerformOcrAndReturnAXTreeUpdate(
-      const ::SkBitmap& image,
-      PerformOcrAndReturnAXTreeUpdateCallback callback) override {
-    ui::AXTreeUpdate update;
-    if (!create_empty_result_) {
-      update.root_id = next_node_id_;
-      ui::AXNodeData node;
-      node.id = next_node_id_;
-      node.role = ax::mojom::Role::kStaticText;
-      node.SetNameChecked("Testing");
-      update.nodes = {node};
-      --next_node_id_;
-    }
-    std::move(callback).Run(update);
-  }
-
-  void ExtractSemanticLayout(const ::SkBitmap& image,
-                             const ::ui::AXTreeID& parent_tree_id,
-                             ExtractSemanticLayoutCallback callback) override {
-    ui::AXTreeID tree_id = ui::AXTreeID::CreateNewAXTreeID();
-    std::move(callback).Run(tree_id);
-  }
-
-  void PerformOcrAndReturnAnnotation(
-      const ::SkBitmap& image,
-      PerformOcrAndReturnAnnotationCallback callback) override {
-    auto annotation = screen_ai::mojom::VisualAnnotation::New();
-    std::move(callback).Run(std::move(annotation));
-  }
-
-  mojo::PendingRemote<screen_ai::mojom::ScreenAIAnnotator>
-  BindNewPipeAndPassRemote() {
-    return receiver_.BindNewPipeAndPassRemote();
-  }
-
- private:
-  mojo::Receiver<screen_ai::mojom::ScreenAIAnnotator> receiver_{this};
-  const bool create_empty_result_;
-  // A negative ID for ui::AXNodeID needs to start from -2 as using -1 for this
-  // node id is still incorrectly treated as invalid.
-  ui::AXNodeID next_node_id_ = -2;
-};
-#endif  // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
-
 class TestPdfAccessibilityTree : public PdfAccessibilityTree {
  public:
   TestPdfAccessibilityTree(
@@ -314,15 +262,15 @@
 
   void CreateFakeOCRService(bool create_empty_result) {
     CreateOcrService();
-    fake_annotator_ =
-        std::make_unique<FakeScreenAIAnnotator>(create_empty_result);
+    fake_annotator_ = std::make_unique<screen_ai::test::FakeScreenAIAnnotator>(
+        create_empty_result);
     ocr_service_for_testing()->SetScreenAIAnnotatorForTesting(
         fake_annotator_->BindNewPipeAndPassRemote());
   }
 
  private:
   std::vector<std::vector<ui::AXTreeUpdate>> tree_updates_;
-  std::unique_ptr<FakeScreenAIAnnotator> fake_annotator_;
+  std::unique_ptr<screen_ai::test::FakeScreenAIAnnotator> fake_annotator_;
 #endif  // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
 };
 
diff --git a/components/performance_manager/BUILD.gn b/components/performance_manager/BUILD.gn
index 709c554..695e3fab 100644
--- a/components/performance_manager/BUILD.gn
+++ b/components/performance_manager/BUILD.gn
@@ -165,6 +165,7 @@
     "public/render_process_host_id.h",
     "public/render_process_host_proxy.h",
     "public/resource_attribution/attribution_helpers.h",
+    "public/resource_attribution/cpu_measurement_delegate.h",
     "public/resource_attribution/cpu_measurement_monitor.h",
     "public/resource_attribution/frame_context.h",
     "public/resource_attribution/graph_change.h",
diff --git a/components/performance_manager/public/resource_attribution/cpu_measurement_delegate.h b/components/performance_manager/public/resource_attribution/cpu_measurement_delegate.h
new file mode 100644
index 0000000..0a4db04
--- /dev/null
+++ b/components/performance_manager/public/resource_attribution/cpu_measurement_delegate.h
@@ -0,0 +1,39 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_RESOURCE_ATTRIBUTION_CPU_MEASUREMENT_DELEGATE_H_
+#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_RESOURCE_ATTRIBUTION_CPU_MEASUREMENT_DELEGATE_H_
+
+#include <memory>
+
+#include "base/functional/callback_forward.h"
+#include "base/time/time.h"
+
+namespace performance_manager {
+class ProcessNode;
+}
+
+namespace performance_manager::resource_attribution {
+
+// A shim that Resource Attribution queries use to request CPU measurements for
+// a process. A new CPUMeasurementDelegate object will be created for each
+// ProcessNode to be measured. Public so that users of the API can inject a test
+// override by passing a factory callback to SetDelegateFactoryForTesting().
+class CPUMeasurementDelegate {
+ public:
+  using FactoryCallback =
+      base::RepeatingCallback<std::unique_ptr<CPUMeasurementDelegate>(
+          const ProcessNode*)>;
+
+  CPUMeasurementDelegate() = default;
+  virtual ~CPUMeasurementDelegate() = default;
+
+  // Requests CPU usage for the process. This is [[nodiscard]] to match the
+  // semantics of ProcessMetrics::GetCumulativeCPUUsage().
+  [[nodiscard]] virtual base::TimeDelta GetCumulativeCPUUsage() = 0;
+};
+
+}  // namespace performance_manager::resource_attribution
+
+#endif  // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_RESOURCE_ATTRIBUTION_CPU_MEASUREMENT_DELEGATE_H_
diff --git a/components/performance_manager/public/resource_attribution/cpu_measurement_monitor.h b/components/performance_manager/public/resource_attribution/cpu_measurement_monitor.h
index b1a14c5..2aa3228 100644
--- a/components/performance_manager/public/resource_attribution/cpu_measurement_monitor.h
+++ b/components/performance_manager/public/resource_attribution/cpu_measurement_monitor.h
@@ -16,6 +16,7 @@
 #include "components/performance_manager/public/graph/process_node.h"
 #include "components/performance_manager/public/graph/worker_node.h"
 #include "components/performance_manager/public/resource_attribution/attribution_helpers.h"
+#include "components/performance_manager/public/resource_attribution/cpu_measurement_delegate.h"
 #include "components/performance_manager/public/resource_attribution/graph_change.h"
 #include "components/performance_manager/public/resource_attribution/query_results.h"
 #include "components/performance_manager/public/resource_attribution/resource_contexts.h"
@@ -39,24 +40,6 @@
                               public ProcessNode::ObserverDefaultImpl,
                               public WorkerNode::ObserverDefaultImpl {
  public:
-  // A shim to request CPU measurements for a process. A new
-  // CPUMeasurementDelegate object will be created for each ProcessNode to be
-  // measured. Can be overridden for testing by passing a factory callback to
-  // SetCPUMeasurementDelegateFactoryForTesting().
-  class CPUMeasurementDelegate {
-   public:
-    using FactoryCallback =
-        base::RepeatingCallback<std::unique_ptr<CPUMeasurementDelegate>(
-            const ProcessNode*)>;
-
-    CPUMeasurementDelegate() = default;
-    virtual ~CPUMeasurementDelegate() = default;
-
-    // Requests CPU usage for the process. This is [[nodiscard]] to match the
-    // semantics of ProcessMetrics::GetCumulativeCPUUsage().
-    [[nodiscard]] virtual base::TimeDelta GetCumulativeCPUUsage() = 0;
-  };
-
   CPUMeasurementMonitor();
   ~CPUMeasurementMonitor() override;
 
diff --git a/components/performance_manager/resource_attribution/cpu_measurement_monitor.cc b/components/performance_manager/resource_attribution/cpu_measurement_monitor.cc
index e77cb500..20ecd4a 100644
--- a/components/performance_manager/resource_attribution/cpu_measurement_monitor.cc
+++ b/components/performance_manager/resource_attribution/cpu_measurement_monitor.cc
@@ -39,8 +39,7 @@
 
 namespace {
 
-class CPUMeasurementDelegateImpl final
-    : public CPUMeasurementMonitor::CPUMeasurementDelegate {
+class CPUMeasurementDelegateImpl final : public CPUMeasurementDelegate {
  public:
   // Default factory function.
   static std::unique_ptr<CPUMeasurementDelegate> Create(
diff --git a/components/performance_manager/resource_attribution/cpu_measurement_monitor_unittest.cc b/components/performance_manager/resource_attribution/cpu_measurement_monitor_unittest.cc
index 3705395..7d16b4c 100644
--- a/components/performance_manager/resource_attribution/cpu_measurement_monitor_unittest.cc
+++ b/components/performance_manager/resource_attribution/cpu_measurement_monitor_unittest.cc
@@ -19,7 +19,6 @@
 #include "base/process/process.h"
 #include "base/process/process_handle.h"
 #include "base/run_loop.h"
-#include "base/test/bind.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_timeouts.h"
 #include "base/test/test_waitable_event.h"
@@ -30,11 +29,14 @@
 #include "components/performance_manager/graph/worker_node_impl.h"
 #include "components/performance_manager/public/graph/process_node.h"
 #include "components/performance_manager/public/performance_manager.h"
+#include "components/performance_manager/public/resource_attribution/cpu_measurement_delegate.h"
 #include "components/performance_manager/public/resource_attribution/query_results.h"
 #include "components/performance_manager/public/resource_attribution/resource_contexts.h"
 #include "components/performance_manager/test_support/graph_test_harness.h"
 #include "components/performance_manager/test_support/mock_graphs.h"
 #include "components/performance_manager/test_support/performance_manager_test_harness.h"
+#include "components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.h"
+#include "components/performance_manager/test_support/run_in_graph.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/process_type.h"
 #include "content/public/test/mock_render_process_host.h"
@@ -77,78 +79,6 @@
 
 constexpr base::TimeDelta kTimeBetweenMeasurements = base::Minutes(5);
 
-// State of a simulated process for CPU measurements.
-class SimulatedCPUMeasurementDelegate final
-    : public CPUMeasurementMonitor::CPUMeasurementDelegate {
- public:
-  struct CPUUsagePeriod {
-    base::TimeTicks start_time;
-    base::TimeTicks end_time;
-    double cpu_usage;
-  };
-
-  explicit SimulatedCPUMeasurementDelegate(
-      base::OnceClosure unregister_callback)
-      : unregister_callback_(std::move(unregister_callback)) {}
-
-  ~SimulatedCPUMeasurementDelegate() final {
-    std::move(unregister_callback_).Run();
-  }
-
-  // Returns the simulated CPU usage of the process by summing
-  // `cpu_usage_periods`.
-  base::TimeDelta GetCumulativeCPUUsage() final;
-
-  // List of periods of varying CPU usage.
-  std::vector<CPUUsagePeriod> cpu_usage_periods;
-
-  // If not nullopt, GetCumulativeCPUUsage() will ignore `cpu_usage_periods` and
-  // return this value to simulate an error.
-  absl::optional<base::TimeDelta> usage_error;
-
- private:
-  base::OnceClosure unregister_callback_;
-};
-
-base::TimeDelta SimulatedCPUMeasurementDelegate::GetCumulativeCPUUsage() {
-  if (usage_error.has_value()) {
-    return usage_error.value();
-  }
-  base::TimeDelta cumulative_usage;
-  for (const auto& usage_period : cpu_usage_periods) {
-    CHECK(!usage_period.start_time.is_null());
-    // The last interval in the list will have no end time.
-    const base::TimeTicks end_time = usage_period.end_time.is_null()
-                                         ? base::TimeTicks::Now()
-                                         : usage_period.end_time;
-    CHECK(end_time >= usage_period.start_time);
-    cumulative_usage +=
-        (end_time - usage_period.start_time) * usage_period.cpu_usage;
-  }
-  return cumulative_usage;
-}
-
-void RunOnPMSequence(base::OnceClosure closure) {
-  base::RunLoop run_loop;
-  PerformanceManager::CallOnGraph(
-      FROM_HERE, base::BindLambdaForTesting([&run_loop, &closure] {
-        std::move(closure).Run();
-        run_loop.Quit();
-      }));
-  run_loop.Run();
-}
-
-void RunOnPMSequence(base::OnceCallback<void(Graph*)> callback) {
-  base::RunLoop run_loop;
-  PerformanceManager::CallOnGraph(
-      FROM_HERE,
-      base::BindLambdaForTesting([&run_loop, &callback](Graph* graph) {
-        std::move(callback).Run(graph);
-        run_loop.Quit();
-      }));
-  run_loop.Run();
-}
-
 }  // namespace
 
 // A test that creates mock processes to simulate exact CPU usage.
@@ -158,9 +88,8 @@
 
   void SetUp() override {
     Super::SetUp();
-    cpu_monitor_.SetCPUMeasurementDelegateFactoryForTesting(base::BindRepeating(
-        &CPUMeasurementMonitorTest::CPUMeasurementDelegateFactory,
-        base::Unretained(this)));
+    cpu_monitor_.SetCPUMeasurementDelegateFactoryForTesting(
+        delegate_factory_.GetFactoryCallback());
   }
 
   // Creates a renderer process and starts mocking its CPU measurements. By
@@ -183,58 +112,16 @@
   }
 
   void SetProcessCPUUsage(const ProcessNodeImpl* process_node, double usage) {
-    SimulatedCPUMeasurementDelegate::CPUUsagePeriod usage_period{
-        .start_time = base::TimeTicks::Now(),
-        .cpu_usage = usage,
-    };
-    auto& delegate = GetOrCreateCPUMeasurementDelegate(process_node);
-    if (!delegate.cpu_usage_periods.empty()) {
-      delegate.cpu_usage_periods.back().end_time = usage_period.start_time;
-    }
-    delegate.cpu_usage_periods.push_back(std::move(usage_period));
+    delegate_factory_.GetDelegate(process_node).SetCPUUsage(usage);
   }
 
   void SetProcessCPUUsageError(const ProcessNodeImpl* process_node,
-                               absl::optional<base::TimeDelta> usage_error) {
-    GetOrCreateCPUMeasurementDelegate(process_node).usage_error = usage_error;
+                               base::TimeDelta usage_error) {
+    delegate_factory_.GetDelegate(process_node).SetError(usage_error);
   }
 
-  std::unique_ptr<SimulatedCPUMeasurementDelegate>
-  CreateSimulatedCPUMeasurementDelegate(const ProcessNode* process_node) {
-    CHECK(!base::Contains(pending_cpu_delegates_, process_node));
-    CHECK(!base::Contains(simulated_cpu_delegates_, process_node));
-    auto delegate = std::make_unique<SimulatedCPUMeasurementDelegate>(
-        // Clear pointers to this delegate when it's deleted.
-        base::BindLambdaForTesting([this, process_node] {
-          this->simulated_cpu_delegates_.erase(process_node);
-        }));
-    simulated_cpu_delegates_.emplace(process_node, delegate.get());
-    return delegate;
-  }
-
-  std::unique_ptr<CPUMeasurementMonitor::CPUMeasurementDelegate>
-  CPUMeasurementDelegateFactory(const ProcessNode* process_node) {
-    auto it = pending_cpu_delegates_.find(process_node);
-    if (it != pending_cpu_delegates_.end()) {
-      auto delegate = std::move(it->second);
-      pending_cpu_delegates_.erase(it);
-      return delegate;
-    }
-    return CreateSimulatedCPUMeasurementDelegate(process_node);
-  }
-
-  SimulatedCPUMeasurementDelegate& GetOrCreateCPUMeasurementDelegate(
-      const ProcessNodeImpl* process_node) {
-    auto it = simulated_cpu_delegates_.find(process_node);
-    if (it != simulated_cpu_delegates_.end()) {
-      return *(it->second);
-    }
-    CHECK(!base::Contains(pending_cpu_delegates_, process_node));
-    auto new_delegate = CreateSimulatedCPUMeasurementDelegate(process_node);
-    auto* delegate_ptr = new_delegate.get();
-    CHECK_EQ(simulated_cpu_delegates_.at(process_node), delegate_ptr);
-    pending_cpu_delegates_.emplace(process_node, std::move(new_delegate));
-    return *delegate_ptr;
+  void ClearProcessCPUUsageError(const ProcessNodeImpl* process_node) {
+    delegate_factory_.GetDelegate(process_node).ClearError();
   }
 
   // Calls StartMonitoring() on the CPUMeasurementMonitor under test, and
@@ -288,18 +175,14 @@
     return Field("start_time", &CPUTimeResult::start_time, expected_start_time);
   }
 
+  // Factory to return CPUMeasurementDelegates for `cpu_monitor_`. This must be
+  // created before `cpu_monitor_` and deleted afterward to ensure that it
+  // outlives all delegates it creates.
+  SimulatedCPUMeasurementDelegateFactory delegate_factory_;
+
+  // The object under test.
   CPUMeasurementMonitor cpu_monitor_;
 
-  // Map of ProcessNode to CPUMeasurementDelegate that simulates that process.
-  // The delegates are owned by `cpu_monitor_` or `pending_cpu_delegates_`.
-  std::map<const ProcessNode*, SimulatedCPUMeasurementDelegate*>
-      simulated_cpu_delegates_;
-
-  // CPUMeasurementDelegates that have been created but not passed to
-  // `cpu_monitor_` yet.
-  std::map<const ProcessNode*, std::unique_ptr<SimulatedCPUMeasurementDelegate>>
-      pending_cpu_delegates_;
-
   // Cached results from UpdateAndGetCPUMeasurements(). Most tests will validate
   // the difference between the "last" and "current" measurements, which is
   // easier to follow than the full cumulative measurements at any given time.
@@ -1203,10 +1086,10 @@
   EXPECT_FALSE(
       base::Contains(current_measurements_, renderer4->resource_context()));
 
-  SetProcessCPUUsageError(renderer1.get(), absl::nullopt);
-  SetProcessCPUUsageError(renderer2.get(), absl::nullopt);
-  SetProcessCPUUsageError(renderer3.get(), absl::nullopt);
-  SetProcessCPUUsageError(renderer4.get(), absl::nullopt);
+  ClearProcessCPUUsageError(renderer1.get());
+  ClearProcessCPUUsageError(renderer2.get());
+  ClearProcessCPUUsageError(renderer3.get());
+  ClearProcessCPUUsageError(renderer4.get());
 
   task_env().FastForwardBy(kTimeBetweenMeasurements);
   UpdateAndGetCPUMeasurements();
@@ -1239,14 +1122,14 @@
 
   void SetUp() override {
     Super::SetUp();
-    RunOnPMSequence(base::BindLambdaForTesting([&](Graph* graph) {
+    RunInGraph([&](Graph* graph) {
       cpu_monitor_ = std::make_unique<CPUMeasurementMonitor>();
       cpu_monitor_->StartMonitoring(graph);
-    }));
+    });
   }
 
   void TearDown() override {
-    RunOnPMSequence(base::BindLambdaForTesting([&] { cpu_monitor_.reset(); }));
+    RunInGraph([&] { cpu_monitor_.reset(); });
     Super::TearDown();
   }
 
@@ -1272,7 +1155,7 @@
   // but has no pid. (Equivalent to the time between OnProcessNodeAdded and
   // OnProcessLifetimeChange.)
   LetTimePass();
-  RunOnPMSequence(base::BindLambdaForTesting([&] {
+  RunInGraph([&] {
     ASSERT_TRUE(process_node);
     EXPECT_EQ(process_node->GetProcessId(), base::kNullProcessId);
 
@@ -1281,7 +1164,7 @@
     EXPECT_FALSE(
         base::Contains(measurements, process_node->GetResourceContext()));
     EXPECT_FALSE(base::Contains(measurements, frame_context));
-  }));
+  });
 
   // Assign a real process to the ProcessNode. (Will call
   // OnProcessLifetimeChange and start monitoring.)
@@ -1291,14 +1174,14 @@
         ->SetProcess(base::Process::Current(), base::TimeTicks::Now());
     EXPECT_NE(process_node->GetProcessId(), base::kNullProcessId);
   };
-  RunOnPMSequence(base::BindLambdaForTesting(set_process_on_pm_sequence));
+  RunInGraph(set_process_on_pm_sequence);
 
   // Let some time pass so there's CPU to measure after monitoring starts.
   LetTimePass();
 
   base::TimeDelta cumulative_process_cpu;
   base::TimeDelta cumulative_frame_cpu;
-  RunOnPMSequence(base::BindLambdaForTesting([&] {
+  RunInGraph([&] {
     ASSERT_TRUE(process_node);
     EXPECT_TRUE(process_node->GetProcess().IsValid());
 
@@ -1314,13 +1197,13 @@
     ASSERT_TRUE(base::Contains(measurements, frame_context));
     cumulative_frame_cpu = measurements.at(frame_context).cumulative_cpu;
     EXPECT_FALSE(cumulative_frame_cpu.is_negative());
-  }));
+  });
 
   // Simulate that the process died.
   process()->SimulateRenderProcessExit(
       base::TERMINATION_STATUS_NORMAL_TERMINATION, 0);
   LetTimePass();
-  RunOnPMSequence(base::BindLambdaForTesting([&] {
+  RunInGraph([&] {
     // Process is no longer running, so can't be measured.
     ASSERT_TRUE(process_node);
     EXPECT_FALSE(process_node->GetProcess().IsValid());
@@ -1343,15 +1226,15 @@
         measurements.at(frame_context).cumulative_cpu;
     EXPECT_GE(new_frame_cpu, cumulative_frame_cpu);
     cumulative_frame_cpu = new_frame_cpu;
-  }));
+  });
 
   // Assign a new process to the same renderer. This should add the CPU usage of
   // the new process to the existing CPU usage.
   EXPECT_TRUE(process()->MayReuseHost());
-  RunOnPMSequence(base::BindLambdaForTesting(set_process_on_pm_sequence));
+  RunInGraph(set_process_on_pm_sequence);
 
   LetTimePass();
-  RunOnPMSequence(base::BindLambdaForTesting([&] {
+  RunInGraph([&] {
     ASSERT_TRUE(process_node);
     EXPECT_TRUE(process_node->GetProcess().IsValid());
 
@@ -1369,7 +1252,7 @@
         measurements.at(frame_context).cumulative_cpu;
     EXPECT_GE(new_frame_cpu, cumulative_frame_cpu);
     cumulative_frame_cpu = new_frame_cpu;
-  }));
+  });
 }
 
 }  // namespace performance_manager::resource_attribution
diff --git a/components/performance_manager/test_support/BUILD.gn b/components/performance_manager/test_support/BUILD.gn
index 2d5fa875..9f2684a3 100644
--- a/components/performance_manager/test_support/BUILD.gn
+++ b/components/performance_manager/test_support/BUILD.gn
@@ -48,6 +48,8 @@
     "mock_graphs.h",
     "performance_manager_test_harness.cc",
     "performance_manager_test_harness.h",
+    "resource_attribution/simulated_cpu_measurement_delegate.cc",
+    "resource_attribution/simulated_cpu_measurement_delegate.h",
     "test_worker_node_factory.cc",
     "test_worker_node_factory.h",
   ]
diff --git a/components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.cc b/components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.cc
new file mode 100644
index 0000000..5aba9b0
--- /dev/null
+++ b/components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.cc
@@ -0,0 +1,141 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.h"
+
+#include <utility>
+
+#include "base/check_op.h"
+#include "base/containers/cxx20_erase_map.h"
+#include "base/functional/bind.h"
+#include "base/functional/callback.h"
+#include "components/performance_manager/public/graph/process_node.h"
+
+namespace performance_manager::resource_attribution {
+
+SimulatedCPUMeasurementDelegateFactory::
+    SimulatedCPUMeasurementDelegateFactory() = default;
+
+SimulatedCPUMeasurementDelegateFactory::
+    ~SimulatedCPUMeasurementDelegateFactory() {
+  // Delete all delegates that are still owned by the factory.
+  pending_cpu_delegates_.clear();
+
+  // Now all delegates, owned and un-owned, should have been deleted.
+  CHECK(simulated_cpu_delegates_.empty());
+}
+
+void SimulatedCPUMeasurementDelegateFactory::SetDefaultCPUUsage(
+    double default_cpu_usage) {
+  default_cpu_usage_ = default_cpu_usage;
+}
+
+CPUMeasurementDelegate::FactoryCallback
+SimulatedCPUMeasurementDelegateFactory::GetFactoryCallback() {
+  return base::BindRepeating(
+      &SimulatedCPUMeasurementDelegateFactory::TakeDelegate,
+      weak_factory_.GetSafeRef());
+}
+
+SimulatedCPUMeasurementDelegate&
+SimulatedCPUMeasurementDelegateFactory::GetDelegate(
+    const ProcessNode* process_node) {
+  // If a delegate already exists, use it.
+  auto it = simulated_cpu_delegates_.find(process_node);
+  if (it != simulated_cpu_delegates_.end()) {
+    return *(it->second);
+  }
+  // Create a new delegate, saving it in `pending_cpu_delegates_` until someone
+  // calls TakeDelegate().
+  auto new_delegate = std::make_unique<SimulatedCPUMeasurementDelegate>(
+      PassKey(), weak_factory_.GetSafeRef());
+  if (default_cpu_usage_) {
+    new_delegate->SetCPUUsage(default_cpu_usage_);
+  }
+  auto* delegate_ptr = new_delegate.get();
+  simulated_cpu_delegates_.emplace(process_node, delegate_ptr);
+  const auto [_, inserted] =
+      pending_cpu_delegates_.emplace(process_node, std::move(new_delegate));
+  CHECK(inserted);
+  return *delegate_ptr;
+}
+
+std::unique_ptr<CPUMeasurementDelegate>
+SimulatedCPUMeasurementDelegateFactory::TakeDelegate(
+    const ProcessNode* process_node) {
+  // If there was a delegate already created, use it.
+  auto it = pending_cpu_delegates_.find(process_node);
+  if (it != pending_cpu_delegates_.end()) {
+    auto delegate = std::move(it->second);
+    pending_cpu_delegates_.erase(it);
+    CHECK_EQ(simulated_cpu_delegates_.at(process_node), delegate.get());
+    return delegate;
+  }
+  // Create a new delegate.
+  auto new_delegate = std::make_unique<SimulatedCPUMeasurementDelegate>(
+      PassKey(), weak_factory_.GetSafeRef());
+  if (default_cpu_usage_) {
+    new_delegate->SetCPUUsage(default_cpu_usage_);
+  }
+  auto* delegate_ptr = new_delegate.get();
+  simulated_cpu_delegates_.emplace(process_node, delegate_ptr);
+  return new_delegate;
+}
+
+void SimulatedCPUMeasurementDelegateFactory::OnDelegateDeleted(
+    base::PassKey<SimulatedCPUMeasurementDelegate>,
+    SimulatedCPUMeasurementDelegate* delegate) {
+  const size_t erased = base::EraseIf(
+      simulated_cpu_delegates_,
+      [delegate](const auto& entry) { return delegate == entry.second; });
+  CHECK_EQ(erased, 1U);
+}
+
+SimulatedCPUMeasurementDelegate::SimulatedCPUMeasurementDelegate(
+    base::PassKey<SimulatedCPUMeasurementDelegateFactory>,
+    base::SafeRef<SimulatedCPUMeasurementDelegateFactory> factory)
+    : factory_(factory) {}
+
+SimulatedCPUMeasurementDelegate::~SimulatedCPUMeasurementDelegate() {
+  factory_->OnDelegateDeleted(PassKey(), this);
+}
+
+void SimulatedCPUMeasurementDelegate::SetCPUUsage(double usage,
+                                                  base::TimeTicks start_time) {
+  if (!cpu_usage_periods_.empty()) {
+    cpu_usage_periods_.back().end_time = start_time;
+  }
+  cpu_usage_periods_.push_back(CPUUsagePeriod{
+      .start_time = start_time,
+      .cpu_usage = usage,
+  });
+}
+
+void SimulatedCPUMeasurementDelegate::SetError(base::TimeDelta usage_error) {
+  usage_error_ = usage_error;
+}
+
+void SimulatedCPUMeasurementDelegate::ClearError() {
+  usage_error_ = absl::nullopt;
+}
+
+base::TimeDelta SimulatedCPUMeasurementDelegate::GetCumulativeCPUUsage() {
+  if (usage_error_.has_value()) {
+    return usage_error_.value();
+  }
+  base::TimeDelta cumulative_usage;
+  for (const auto& usage_period : cpu_usage_periods_) {
+    CHECK(!usage_period.start_time.is_null());
+    // The last interval in the list will have no end time.
+    const base::TimeTicks end_time = usage_period.end_time.is_null()
+                                         ? base::TimeTicks::Now()
+                                         : usage_period.end_time;
+    CHECK_GE(end_time, usage_period.start_time);
+    cumulative_usage +=
+        (end_time - usage_period.start_time) * usage_period.cpu_usage;
+  }
+  return cumulative_usage;
+}
+
+}  // namespace performance_manager::resource_attribution
diff --git a/components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.h b/components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.h
new file mode 100644
index 0000000..de65ed1
--- /dev/null
+++ b/components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.h
@@ -0,0 +1,141 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PERFORMANCE_MANAGER_TEST_SUPPORT_RESOURCE_ATTRIBUTION_SIMULATED_CPU_MEASUREMENT_DELEGATE_H_
+#define COMPONENTS_PERFORMANCE_MANAGER_TEST_SUPPORT_RESOURCE_ATTRIBUTION_SIMULATED_CPU_MEASUREMENT_DELEGATE_H_
+
+#include "components/performance_manager/public/resource_attribution/cpu_measurement_delegate.h"
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include "base/memory/safe_ref.h"
+#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
+#include "base/types/pass_key.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace performance_manager {
+class ProcessNode;
+}
+
+namespace performance_manager::resource_attribution {
+
+class SimulatedCPUMeasurementDelegate;
+
+// A factory that manages SimulatedCPUMeasurementDelegate instances. Embed an
+// instance of this in a unit test, and pass the result of GetFactoryCallback()
+// to CPUMeasurementDelegate::SetDelegateFactoryForTesting().
+class SimulatedCPUMeasurementDelegateFactory {
+ public:
+  using PassKey = base::PassKey<SimulatedCPUMeasurementDelegateFactory>;
+
+  SimulatedCPUMeasurementDelegateFactory();
+  ~SimulatedCPUMeasurementDelegateFactory();
+
+  SimulatedCPUMeasurementDelegateFactory(
+      const SimulatedCPUMeasurementDelegateFactory&) = delete;
+  SimulatedCPUMeasurementDelegateFactory& operator=(
+      const SimulatedCPUMeasurementDelegateFactory&) = delete;
+
+  // Sets the default CPU usage reported by delegates created by this factory.
+  void SetDefaultCPUUsage(double default_cpu_usage);
+
+  // Returns a callback that can be passed to
+  // CPUMeasurementDelegate::SetDelegateFactoryForTesting to use
+  // SimulatedCPUMeasurementDelegates in tests. The caller must ensure that the
+  // SimulatedCPUMeasurementDelegateFactory outlives all users of the callback,
+  // otherwise it will crash when it's invoked.
+  CPUMeasurementDelegate::FactoryCallback GetFactoryCallback();
+
+  // Returns a delegate for `process_node`. This can be used to set initial
+  // values on delegates before the code under test gets a pointer to them using
+  // the factory callback returned from GetCallback().
+  SimulatedCPUMeasurementDelegate& GetDelegate(const ProcessNode* process_node);
+
+  // Called by `delegate` when it's deleted.
+  void OnDelegateDeleted(base::PassKey<SimulatedCPUMeasurementDelegate>,
+                         SimulatedCPUMeasurementDelegate* delegate);
+
+  // Factory function for SimulatedCPUMeasurementDelegate objects. Passes
+  // ownership of the delegate for `process_node` to the caller, creating a
+  // delegate if none exists yet. Exposed through GetFactoryCallback().
+  std::unique_ptr<CPUMeasurementDelegate> TakeDelegate(
+      const ProcessNode* process_node);
+
+  // The default CPU usage of delegates created by this factory.
+  double default_cpu_usage_ = 0.0;
+
+  // Map of ProcessNode to CPUMeasurementDelegate that simulates that process.
+  // The delegates are owned by `pending_cpu_delegates_` when they're created,
+  // then ownership is passed to the caller of TakeDelegate().
+  std::map<const ProcessNode*, SimulatedCPUMeasurementDelegate*>
+      simulated_cpu_delegates_;
+
+  // CPUMeasurementDelegates that have been created but not passed to the caller
+  // of TakeDelegate() yet.
+  std::map<const ProcessNode*, std::unique_ptr<SimulatedCPUMeasurementDelegate>>
+      pending_cpu_delegates_;
+
+  base::WeakPtrFactory<SimulatedCPUMeasurementDelegateFactory> weak_factory_{
+      this};
+};
+
+// State of a simulated process for CPU measurements.
+class SimulatedCPUMeasurementDelegate final : public CPUMeasurementDelegate {
+ public:
+  using PassKey = base::PassKey<SimulatedCPUMeasurementDelegate>;
+
+  // Only SimulatedCPUMeasurementDelegateFactory can call the constructor.
+  SimulatedCPUMeasurementDelegate(
+      base::PassKey<SimulatedCPUMeasurementDelegateFactory>,
+      base::SafeRef<SimulatedCPUMeasurementDelegateFactory> factory);
+
+  ~SimulatedCPUMeasurementDelegate() final;
+
+  SimulatedCPUMeasurementDelegate(const SimulatedCPUMeasurementDelegate&) =
+      delete;
+  SimulatedCPUMeasurementDelegate& operator=(
+      const SimulatedCPUMeasurementDelegate&) = delete;
+
+  // Sets the CPU usage to `usage`, starting at `start_time` (which must be
+  // later than any `start_time` previously used).
+  void SetCPUUsage(double usage,
+                   base::TimeTicks start_time = base::TimeTicks::Now());
+
+  // Sets the process to have an error that will be reported as `usage_error`.
+  void SetError(base::TimeDelta usage_error);
+
+  // Clears any error that was set with SetCPUUsageError().
+  void ClearError();
+
+  // CPUMeasurementDelegate interface:
+
+  // Returns the simulated CPU usage of the process by summing
+  // `cpu_usage_periods`.
+  base::TimeDelta GetCumulativeCPUUsage() final;
+
+ private:
+  struct CPUUsagePeriod {
+    base::TimeTicks start_time;
+    base::TimeTicks end_time;
+    double cpu_usage;
+  };
+
+  // The factory that created this delegate. The factory's destructor CHECK's
+  // that all delegates it created have already been destroyed.
+  base::SafeRef<SimulatedCPUMeasurementDelegateFactory> factory_;
+
+  // List of periods of varying CPU usage.
+  std::vector<CPUUsagePeriod> cpu_usage_periods_;
+
+  // If not nullopt, GetCumulativeCPUUsage() will ignore `cpu_usage_periods` and
+  // return this value to simulate an error.
+  absl::optional<base::TimeDelta> usage_error_;
+};
+
+}  // namespace performance_manager::resource_attribution
+
+#endif  // COMPONENTS_PERFORMANCE_MANAGER_TEST_SUPPORT_RESOURCE_ATTRIBUTION_SIMULATED_CPU_MEASUREMENT_DELEGATE_H_
diff --git a/components/permissions/BUILD.gn b/components/permissions/BUILD.gn
index 0dcd3d2..c507b6f 100644
--- a/components/permissions/BUILD.gn
+++ b/components/permissions/BUILD.gn
@@ -184,6 +184,7 @@
       "//components/security_state/core:core",
       "//third_party/jni_zero:jni_helpers",
       "//ui/android",
+      "//ui/strings:ui_strings_grit",
     ]
   } else {
     sources += [
diff --git a/components/permissions/android/DEPS b/components/permissions/android/DEPS
index b0d78aa8..6c3c02d 100644
--- a/components/permissions/android/DEPS
+++ b/components/permissions/android/DEPS
@@ -8,4 +8,5 @@
   "+content/public/android",
   "+third_party/jni_zero",
   "+ui/android",
+  "+ui/strings/grit/ui_strings.h",
 ]
diff --git a/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogDelegate.java b/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogDelegate.java
index 60140c34..c771dc45 100644
--- a/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogDelegate.java
+++ b/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogDelegate.java
@@ -35,9 +35,6 @@
     /** Text shown in the dialog. */
     private String mMessageText;
 
-    /** Optional secondary text shown in the dialog. */
-    private String mSecondaryText;
-
     /** Text shown on the primary button, e.g. "Allow". */
     private String mPrimaryButtonText;
 
@@ -63,10 +60,6 @@
         return mMessageText;
     }
 
-    public String getSecondaryText() {
-        return mSecondaryText;
-    }
-
     public String getPrimaryButtonText() {
         return mPrimaryButtonText;
     }
@@ -118,35 +111,47 @@
     /**
      * Called from C++ by |nativeDelegatePtr| to instantiate this class.
      *
-     * @param nativeDelegatePtr     The native counterpart that this object owns.
-     * @param window                   The window to create the dialog for.
-     * @param contentSettingsTypes  The content settings types requested by this dialog.
-     * @param iconId                The id of the icon to display in the dialog.
-     * @param message               The message to display in the dialog.
-     * @param secondaryText         The secondary text to display in the dialog bellow the message.
-     * @param primaryTextButton     The text to display on the primary button.
-     * @param secondaryTextButton   The text to display on the primary button.
+     * @param nativeDelegatePtr The native counterpart that this object owns.
+     * @param window The window to create the dialog for.
+     * @param contentSettingsTypes The content settings types requested by this dialog.
+     * @param iconId The id of the icon to display in the dialog.
+     * @param message The message to display in the dialog.
+     * @param primaryTextButton The text to display on the primary button.
+     * @param secondaryTextButton The text to display on the primary button.
      */
     @CalledByNative
-    private static PermissionDialogDelegate create(long nativeDelegatePtr, WindowAndroid window,
-            int[] contentSettingsTypes, int iconId, String message, String secondaryText,
-            String primaryButtonText, String secondaryButtonText) {
-        return new PermissionDialogDelegate(nativeDelegatePtr, window, contentSettingsTypes, iconId,
-                message, secondaryText, primaryButtonText, secondaryButtonText);
+    private static PermissionDialogDelegate create(
+            long nativeDelegatePtr,
+            WindowAndroid window,
+            int[] contentSettingsTypes,
+            int iconId,
+            String message,
+            String primaryButtonText,
+            String secondaryButtonText) {
+        return new PermissionDialogDelegate(
+                nativeDelegatePtr,
+                window,
+                contentSettingsTypes,
+                iconId,
+                message,
+                primaryButtonText,
+                secondaryButtonText);
     }
 
-    /**
-     * Upon construction, this class takes ownership of the passed in native delegate.
-     */
-    private PermissionDialogDelegate(long nativeDelegatePtr, WindowAndroid window,
-            int[] contentSettingsTypes, int iconId, String message, String secondaryText,
-            String primaryButtonText, String secondaryButtonText) {
+    /** Upon construction, this class takes ownership of the passed in native delegate. */
+    private PermissionDialogDelegate(
+            long nativeDelegatePtr,
+            WindowAndroid window,
+            int[] contentSettingsTypes,
+            int iconId,
+            String message,
+            String primaryButtonText,
+            String secondaryButtonText) {
         mNativeDelegatePtr = nativeDelegatePtr;
         mWindow = window;
         mContentSettingsTypes = contentSettingsTypes;
         mDrawableId = iconId;
         mMessageText = message;
-        mSecondaryText = secondaryText;
         mPrimaryButtonText = primaryButtonText;
         mSecondaryButtonText = secondaryButtonText;
     }
diff --git a/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogModel.java b/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogModel.java
index c31976a9..da710b25 100644
--- a/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogModel.java
+++ b/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogModel.java
@@ -34,13 +34,6 @@
         TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(
                 messageTextView, delegate.getDrawableId(), 0, 0, 0);
 
-        String secondaryText = delegate.getSecondaryText();
-        if (!secondaryText.isEmpty()) {
-            TextView secondaryTextView = customView.findViewById(R.id.secondary);
-            secondaryTextView.setText(secondaryText);
-            secondaryTextView.setVisibility(View.VISIBLE);
-        }
-
         return new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS)
                 .with(ModalDialogProperties.CONTROLLER, controller)
                 .with(ModalDialogProperties.FOCUS_DIALOG, true)
diff --git a/components/permissions/android/permission_prompt/permission_dialog_delegate.cc b/components/permissions/android/permission_prompt/permission_dialog_delegate.cc
index 95938a9..6e849178 100644
--- a/components/permissions/android/permission_prompt/permission_dialog_delegate.cc
+++ b/components/permissions/android/permission_prompt/permission_dialog_delegate.cc
@@ -50,7 +50,6 @@
       PermissionsClient::Get()->MapToJavaDrawableId(
           permission_prompt_->GetIconId()),
       ConvertUTF16ToJavaString(env, permission_prompt_->GetMessageText()),
-      ConvertUTF16ToJavaString(env, permission_prompt_->GetSecondaryText()),
       primaryButtonText, secondaryButtonText));
 }
 
diff --git a/components/permissions/android/permission_prompt/permission_prompt_android.cc b/components/permissions/android/permission_prompt/permission_prompt_android.cc
index 5d49d7a..9d49dee1 100644
--- a/components/permissions/android/permission_prompt/permission_prompt_android.cc
+++ b/components/permissions/android/permission_prompt/permission_prompt_android.cc
@@ -12,6 +12,7 @@
 #include "components/strings/grit/components_strings.h"
 #include "components/url_formatter/elide_url.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/strings/grit/ui_strings.h"
 
 namespace permissions {
 
@@ -110,11 +111,21 @@
     if (requests[0]->request_type() == RequestType::kStorageAccess) {
       if (base::FeatureList::IsEnabled(
               permissions::features::kPermissionStorageAccessAPI)) {
+        auto requesting_origin = url_formatter::FormatUrlForSecurityDisplay(
+            delegate_->GetRequestingOrigin(),
+            url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC);
+        auto embedding_origin = url_formatter::FormatUrlForSecurityDisplay(
+            delegate_->GetEmbeddingOrigin(),
+            url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC);
+
         return l10n_util::GetStringFUTF16(
-            IDS_STORAGE_ACCESS_PERMISSION_TWO_ORIGIN_PROMPT_TITLE,
-            url_formatter::FormatUrlForSecurityDisplay(
-                delegate_->GetRequestingOrigin(),
-                url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC));
+            IDS_CONCAT_TWO_STRINGS_WITH_PERIODS,
+            l10n_util::GetStringFUTF16(
+                IDS_STORAGE_ACCESS_PERMISSION_TWO_ORIGIN_PROMPT_TITLE,
+                requesting_origin),
+            l10n_util::GetStringFUTF16(
+                IDS_STORAGE_ACCESS_PERMISSION_TWO_ORIGIN_EXPLANATION,
+                requesting_origin, embedding_origin));
       }
       return l10n_util::GetStringFUTF16(
           IDS_STORAGE_ACCESS_INFOBAR_TEXT,
@@ -134,24 +145,4 @@
           delegate_->GetRequestingOrigin(),
           url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC));
 }
-
-std::u16string PermissionPromptAndroid::GetSecondaryText() const {
-  const std::vector<PermissionRequest*>& requests = delegate_->Requests();
-  CHECK_GT(requests.size(), 0U);
-
-  if (requests[0]->request_type() == RequestType::kStorageAccess &&
-      base::FeatureList::IsEnabled(
-          permissions::features::kPermissionStorageAccessAPI)) {
-    return l10n_util::GetStringFUTF16(
-        IDS_STORAGE_ACCESS_PERMISSION_TWO_ORIGIN_EXPLANATION,
-        url_formatter::FormatUrlForSecurityDisplay(
-            delegate_->GetRequestingOrigin(),
-            url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC),
-        url_formatter::FormatUrlForSecurityDisplay(
-            delegate_->GetEmbeddingOrigin(),
-            url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC));
-  }
-  return std::u16string();
-}
-
 }  // namespace permissions
diff --git a/components/permissions/android/permission_prompt/permission_prompt_android.h b/components/permissions/android/permission_prompt/permission_prompt_android.h
index 5cfac255..23c4329 100644
--- a/components/permissions/android/permission_prompt/permission_prompt_android.h
+++ b/components/permissions/android/permission_prompt/permission_prompt_android.h
@@ -59,7 +59,6 @@
   ContentSettingsType GetContentSettingType(size_t position) const;
   int GetIconId() const;
   std::u16string GetMessageText() const;
-  std::u16string GetSecondaryText() const;
 
   content::WebContents* web_contents() { return web_contents_; }
 
diff --git a/components/permissions_strings.grdp b/components/permissions_strings.grdp
index baa961c..436608d 100644
--- a/components/permissions_strings.grdp
+++ b/components/permissions_strings.grdp
@@ -133,7 +133,7 @@
 This will otherwise be blocked by your privacy settings. This will allow the content you interacted with to work correctly, but may allow <ph name="EMBEDDED_URL">$1<ex>news.site</ex></ph> to track your activity.
   </message>
   <message name="IDS_STORAGE_ACCESS_PERMISSION_TWO_ORIGIN_EXPLANATION" desc="The body content of a dialog box that's prompting the user for permission. In the description below, “www.myfavoritesite.com” and “Google Docs” are just used as examples. This sentence describes the consequences of granting this permission. When the user agrees, both “www.myfavoritesite.com” and “Google Docs” can know that the user visited www.myfavoritesite.com.A user might visit a site called www.myfavoritesite.com. That site might embed content and services from other sites. Embedded content can include things like text, images, audio, and services (for example, Google Docs). In this example, the dialog box is shown by Google Docs. The permission is to enable a connection between www.myfavoritesite.com and Google Docs and to allow Google Docs to access information that services has previously saved about the user. For example, Google Docs would need this permission to verify the user's identity and display the user's documents as they browse www.myfavoritesite.com.">
-    <ph name="EMBEDDED_URL">$1<ex>google.com</ex></ph> will know that you visited <ph name="TOP_LEVEL_URL">$2<ex>top-level-site.com</ex></ph>.
+    <ph name="EMBEDDED_URL">$1<ex>google.com</ex></ph> will know that you visited <ph name="TOP_LEVEL_URL">$2<ex>top-level-site.com</ex></ph>
   </message>
   <message name="IDS_STORAGE_ACCESS_PERMISSION_TWO_ORIGIN_LINK" desc="The last sentence of a dialog box that's prompting the user for permission. 1) “embedded content” is the name of a setting in Chrome settings.">
     Learn more about embedded content
diff --git a/components/permissions_strings_grdp/IDS_STORAGE_ACCESS_PERMISSION_TWO_ORIGIN_EXPLANATION.png.sha1 b/components/permissions_strings_grdp/IDS_STORAGE_ACCESS_PERMISSION_TWO_ORIGIN_EXPLANATION.png.sha1
index a36de0c..88ccd7b 100644
--- a/components/permissions_strings_grdp/IDS_STORAGE_ACCESS_PERMISSION_TWO_ORIGIN_EXPLANATION.png.sha1
+++ b/components/permissions_strings_grdp/IDS_STORAGE_ACCESS_PERMISSION_TWO_ORIGIN_EXPLANATION.png.sha1
@@ -1 +1 @@
-b525a4467361b679d88fde27915a25297b49b8ca
\ No newline at end of file
+6447485162a36bf6da7e4e6d6ff680f5c200d999
\ No newline at end of file
diff --git a/components/plus_addresses/plus_address_service.cc b/components/plus_addresses/plus_address_service.cc
index b601649..324cfb80 100644
--- a/components/plus_addresses/plus_address_service.cc
+++ b/components/plus_addresses/plus_address_service.cc
@@ -4,8 +4,7 @@
 
 #include "components/plus_addresses/plus_address_service.h"
 
-#include "base/strings/strcat.h"
-#include "base/strings/string_split.h"
+#include "base/scoped_observation.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/plus_addresses/features.h"
 #include "components/plus_addresses/plus_address_client.h"
@@ -13,7 +12,9 @@
 #include "components/plus_addresses/plus_address_types.h"
 #include "components/signin/public/base/consent_level.h"
 #include "components/signin/public/base/persistent_repeating_timer.h"
+#include "components/signin/public/identity_manager/account_info.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
+#include "google_apis/gaia/google_service_auth_error.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 
 namespace plus_addresses {
@@ -48,11 +49,12 @@
     PrefService* pref_service,
     PlusAddressClient plus_address_client)
     : identity_manager_(identity_manager),
-      repeating_timer_(CreateTimer(pref_service)),
+      pref_service_(pref_service),
       plus_address_client_(std::move(plus_address_client)) {
   // Begin PlusAddress periodic actions at construction.
-  if (repeating_timer_) {
-    repeating_timer_->Start();
+  CreateAndStartTimer();
+  if (identity_manager) {
+    identity_manager_observation_.Observe(identity_manager);
   }
 }
 
@@ -139,26 +141,31 @@
          identity_manager_ != nullptr &&
          // Note that having a primary account implies that account's email will
          // be populated.
-         identity_manager_->HasPrimaryAccount(signin::ConsentLevel::kSignin);
+         identity_manager_->HasPrimaryAccount(signin::ConsentLevel::kSignin) &&
+         primary_account_auth_error_.state() ==
+             GoogleServiceAuthError::State::NONE;
 }
 
-std::unique_ptr<signin::PersistentRepeatingTimer>
-PlusAddressService::CreateTimer(PrefService* pref_service) {
-  if (!is_enabled() || !pref_service ||
-      !kSyncWithEnterprisePlusAddressServer.Get()) {
-    return nullptr;
+void PlusAddressService::CreateAndStartTimer() {
+  if (!is_enabled() || !pref_service_ ||
+      !kSyncWithEnterprisePlusAddressServer.Get() || repeating_timer_) {
+    return;
   }
-  return std::make_unique<signin::PersistentRepeatingTimer>(
-      pref_service, prefs::kPlusAddressLastFetchedTime,
+  repeating_timer_ = std::make_unique<signin::PersistentRepeatingTimer>(
+      pref_service_, prefs::kPlusAddressLastFetchedTime,
       /*delay=*/kEnterprisePlusAddressTimerDelay.Get(),
       /*task=*/
       base::BindRepeating(&PlusAddressService::SyncPlusAddressMapping,
                           // base::Unretained(this) is safe here since the timer
                           // that is created has same lifetime as this service.
                           base::Unretained(this)));
+  repeating_timer_->Start();
 }
 
 void PlusAddressService::SyncPlusAddressMapping() {
+  if (!is_enabled()) {
+    return;
+  }
   plus_address_client_.GetAllPlusAddresses(base::BindOnce(
       &PlusAddressService::UpdatePlusAddressMap,
       // base::Unretained is safe here since PlusAddressService owns
@@ -177,4 +184,37 @@
   }
 }
 
+void PlusAddressService::OnPrimaryAccountChanged(
+    const signin::PrimaryAccountChangeEvent& event) {
+  signin::PrimaryAccountChangeEvent::Type type =
+      event.GetEventTypeFor(signin::ConsentLevel::kSignin);
+  if (type == signin::PrimaryAccountChangeEvent::Type::kCleared) {
+    HandleSignout();
+  } else if (type == signin::PrimaryAccountChangeEvent::Type::kSet) {
+    CreateAndStartTimer();
+  }
+}
+
+void PlusAddressService::OnErrorStateOfRefreshTokenUpdatedForAccount(
+    const CoreAccountInfo& account_info,
+    const GoogleServiceAuthError& error) {
+  if (auto primary_account = identity_manager_->GetPrimaryAccountInfo(
+          signin::ConsentLevel::kSignin);
+      primary_account.IsEmpty() ||
+      primary_account.account_id != account_info.account_id) {
+    return;
+  }
+  if (error.state() != GoogleServiceAuthError::NONE) {
+    HandleSignout();
+  }
+  primary_account_auth_error_ = error;
+}
+
+void PlusAddressService::HandleSignout() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  plus_address_by_site_.clear();
+  plus_addresses_.clear();
+  repeating_timer_.reset();
+}
+
 }  // namespace plus_addresses
diff --git a/components/plus_addresses/plus_address_service.h b/components/plus_addresses/plus_address_service.h
index 094a7dbd..96bb6023 100644
--- a/components/plus_addresses/plus_address_service.h
+++ b/components/plus_addresses/plus_address_service.h
@@ -7,10 +7,14 @@
 
 #include <unordered_set>
 
-#include "base/functional/callback_helpers.h"
+#include "base/scoped_observation.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/plus_addresses/plus_address_client.h"
 #include "components/plus_addresses/plus_address_types.h"
+#include "components/signin/public/identity_manager/account_info.h"
+#include "components/signin/public/identity_manager/identity_manager.h"
+#include "components/signin/public/identity_manager/primary_account_change_event.h"
+#include "google_apis/gaia/google_service_auth_error.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
 
@@ -25,7 +29,8 @@
 
 // An experimental class for filling plus addresses (asdf+123@some-domain.com).
 // Not intended for widespread use.
-class PlusAddressService : public KeyedService {
+class PlusAddressService : public KeyedService,
+                           public signin::IdentityManager::Observer {
  public:
   // Used to simplify testing in cases where calls depending on external classes
   // can be mocked out.
@@ -80,17 +85,28 @@
   // TODO (crbug.com/1467623): Make this private when testing improves.
   void SyncPlusAddressMapping();
 
- private:
   bool is_enabled() const;
 
-  // Create a timer to keep `plus_address_by_site_` and `plus_addresses` in sync
-  // with a remote plus address server.
-  std::unique_ptr<signin::PersistentRepeatingTimer> CreateTimer(
-      PrefService* pref_service);
+ private:
+  // Creates and starts a timer to keep `plus_address_by_site_` and
+  // `plus_addresses` in sync with a remote plus address server.
+  //
+  // This has no effect if this service is not enabled, `pref_service_` is null
+  // or `repeating_timer_` has already been created.
+  void CreateAndStartTimer();
 
   // Updates `plus_address_by_site_` and `plus_addresses_` using `map`.
   void UpdatePlusAddressMap(const PlusAddressMap& map);
 
+  // signin::IdentityManager::Observer:
+  void OnPrimaryAccountChanged(
+      const signin::PrimaryAccountChangeEvent& event) override;
+  void OnErrorStateOfRefreshTokenUpdatedForAccount(
+      const CoreAccountInfo& account_info,
+      const GoogleServiceAuthError& error) override;
+
+  void HandleSignout();
+
   // The user's existing set of plus addresses, scoped to sites.
   PlusAddressMap plus_address_by_site_ GUARDED_BY_CONTEXT(sequence_checker_);
 
@@ -103,6 +119,10 @@
   // PlusAddressService and can be null during tests.
   const raw_ptr<signin::IdentityManager> identity_manager_;
 
+  // Stores pointer to a PrefService to create `repeating_timer_` when the user
+  // signs in after PlusAddressService is created.
+  const raw_ptr<PrefService> pref_service_;
+
   // A timer to periodically retrieve all plus addresses from a remote server
   // to keep this service in sync.
   std::unique_ptr<signin::PersistentRepeatingTimer> repeating_timer_;
@@ -110,6 +130,15 @@
   // Handles requests to a remote server that this service uses.
   PlusAddressClient plus_address_client_;
 
+  // Stores last auth error (potentially NONE) to toggle is_enabled() on/off.
+  // Defaults to NONE to enable this service while refresh tokens (and potential
+  // auth errors) are loading.
+  GoogleServiceAuthError primary_account_auth_error_;
+
+  base::ScopedObservation<signin::IdentityManager,
+                          signin::IdentityManager::Observer>
+      identity_manager_observation_{this};
+
   SEQUENCE_CHECKER(sequence_checker_);
 };
 
diff --git a/components/plus_addresses/plus_address_service_unittest.cc b/components/plus_addresses/plus_address_service_unittest.cc
index cf381dc2..8589844 100644
--- a/components/plus_addresses/plus_address_service_unittest.cc
+++ b/components/plus_addresses/plus_address_service_unittest.cc
@@ -190,13 +190,12 @@
       url::Origin::Create(GURL("https://test.example"));
   service.OfferPlusAddressCreation(no_subdomain_origin, future.GetCallback());
 
-  // Check that the future callback is still blocked, and unblock it.
+  // Check that the future callback is blocked and unblock it.
   ASSERT_FALSE(future.IsReady());
   test_url_loader_factory.SimulateResponseForPendingRequest(
       plus_profiles_endpoint,
       MakeCreateResponse("test.example", "plus+remote@plus.plus"));
   ASSERT_TRUE(future.IsReady());
-  std::string plus_address = future.Get();
   EXPECT_EQ(future.Get(), "plus+remote@plus.plus");
 
   // Assert that ensuing calls to the same facet do not make a network request.
@@ -209,6 +208,86 @@
   EXPECT_EQ(second_future.Get(), "plus+remote@plus.plus");
 }
 
+// Doesn't run on ChromeOS since ClearPrimaryAccount() doesn't exist for it.
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
+TEST_F(PlusAddressServiceRequestsTest,
+       PrimaryAccountCleared_TogglesPlusAddressCreationOff) {
+  // Setup state where the PlusAddressService would create a PlusAddress.
+  signin::IdentityTestEnvironment identity_test_env;
+  identity_test_env.MakePrimaryAccountAvailable("plus@plus.plus",
+                                                signin::ConsentLevel::kSignin);
+  PlusAddressClient client(identity_test_env.identity_manager(),
+                           test_shared_loader_factory);
+  client.SetAccessTokenInfoForTesting(eternal_access_token_info);
+  PlusAddressService service(identity_test_env.identity_manager(), nullptr,
+                             std::move(client));
+  const url::Origin test_origin =
+      url::Origin::Create(GURL("https://test.example"));
+
+  // Toggle creation off by removing the primary account.
+  identity_test_env.ClearPrimaryAccount();
+
+  // Verify that Plus Address creation doesn't occur.
+  base::MockOnceCallback<void(const std::string&)> on_created;
+  EXPECT_CALL(on_created, Run).Times(0);
+  service.OfferPlusAddressCreation(test_origin, on_created.Get());
+
+  // Toggle creation back on by signing in again.
+  identity_test_env.MakePrimaryAccountAvailable("plus@plus.plus",
+                                                signin::ConsentLevel::kSignin);
+
+  // Verify that Plus Address creation occurs and makes a network request.
+  base::test::TestFuture<const std::string&> future;
+  service.OfferPlusAddressCreation(test_origin, future.GetCallback());
+  ASSERT_FALSE(future.IsReady());
+  test_url_loader_factory.SimulateResponseForPendingRequest(
+      plus_profiles_endpoint,
+      MakeCreateResponse("test.example", "plus+remote@plus.plus"));
+  ASSERT_TRUE(future.IsReady());
+  EXPECT_EQ(future.Get(), "plus+remote@plus.plus");
+}
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
+
+TEST_F(PlusAddressServiceRequestsTest,
+       PrimaryRefreshTokenError_TogglesPlusAddressCreationOff) {
+  // Setup state where the PlusAddressService would create a PlusAddress.
+  signin::IdentityTestEnvironment identity_test_env;
+  AccountInfo primary_account = identity_test_env.MakePrimaryAccountAvailable(
+      "plus@plus.plus", signin::ConsentLevel::kSignin);
+  PlusAddressClient client(identity_test_env.identity_manager(),
+                           test_shared_loader_factory);
+  client.SetAccessTokenInfoForTesting(eternal_access_token_info);
+  PlusAddressService service(identity_test_env.identity_manager(), nullptr,
+                             std::move(client));
+  const url::Origin test_origin =
+      url::Origin::Create(GURL("https://test.example"));
+
+  // Toggle creation off by triggering an error for the primary refresh token.
+  identity_test_env.UpdatePersistentErrorOfRefreshTokenForAccount(
+      primary_account.account_id,
+      GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
+
+  // Verify that Plus Address creation doesn't occur.
+  base::MockOnceCallback<void(const std::string&)> on_created;
+  EXPECT_CALL(on_created, Run).Times(0);
+  service.OfferPlusAddressCreation(test_origin, on_created.Get());
+
+  // Toggle creation back on by removing the error.
+  identity_test_env.UpdatePersistentErrorOfRefreshTokenForAccount(
+      primary_account.account_id,
+      GoogleServiceAuthError(GoogleServiceAuthError::NONE));
+
+  // Verify that Plus Address creation occurs and makes a network request.
+  base::test::TestFuture<const std::string&> future;
+  service.OfferPlusAddressCreation(test_origin, future.GetCallback());
+  ASSERT_FALSE(future.IsReady());
+  test_url_loader_factory.SimulateResponseForPendingRequest(
+      plus_profiles_endpoint,
+      MakeCreateResponse("test.example", "plus+remote@plus.plus"));
+  ASSERT_TRUE(future.IsReady());
+  EXPECT_EQ(future.Get(), "plus+remote@plus.plus");
+}
+
 // Tests the PlusAddressService ability to make network requests.
 class PlusAddressServicePolling : public PlusAddressServiceRequestsTest {
  public:
@@ -251,7 +330,7 @@
   TestingPrefServiceSimple pref_service_;
 };
 
-// TODO (kaklilu): Make this test simulate timer firing instead of directly
+// TODO: b/305696884 - Make this test simulate timer firing instead of directly
 // calling SyncPlusAddressMapping.
 TEST_F(PlusAddressServicePolling, CallsGetAllPlusAddresses) {
   signin::IdentityTestEnvironment identity_test_env;
@@ -291,6 +370,85 @@
   EXPECT_TRUE(service.IsPlusAddress("plus+bar@plus.plus"));
 }
 
+// Doesn't run on ChromeOS since ClearPrimaryAccount() doesn't exist for it.
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
+TEST_F(PlusAddressServicePolling, PrimaryAccountCleared_TogglesPollingOff) {
+  // Setup state where the PlusAddressService begins polling on creation.
+  signin::IdentityTestEnvironment identity_test_env;
+  identity_test_env.MakePrimaryAccountAvailable("plus1@plus.plus",
+                                                signin::ConsentLevel::kSignin);
+  PlusAddressClient client(identity_test_env.identity_manager(),
+                           test_shared_loader_factory);
+  client.SetAccessTokenInfoForTesting(eternal_access_token_info);
+  PlusAddressService service(identity_test_env.identity_manager(), prefs(),
+                             std::move(client));
+  // Unblock initial poll.
+  test_url_loader_factory.SimulateResponseForPendingRequest(
+      plus_profiles_endpoint, MakeListResponse({}));
+
+  identity_test_env.ClearPrimaryAccount();
+  service.SyncPlusAddressMapping();
+  // The above doesn't block since it doesn't make network requests in this
+  // state.
+
+  // Toggle polling back on by signing into a primary account.
+  identity_test_env.MakePrimaryAccountAvailable("plus2@plus.plus",
+                                                signin::ConsentLevel::kSignin);
+  service.SyncPlusAddressMapping();
+  // TODO: b/305696884 - Remove above call to verify that observing
+  // OnPrimaryAccountChanged will trigger this via CreateAndStartTimer().
+  test_url_loader_factory.SimulateResponseForPendingRequest(
+      plus_profiles_endpoint,
+      MakeListResponse({PlusProfile{.facet = "foo.com",
+                                    .plus_address = "plus+foo@plus.plus"}}));
+  url::Origin foo_origin = url::Origin::Create(GURL("https://foo.com"));
+  ASSERT_TRUE(service.GetPlusAddress(foo_origin).has_value());
+  EXPECT_EQ(service.GetPlusAddress(foo_origin).value(), "plus+foo@plus.plus");
+  EXPECT_TRUE(service.IsPlusAddress("plus+foo@plus.plus"));
+}
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
+
+TEST_F(PlusAddressServicePolling,
+       PrimaryRefreshTokenError_TogglesPlusAddressCreationOff) {
+  // Setup state where the PlusAddressService begins polling on creation.
+  signin::IdentityTestEnvironment identity_test_env;
+  CoreAccountInfo primary_account =
+      identity_test_env.MakePrimaryAccountAvailable(
+          "plus1@plus.plus", signin::ConsentLevel::kSignin);
+  PlusAddressClient client(identity_test_env.identity_manager(),
+                           test_shared_loader_factory);
+  client.SetAccessTokenInfoForTesting(eternal_access_token_info);
+  PlusAddressService service(identity_test_env.identity_manager(), prefs(),
+                             std::move(client));
+  // Unblock initial poll.
+  test_url_loader_factory.SimulateResponseForPendingRequest(
+      plus_profiles_endpoint, MakeListResponse({}));
+
+  // Toggle creation off by triggering an error for the primary refresh token.
+  identity_test_env.UpdatePersistentErrorOfRefreshTokenForAccount(
+      primary_account.account_id,
+      GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
+  service.SyncPlusAddressMapping();
+  // The above doesn't block since it doesn't make network requests in this
+  // state.
+
+  // Toggle creation back on by removing the error.
+  identity_test_env.UpdatePersistentErrorOfRefreshTokenForAccount(
+      primary_account.account_id,
+      GoogleServiceAuthError(GoogleServiceAuthError::NONE));
+  service.SyncPlusAddressMapping();
+  // TODO: b/305696884 - Remove above call to verify that observing
+  // OnPrimaryAccountChanged will trigger this via CreateAndStartTimer().
+  test_url_loader_factory.SimulateResponseForPendingRequest(
+      plus_profiles_endpoint,
+      MakeListResponse({PlusProfile{.facet = "foo.com",
+                                    .plus_address = "plus+foo@plus.plus"}}));
+  url::Origin foo_origin = url::Origin::Create(GURL("https://foo.com"));
+  ASSERT_TRUE(service.GetPlusAddress(foo_origin).has_value());
+  EXPECT_EQ(service.GetPlusAddress(foo_origin).value(), "plus+foo@plus.plus");
+  EXPECT_TRUE(service.IsPlusAddress("plus+foo@plus.plus"));
+}
+
 class PlusAddressServiceDisabledTest : public PlusAddressServiceTest {
  protected:
   void SetUp() override {
@@ -376,4 +534,92 @@
   PlusAddressService service(identity_test_env.identity_manager());
   EXPECT_EQ(service.GetPrimaryEmail(), expected_email);
 }
+
+// Tests that PlusAddresses is "disabled" in the following states:
+// - When a primary account is unset after login.
+// - When a primary account's refresh token has an auth error.
+//
+// If PlusAddressService is "disabled" it should stop offering the feature,
+// clear any local storage, and not issue network requests.
+class PlusAddressServiceSignoutTest : public ::testing::Test {
+ public:
+  PlusAddressServiceSignoutTest() {
+    secondary_account = identity_test_env_.MakeAccountAvailable(
+        "beta@plus.plus", {signin::ConsentLevel::kSignin});
+    primary_account = identity_test_env_.MakePrimaryAccountAvailable(
+        "alpha@plus.plus", signin::ConsentLevel::kSignin);
+  }
+
+  CoreAccountInfo primary_account;
+  AccountInfo secondary_account;
+
+  signin::IdentityTestEnvironment* identity_test_env() {
+    return &identity_test_env_;
+  }
+
+ private:
+  base::test::TaskEnvironment task_environment_;
+  signin::IdentityTestEnvironment identity_test_env_;
+  base::test::ScopedFeatureList scoped_feature_list_{plus_addresses::kFeature};
+};
+
+// Doesn't run on ChromeOS since ClearPrimaryAccount() doesn't exist for it.
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
+TEST_F(PlusAddressServiceSignoutTest, PrimaryAccountCleared_TogglesIsEnabled) {
+  PlusAddressService service(identity_test_env()->identity_manager());
+  ASSERT_TRUE(service.is_enabled());
+
+  // Verify behaviors expected when service is enabled.
+  url::Origin site = url::Origin::Create(GURL("https://foo.com"));
+  service.SavePlusAddress(site, "plus@plus.plus");
+  EXPECT_TRUE(service.SupportsPlusAddresses(site));
+  EXPECT_TRUE(service.GetPlusAddress(site));
+  EXPECT_EQ(service.GetPlusAddress(site).value(), "plus@plus.plus");
+  EXPECT_TRUE(service.IsPlusAddress("plus@plus.plus"));
+
+  identity_test_env()->ClearPrimaryAccount();
+  EXPECT_FALSE(service.is_enabled());
+
+  // Ensure that the local data is cleared on disabling.
+  EXPECT_FALSE(service.SupportsPlusAddresses(site));
+  EXPECT_FALSE(service.IsPlusAddress("plus@plus.plus"));
+}
+#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
+
+TEST_F(PlusAddressServiceSignoutTest,
+       PrimaryRefreshTokenError_TogglesIsEnabled) {
+  PlusAddressService service(identity_test_env()->identity_manager());
+  ASSERT_TRUE(service.is_enabled());
+
+  // Verify behaviors expected when service is enabled.
+  url::Origin site = url::Origin::Create(GURL("https://foo.com"));
+  service.SavePlusAddress(site, "plus@plus.plus");
+  EXPECT_TRUE(service.SupportsPlusAddresses(site));
+  EXPECT_TRUE(service.GetPlusAddress(site));
+  EXPECT_EQ(service.GetPlusAddress(site).value(), "plus@plus.plus");
+  EXPECT_TRUE(service.IsPlusAddress("plus@plus.plus"));
+
+  // Setting to NONE doesn't disable the service.
+  identity_test_env()->UpdatePersistentErrorOfRefreshTokenForAccount(
+      primary_account.account_id,
+      GoogleServiceAuthError(GoogleServiceAuthError::NONE));
+  EXPECT_TRUE(service.is_enabled());
+
+  // The PlusAddressService isn't disabled for secondary account auth errors.
+  identity_test_env()->UpdatePersistentErrorOfRefreshTokenForAccount(
+      secondary_account.account_id,
+      GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
+  EXPECT_TRUE(service.is_enabled());
+
+  // Being in the "sync-paused" state results in this error.
+  identity_test_env()->UpdatePersistentErrorOfRefreshTokenForAccount(
+      primary_account.account_id,
+      GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
+  EXPECT_FALSE(service.is_enabled());
+
+  // Ensure that the local data is cleared on disabling.
+  EXPECT_FALSE(service.SupportsPlusAddresses(site));
+  EXPECT_FALSE(service.IsPlusAddress("plus@plus.plus"));
+}
+
 }  // namespace plus_addresses
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto
index b781191..a1857a2 100644
--- a/components/policy/proto/chrome_device_policy.proto
+++ b/components/policy/proto/chrome_device_policy.proto
@@ -1823,12 +1823,6 @@
   optional bool enabled = 1;
 }
 
-message DeviceFlexHwDataForProductImprovementEnabledProto {
-  // Enable sending hardware data specifically for product improvement on
-  // managed ChromeOS Flex devices.
-  optional bool enabled = 1 [default = true];
-}
-
 // Mirrors ExtendedFkeysModifier from the extended_fkeys_modifier.mojom
 message ExtendedFkeysModifierProto {
   enum ExtendedFkeysModifier {
@@ -2050,6 +2044,4 @@
   optional StringListPolicyProto device_dlc_predownload_list = 154;
   optional BooleanPolicyProto device_ephemeral_network_policies_enabled = 155;
   optional ExtendedFkeysModifierProto extended_fkeys_modifier = 156;
-  optional DeviceFlexHwDataForProductImprovementEnabledProto
-      device_flex_hw_data_for_product_improvement_enabled = 157;
 }
diff --git a/components/policy/resources/templates/device_policy_proto_map.yaml b/components/policy/resources/templates/device_policy_proto_map.yaml
index 41d6c39..24b370d 100644
--- a/components/policy/resources/templates/device_policy_proto_map.yaml
+++ b/components/policy/resources/templates/device_policy_proto_map.yaml
@@ -44,7 +44,6 @@
 DeviceExternalPrintServers: external_print_servers.external_policy
 DeviceExternalPrintServersAllowlist: external_print_servers_allowlist.allowlist
 DeviceFamilyLinkAccountsAllowed: family_link_accounts_allowed.family_link_accounts_allowed
-DeviceFlexHwDataForProductImprovementEnabledProto: device_flex_hw_data_for_product_improvement_enabled.enabled
 DeviceLoginScreenGeolocationAccessLevel: device_login_screen_geolocation_access_level.geolocation_access_level
 DeviceGpoCacheLifetime: device_gpo_cache_lifetime.lifetime_hours
 DeviceGuestModeEnabled: guest_mode_enabled.guest_mode_enabled
diff --git a/components/policy/resources/templates/policies.yaml b/components/policy/resources/templates/policies.yaml
index f53536e..3bf45fc 100644
--- a/components/policy/resources/templates/policies.yaml
+++ b/components/policy/resources/templates/policies.yaml
@@ -1172,7 +1172,6 @@
   1171: ZstdContentEncodingEnabled
   1172: IPv6ReachabilityOverrideEnabled
   1173: UserFeedbackWithLowLevelDebugDataAllowed
-  1174: DeviceFlexHwDataForProductImprovementEnabled
 atomic_groups:
   1: Homepage
   2: RemoteAccess
diff --git a/components/policy/resources/templates/policy_definitions/UserAndDeviceReporting/DeviceFlexHwDataForProductImprovementEnabled.yaml b/components/policy/resources/templates/policy_definitions/UserAndDeviceReporting/DeviceFlexHwDataForProductImprovementEnabled.yaml
deleted file mode 100644
index 94c3925..0000000
--- a/components/policy/resources/templates/policy_definitions/UserAndDeviceReporting/DeviceFlexHwDataForProductImprovementEnabled.yaml
+++ /dev/null
@@ -1,32 +0,0 @@
-owners:
-- tbrandston@google.com
-- chromeos-flex-eng@google.com
-caption: Send hardware data to Google to support improvements to ChromeOS Flex
-desc: |-
-  Allows some services on <ph name="PRODUCT_OS_FLEX_NAME">Google ChromeOS Flex</ph> to send additional hardware data.
-
-  This hardware data is used for overall improvements to <ph name="PRODUCT_OS_FLEX_NAME">Google ChromeOS Flex</ph>.
-  For example, we might analyze the impact of a crash based on CPU,
-  or prioritize a bugfix based on how many devices share a component.
-
-  If the policy is Enabled or left unset, additional hardware details
-  will be sent from <ph name="PRODUCT_OS_FLEX_NAME">Google ChromeOS Flex</ph>
-  devices.
-  If Disabled, only standard hardware data will be sent.
-supported_on:
-- chrome_os:120-
-device_only: true
-features:
-  dynamic_refresh: true
-  per_profile: false
-type: main
-schema:
-  type: boolean
-items:
-- caption: Send additional hardware data on ChromeOS Flex
-  value: true
-- caption: Do not send additional hardware data on ChromeOS Flex
-  value: false
-default: true
-example_value: true
-tags: ['google-sharing']
diff --git a/components/policy/test/data/policy_test_cases.json b/components/policy/test/data/policy_test_cases.json
index d76dd97..5716727 100644
--- a/components/policy/test/data/policy_test_cases.json
+++ b/components/policy/test/data/policy_test_cases.json
@@ -17466,7 +17466,7 @@
           }
         },
         "prefs": {
-          "enterprise_reporting.legachy_tech.urls": {
+          "enterprise_reporting.legacy_tech.urls": {
             "value": [
               "https://www.example.com",
               "www.example.com/path",
@@ -17487,7 +17487,7 @@
           }
         },
         "prefs": {
-          "enterprise_reporting.legachy_tech.urls": {
+          "enterprise_reporting.legacy_tech.urls": {
             "value": []
           }
         }
@@ -25607,8 +25607,5 @@
         }
       }
     ]
-  },
-  "DeviceFlexHwDataForProductImprovementEnabled": {
-    "reason_for_missing_test": "ChromeOS Flex device policy only read by services, not used in Chrome."
   }
 }
diff --git a/components/privacy_sandbox/tracking_protection_onboarding.cc b/components/privacy_sandbox/tracking_protection_onboarding.cc
index 6049869..dd7e865 100644
--- a/components/privacy_sandbox/tracking_protection_onboarding.cc
+++ b/components/privacy_sandbox/tracking_protection_onboarding.cc
@@ -6,6 +6,7 @@
 #include "base/check.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
 #include "base/time/time.h"
@@ -71,6 +72,100 @@
   }
 }
 
+void CreateHistogramOnboardingStartupState(
+    TrackingProtectionOnboarding::OnboardingStartupState state) {
+  base::UmaHistogramEnumeration(
+      "PrivacySandbox.TrackingProtection.OnboardingStartup.State", state);
+}
+
+void CreateTimingHistogramOnboardingStartup(const char* name,
+                                            base::TimeDelta sample) {
+  base::UmaHistogramCustomTimes(name, sample, base::Milliseconds(1),
+                                base::Days(10), 100);
+}
+
+void RecordOnboardedHistogramsOnStartup(PrefService* pref_service) {
+  if (!pref_service->GetBoolean(prefs::kTrackingProtectionOnboardingAcked)) {
+    CreateHistogramOnboardingStartupState(
+        TrackingProtectionOnboarding::OnboardingStartupState::
+            kOnboardedWaitingToAck);
+    auto waiting_to_ack_since =
+        base::Time::Now() -
+        pref_service->GetTime(prefs::kTrackingProtectionOnboardedSince);
+    auto eligible_to_onboarded_duration =
+        pref_service->GetTime(prefs::kTrackingProtectionOnboardedSince) -
+        pref_service->GetTime(prefs::kTrackingProtectionEligibleSince);
+    CreateTimingHistogramOnboardingStartup(
+        "PrivacySandbox.TrackingProtection.OnboardingStartup.WaitingToAckSince",
+        waiting_to_ack_since);
+    CreateTimingHistogramOnboardingStartup(
+        "PrivacySandbox.TrackingProtection.OnboardingStartup."
+        "EligibleToOnboardedDuration",
+        eligible_to_onboarded_duration);
+    return;
+  }
+  auto eligible_to_onboarded_duration =
+      pref_service->GetTime(prefs::kTrackingProtectionOnboardedSince) -
+      pref_service->GetTime(prefs::kTrackingProtectionEligibleSince);
+  CreateTimingHistogramOnboardingStartup(
+      "PrivacySandbox.TrackingProtection.OnboardingStartup."
+      "EligibleToOnboardedDuration",
+      eligible_to_onboarded_duration);
+  auto action = static_cast<TrackingProtectionOnboardingAckAction>(
+      pref_service->GetInteger(prefs::kTrackingProtectionOnboardingAckAction));
+  switch (action) {
+    case tracking_protection::TrackingProtectionOnboardingAckAction::kNotSet:
+      break;
+    case tracking_protection::TrackingProtectionOnboardingAckAction::kGotIt:
+      CreateHistogramOnboardingStartupState(
+          TrackingProtectionOnboarding::OnboardingStartupState::kAckedGotIt);
+      break;
+    case tracking_protection::TrackingProtectionOnboardingAckAction::kSettings:
+      CreateHistogramOnboardingStartupState(
+          TrackingProtectionOnboarding::OnboardingStartupState::kAckedSettings);
+      break;
+    case tracking_protection::TrackingProtectionOnboardingAckAction::kClosed:
+      CreateHistogramOnboardingStartupState(
+          TrackingProtectionOnboarding::OnboardingStartupState::kAckedClosed);
+      break;
+    case tracking_protection::TrackingProtectionOnboardingAckAction::kLearnMore:
+      CreateHistogramOnboardingStartupState(
+          TrackingProtectionOnboarding::OnboardingStartupState::
+              kAckedLearnMore);
+      break;
+    case tracking_protection::TrackingProtectionOnboardingAckAction::kOther:
+      CreateHistogramOnboardingStartupState(
+          TrackingProtectionOnboarding::OnboardingStartupState::kAckedOther);
+      break;
+  }
+}
+
+void RecordHistogramsOnStartup(PrefService* pref_service) {
+  auto status = GetInternalOnboardingStatus(pref_service);
+  switch (status) {
+    case TrackingProtectionOnboardingStatus::kIneligible:
+      CreateHistogramOnboardingStartupState(
+          TrackingProtectionOnboarding::OnboardingStartupState::kIneligible);
+      break;
+    case TrackingProtectionOnboardingStatus::kEligible: {
+      CreateHistogramOnboardingStartupState(
+          TrackingProtectionOnboarding::OnboardingStartupState::
+              kEligibleWaitingToOnboard);
+      auto waiting_to_onboard_since =
+          base::Time::Now() -
+          pref_service->GetTime(prefs::kTrackingProtectionEligibleSince);
+      CreateTimingHistogramOnboardingStartup(
+          "PrivacySandbox.TrackingProtection.OnboardingStartup."
+          "WaitingToOnboardSince",
+          waiting_to_onboard_since);
+      break;
+    }
+    case TrackingProtectionOnboardingStatus::kOnboarded:
+      RecordOnboardedHistogramsOnStartup(pref_service);
+      break;
+  }
+}
+
 }  // namespace
 
 TrackingProtectionOnboarding::TrackingProtectionOnboarding(
@@ -90,7 +185,6 @@
       base::BindRepeating(
           &TrackingProtectionOnboarding::OnOnboardingAckedChanged,
           base::Unretained(this)));
-
   // If we're forcing eligibility, then let' set it now.
   if (base::FeatureList::IsEnabled(
           privacy_sandbox::kTrackingProtectionOnboardingForceEligibility) &&
@@ -98,6 +192,7 @@
           TrackingProtectionOnboardingStatus::kIneligible) {
     MaybeMarkEligible();
   }
+  RecordHistogramsOnStartup(pref_service_);
 }
 
 TrackingProtectionOnboarding::~TrackingProtectionOnboarding() = default;
@@ -196,6 +291,13 @@
       prefs::kTrackingProtectionOnboardingStatus,
       static_cast<int>(
           TrackingProtectionOnboarding::OnboardingStatus::kOnboarded));
+  auto eligible_to_onboarded_duration =
+      pref_service_->GetTime(prefs::kTrackingProtectionOnboardedSince) -
+      pref_service_->GetTime(prefs::kTrackingProtectionEligibleSince);
+  CreateTimingHistogramOnboardingStartup(
+      "PrivacySandbox.TrackingProtection.Onboarding."
+      "EligibleToOnboardedDuration",
+      eligible_to_onboarded_duration);
 }
 
 void TrackingProtectionOnboarding::OnboardingNoticeActionTaken(
@@ -217,6 +319,18 @@
   pref_service_->SetBoolean(prefs::kTrackingProtectionOnboardingAcked, true);
   pref_service_->SetInteger(prefs::kTrackingProtectionOnboardingAckAction,
                             static_cast<int>(ToInternalAckAction(action)));
+  auto onboarding_to_acked_duration =
+      base::Time::Now() -
+      pref_service_->GetTime(prefs::kTrackingProtectionOnboardedSince);
+  auto last_shown_to_acked_duration =
+      base::Time::Now() -
+      pref_service_->GetTime(prefs::kTrackingProtectionNoticeLastShown);
+  CreateTimingHistogramOnboardingStartup(
+      "PrivacySandbox.TrackingProtection.Onboarding.OnboardedToAckedDuration",
+      onboarding_to_acked_duration);
+  CreateTimingHistogramOnboardingStartup(
+      "PrivacySandbox.TrackingProtection.Onboarding.LastShownToAckedDuration",
+      last_shown_to_acked_duration);
 }
 
 bool TrackingProtectionOnboarding::ShouldShowOnboardingNotice() {
diff --git a/components/privacy_sandbox/tracking_protection_onboarding.h b/components/privacy_sandbox/tracking_protection_onboarding.h
index fe01a83..b20c1fd 100644
--- a/components/privacy_sandbox/tracking_protection_onboarding.h
+++ b/components/privacy_sandbox/tracking_protection_onboarding.h
@@ -53,6 +53,30 @@
     kOffboarding
   };
 
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
+  // Enum value to indicate the state of onboarding on startup.
+  enum class OnboardingStartupState {
+    // User was ineligible on startup.
+    kIneligible = 0,
+    // User was eligible on startup but hasn't been onboarded yet on startup.
+    kEligibleWaitingToOnboard = 1,
+    // User was onboarded but has not yet acknowledged the notice on startup.
+    kOnboardedWaitingToAck = 2,
+    // User acknowledged with the GotIt button on startup.
+    kAckedGotIt = 3,
+    // User acknowledged with the Settings button on startup
+    kAckedSettings = 4,
+    // User acknowledged with the closed button on startup.
+    kAckedClosed = 5,
+    // User acknowledged with the learn more button (only on Clank) on startup.
+    kAckedLearnMore = 6,
+    // User acknowledged the notice by dismissing due to other actions on
+    // startup.
+    kAckedOther = 7,
+    kMaxValue = kAckedOther,
+  };
+
   class Observer {
    public:
     // Fired when a profile's tracking protection onboarding state is changed.
diff --git a/components/privacy_sandbox/tracking_protection_onboarding_unittest.cc b/components/privacy_sandbox/tracking_protection_onboarding_unittest.cc
index 2fb923a..0dcf3be 100644
--- a/components/privacy_sandbox/tracking_protection_onboarding_unittest.cc
+++ b/components/privacy_sandbox/tracking_protection_onboarding_unittest.cc
@@ -5,6 +5,7 @@
 #include "components/privacy_sandbox/tracking_protection_onboarding.h"
 #include <memory>
 #include <utility>
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/metrics/user_action_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
@@ -61,6 +62,7 @@
   TestingPrefServiceSimple prefs_;
   std::unique_ptr<TrackingProtectionOnboarding>
       tracking_protection_onboarding_service_;
+  base::HistogramTester histogram_tester_;
 };
 
 TEST_F(TrackingProtectionOnboardingTest,
@@ -527,5 +529,211 @@
             TrackingProtectionOnboarding::OnboardingStatus::kEligible);
 }
 
+class TrackingProtectionOnboardingStartupStateTest
+    : public TrackingProtectionOnboardingTest {
+ protected:
+  base::HistogramTester histogram_tester_;
+};
+
+TEST_F(TrackingProtectionOnboardingStartupStateTest,
+       OnboardingStartupStateIneligible) {
+  // Onboarding startup state starts as ineligible
+  histogram_tester_.ExpectBucketCount(
+      "PrivacySandbox.TrackingProtection.OnboardingStartup.State",
+      TrackingProtectionOnboarding::OnboardingStartupState::kIneligible, 1);
+}
+
+TEST_F(TrackingProtectionOnboardingStartupStateTest,
+       OnboardingStartupStateEligible) {
+  tracking_protection_onboarding_service_->MaybeMarkEligible();
+  tracking_protection_onboarding_service_.reset();
+  tracking_protection_onboarding_service_ =
+      std::make_unique<TrackingProtectionOnboarding>(
+          prefs(), version_info::Channel::UNKNOWN);
+  histogram_tester_.ExpectBucketCount(
+      "PrivacySandbox.TrackingProtection.OnboardingStartup.State",
+      TrackingProtectionOnboarding::OnboardingStartupState::
+          kEligibleWaitingToOnboard,
+      1);
+}
+
+TEST_F(TrackingProtectionOnboardingStartupStateTest,
+       OnboardingStartupStateOnboardingWaitingToAck) {
+  tracking_protection_onboarding_service_->MaybeMarkEligible();
+  tracking_protection_onboarding_service_->OnboardingNoticeShown();
+  tracking_protection_onboarding_service_.reset();
+  tracking_protection_onboarding_service_ =
+      std::make_unique<TrackingProtectionOnboarding>(
+          prefs(), version_info::Channel::UNKNOWN);
+  histogram_tester_.ExpectBucketCount(
+      "PrivacySandbox.TrackingProtection.OnboardingStartup.State",
+      TrackingProtectionOnboarding::OnboardingStartupState::
+          kOnboardedWaitingToAck,
+      1);
+}
+
+class TrackingProtectionOnboardingStartupStateAckedTest
+    : public TrackingProtectionOnboardingTest,
+      public testing::WithParamInterface<
+          std::pair<TrackingProtectionOnboarding::NoticeAction,
+                    TrackingProtectionOnboarding::OnboardingStartupState>> {
+ protected:
+  base::HistogramTester histogram_tester_;
+};
+
+TEST_P(TrackingProtectionOnboardingStartupStateAckedTest,
+       OnboardingStartupStateAckedAction) {
+  tracking_protection_onboarding_service_->MaybeMarkEligible();
+  tracking_protection_onboarding_service_->OnboardingNoticeShown();
+  tracking_protection_onboarding_service_->OnboardingNoticeActionTaken(
+      std::get<0>(GetParam()));
+  tracking_protection_onboarding_service_.reset();
+  tracking_protection_onboarding_service_ =
+      std::make_unique<TrackingProtectionOnboarding>(
+          prefs(), version_info::Channel::UNKNOWN);
+  histogram_tester_.ExpectBucketCount(
+      "PrivacySandbox.TrackingProtection.OnboardingStartup.State",
+      std::get<1>(GetParam()), 1);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    TrackingProtectionOnboardingStartupStateAckedTest,
+    TrackingProtectionOnboardingStartupStateAckedTest,
+    testing::Values(
+        std::pair(
+            TrackingProtectionOnboarding::NoticeAction::kGotIt,
+            TrackingProtectionOnboarding::OnboardingStartupState::kAckedGotIt),
+        std::pair(TrackingProtectionOnboarding::NoticeAction::kSettings,
+                  TrackingProtectionOnboarding::OnboardingStartupState::
+                      kAckedSettings),
+        std::pair(
+            TrackingProtectionOnboarding::NoticeAction::kClosed,
+            TrackingProtectionOnboarding::OnboardingStartupState::kAckedClosed),
+        std::pair(TrackingProtectionOnboarding::NoticeAction::kLearnMore,
+                  TrackingProtectionOnboarding::OnboardingStartupState::
+                      kAckedLearnMore),
+        std::pair(TrackingProtectionOnboarding::NoticeAction::kOther,
+                  TrackingProtectionOnboarding::OnboardingStartupState::
+                      kAckedOther)));
+
+TEST_F(TrackingProtectionOnboardingStartupStateTest,
+       OnboardingStartupStateEligibleWaitingToOnboardSince) {
+  // Setup
+  tracking_protection_onboarding_service_->MaybeMarkEligible();
+  auto delay = base::Seconds(15);
+  task_env_.FastForwardBy(delay);
+
+  // Action
+  tracking_protection_onboarding_service_.reset();
+  tracking_protection_onboarding_service_ =
+      std::make_unique<TrackingProtectionOnboarding>(
+          prefs(), version_info::Channel::UNKNOWN);
+
+  // Verification
+  histogram_tester_.ExpectTimeBucketCount(
+      "PrivacySandbox.TrackingProtection.OnboardingStartup."
+      "WaitingToOnboardSince",
+      delay, 1);
+}
+
+TEST_F(TrackingProtectionOnboardingStartupStateTest,
+       OnboardingStartupStateOnboardedWaitingToAckTimings) {
+  // Setup
+  tracking_protection_onboarding_service_->MaybeMarkEligible();
+  tracking_protection_onboarding_service_->OnboardingNoticeShown();
+  auto delay = base::Seconds(15);
+  task_env_.FastForwardBy(delay);
+
+  // Action
+  tracking_protection_onboarding_service_.reset();
+  tracking_protection_onboarding_service_ =
+      std::make_unique<TrackingProtectionOnboarding>(
+          prefs(), version_info::Channel::UNKNOWN);
+
+  // Verification
+  histogram_tester_.ExpectTimeBucketCount(
+      "PrivacySandbox.TrackingProtection.OnboardingStartup.WaitingToAckSince",
+      delay, 1);
+  auto eligible_to_onboarded_duration =
+      prefs()->GetTime(prefs::kTrackingProtectionOnboardedSince) -
+      prefs()->GetTime(prefs::kTrackingProtectionEligibleSince);
+  histogram_tester_.ExpectTimeBucketCount(
+      "PrivacySandbox.TrackingProtection.OnboardingStartup."
+      "EligibleToOnboardedDuration",
+      eligible_to_onboarded_duration, 1);
+}
+
+TEST_F(TrackingProtectionOnboardingStartupStateTest,
+       OnboardingStartupStateEligibleToOnboardingDuration) {
+  tracking_protection_onboarding_service_->MaybeMarkEligible();
+  tracking_protection_onboarding_service_->OnboardingNoticeShown();
+  tracking_protection_onboarding_service_->OnboardingNoticeActionTaken(
+      TrackingProtectionOnboarding::NoticeAction::kOther);
+  tracking_protection_onboarding_service_.reset();
+  tracking_protection_onboarding_service_ =
+      std::make_unique<TrackingProtectionOnboarding>(
+          prefs(), version_info::Channel::UNKNOWN);
+  auto eligible_to_onboarded_duration =
+      prefs()->GetTime(prefs::kTrackingProtectionOnboardedSince) -
+      prefs()->GetTime(prefs::kTrackingProtectionEligibleSince);
+  histogram_tester_.ExpectTimeBucketCount(
+      "PrivacySandbox.TrackingProtection.OnboardingStartup."
+      "EligibleToOnboardedDuration",
+      eligible_to_onboarded_duration, 1);
+}
+
+TEST_F(TrackingProtectionOnboardingTest,
+       OnboardingEligibleToOnboardingDuration) {
+  tracking_protection_onboarding_service_->MaybeMarkEligible();
+  tracking_protection_onboarding_service_->OnboardingNoticeShown();
+  tracking_protection_onboarding_service_.reset();
+  tracking_protection_onboarding_service_ =
+      std::make_unique<TrackingProtectionOnboarding>(
+          prefs(), version_info::Channel::UNKNOWN);
+
+  auto eligible_to_onboarded_duration =
+      prefs()->GetTime(prefs::kTrackingProtectionOnboardedSince) -
+      prefs()->GetTime(prefs::kTrackingProtectionEligibleSince);
+  histogram_tester_.ExpectTimeBucketCount(
+      "PrivacySandbox.TrackingProtection.Onboarding."
+      "EligibleToOnboardedDuration",
+      eligible_to_onboarded_duration, 1);
+}
+
+TEST_F(TrackingProtectionOnboardingTest, OnboardingOnboardedToAckedDuration) {
+  tracking_protection_onboarding_service_->MaybeMarkEligible();
+  tracking_protection_onboarding_service_->OnboardingNoticeShown();
+  tracking_protection_onboarding_service_->OnboardingNoticeActionTaken(
+      TrackingProtectionOnboarding::NoticeAction::kOther);
+  tracking_protection_onboarding_service_.reset();
+  tracking_protection_onboarding_service_ =
+      std::make_unique<TrackingProtectionOnboarding>(
+          prefs(), version_info::Channel::UNKNOWN);
+
+  auto onboarding_to_acked_duration =
+      base::Time::Now() -
+      prefs()->GetTime(prefs::kTrackingProtectionOnboardedSince);
+  histogram_tester_.ExpectTimeBucketCount(
+      "PrivacySandbox.TrackingProtection.Onboarding.OnboardedToAckedDuration",
+      onboarding_to_acked_duration, 1);
+}
+
+TEST_F(TrackingProtectionOnboardingTest, OnboardingLastShownToAckedDuration) {
+  tracking_protection_onboarding_service_->MaybeMarkEligible();
+  tracking_protection_onboarding_service_->OnboardingNoticeShown();
+  tracking_protection_onboarding_service_->OnboardingNoticeActionTaken(
+      TrackingProtectionOnboarding::NoticeAction::kOther);
+  tracking_protection_onboarding_service_.reset();
+  tracking_protection_onboarding_service_ =
+      std::make_unique<TrackingProtectionOnboarding>(
+          prefs(), version_info::Channel::UNKNOWN);
+
+  auto last_shown_to_acked_duration =
+      prefs()->GetTime(prefs::kTrackingProtectionNoticeLastShown) -
+      base::Time::Now();
+  histogram_tester_.ExpectTimeBucketCount(
+      "PrivacySandbox.TrackingProtection.Onboarding.LastShownToAckedDuration",
+      last_shown_to_acked_duration, 1);
+}
 }  // namespace
 }  // namespace privacy_sandbox
diff --git a/components/privacy_sandbox_strings.grdp b/components/privacy_sandbox_strings.grdp
index b6c38e7..b26c0f6 100644
--- a/components/privacy_sandbox_strings.grdp
+++ b/components/privacy_sandbox_strings.grdp
@@ -2184,6 +2184,17 @@
   <message name="IDS_TRACKING_PROTECTION_ONBOARDING_NOTICE_LEARN_MORE_BUTTON_LABEL" desc="Onboarding notice secondary menu button text." formatter_data="android_java">
     Learn more
   </message>
+
+  <!-- Offboarding -->
+  <message name="IDS_TRACKING_PROTECTION_OFFBOARDING_NOTICE_TITLE"
+    desc="Title of the tracking protection offboarding notice" translateable="false" >
+    Tracking Protection is temporarily unavailable
+  </message>
+  <message name="IDS_TRACKING_PROTECTION_OFFBOARDING_NOTICE_BODY"
+    desc="Content of the tracking protection notice, informing the user that they now have their third party cookies disabled by default" translateable="false" >
+    While Chrome is updating this feature, sites can temporarily use third-party cookies unless youn block them in settings.
+  </message>
+
   <message name="IDS_PRIVACY_SANDBOX_TRACKING_PROTECTION_BULLET_ONE_TITLE" desc="" translateable="false" formatter_data="android_java">
     Chrome automatically limits third-party cookies
   </message>
diff --git a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
index b4659e13..77b57e29 100644
--- a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
+++ b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.cc
@@ -22,7 +22,7 @@
 #include "base/i18n/time_formatting.h"
 #include "base/json/json_string_value_serializer.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/singleton.h"
+#include "base/no_destructor.h"
 #include "base/notreached.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
@@ -82,7 +82,8 @@
             .empty())
       << "chrome://safe-browsing WebUI is only available in the browser "
          "process";
-  return base::Singleton<WebUIInfoSingleton>::get();
+  static base::NoDestructor<WebUIInfoSingleton> instance;
+  return instance.get();
 }
 
 // static
diff --git a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h
index ec626fa7..19a3351 100644
--- a/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h
+++ b/components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h
@@ -33,11 +33,6 @@
 #include "components/enterprise/common/proto/connectors.pb.h"
 #endif
 
-namespace base {
-template <typename T>
-struct DefaultSingletonTraits;
-}  // namespace base
-
 namespace safe_browsing {
 class WebUIInfoSingleton;
 class ReferrerChainProvider;
@@ -642,8 +637,6 @@
  private:
   void MaybeClearData();
 
-  friend struct base::DefaultSingletonTraits<WebUIInfoSingleton>;
-
   // List of download URLs checked since the oldest currently open
   // chrome://safe-browsing tab was opened.
   std::vector<std::pair<std::vector<GURL>, DownloadCheckResult>>
diff --git a/components/safe_browsing/core/common/features.cc b/components/safe_browsing/core/common/features.cc
index 8b37370..4eb37bb 100644
--- a/components/safe_browsing/core/common/features.cc
+++ b/components/safe_browsing/core/common/features.cc
@@ -258,12 +258,7 @@
 
 BASE_FEATURE(kSafeBrowsingSkipSubresources,
              "SafeBrowsingSkipSubResources",
-#if BUILDFLAG(IS_IOS)
-             base::FEATURE_DISABLED_BY_DEFAULT
-#else
-             base::FEATURE_ENABLED_BY_DEFAULT
-#endif
-);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 BASE_FEATURE(kSafeBrowsingSkipSubresources2,
              "SafeBrowsingSkipSubResources2",
diff --git a/components/segmentation_platform/internal/BUILD.gn b/components/segmentation_platform/internal/BUILD.gn
index e308664..e8283b4 100644
--- a/components/segmentation_platform/internal/BUILD.gn
+++ b/components/segmentation_platform/internal/BUILD.gn
@@ -398,10 +398,10 @@
 
     deps = [
       "//base:base_java",
-      "//base:jni_java",
       "//build/android:build_java",
       "//components/optimization_guide/proto:optimization_guide_proto_java",
       "//components/segmentation_platform/public:public_java",
+      "//third_party/jni_zero:jni_zero_java",
     ]
   }
 
diff --git a/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformServiceImpl.java b/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformServiceImpl.java
index a660598..069bce98 100644
--- a/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformServiceImpl.java
+++ b/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/SegmentationPlatformServiceImpl.java
@@ -4,10 +4,11 @@
 
 package org.chromium.components.segmentation_platform;
 
+import org.jni_zero.CalledByNative;
+import org.jni_zero.JNINamespace;
+import org.jni_zero.NativeMethods;
+
 import org.chromium.base.Callback;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
 
 /**
  * Java side of the JNI bridge between SegmentationPlatformServiceImpl in Java
diff --git a/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/execution/processing/CustomDeviceUtils.java b/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/execution/processing/CustomDeviceUtils.java
index d24c64b6..f27ac0a 100644
--- a/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/execution/processing/CustomDeviceUtils.java
+++ b/components/segmentation_platform/internal/android/java/src/org/chromium/components/segmentation_platform/execution/processing/CustomDeviceUtils.java
@@ -6,9 +6,10 @@
 
 import android.util.DisplayMetrics;
 
+import org.jni_zero.CalledByNative;
+import org.jni_zero.JNINamespace;
+
 import org.chromium.base.ContextUtils;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
 
 /**
  * Implements methods to get device info.
diff --git a/components/segmentation_platform/internal/database/database_maintenance_impl.cc b/components/segmentation_platform/internal/database/database_maintenance_impl.cc
index 9f7f8877..a0523acd 100644
--- a/components/segmentation_platform/internal/database/database_maintenance_impl.cc
+++ b/components/segmentation_platform/internal/database/database_maintenance_impl.cc
@@ -22,7 +22,6 @@
 #include "components/prefs/pref_service.h"
 #include "components/segmentation_platform/internal/constants.h"
 #include "components/segmentation_platform/internal/database/signal_database.h"
-#include "components/segmentation_platform/internal/database/signal_storage_config.h"
 #include "components/segmentation_platform/internal/metadata/metadata_utils.h"
 #include "components/segmentation_platform/internal/stats.h"
 #include "components/segmentation_platform/public/proto/types.pb.h"
@@ -34,7 +33,6 @@
 
 namespace segmentation_platform {
 using SignalIdentifier = DatabaseMaintenanceImpl::SignalIdentifier;
-using CleanupItem = DatabaseMaintenanceImpl::CleanupItem;
 
 namespace {
 // Gets the end of the UTC day time for `current_time`.
@@ -154,8 +152,13 @@
   auto cleanup_state = std::make_unique<CleanupState>();
   // Convert the vector of cleanup items to a deque so we can easily handle
   // the state by popping the first one until it is empty.
-  for (auto& item : signals_to_cleanup)
-    cleanup_state->signals_to_cleanup_.emplace_back(item);
+  for (auto& signal : signals_to_cleanup) {
+    // If UKM signal, skip deleting it as it is not present in signal database.
+    if (signal.event_hash != CleanupItem::kNonUkmEventHash) {
+      continue;
+    }
+    cleanup_state->signals_to_cleanup_.emplace_back(signal);
+  }
 
   CleanupSignalStorageProcessNext(
       std::move(cleanup_state),
@@ -181,9 +184,10 @@
   CleanupItem cleanup_item = cleanup_state->signals_to_cleanup_.front();
   cleanup_state->signals_to_cleanup_.pop_front();
 
-  proto::SignalType signal_type = std::get<1>(cleanup_item);
-  uint64_t name_hash = std::get<0>(cleanup_item);
-  base::Time end_time = std::get<2>(cleanup_item);
+  proto::SignalType signal_type = cleanup_item.signal_type;
+  uint64_t name_hash = cleanup_item.name_hash;
+  base::Time end_time = cleanup_item.timestamp;
+
   signal_database_->DeleteSamples(
       signal_type, name_hash, end_time,
       base::BindOnce(&DatabaseMaintenanceImpl::CleanupSignalStorageProcessNext,
diff --git a/components/segmentation_platform/internal/database/database_maintenance_impl.h b/components/segmentation_platform/internal/database/database_maintenance_impl.h
index 512bf2c..60243689 100644
--- a/components/segmentation_platform/internal/database/database_maintenance_impl.h
+++ b/components/segmentation_platform/internal/database/database_maintenance_impl.h
@@ -17,6 +17,7 @@
 #include "base/time/time.h"
 #include "components/segmentation_platform/internal/database/database_maintenance.h"
 #include "components/segmentation_platform/internal/database/segment_info_database.h"
+#include "components/segmentation_platform/internal/database/signal_storage_config.h"
 #include "components/segmentation_platform/public/proto/segmentation_platform.pb.h"
 #include "components/segmentation_platform/public/proto/types.pb.h"
 
@@ -39,7 +40,6 @@
 class DatabaseMaintenanceImpl : public DatabaseMaintenance {
  public:
   using SignalIdentifier = std::pair<uint64_t, proto::SignalType>;
-  using CleanupItem = std::tuple<uint64_t, proto::SignalType, base::Time>;
 
   explicit DatabaseMaintenanceImpl(const base::flat_set<SegmentId>& segment_ids,
                                    base::Clock* clock,
diff --git a/components/segmentation_platform/internal/database/database_maintenance_impl_unittest.cc b/components/segmentation_platform/internal/database/database_maintenance_impl_unittest.cc
index e4cb4b7..048a8e7 100644
--- a/components/segmentation_platform/internal/database/database_maintenance_impl_unittest.cc
+++ b/components/segmentation_platform/internal/database/database_maintenance_impl_unittest.cc
@@ -39,11 +39,12 @@
 using SignalType = proto::SignalType;
 using Aggregation = proto::Aggregation;
 using SignalIdentifier = std::pair<uint64_t, SignalType>;
-using CleanupItem = std::tuple<uint64_t, SignalType, base::Time>;
 
 namespace {
 constexpr uint64_t kLatestCompactionDaysAgo = 2;
 constexpr uint64_t kEarliestCompactionDaysAgo = 60;
+// Event hash for non UKM signals.
+static const uint64_t kNonUkmEventHash = 0;
 
 std::string kTestSegmentationKey = "some_key";
 
@@ -73,7 +74,7 @@
 std::vector<CleanupItem> GetCleanupItems(std::vector<SignalData> signal_datas) {
   std::vector<CleanupItem> cleanup_items;
   for (auto& sd : signal_datas) {
-    cleanup_items.emplace_back(sd.name_hash, sd.signal_type,
+    cleanup_items.emplace_back(sd.name_hash, kNonUkmEventHash, sd.signal_type,
                                sd.earliest_needed_timestamp);
   }
   return cleanup_items;
@@ -164,7 +165,7 @@
     cleanup_items.erase(
         std::remove_if(cleanup_items.begin(), cleanup_items.end(),
                        [](CleanupItem item) {
-                         return std::get<0>(item) ==
+                         return item.name_hash ==
                                 base::HashMetricName("Failed");
                        }),
         cleanup_items.end());
diff --git a/components/segmentation_platform/internal/database/mock_signal_storage_config.h b/components/segmentation_platform/internal/database/mock_signal_storage_config.h
index 6ebd3b16..369b981 100644
--- a/components/segmentation_platform/internal/database/mock_signal_storage_config.h
+++ b/components/segmentation_platform/internal/database/mock_signal_storage_config.h
@@ -23,7 +23,6 @@
  public:
   using SignalType = proto::SignalType;
   using SignalIdentifier = std::pair<uint64_t, SignalType>;
-  using CleanupItem = std::tuple<uint64_t, SignalType, base::Time>;
 
   MockSignalStorageConfig();
   ~MockSignalStorageConfig() override;
diff --git a/components/segmentation_platform/internal/database/signal_storage_config.cc b/components/segmentation_platform/internal/database/signal_storage_config.cc
index 142e5f7..f66f49d5 100644
--- a/components/segmentation_platform/internal/database/signal_storage_config.cc
+++ b/components/segmentation_platform/internal/database/signal_storage_config.cc
@@ -15,6 +15,23 @@
 const char kDatabaseKey[] = "config";
 }  // namespace
 
+CleanupItem::CleanupItem() = default;
+CleanupItem::CleanupItem(uint64_t name_hash,
+                         uint64_t event_hash,
+                         proto::SignalType signal_type,
+                         base::Time timestamp)
+    : name_hash(name_hash),
+      event_hash(event_hash),
+      signal_type(signal_type),
+      timestamp(timestamp) {}
+
+CleanupItem::~CleanupItem() = default;
+
+bool CleanupItem::operator==(const CleanupItem& other) const {
+  return other.name_hash == name_hash && other.event_hash == event_hash &&
+         other.signal_type == signal_type && other.timestamp == timestamp;
+}
+
 SignalStorageConfig::SignalStorageConfig(
     std::unique_ptr<SignalStorageConfigProtoDb> database,
     base::Clock* clock)
@@ -86,8 +103,8 @@
       metadata_utils::ValidationResult::kValidationSuccess) {
     return;
   }
-  if (UpdateConfigForSignal(signal_storage_length, feature.name_hash(), 0,
-                            feature.type())) {
+  if (UpdateConfigForSignal(signal_storage_length, feature.name_hash(),
+                            CleanupItem::kNonUkmEventHash, feature.type())) {
     *is_dirty = true;
   }
 }
@@ -166,8 +183,8 @@
         }
 
         if (!config->MeetsSignalCollectionRequirementForSignal(
-                min_signal_collection_length, feature.name_hash(), 0,
-                feature.type())) {
+                min_signal_collection_length, feature.name_hash(),
+                CleanupItem::kNonUkmEventHash, feature.type())) {
           *meets_requirement = false;
           return;
         };
@@ -251,10 +268,8 @@
 
 void SignalStorageConfig::GetSignalsForCleanup(
     const std::set<std::pair<uint64_t, proto::SignalType>>& known_signals,
-    std::vector<std::tuple<uint64_t, proto::SignalType, base::Time>>& result)
-    const {
-  // Collect the signals that have longer than required data.
-  // TODO(haileywang): Handle UKM signals.
+    std::vector<CleanupItem>& result) const {
+  // Ukm signals are included only when its over required length.
   for (int i = 0; i < config_.signals_size(); ++i) {
     const auto& signal_config = config_.signals(i);
     base::Time collection_start_time = base::Time::FromDeltaSinceWindowsEpoch(
@@ -267,9 +282,8 @@
     if (earliest_needed_timestamp < collection_start_time)
       continue;
 
-    result.emplace_back(std::make_tuple(signal_config.name_hash(),
-                                        signal_config.signal_type(),
-                                        earliest_needed_timestamp));
+    result.emplace_back(signal_config.name_hash(), signal_config.event_hash(),
+                        signal_config.signal_type(), earliest_needed_timestamp);
   }
 
   // Now collect the signals that aren't used by any of the models.
@@ -278,33 +292,34 @@
 
   for (int i = 0; i < config_.signals_size(); ++i) {
     const auto& signal_config = config_.signals(i);
+    // UKM database cleans up signals after `kUkmEntriesTTL` time. Hence don't
+    // include signals when not needed. For UMA signals, skip adding signals
+    // that are used by any models.
+    // TODO(ssid) : Handle this for UKM signals.
     if (base::Contains(known_signals,
                        std::make_pair(signal_config.name_hash(),
-                                      signal_config.signal_type()))) {
+                                      signal_config.signal_type())) ||
+        signal_config.signal_type() == proto::SignalType::UKM_EVENT) {
       continue;
     }
 
-    result.emplace_back(std::make_tuple(
-        signal_config.name_hash(), signal_config.signal_type(), clock_->Now()));
+    result.emplace_back(signal_config.name_hash(), signal_config.event_hash(),
+                        signal_config.signal_type(), clock_->Now());
   }
 }
 
 void SignalStorageConfig::UpdateSignalsForCleanup(
-    const std::vector<std::tuple<uint64_t, proto::SignalType, base::Time>>&
-        signals) {
+    const std::vector<CleanupItem>& signals) {
   bool is_dirty = false;
-  for (auto& tuple : signals) {
-    uint64_t name_hash = std::get<0>(tuple);
-    proto::SignalType signal_type = std::get<1>(tuple);
-    base::Time timestamp = std::get<2>(tuple);
-
+  for (auto& signal_for_cleanup : signals) {
     proto::SignalStorageConfig* signal_config =
-        FindSignal(name_hash, 0, signal_type);
+        FindSignal(signal_for_cleanup.name_hash, signal_for_cleanup.event_hash,
+                   signal_for_cleanup.signal_type);
     if (!signal_config)
       continue;
 
     signal_config->set_collection_start_time_s(
-        timestamp.ToDeltaSinceWindowsEpoch().InSeconds());
+        signal_for_cleanup.timestamp.ToDeltaSinceWindowsEpoch().InSeconds());
     is_dirty = true;
   }
 
diff --git a/components/segmentation_platform/internal/database/signal_storage_config.h b/components/segmentation_platform/internal/database/signal_storage_config.h
index a6f62a4b..437353f4 100644
--- a/components/segmentation_platform/internal/database/signal_storage_config.h
+++ b/components/segmentation_platform/internal/database/signal_storage_config.h
@@ -17,6 +17,30 @@
 
 namespace segmentation_platform {
 
+// CleanupItem is used to store signals for cleanup.
+struct CleanupItem {
+ public:
+  CleanupItem();
+  CleanupItem(uint64_t name_hash,
+              uint64_t event_hash,
+              proto::SignalType signal_type,
+              base::Time timestamp);
+  ~CleanupItem();
+
+  bool operator==(const CleanupItem& other) const;
+
+  // Name of the signal to be cleaned up.
+  uint64_t name_hash;
+  // Event hash for the signal.
+  uint64_t event_hash;
+  // Type of signal.
+  proto::SignalType signal_type;
+  // Indicates the time when the signal was last cleaned up.
+  base::Time timestamp;
+  // Event hash for non UKM signals.
+  static const uint64_t kNonUkmEventHash = 0;
+};
+
 // SignalStorageConfig is used to determine whether the signals for a model have
 // been captured long enough to be used for model evaluation. It is also used
 // for cleaning up the old entries for a signal in the signal database. It's
@@ -66,14 +90,11 @@
   // The result of the operation will be stored in the |result|.
   virtual void GetSignalsForCleanup(
       const std::set<std::pair<uint64_t, proto::SignalType>>& known_signals,
-      std::vector<std::tuple<uint64_t, proto::SignalType, base::Time>>& result)
-      const;
+      std::vector<CleanupItem>& result) const;
 
   // Called to notify that the SignalDatabase entries have been cleaned up. Now
   // it should update the collection start timestamp in the SignalStorageConfig.
-  virtual void UpdateSignalsForCleanup(
-      const std::vector<std::tuple<uint64_t, proto::SignalType, base::Time>>&
-          signals);
+  virtual void UpdateSignalsForCleanup(const std::vector<CleanupItem>& signals);
 
  private:
   void OnDatabaseInitialized(SuccessCallback callback,
diff --git a/components/segmentation_platform/internal/database/signal_storage_config_unittest.cc b/components/segmentation_platform/internal/database/signal_storage_config_unittest.cc
index 2a7d3127..bbc09f0 100644
--- a/components/segmentation_platform/internal/database/signal_storage_config_unittest.cc
+++ b/components/segmentation_platform/internal/database/signal_storage_config_unittest.cc
@@ -235,6 +235,16 @@
                                            .InSeconds());
   signal1->set_storage_length_s(base::Days(2).InSeconds());
 
+  // Expired UKM signal.
+  proto::SignalStorageConfig* ukm_signal = config.add_signals();
+  ukm_signal->set_name_hash(base::HashMetricName("4"));
+  ukm_signal->set_signal_type(proto::SignalType::UKM_EVENT);
+  ukm_signal->set_event_hash(base::HashMetricName("4"));
+  ukm_signal->set_collection_start_time_s((test_clock_.Now() - base::Days(3))
+                                              .ToDeltaSinceWindowsEpoch()
+                                              .InSeconds());
+  ukm_signal->set_storage_length_s(base::Days(2).InSeconds());
+
   // Unknown.
   proto::SignalStorageConfig* signal2 = config.add_signals();
   signal2->set_name_hash(base::HashMetricName("2"));
@@ -264,12 +274,16 @@
 
   // Run cleanup to find expired signals
   std::set<std::pair<uint64_t, proto::SignalType>> known_signals;
-  std::vector<std::tuple<uint64_t, proto::SignalType, base::Time>> result;
+  std::vector<CleanupItem> result;
   signal_storage_config_->GetSignalsForCleanup(known_signals, result);
-  EXPECT_EQ(1u, result.size());
-  // The first element in result tuple is the name hash.
-  EXPECT_EQ(base::HashMetricName("1"), std::get<0>(result[0]));
-  EXPECT_EQ(proto::SignalType::HISTOGRAM_VALUE, std::get<1>(result[0]));
+  EXPECT_EQ(2u, result.size());
+  EXPECT_EQ(base::HashMetricName("1"), result[0].name_hash);
+  EXPECT_EQ(0u, result[0].event_hash);
+  EXPECT_EQ(proto::SignalType::HISTOGRAM_VALUE, result[0].signal_type);
+
+  EXPECT_EQ(base::HashMetricName("4"), result[1].name_hash);
+  EXPECT_EQ(base::HashMetricName("4"), result[1].event_hash);
+  EXPECT_EQ(proto::SignalType::UKM_EVENT, result[1].signal_type);
 
   // Run cleanup to find expired and unknown signals.
   result.clear();
@@ -278,10 +292,18 @@
   known_signals.insert(
       {base::HashMetricName("3"), proto::SignalType::HISTOGRAM_VALUE});
   signal_storage_config_->GetSignalsForCleanup(known_signals, result);
-  EXPECT_EQ(2u, result.size());
-  // The first element in result tuple is the name hash.
-  EXPECT_EQ(base::HashMetricName("2"), std::get<0>(result[1]));
-  EXPECT_EQ(proto::SignalType::HISTOGRAM_VALUE, std::get<1>(result[1]));
+  EXPECT_EQ(3u, result.size());
+  EXPECT_EQ(base::HashMetricName("1"), result[0].name_hash);
+  EXPECT_EQ(0u, result[0].event_hash);
+  EXPECT_EQ(proto::SignalType::HISTOGRAM_VALUE, result[0].signal_type);
+
+  EXPECT_EQ(base::HashMetricName("4"), result[1].name_hash);
+  EXPECT_EQ(base::HashMetricName("4"), result[1].event_hash);
+  EXPECT_EQ(proto::SignalType::UKM_EVENT, result[1].signal_type);
+
+  EXPECT_EQ(base::HashMetricName("2"), result[2].name_hash);
+  EXPECT_EQ(0u, result[2].event_hash);
+  EXPECT_EQ(proto::SignalType::HISTOGRAM_VALUE, result[2].signal_type);
 
   // Cleanup the signals from this DB. The collection start time should be
   // updated.
@@ -292,6 +314,12 @@
                 .ToDeltaSinceWindowsEpoch()
                 .InSeconds(),
             signal.collection_start_time_s());
+
+  auto ukm_signal1 = db_entries_[kDatabaseKey].signals(1);
+  EXPECT_EQ((test_clock_.Now() - base::Days(2))
+                .ToDeltaSinceWindowsEpoch()
+                .InSeconds(),
+            ukm_signal1.collection_start_time_s());
 }
 
 }  // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/scheduler/model_execution_scheduler_unittest.cc b/components/segmentation_platform/internal/scheduler/model_execution_scheduler_unittest.cc
index dd0fd27..659042a 100644
--- a/components/segmentation_platform/internal/scheduler/model_execution_scheduler_unittest.cc
+++ b/components/segmentation_platform/internal/scheduler/model_execution_scheduler_unittest.cc
@@ -27,7 +27,6 @@
 namespace segmentation_platform {
 using SignalType = proto::SignalType;
 using SignalIdentifier = std::pair<uint64_t, SignalType>;
-using CleanupItem = std::tuple<uint64_t, SignalType, base::Time>;
 
 namespace {
 constexpr auto kTestSegmentId =
diff --git a/components/services/app_service/public/cpp/BUILD.gn b/components/services/app_service/public/cpp/BUILD.gn
index e5deeb6..6c3d3d07 100644
--- a/components/services/app_service/public/cpp/BUILD.gn
+++ b/components/services/app_service/public/cpp/BUILD.gn
@@ -19,12 +19,15 @@
     "capability_access.h",
     "features.cc",
     "features.h",
+    "icon_effects.h",
     "icon_types.cc",
     "icon_types.h",
     "intent_filter.cc",
     "intent_filter.h",
     "menu.cc",
     "menu.h",
+    "package_id.cc",
+    "package_id.h",
     "permission.cc",
     "permission.h",
     "preferred_app.cc",
@@ -303,6 +306,7 @@
     "icon_coalescer_unittest.cc",
     "intent_filter_util_unittest.cc",
     "intent_util_unittest.cc",
+    "package_id_unittest.cc",
     "preferred_apps_converter_unittest.cc",
     "preferred_apps_list_unittest.cc",
   ]
diff --git a/chrome/browser/apps/app_service/app_icon/icon_effects.h b/components/services/app_service/public/cpp/icon_effects.h
similarity index 91%
rename from chrome/browser/apps/app_service/app_icon/icon_effects.h
rename to components/services/app_service/public/cpp/icon_effects.h
index 41a2e2c1..f244d07 100644
--- a/chrome/browser/apps/app_service/app_icon/icon_effects.h
+++ b/components/services/app_service/public/cpp/icon_effects.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_APPS_APP_SERVICE_APP_ICON_ICON_EFFECTS_H_
-#define CHROME_BROWSER_APPS_APP_SERVICE_APP_ICON_ICON_EFFECTS_H_
+#ifndef COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_ICON_EFFECTS_H_
+#define COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_ICON_EFFECTS_H_
 
 #include <cstdint>
 
@@ -61,4 +61,4 @@
 
 }  // namespace apps
 
-#endif  // CHROME_BROWSER_APPS_APP_SERVICE_APP_ICON_ICON_EFFECTS_H_
+#endif  // COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_ICON_EFFECTS_H_
diff --git a/chrome/browser/apps/app_service/package_id.cc b/components/services/app_service/public/cpp/package_id.cc
similarity index 97%
rename from chrome/browser/apps/app_service/package_id.cc
rename to components/services/app_service/public/cpp/package_id.cc
index 5691e91..d08240e 100644
--- a/chrome/browser/apps/app_service/package_id.cc
+++ b/components/services/app_service/public/cpp/package_id.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/apps/app_service/package_id.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 
 #include <string>
 
diff --git a/chrome/browser/apps/app_service/package_id.h b/components/services/app_service/public/cpp/package_id.h
similarity index 90%
rename from chrome/browser/apps/app_service/package_id.h
rename to components/services/app_service/public/cpp/package_id.h
index 00b86b9..6b464e6 100644
--- a/chrome/browser/apps/app_service/package_id.h
+++ b/components/services/app_service/public/cpp/package_id.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_APPS_APP_SERVICE_PACKAGE_ID_H_
-#define CHROME_BROWSER_APPS_APP_SERVICE_PACKAGE_ID_H_
+#ifndef COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_PACKAGE_ID_H_
+#define COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_PACKAGE_ID_H_
 
 #include <string>
 
@@ -29,7 +29,7 @@
 // --------|-----------|-----------------------|--------------------------
 // kArc    | "android" | package name          | "android:com.foo.bar"
 // kWeb    | "web"     | processed manifest ID | "web:https://app.com/id"
-class PackageId {
+class COMPONENT_EXPORT(APP_TYPES) PackageId {
  public:
   // Creates a Package ID from App Type and opaque package identifier.
   // `app_type` must be a supported type (Web or ARC), and `identifier` must be
@@ -65,4 +65,4 @@
 
 }  // namespace apps
 
-#endif  // CHROME_BROWSER_APPS_APP_SERVICE_PACKAGE_ID_H_
+#endif  // COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_PACKAGE_ID_H_
diff --git a/chrome/browser/apps/app_service/package_id_unittest.cc b/components/services/app_service/public/cpp/package_id_unittest.cc
similarity index 95%
rename from chrome/browser/apps/app_service/package_id_unittest.cc
rename to components/services/app_service/public/cpp/package_id_unittest.cc
index b0a6aa2..a52c874 100644
--- a/chrome/browser/apps/app_service/package_id_unittest.cc
+++ b/components/services/app_service/public/cpp/package_id_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/apps/app_service/package_id.h"
+#include "components/services/app_service/public/cpp/package_id.h"
 
 #include "base/strings/string_piece.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/services/screen_ai/BUILD.gn b/components/services/screen_ai/BUILD.gn
index f41c6c0..93fce1e 100644
--- a/components/services/screen_ai/BUILD.gn
+++ b/components/services/screen_ai/BUILD.gn
@@ -94,3 +94,18 @@
     data_deps = [ ":test_support_data" ]
   }
 }
+
+source_set("test_support") {
+  testonly = true
+
+  sources = [
+    "public/test/fake_screen_ai_annotator.cc",
+    "public/test/fake_screen_ai_annotator.h",
+  ]
+
+  deps = [
+    "//base/test:test_support",
+    "//components/services/screen_ai/public/mojom",
+    "//ui/accessibility:test_support",
+  ]
+}
diff --git a/components/services/screen_ai/DEPS b/components/services/screen_ai/DEPS
index 663ab30..0746d6ff 100644
--- a/components/services/screen_ai/DEPS
+++ b/components/services/screen_ai/DEPS
@@ -10,6 +10,7 @@
   "+ui/accessibility/ax_enums.mojom.h",
   "+ui/accessibility/ax_node.h",
   "+ui/accessibility/ax_node_data.h",
+  "+ui/accessibility/ax_node_id_forward.h",
   "+ui/accessibility/ax_role_properties.h",
   "+ui/accessibility/ax_serializable_tree.h",
   "+ui/accessibility/ax_tree.h",
diff --git a/components/services/screen_ai/public/test/fake_screen_ai_annotator.cc b/components/services/screen_ai/public/test/fake_screen_ai_annotator.cc
new file mode 100644
index 0000000..1444842
--- /dev/null
+++ b/components/services/screen_ai/public/test/fake_screen_ai_annotator.cc
@@ -0,0 +1,56 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/services/screen_ai/public/test/fake_screen_ai_annotator.h"
+
+#include <utility>
+
+#include "ui/accessibility/ax_enums.mojom.h"
+#include "ui/accessibility/ax_node_data.h"
+#include "ui/accessibility/ax_tree_update.h"
+
+namespace screen_ai::test {
+
+FakeScreenAIAnnotator::FakeScreenAIAnnotator(bool create_empty_result)
+    : create_empty_result_(create_empty_result) {}
+
+FakeScreenAIAnnotator::~FakeScreenAIAnnotator() = default;
+
+void FakeScreenAIAnnotator::PerformOcrAndReturnAXTreeUpdate(
+    const ::SkBitmap& image,
+    PerformOcrAndReturnAXTreeUpdateCallback callback) {
+  ui::AXTreeUpdate update;
+  if (!create_empty_result_) {
+    update.root_id = next_node_id_;
+    ui::AXNodeData node;
+    node.id = next_node_id_;
+    node.role = ax::mojom::Role::kStaticText;
+    node.SetNameChecked("Testing");
+    update.nodes = {node};
+    --next_node_id_;
+  }
+  std::move(callback).Run(update);
+}
+
+void FakeScreenAIAnnotator::ExtractSemanticLayout(
+    const ::SkBitmap& image,
+    const ::ui::AXTreeID& parent_tree_id,
+    ExtractSemanticLayoutCallback callback) {
+  ui::AXTreeID tree_id = ui::AXTreeID::CreateNewAXTreeID();
+  std::move(callback).Run(tree_id);
+}
+
+void FakeScreenAIAnnotator::PerformOcrAndReturnAnnotation(
+    const ::SkBitmap& image,
+    PerformOcrAndReturnAnnotationCallback callback) {
+  auto annotation = screen_ai::mojom::VisualAnnotation::New();
+  std::move(callback).Run(std::move(annotation));
+}
+
+mojo::PendingRemote<mojom::ScreenAIAnnotator>
+FakeScreenAIAnnotator::BindNewPipeAndPassRemote() {
+  return receiver_.BindNewPipeAndPassRemote();
+}
+
+}  // namespace screen_ai::test
diff --git a/components/services/screen_ai/public/test/fake_screen_ai_annotator.h b/components/services/screen_ai/public/test/fake_screen_ai_annotator.h
new file mode 100644
index 0000000..4dbbe48
--- /dev/null
+++ b/components/services/screen_ai/public/test/fake_screen_ai_annotator.h
@@ -0,0 +1,48 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SERVICES_SCREEN_AI_PUBLIC_TEST_FAKE_SCREEN_AI_ANNOTATOR_H_
+#define COMPONENTS_SERVICES_SCREEN_AI_PUBLIC_TEST_FAKE_SCREEN_AI_ANNOTATOR_H_
+
+#include "components/services/screen_ai/public/mojom/screen_ai_service.mojom.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/accessibility/ax_node_id_forward.h"
+#include "ui/accessibility/ax_tree_id.h"
+
+namespace screen_ai::test {
+
+class FakeScreenAIAnnotator : public mojom::ScreenAIAnnotator {
+ public:
+  explicit FakeScreenAIAnnotator(bool create_empty_result);
+  FakeScreenAIAnnotator(const FakeScreenAIAnnotator&) = delete;
+  FakeScreenAIAnnotator& operator=(const FakeScreenAIAnnotator&) = delete;
+  ~FakeScreenAIAnnotator() override;
+
+  void PerformOcrAndReturnAXTreeUpdate(
+      const ::SkBitmap& image,
+      PerformOcrAndReturnAXTreeUpdateCallback callback) override;
+
+  void ExtractSemanticLayout(const ::SkBitmap& image,
+                             const ::ui::AXTreeID& parent_tree_id,
+                             ExtractSemanticLayoutCallback callback) override;
+
+  void PerformOcrAndReturnAnnotation(
+      const ::SkBitmap& image,
+      PerformOcrAndReturnAnnotationCallback callback) override;
+
+  mojo::PendingRemote<mojom::ScreenAIAnnotator> BindNewPipeAndPassRemote();
+
+ private:
+  mojo::Receiver<mojom::ScreenAIAnnotator> receiver_{this};
+  const bool create_empty_result_;
+  // A negative ID for ui::AXNodeID needs to start from -2 as using -1 for this
+  // node id is still incorrectly treated as invalid.
+  ui::AXNodeID next_node_id_ = -2;
+};
+
+}  // namespace screen_ai::test
+
+#endif  // COMPONENTS_SERVICES_SCREEN_AI_PUBLIC_TEST_FAKE_SCREEN_AI_ANNOTATOR_H_
diff --git a/components/sync/nigori/nigori_model_type_processor.cc b/components/sync/nigori/nigori_model_type_processor.cc
index 8e453bf..783b52ca 100644
--- a/components/sync/nigori/nigori_model_type_processor.cc
+++ b/components/sync/nigori/nigori_model_type_processor.cc
@@ -180,12 +180,13 @@
     // Remote update always win in case of conflict, because bridge takes care
     // of reapplying pending local changes after processing the remote update.
     entity_->RecordForcedRemoteUpdate(updates[0], /*trimmed_specifics=*/{});
-    error = bridge_->ApplyIncrementalSyncChanges(std::move(updates[0].entity));
   } else if (!entity_->MatchesData(updates[0].entity)) {
     // Inform the bridge of the new or updated data.
     entity_->RecordAcceptedRemoteUpdate(updates[0], /*trimmed_specifics=*/{});
-    error = bridge_->ApplyIncrementalSyncChanges(std::move(updates[0].entity));
   }
+  LogNonReflectionUpdateFreshnessToUma(NIGORI,
+                                       updates[0].entity.modification_time);
+  error = bridge_->ApplyIncrementalSyncChanges(std::move(updates[0].entity));
 
   if (error) {
     ReportError(*error);
diff --git a/components/sync/nigori/nigori_model_type_processor_unittest.cc b/components/sync/nigori/nigori_model_type_processor_unittest.cc
index 626cc7c7..3f14cef 100644
--- a/components/sync/nigori/nigori_model_type_processor_unittest.cc
+++ b/components/sync/nigori/nigori_model_type_processor_unittest.cc
@@ -10,8 +10,11 @@
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_callback.h"
 #include "base/test/scoped_feature_list.h"
+#include "base/test/task_environment.h"
+#include "base/time/time.h"
 #include "components/sync/base/client_tag_hash.h"
 #include "components/sync/base/time.h"
 #include "components/sync/engine/data_type_activation_response.h"
@@ -168,6 +171,8 @@
   }
 
  private:
+  base::test::SingleThreadTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
   testing::NiceMock<MockNigoriSyncBridge> mock_nigori_sync_bridge_;
   std::unique_ptr<testing::NiceMock<MockCommitQueue>> mock_commit_queue_ =
       std::make_unique<testing::NiceMock<MockCommitQueue>>();
@@ -433,6 +438,8 @@
 }
 
 TEST_F(NigoriModelTypeProcessorTest, ShouldMergeFullSyncData) {
+  base::HistogramTester histogram_tester;
+
   SimulateModelReadyToSync(/*initial_sync_done=*/false);
 
   const std::string kDecryptorTokenKeyName = "key_name";
@@ -446,15 +453,21 @@
 
   processor()->OnUpdateReceived(CreateDummyModelTypeState(), std::move(updates),
                                 /*gc_directive=*/absl::nullopt);
+
+  histogram_tester.ExpectTotalCount(
+      "Sync.NonReflectionUpdateFreshnessPossiblySkewed2", 0);
 }
 
 TEST_F(NigoriModelTypeProcessorTest, ShouldApplyIncrementalSyncChanges) {
+  base::HistogramTester histogram_tester;
+
   SimulateModelReadyToSync(/*initial_sync_done=*/true, /*server_version=*/1);
 
   const std::string kDecryptorTokenKeyName = "key_name";
   UpdateResponseDataList updates;
   updates.push_back(CreateDummyNigoriUpdateResponseData(kDecryptorTokenKeyName,
                                                         /*server_version=*/2));
+  updates.back().entity.modification_time = base::Time::Now() - base::Hours(1);
 
   EXPECT_CALL(
       *mock_nigori_sync_bridge(),
@@ -463,6 +476,9 @@
 
   processor()->OnUpdateReceived(CreateDummyModelTypeState(), std::move(updates),
                                 /*gc_directive=*/absl::nullopt);
+
+  histogram_tester.ExpectUniqueTimeSample(
+      "Sync.NonReflectionUpdateFreshnessPossiblySkewed2", base::Hours(1), 1);
 }
 
 TEST_F(NigoriModelTypeProcessorTest,
@@ -482,6 +498,8 @@
 
 TEST_F(NigoriModelTypeProcessorTest,
        ShouldApplyIncrementalSyncChangesWhenReflection) {
+  base::HistogramTester histogram_tester;
+
   const int kServerVersion = 1;
   SimulateModelReadyToSync(/*initial_sync_done=*/true, kServerVersion);
 
@@ -496,6 +514,9 @@
 
   processor()->OnUpdateReceived(CreateDummyModelTypeState(), std::move(updates),
                                 /*gc_directive=*/absl::nullopt);
+
+  histogram_tester.ExpectTotalCount(
+      "Sync.NonReflectionUpdateFreshnessPossiblySkewed2", 0);
 }
 
 TEST_F(NigoriModelTypeProcessorTest, ShouldStopSyncingAndKeepMetadata) {
diff --git a/components/url_formatter/spoof_checks/common_words/data/README.md b/components/url_formatter/spoof_checks/common_words/data/README.md
index b946d62..b6c0db0 100644
--- a/components/url_formatter/spoof_checks/common_words/data/README.md
+++ b/components/url_formatter/spoof_checks/common_words/data/README.md
@@ -4,33 +4,55 @@
 dataset, itself derived from Google's Web Trillion Word Corpus. See
 https://norvig.com/ngrams/.
 
-## `common_words.list`
+## `common_words.gperf`
 This file contains a list of 10k most common English words, all of which are at
 least 3 characters long, and containing no brands from the current top domain
-list.
+list. This file is used to generate a DAFSA which is then embedded in Chrome.
 
-The file can be generated by running `generate_common_words.sh`.
+## `brands_in_common_words.list`
+This file contains a list of brands, where each brand is identified by
+manually looking through overlaps between brand names in `domains.list` and
+common English words.
 
-## `brands_in_common_words_regex.list`
-This file contains a list of `^BRAND$` patterns, where each `BRAND` was
-identified by manually looking through overlaps between this list with the e2LDs
-in `top_domains.list`.
+## How to generate the files
 
-The initial list of overlaps was generated with:
-```
-$ cut -f1 -d. top_domains.list | sort > top_domains_sorted.list
-$ awk 'length($1) > 2 {print $1}' count_1w.txt \
-  | head -n 10000 | sort | comm -12 - top_domains_sorted.list > overlap.list
+`common_words.gperf` is generated by downloading a publicly available common
+words file, computing the overlap of this file with `domains.list` and manually
+filtering the overlap file.
+
+1. Generate the initial list of overlaps with:
 ```
 
-I then manually filtered `overlap.list`, removing anything that wasn't
-indisputably a brand and not also a valid English word (i.e. excluding any words
-where there were common non-brand meanings as in "apple").
+# Run this from the src/ dir:
+cd components/url_formatter/spoof_checks/top_domains
+
+# Get the count_1w.txt file:
+wget https://norvig.com/ngrams/count_1w.txt
+
+# Sort the registered-part of the domains from the top domain list, such as
+# "google" and "apple":
+cut -f1 -d. domains.list | sort > brands_sorted.list
+
+# Generate overlap.list file which contains words common between count_1w.txt
+# and brands_sorted.list. Only uses top 10K words with at least three characters
+# from count_1w.txt.
+awk 'length($1) > 2 {print $1}' count_1w.txt \
+  | head -n 10000 | sort | comm -12 - brands_sorted.list > overlap.list
+```
+
+2. Manually filter `overlap.list`, removing anything that either isn't a brand
+(e.g. "weather"), or is a brand but is also a valid English word (e.g. "apple").
 
 This approach isn't perfect -- the common words list still contains lots of
-brands, but at least it doesn't contain brands that are in the current top
-domain list. The final list also contains `|brands_in_common_words_regex.list|`
-extra unfiltered words. I spot-checked the final entries of the list to ensure
-no brands snuck in.
+brands, but at least it shouldn't contain brands that are in the current top
+domain list.
+
+3. Copy the contents of `overlap.list` to `brands_in_common_words.list`.
+
+4. Run `./generate_common_words.sh` to generate `common_words.gperf`.
+
+The final list also contains extra unfiltered words. Spot-check the final
+`common_words.gperf` file to ensure no brands snuck in. If there are any brands,
+remove them manually.
 
 **This list should be regenerated whenever the top domains list is updated.**
diff --git a/components/user_education/common/feature_promo_specification.cc b/components/user_education/common/feature_promo_specification.cc
index 12b8152..2746e2e 100644
--- a/components/user_education/common/feature_promo_specification.cc
+++ b/components/user_education/common/feature_promo_specification.cc
@@ -23,7 +23,9 @@
 bool IsAllowedLegalNotice(const base::Feature& promo_feature) {
   // Add the text names of allowlisted critical promos here:
   static const char* const kAllowedPromoNames[] = {
-      "IPH_TrackingProtectionOnboarding"};
+      "IPH_TrackingProtectionOnboarding",
+      "IPH_TrackingProtectionOffboarding",
+  };
   for (const auto* promo_name : kAllowedPromoNames) {
     if (!strcmp(promo_feature.name, promo_name)) {
       return true;
diff --git a/components/vector_icons/BUILD.gn b/components/vector_icons/BUILD.gn
index fa829e1..221fc8cd 100644
--- a/components/vector_icons/BUILD.gn
+++ b/components/vector_icons/BUILD.gn
@@ -168,6 +168,7 @@
     "photo.icon",
     "photo_chrome_refresh.icon",
     "photo_off_chrome_refresh.icon",
+    "picture_in_picture.icon",
     "picture_in_picture_alt.icon",
     "play_arrow.icon",
     "play_arrow_chrome_refresh.icon",
diff --git a/components/vector_icons/picture_in_picture.icon b/components/vector_icons/picture_in_picture.icon
new file mode 100644
index 0000000..b581e3a
--- /dev/null
+++ b/components/vector_icons/picture_in_picture.icon
@@ -0,0 +1,33 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+CANVAS_DIMENSIONS, 16,
+MOVE_TO, 2.67f, 13.33f,
+CUBIC_TO, 2.3f, 13.33f, 1.98f, 13.2f, 1.73f, 12.94f,
+CUBIC_TO, 1.46f, 12.68f, 1.33f, 12.37f, 1.33f, 12,
+LINE_TO, 1.33f, 4,
+CUBIC_TO, 1.33f, 3.63f, 1.46f, 3.32f, 1.73f, 3.06f,
+CUBIC_TO, 1.98f, 2.8f, 2.3f, 2.67f, 2.67f, 2.67f,
+LINE_TO, 13.33f, 2.67f,
+CUBIC_TO, 13.7f, 2.67f, 14.02f, 2.8f, 14.27f, 3.06f,
+CUBIC_TO, 14.54f, 3.32f, 14.67f, 3.63f, 14.67f, 4,
+LINE_TO, 14.67f, 12,
+CUBIC_TO, 14.67f, 12.37f, 14.54f, 12.68f, 14.27f, 12.94f,
+CUBIC_TO, 14.02f, 13.2f, 13.7f, 13.33f, 13.33f, 13.33f,
+CLOSE,
+MOVE_TO, 2.67f, 12,
+LINE_TO, 13.33f, 12,
+LINE_TO, 13.33f, 4,
+LINE_TO, 2.67f, 4,
+CLOSE,
+MOVE_TO, 7.33f, 8.67f,
+LINE_TO, 12.67f, 8.67f,
+LINE_TO, 12.67f, 4.67f,
+LINE_TO, 7.33f, 4.67f,
+CLOSE,
+MOVE_TO, 2.67f, 12,
+LINE_TO, 2.67f, 4,
+CLOSE,
+MOVE_TO, 2.67f, 12,
+CLOSE
diff --git a/components/viz/client/client_resource_provider.h b/components/viz/client/client_resource_provider.h
index 0d031b0..fc0230df 100644
--- a/components/viz/client/client_resource_provider.h
+++ b/components/viz/client/client_resource_provider.h
@@ -14,7 +14,6 @@
 #include "components/viz/common/display/renderer_settings.h"
 #include "components/viz/common/resources/release_callback.h"
 #include "components/viz/common/resources/resource_id.h"
-#include "components/viz/common/resources/resource_settings.h"
 #include "components/viz/common/resources/returned_resource.h"
 #include "components/viz/common/resources/transferable_resource.h"
 #include "third_party/khronos/GLES2/gl2.h"
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn
index 25c9d89..4fb0378 100644
--- a/components/viz/common/BUILD.gn
+++ b/components/viz/common/BUILD.gn
@@ -221,8 +221,6 @@
     "resources/platform_color.h",
     "resources/release_callback.h",
     "resources/resource_id.h",
-    "resources/resource_settings.cc",
-    "resources/resource_settings.h",
     "resources/return_callback.h",
     "resources/returned_resource.cc",
     "resources/returned_resource.h",
diff --git a/components/viz/common/features.cc b/components/viz/common/features.cc
index a4ff507..5e3982a 100644
--- a/components/viz/common/features.cc
+++ b/components/viz/common/features.cc
@@ -326,6 +326,13 @@
              "InvalidateLocalSurfaceIdPreCommit",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+// On mac, when the RenderWidgetHostViewMac is hidden, also hide the
+// DelegatedFrameHost. Among other things, it unlocks the compositor frames,
+// which can saves hundreds of MiB of memory with bfcache entries.
+BASE_FEATURE(kHideDelegatedFrameHostMac,
+             "HideDelegatedFrameHostMac",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 bool IsDelegatedCompositingEnabled() {
   return base::FeatureList::IsEnabled(kDelegatedCompositing);
 }
diff --git a/components/viz/common/features.h b/components/viz/common/features.h
index d9c9e70..6424b5f 100644
--- a/components/viz/common/features.h
+++ b/components/viz/common/features.h
@@ -83,6 +83,7 @@
 VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kEnableADPFRendererMain);
 VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kEnableADPFAsyncThreadsVerification);
 VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kInvalidateLocalSurfaceIdPreCommit);
+VIZ_COMMON_EXPORT BASE_DECLARE_FEATURE(kHideDelegatedFrameHostMac);
 
 VIZ_COMMON_EXPORT extern const char kDraw1Point12Ms[];
 VIZ_COMMON_EXPORT extern const char kDraw2Points6Ms[];
diff --git a/components/viz/common/resources/resource_settings.cc b/components/viz/common/resources/resource_settings.cc
deleted file mode 100644
index ef28ff5..0000000
--- a/components/viz/common/resources/resource_settings.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/viz/common/resources/resource_settings.h"
-
-namespace viz {
-
-ResourceSettings::ResourceSettings() = default;
-
-ResourceSettings::ResourceSettings(const ResourceSettings& other) = default;
-
-ResourceSettings::~ResourceSettings() = default;
-
-ResourceSettings& ResourceSettings::operator=(const ResourceSettings& other) =
-    default;
-
-}  // namespace viz
diff --git a/components/viz/common/resources/resource_settings.h b/components/viz/common/resources/resource_settings.h
deleted file mode 100644
index 8ce8ea7..0000000
--- a/components/viz/common/resources/resource_settings.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_SETTINGS_H_
-#define COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_SETTINGS_H_
-
-#include <stddef.h>
-
-#include "components/viz/common/viz_common_export.h"
-
-namespace viz {
-
-// ResourceSettings contains all the settings that are needed to create a
-// ResourceProvider.
-class VIZ_COMMON_EXPORT ResourceSettings {
- public:
-  ResourceSettings();
-  ResourceSettings(const ResourceSettings& other);
-  ResourceSettings& operator=(const ResourceSettings& other);
-  ~ResourceSettings();
-
-  bool use_gpu_memory_buffer_resources = false;
-  // TODO(crbug.com/759456): Remove after r16 is used without the flag.
-  bool use_r16_texture = false;
-};
-
-}  // namespace viz
-
-#endif  // COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_SETTINGS_H_
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc
index d3512fe..1c92c72 100644
--- a/components/viz/service/display/renderer_pixeltest.cc
+++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -2000,17 +2000,16 @@
     IntersectingQuadPixelTest::SetUp();
     constexpr bool kUseStreamVideoDrawQuad = false;
     constexpr bool kUseGpuMemoryBufferResources = false;
-    constexpr bool kUseR16Texture = false;
     constexpr int kMaxResourceSize = 10000;
 
     video_resource_updater_ = std::make_unique<media::VideoResourceUpdater>(
         this->child_context_provider_.get(), nullptr,
         this->child_resource_provider_.get(), kUseStreamVideoDrawQuad,
-        kUseGpuMemoryBufferResources, kUseR16Texture, kMaxResourceSize);
+        kUseGpuMemoryBufferResources, kMaxResourceSize);
     video_resource_updater2_ = std::make_unique<media::VideoResourceUpdater>(
         this->child_context_provider_.get(), nullptr,
         this->child_resource_provider_.get(), kUseStreamVideoDrawQuad,
-        kUseGpuMemoryBufferResources, kUseR16Texture, kMaxResourceSize);
+        kUseGpuMemoryBufferResources, kMaxResourceSize);
   }
 
   void TearDown() override {
@@ -2422,11 +2421,10 @@
     VizPixelTest::SetUp();
     constexpr bool kUseStreamVideoDrawQuad = false;
     constexpr bool kUseGpuMemoryBufferResources = false;
-    constexpr bool kUseR16Texture = false;
     constexpr int kMaxResourceSize = 10000;
     video_resource_updater_ = std::make_unique<media::VideoResourceUpdater>(
         child_context_provider_.get(), nullptr, child_resource_provider_.get(),
-        kUseStreamVideoDrawQuad, kUseGpuMemoryBufferResources, kUseR16Texture,
+        kUseStreamVideoDrawQuad, kUseGpuMemoryBufferResources,
         kMaxResourceSize);
   }
 
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
index 2016edc9..17718f38f6 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -77,6 +77,7 @@
 #include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
 #include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
 #include "third_party/skia/include/gpu/graphite/Context.h"
+#include "third_party/skia/include/gpu/graphite/Surface.h"
 #include "third_party/skia/include/private/chromium/GrDeferredDisplayList.h"
 #include "third_party/skia/include/private/chromium/GrPromiseImageTexture.h"
 #include "ui/gfx/color_space.h"
@@ -1030,35 +1031,31 @@
     SkSurface* surface,
     std::vector<GrBackendSemaphore>& end_semaphores,
     gpu::SkiaImageRepresentation::ScopedWriteAccess* scoped_write_access,
-    GrGpuFinishedProc finished_proc,
-    GrGpuFinishedContext finished_context) {
+    GrGpuFinishedProc ganesh_finished_proc,
+    GrGpuFinishedContext ganesh_finished_context,
+    skgpu::graphite::GpuFinishedProc graphite_finished_proc,
+    skgpu::graphite::GpuFinishedContext graphite_finished_context) {
   return FlushInternal(surface, end_semaphores, scoped_write_access,
-                       finished_proc, finished_context);
-}
-
-bool SkiaOutputSurfaceImplOnGpu::FlushContext(
-    std::vector<GrBackendSemaphore>& end_semaphores,
-    gpu::SkiaImageRepresentation::ScopedWriteAccess* scoped_write_access,
-    GrGpuFinishedProc finished_proc,
-    GrGpuFinishedContext finished_context) {
-  return FlushInternal(/*surface=*/nullptr, end_semaphores, scoped_write_access,
-                       finished_proc, finished_context);
+                       ganesh_finished_proc, ganesh_finished_context,
+                       graphite_finished_proc, graphite_finished_context);
 }
 
 bool SkiaOutputSurfaceImplOnGpu::FlushInternal(
     SkSurface* surface,
     std::vector<GrBackendSemaphore>& end_semaphores,
     gpu::SkiaImageRepresentation::ScopedWriteAccess* scoped_write_access,
-    GrGpuFinishedProc finished_proc,
-    GrGpuFinishedContext finished_context) {
+    GrGpuFinishedProc ganesh_finished_proc,
+    GrGpuFinishedContext ganesh_finished_context,
+    skgpu::graphite::GpuFinishedProc graphite_finished_proc,
+    skgpu::graphite::GpuFinishedContext graphite_finished_context) {
   gl::ScopedProgressReporter scoped_process_reporter(
       context_state_->progress_reporter());
   if (gr_context()) {
     GrFlushInfo flush_info;
     flush_info.fNumSemaphores = end_semaphores.size();
     flush_info.fSignalSemaphores = end_semaphores.data();
-    flush_info.fFinishedProc = finished_proc;
-    flush_info.fFinishedContext = finished_context;
+    flush_info.fFinishedProc = ganesh_finished_proc;
+    flush_info.fFinishedContext = ganesh_finished_context;
     gpu::AddVulkanCleanupTaskForSkiaFlush(vulkan_context_provider_,
                                           &flush_info);
     GrSemaphoresSubmitted flush_result =
@@ -1076,6 +1073,9 @@
   if (recording) {
     skgpu::graphite::InsertRecordingInfo info = {};
     info.fRecording = recording.get();
+    info.fTargetSurface = surface;
+    info.fFinishedContext = graphite_finished_context;
+    info.fFinishedProc = graphite_finished_proc;
     return graphite_context()->insertRecording(info);
   }
   return false;
@@ -1122,18 +1122,20 @@
             &mailbox_access_data.end_semaphores,
             gpu::SharedImageRepresentation::AllowUnclearedAccess::kYes);
 
-    if (is_multiplane) {
-      // NOTE: For multiplanar SharedImage there is only one set of semaphores
-      // for all of the planes. Rather than waiting on one of the planes we wait
-      // on the context, which facilitates flushing later: we first flush the
-      // individual surfaces without signaling followed by flushing+signaling
-      // the context.
-      gr_context()->wait(mailbox_access_data.begin_semaphores.size(),
-                         mailbox_access_data.begin_semaphores.data());
-    } else {
-      SkSurface* dest_surface = scoped_write->surface();
-      dest_surface->wait(mailbox_access_data.begin_semaphores.size(),
-                         mailbox_access_data.begin_semaphores.data());
+    if (gr_context()) {
+      if (is_multiplane) {
+        // NOTE: For multiplanar SharedImage there is only one set of semaphores
+        // for all of the planes. Rather than waiting on one of the planes we
+        // wait on the context, which facilitates flushing later: we first flush
+        // the individual surfaces without signaling followed by
+        // flushing+signaling the context.
+        gr_context()->wait(mailbox_access_data.begin_semaphores.size(),
+                           mailbox_access_data.begin_semaphores.data());
+      } else {
+        SkSurface* dest_surface = scoped_write->surface();
+        dest_surface->wait(mailbox_access_data.begin_semaphores.size(),
+                           mailbox_access_data.begin_semaphores.data());
+      }
     }
 
     // Semaphores have already been populated in `mailbox_access_data`.
@@ -1178,18 +1180,20 @@
             &mailbox_access_data.end_semaphores,
             gpu::SharedImageRepresentation::AllowUnclearedAccess::kYes);
 
-    if (is_multiplane) {
-      // NOTE: For multiplanar SharedImage there is only one set of semaphores
-      // for all of the planes. Rather than waiting on one of the planes we wait
-      // on the context, which facilitates flushing later: we first flush the
-      // individual surfaces without signaling followed by flushing+signaling
-      // the context.
-      gr_context()->wait(mailbox_access_data.begin_semaphores.size(),
-                         mailbox_access_data.begin_semaphores.data());
-    } else {
-      SkSurface* dest_surface = scoped_write->surface();
-      dest_surface->wait(mailbox_access_data.begin_semaphores.size(),
-                         mailbox_access_data.begin_semaphores.data());
+    if (gr_context()) {
+      if (is_multiplane) {
+        // NOTE: For multiplanar SharedImage there is only one set of semaphores
+        // for all of the planes. Rather than waiting on one of the planes we
+        // wait on the context, which facilitates flushing later: we first flush
+        // the individual surfaces without signaling followed by
+        // flushing+signaling the context.
+        gr_context()->wait(mailbox_access_data.begin_semaphores.size(),
+                           mailbox_access_data.begin_semaphores.data());
+      } else {
+        SkSurface* dest_surface = scoped_write->surface();
+        dest_surface->wait(mailbox_access_data.begin_semaphores.size(),
+                           mailbox_access_data.begin_semaphores.data());
+      }
     }
 
     // Semaphores have already been populated in `mailbox_access_data`.
@@ -1218,7 +1222,6 @@
   }
 }
 
-// TODO(crbug.com/1452092): Make this path work with Graphite.
 void SkiaOutputSurfaceImplOnGpu::CopyOutputNV12(
     SkSurface* surface,
     copy_output::RenderPassGeometry geometry,
@@ -1305,6 +1308,7 @@
     if (!blit_target_image_rect.Contains(blit_destination_rect)) {
       // Send empty result, the blit target image is not large enough to fit the
       // results.
+      DVLOG(1) << "blit target image is not large enough to fit results";
       return;
     }
   } else {
@@ -1324,12 +1328,24 @@
   }
 
   // Create a destination for the scaled & clipped result:
-  auto intermediate_surface = SkSurfaces::RenderTarget(
-      gr_context(), skgpu::Budgeted::kYes,
-      SkImageInfo::Make(gfx::SizeToSkISize(intermediate_dst_size),
-                        SkColorType::kRGBA_8888_SkColorType,
-                        SkAlphaType::kPremul_SkAlphaType,
-                        color_space.ToSkColorSpace()));
+  sk_sp<SkSurface> intermediate_surface;
+  if (gr_context()) {
+    intermediate_surface = SkSurfaces::RenderTarget(
+        gr_context(), skgpu::Budgeted::kYes,
+        SkImageInfo::Make(gfx::SizeToSkISize(intermediate_dst_size),
+                          SkColorType::kRGBA_8888_SkColorType,
+                          SkAlphaType::kPremul_SkAlphaType,
+                          color_space.ToSkColorSpace()));
+  } else {
+    CHECK(graphite_context());
+    intermediate_surface = SkSurfaces::RenderTarget(
+        graphite_recorder(),
+        SkImageInfo::Make(gfx::SizeToSkISize(intermediate_dst_size),
+                          SkColorType::kRGBA_8888_SkColorType,
+                          SkAlphaType::kPremul_SkAlphaType,
+                          color_space.ToSkColorSpace()),
+        skgpu::Mipmapped::kNo);
+  }
 
   if (!intermediate_surface) {
     DVLOG(1) << "failed to create surface for the intermediate texture";
@@ -1354,7 +1370,9 @@
                         request->blit_request());
   }
 
-  gr_context()->flush(intermediate_surface.get());
+  if (gr_context()) {
+    gr_context()->flush(intermediate_surface.get());
+  }
 
   auto intermediate_image = intermediate_surface->makeImageSnapshot();
   if (!intermediate_image) {
@@ -1439,12 +1457,12 @@
         mailbox_holders, color_space, is_multiplane);
   }
 
-  bool should_submit = false;
+  bool should_submit_gr_context = false;
   size_t num_mailboxes = is_multiplane ? 1 : CopyOutputResult::kNV12MaxPlanes;
   for (size_t i = 0; i < num_mailboxes; ++i) {
     mailbox_access_datas[i].representation->SetCleared();
 
-    should_submit |= !mailbox_access_datas[i].end_semaphores.empty();
+    should_submit_gr_context |= !mailbox_access_datas[i].end_semaphores.empty();
 
     // Prepare a per-mailbox context that will notify the per-request context
     // that the GPU-side work for this mailbox has completed.
@@ -1460,29 +1478,37 @@
       ++num_readbacks_pending_;
     }
 
-    bool flush_succeeded = false;
-    if (is_multiplane) {
+    if (is_multiplane && gr_context()) {
       // Flush the individual surfaces followed by flushing the context and
       // signaling.
       gr_context()->flush(plane_surfaces[0], GrFlushInfo());
       gr_context()->flush(plane_surfaces[1], GrFlushInfo());
-      flush_succeeded = FlushContext(
-          mailbox_access_datas[i].end_semaphores,
-          mailbox_access_datas[i].scoped_write.get(),
-          should_wait_for_gpu_work
-              ? &NV12SingleMailboxReadyContext::OnMailboxReady
-              : nullptr,
-          should_wait_for_gpu_work ? nv12_plane_ready.release() : nullptr);
-    } else {
-      flush_succeeded = FlushSurface(
-          plane_surfaces[i], mailbox_access_datas[i].end_semaphores,
-          mailbox_access_datas[i].scoped_write.get(),
-          should_wait_for_gpu_work
-              ? &NV12SingleMailboxReadyContext::OnMailboxReady
-              : nullptr,
-          should_wait_for_gpu_work ? nv12_plane_ready.release() : nullptr);
     }
 
+    auto* finished_context =
+        should_wait_for_gpu_work ? nv12_plane_ready.release() : nullptr;
+    auto* plane_surface = is_multiplane ? nullptr : plane_surfaces[i];
+    bool flush_succeeded = false;
+    if (gr_context()) {
+      flush_succeeded =
+          FlushSurface(plane_surface, mailbox_access_datas[i].end_semaphores,
+                       mailbox_access_datas[i].scoped_write.get(),
+                       should_wait_for_gpu_work
+                           ? &NV12SingleMailboxReadyContext::OnMailboxReady
+                           : nullptr,
+                       finished_context);
+    } else {
+      CHECK(graphite_context());
+      skgpu::graphite::GpuFinishedProc graphite_proc =
+          [](void* context, skgpu::CallbackResult result) {
+            NV12SingleMailboxReadyContext::OnMailboxReady(context);
+          };
+      flush_succeeded = FlushSurface(
+          plane_surface, mailbox_access_datas[i].end_semaphores,
+          mailbox_access_datas[i].scoped_write.get(),
+          /*ganesh_finished_proc=*/nullptr, /*ganesh_finished_context=*/nullptr,
+          should_wait_for_gpu_work ? graphite_proc : nullptr, finished_context);
+    }
     if (!flush_succeeded) {
       // TODO(penghuang): handle vulkan device lost.
       FailedSkiaFlush("CopyOutputNV12 plane_surfaces[i]->flush()");
@@ -1490,11 +1516,16 @@
     }
   }
 
-  if (should_submit && !gr_context()->submit()) {
+  if (should_submit_gr_context && !gr_context()->submit()) {
     DLOG(ERROR) << "CopyOutputNV12 gr_context->submit() failed";
     return;
   }
 
+  if (graphite_context() && !graphite_context()->submit()) {
+    DLOG(ERROR) << "CopyOutputNV12 graphite_context->submit() failed";
+    return;
+  }
+
   if (should_wait_for_gpu_work) {
     // Flow will continue after GPU work is done - see
     // `NV12PlanesReadyContext::OnMailboxReady()` that eventually gets called.
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
index d945e91..4aa098c 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -364,8 +364,10 @@
       SkSurface* surface,
       std::vector<GrBackendSemaphore>& end_semaphores,
       gpu::SkiaImageRepresentation::ScopedWriteAccess* scoped_write_access,
-      GrGpuFinishedProc finished_proc = nullptr,
-      GrGpuFinishedContext finished_context = nullptr);
+      GrGpuFinishedProc ganesh_finished_proc = nullptr,
+      GrGpuFinishedContext ganesh_finished_context = nullptr,
+      skgpu::graphite::GpuFinishedProc graphite_finished_proc = nullptr,
+      skgpu::graphite::GpuFinishedContext graphite_finished_context = nullptr);
 
   // Helper for `CopyOutput()` method, handles the RGBA format.
   void CopyOutputRGBA(SkSurface* surface,
@@ -415,16 +417,10 @@
       SkSurface* surface,
       std::vector<GrBackendSemaphore>& end_semaphores,
       gpu::SkiaImageRepresentation::ScopedWriteAccess* scoped_write_access,
-      GrGpuFinishedProc finished_proc = nullptr,
-      GrGpuFinishedContext finished_context = nullptr);
-
-  // Helper for `CopyOutputNV12()` & `CopyOutputRGBA()` methods, flushes writes
-  // to the Skia context with |end_semaphores| and |end_state|.
-  bool FlushContext(
-      std::vector<GrBackendSemaphore>& end_semaphores,
-      gpu::SkiaImageRepresentation::ScopedWriteAccess* scoped_write_access,
-      GrGpuFinishedProc finished_proc = nullptr,
-      GrGpuFinishedContext finished_context = nullptr);
+      GrGpuFinishedProc ganesh_finished_proc = nullptr,
+      GrGpuFinishedContext ganesh_finished_context = nullptr,
+      skgpu::graphite::GpuFinishedProc graphite_finished_proc = nullptr,
+      skgpu::graphite::GpuFinishedContext graphite_finished_context = nullptr);
 
   // Creates surfaces needed to store the data in NV12 format.
   // |mailbox_access_datas| will be populated with information needed to access
diff --git a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
index 61e8625..695688d2 100644
--- a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
+++ b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
@@ -55,33 +55,28 @@
     return;
   }
 
-  web_contents()->GetPrimaryMainFrame()->ForEachRenderFrameHost(
-      [this](RenderFrameHostImpl* frame) {
-        if (frame->IsRenderFrameLive()) {
-          InstallFilterAndRegisterRoutingId(frame);
-        }
-      });
-}
+  web_contents()
+      ->GetPrimaryMainFrame()
+      ->ForEachRenderFrameHost(
+          [this](RenderFrameHostImpl* frame) {
+            AgentSchedulingGroupHost& agent_scheduling_group =
+                frame->GetAgentSchedulingGroup();
 
-void GinJavaBridgeDispatcherHost::InstallFilterAndRegisterRoutingId(
-    RenderFrameHost* render_frame_host) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  AgentSchedulingGroupHost& agent_scheduling_group =
-      static_cast<RenderFrameHostImpl*>(render_frame_host)
-          ->GetAgentSchedulingGroup();
-  scoped_refptr<GinJavaBridgeMessageFilter> per_asg_filter =
-      GinJavaBridgeMessageFilter::FromHost(agent_scheduling_group,
-                                           /*create_if_not_exists=*/true);
-  if (base::FeatureList::IsEnabled(features::kMBIMode)) {
-    scoped_refptr<GinJavaBridgeObjectDeletionMessageFilter>
-        process_global_filter =
-            GinJavaBridgeObjectDeletionMessageFilter::FromHost(
-                agent_scheduling_group.GetProcess(),
-                /*create_if_not_exists=*/true);
-    process_global_filter->AddRoutingIdForHost(this, render_frame_host);
-  }
+            scoped_refptr<GinJavaBridgeMessageFilter> per_asg_filter =
+                GinJavaBridgeMessageFilter::FromHost(
+                    agent_scheduling_group,
+                    /*create_if_not_exists=*/true);
+            if (base::FeatureList::IsEnabled(features::kMBIMode)) {
+              scoped_refptr<GinJavaBridgeObjectDeletionMessageFilter>
+                  process_global_filter =
+                      GinJavaBridgeObjectDeletionMessageFilter::FromHost(
+                          agent_scheduling_group.GetProcess(),
+                          /*create_if_not_exists=*/true);
+              process_global_filter->AddRoutingIdForHost(this, frame);
+            }
 
-  per_asg_filter->AddRoutingIdForHost(this, render_frame_host);
+            per_asg_filter->AddRoutingIdForHost(this, frame);
+          });
 }
 
 WebContentsImpl* GinJavaBridgeDispatcherHost::web_contents() const {
@@ -91,11 +86,16 @@
 void GinJavaBridgeDispatcherHost::RenderFrameCreated(
     RenderFrameHost* render_frame_host) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (named_objects_.empty()) {
-    return;
+  AgentSchedulingGroupHost& agent_scheduling_group =
+      static_cast<RenderFrameHostImpl*>(render_frame_host)
+          ->GetAgentSchedulingGroup();
+  if (scoped_refptr<GinJavaBridgeMessageFilter> filter =
+          GinJavaBridgeMessageFilter::FromHost(
+              agent_scheduling_group, /*create_if_not_exists=*/false)) {
+    filter->AddRoutingIdForHost(this, render_frame_host);
+  } else {
+    InstallFilterAndRegisterAllRoutingIds();
   }
-
-  InstallFilterAndRegisterRoutingId(render_frame_host);
   for (NamedObjectMap::const_iterator iter = named_objects_.begin();
        iter != named_objects_.end();
        ++iter) {
@@ -104,18 +104,19 @@
   }
 }
 
-void GinJavaBridgeDispatcherHost::RenderFrameDeleted(
-    RenderFrameHost* render_frame_host) {
-  AgentSchedulingGroupHost& agent_scheduling_group =
-      static_cast<RenderFrameHostImpl*>(render_frame_host)
-          ->GetAgentSchedulingGroup();
-  scoped_refptr<GinJavaBridgeMessageFilter> filter =
-      GinJavaBridgeMessageFilter::FromHost(agent_scheduling_group,
-                                           /*create_if_not_exists=*/false);
+void GinJavaBridgeDispatcherHost::WebContentsDestroyed() {
+  // Unretained() is safe because ForEachRenderFrameHost() is synchronous.
+  web_contents()->GetPrimaryMainFrame()->ForEachRenderFrameHost(
+      [this](RenderFrameHostImpl* frame) {
+        AgentSchedulingGroupHost& agent_scheduling_group =
+            frame->GetAgentSchedulingGroup();
+        scoped_refptr<GinJavaBridgeMessageFilter> filter =
+            GinJavaBridgeMessageFilter::FromHost(
+                agent_scheduling_group, /*create_if_not_exists=*/false);
 
-  if (filter) {
-    filter->RemoveHost(this);
-  }
+        if (filter)
+          filter->RemoveHost(this);
+      });
 }
 
 void GinJavaBridgeDispatcherHost::PrimaryPageChanged(Page& page) {
diff --git a/content/browser/android/java/gin_java_bridge_dispatcher_host.h b/content/browser/android/java/gin_java_bridge_dispatcher_host.h
index eba544c67f..2e29b17b 100644
--- a/content/browser/android/java/gin_java_bridge_dispatcher_host.h
+++ b/content/browser/android/java/gin_java_bridge_dispatcher_host.h
@@ -51,8 +51,8 @@
 
   // WebContentsObserver
   void RenderFrameCreated(RenderFrameHost* render_frame_host) override;
-  void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
   void PrimaryMainDocumentElementAvailable() override;
+  void WebContentsDestroyed() override;
   void PrimaryPageChanged(Page& page) override;
 
   // GinJavaMethodInvocationHelper::DispatcherDelegate
@@ -84,7 +84,6 @@
 
   // Run on the UI thread.
   void InstallFilterAndRegisterAllRoutingIds();
-  void InstallFilterAndRegisterRoutingId(RenderFrameHost* render_frame_host);
   WebContentsImpl* web_contents() const;
 
   // Run on any thread.
diff --git a/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc b/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc
index 2601834..3bd1e25 100644
--- a/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc
+++ b/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc
@@ -117,10 +117,8 @@
     pending_read_ = nullptr;
   }
 
-  uint32_t available = 0;
-
   MojoResult result = network::MojoToNetPendingBuffer::BeginRead(
-      &consumer_handle_, &pending_read_, &available);
+      &consumer_handle_, &pending_read_);
 
   if (result == MOJO_RESULT_SHOULD_WAIT) {
     handle_watcher_.ArmOrNotify();
@@ -142,8 +140,7 @@
     return;
   }
 
-  int bytes_to_read = std::min<int>(kBufferSize, available);
-
+  const int bytes_to_read = std::min<int>(kBufferSize, pending_read_->size());
   auto buffer = base::MakeRefCounted<network::MojoToNetIOBuffer>(
       pending_read_.get(), bytes_to_read);
 
@@ -154,8 +151,10 @@
   int rv = entry_->WriteData(
       disk_cache_body_index_, cache_entry_offset_, buffer.get(), bytes_to_read,
       std::move(cache_write_callback), true /* truncate */);
-  if (rv != net::ERR_IO_PENDING)
+
+  if (rv != net::ERR_IO_PENDING) {
     CacheStorageBlobToDiskCache::DidWriteDataToEntry(bytes_to_read, rv);
+  }
 }
 
 }  // namespace content
diff --git a/content/browser/cross_origin_opener_policy_browsertest.cc b/content/browser/cross_origin_opener_policy_browsertest.cc
index 0c089e2..d71a9b2 100644
--- a/content/browser/cross_origin_opener_policy_browsertest.cc
+++ b/content/browser/cross_origin_opener_policy_browsertest.cc
@@ -4543,15 +4543,18 @@
   int rph_id_3 = current_frame_host()->GetProcess()->GetID();
   EXPECT_EQ(rph_id_2, rph_id_3);
 
-  // This test is parameterized on whether the bfcache is enabled.  With
-  // bfcache, we force a BrowsingInstance swap at the very beginning when the
-  // navigation to `url_2` starts, so there's no need to create a new
-  // SiteInstance when we learn about COOP at response time, since the
+  // The original speculative RFH should always be destroyed.
+  //
+  // Subtle note: this happens even when bfcache is enabled. With bfcache,
+  // we force a BrowsingInstance swap at the very beginning when the navigation
+  // to `url_2` starts.  So when we learn about COOP at response time, the
   // candidate (speculative RFH's) SiteInstance is already in a fresh
-  // BrowsingInstance.  Therefore, with bfcache, the original speculative RFH
-  // will be the RFH that eventually commits.  Otherwise, the original
-  // speculative RFH should be destroyed and replaced by another RFH.
-  EXPECT_NE(IsBackForwardCacheEnabled(), speculative_rfh.IsDestroyed());
+  // BrowsingInstance. However, it cannot be reused, because COOP requires a
+  // BrowsingInstance with b.test as its common_coop_origin(), and the
+  // candidate SiteInstance's BrowsingInstance has no common_coop_origin(), so
+  // it cannot be reused, and we end up creating a new speculative RFH and
+  // destroying the original one.
+  EXPECT_TRUE(speculative_rfh.IsDestroyed());
 }
 
 // Ensure that same-site navigations that result in a COOP mismatch avoid an
@@ -9825,6 +9828,62 @@
   EXPECT_EQ(true, EvalJs(popup_rfh, "opener.closed == false"));
 }
 
+// Regression test for https://crbug.com/1491282.  Ensure that when a
+// navigation to a COOP: RP page requires a new BrowsingInstance in a new
+// CoopRelatedGroup, a subsequent navigation that stays in the same
+// CoopRelatedGroup does not crash.  In this case, it is essential that when a
+// new non-COOP BrowsingInstance in a new CoopRelatedGroup is created at
+// request start time, that BrowsingInstance isn't incorrectly reused at
+// response started time, if the response came back with COOP: RP headers and
+// requires a BrowsingInstance with a different common_coop_origin().
+IN_PROC_BROWSER_TEST_P(CoopRestrictPropertiesAccessBrowserTest,
+                       NewBrowsingInstanceFromBeginNavigationCannotBeReused) {
+  // Start on a WebUI page. The repro for https://crbug.com/1491282 required
+  // this, because the security swap from WebUI to normal pages requires a new
+  // BrowsingInstance (with no common_coop_origin) and a new CoopRelatedGroup
+  // at both request and response time. In contrast, navigating from a normal
+  // page to a COOP:RP page would pick a new BrowsingInstance (with a
+  // common_coop_origin) in the same CoopRelatedGroup at response time, because
+  // the kRelatedCoopSwap reason is chosen after checking for security swaps
+  // but before checking for proactive swaps. A new CoopRelatedGroup guarantees
+  // that ConvertToSiteInstance() will attempt to reuse the speculative
+  // RenderFrameHost's SiteInstance (the "candidate_instance") at response
+  // time, rather than getting a SiteInstance + BrowsingInstance in the same
+  // CoopRelatedGroup.
+  GURL webui_page("chrome://ukm");
+  ASSERT_TRUE(NavigateToURL(shell(), webui_page));
+  scoped_refptr<SiteInstanceImpl> webui_instance(
+      current_frame_host()->GetSiteInstance());
+
+  // Now, navigate to a COOP: restrict-properties page.  This will create a
+  // fresh BrowsingInstance at request start time, and evaluate whether it can
+  // stay in that BrowsingInstance after receiving the response.  In
+  // https://crbug.com/1491282, the BrowsingInstance from request start was
+  // incorrectly reused, resulting in not having a common_coop_origin() at the
+  // end of this navigation.  Ensure this is not the case.
+  GURL coop_rp_page(https_server()->GetURL(
+      "a.test",
+      "/set-header"
+      "?cross-origin-opener-policy: restrict-properties"));
+  ASSERT_TRUE(NavigateToURL(shell(), coop_rp_page));
+  scoped_refptr<SiteInstanceImpl> coop_rp_instance(
+      current_frame_host()->GetSiteInstance());
+  EXPECT_FALSE(
+      webui_instance->IsCoopRelatedSiteInstance(coop_rp_instance.get()));
+  EXPECT_TRUE(coop_rp_instance->GetCommonCoopOrigin().has_value());
+  EXPECT_EQ("a.test", coop_rp_instance->GetCommonCoopOrigin()->host());
+
+  // Ensure that we can navigate to a page without COOP: restrict-properties.
+  // This should swap BrowsingInstances but stay in the same CoopRelatedGroup,
+  // and this shouldn't crash.
+  GURL non_coop_rp_page(https_server()->GetURL("b.test", "/title1.html"));
+  ASSERT_TRUE(NavigateToURL(shell(), non_coop_rp_page));
+  SiteInstanceImpl* non_coop_instance(current_frame_host()->GetSiteInstance());
+  EXPECT_FALSE(non_coop_instance->GetCommonCoopOrigin().has_value());
+  EXPECT_FALSE(coop_rp_instance->IsRelatedSiteInstance(non_coop_instance));
+  EXPECT_TRUE(coop_rp_instance->IsCoopRelatedSiteInstance(non_coop_instance));
+}
+
 IN_PROC_BROWSER_TEST_P(CoopRestrictPropertiesAccessBrowserTest, Prerender) {
   GURL regular_page(https_server()->GetURL("a.test", "/title1.html"));
   GURL coop_rp_page(https_server()->GetURL(
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc
index efa424d..4a1f062 100644
--- a/content/browser/devtools/devtools_instrumentation.cc
+++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -5,6 +5,7 @@
 #include "content/browser/devtools/devtools_instrumentation.h"
 
 #include "base/containers/adapters.h"
+#include "base/feature_list.h"
 #include "base/strings/stringprintf.h"
 #include "base/trace_event/traced_value.h"
 #include "components/download/public/common/download_create_info.h"
@@ -48,6 +49,7 @@
 #include "devtools_instrumentation.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
+#include "net/base/features.h"
 #include "net/base/load_flags.h"
 #include "net/cookies/canonical_cookie.h"
 #include "net/cookies/cookie_inclusion_status.h"
@@ -510,6 +512,31 @@
   return issue;
 }
 
+std::unique_ptr<protocol::Audits::InspectorIssue>
+BuildCookieDeprecationMetadataIssue(
+    const blink::mojom::CookieDeprecationMetadataIssueDetailsPtr&
+        issue_details) {
+  auto metadata_issue_details =
+      protocol::Audits::CookieDeprecationMetadataIssueDetails::Create()
+          .SetAllowedSites(std::make_unique<protocol::Array<protocol::String>>(
+              issue_details->allowed_sites))
+          .Build();
+
+  auto protocol_issue_details =
+      protocol::Audits::InspectorIssueDetails::Create()
+          .SetCookieDeprecationMetadataIssueDetails(
+              std::move(metadata_issue_details))
+          .Build();
+
+  auto issue = protocol::Audits::InspectorIssue::Create()
+                   .SetCode(protocol::Audits::InspectorIssueCodeEnum::
+                                CookieDeprecationMetadataIssue)
+                   .SetDetails(std::move(protocol_issue_details))
+                   .Build();
+
+  return issue;
+}
+
 void UpdateChildFrameTrees(FrameTreeNode* ftn, bool update_target_info) {
   if (auto* agent_host = WebContentsDevToolsAgentHost::GetFor(
           WebContentsImpl::FromFrameTreeNode(ftn))) {
@@ -570,7 +597,9 @@
   scoped_refptr<RenderFrameDevToolsAgentHost> previous_host =
       static_cast<RenderFrameDevToolsAgentHost*>(
           RenderFrameDevToolsAgentHost::GetFor(&new_node));
-  previous_host->SetFrameTreeNode(nullptr);
+  // Disconnect old host entirely, so it detaches from renderer and does not
+  // cause problem if renderer comes back from the BFCache.
+  previous_host->DisconnectWebContents();
   host->SetFrameTreeNode(&new_node);
 }
 
@@ -1686,6 +1715,18 @@
         protocol::Audits::CookieWarningReasonEnum::WarnThirdPartyPhaseout);
   }
 
+  // This warning only affects cookies when the corresponding feature is
+  // enabled, therefore we should only create an issue for it then.
+  if (base::FeatureList::IsEnabled(
+          net::features::kCookieSameSiteConsidersRedirectChain) &&
+      status.HasWarningReason(
+          net::CookieInclusionStatus::
+              WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION)) {
+    warning_reasons->push_back(
+        protocol::Audits::CookieWarningReasonEnum::
+            WarnCrossSiteRedirectDowngradeChangesInclusion);
+  }
+
   return warning_reasons;
 }
 
@@ -1812,6 +1853,10 @@
     issue =
         BuildBounceTrackingIssue(info->details->bounce_tracking_issue_details);
   } else if (info->code == blink::mojom::InspectorIssueCode::
+                               kCookieDeprecationMetadataIssue) {
+    issue = BuildCookieDeprecationMetadataIssue(
+        info->details->cookie_deprecation_metadata_issue_details);
+  } else if (info->code == blink::mojom::InspectorIssueCode::
                                kFederatedAuthUserInfoRequestIssue) {
     issue = BuildFederatedAuthUserInfoRequestIssue(
         info->details->federated_auth_user_info_request_details);
diff --git a/content/browser/display_cutout/display_cutout_host_impl.cc b/content/browser/display_cutout/display_cutout_host_impl.cc
index 0827acd..0365eac 100644
--- a/content/browser/display_cutout/display_cutout_host_impl.cc
+++ b/content/browser/display_cutout/display_cutout_host_impl.cc
@@ -97,8 +97,15 @@
 }
 
 void DisplayCutoutHostImpl::SetCurrentRenderFrameHost(RenderFrameHost* rfh) {
-  if (current_rfh_.get() == rfh)
+  if (current_rfh_.get() == rfh) {
+    if (rfh) {
+      // Send an update even when navigating to the same page or doing a reload.
+      // When we finish navigation we need to push the Safe Area back to the
+      // client to set env() variables for that frame so it can draw correctly.
+      SendSafeAreaToFrame(rfh, insets_);
+    }
     return;
+  }
 
   // If we had a previous frame then we should clear the insets on that frame.
   if (current_rfh_)
diff --git a/content/browser/interest_group/interest_group_pa_report_util.cc b/content/browser/interest_group/interest_group_pa_report_util.cc
index c2507f2..c78bcd4 100644
--- a/content/browser/interest_group/interest_group_pa_report_util.cc
+++ b/content/browser/interest_group/interest_group_pa_report_util.cc
@@ -40,8 +40,6 @@
 // Returns the actual value of `base_value` with corresponding post auction
 // signal such as `winning_bid`. Returns absl::nullopt if corresponding signal
 // is not available.
-// TODO(crbug.com/1385549): Pass in signals for script run time and signals
-// fetch time.
 absl::optional<double> GetBaseValue(
     auction_worklet::mojom::BaseValue base_value,
     double winning_bid,
@@ -82,8 +80,6 @@
     const auction_worklet::mojom::SignalBucketPtr& bucket_obj,
     absl::optional<double> base) {
   if (!base.has_value()) {
-    // Once kScriptRunTime and kSignalsFetchTime are supported, this should not
-    // happen.
     return absl::nullopt;
   }
 
diff --git a/content/browser/media/capture/frame_sink_video_capture_device.cc b/content/browser/media/capture/frame_sink_video_capture_device.cc
index 03cd350..b52773e 100644
--- a/content/browser/media/capture/frame_sink_video_capture_device.cc
+++ b/content/browser/media/capture/frame_sink_video_capture_device.cc
@@ -398,12 +398,13 @@
 void FrameSinkVideoCaptureDevice::Crop(
     const base::Token& crop_id,
     uint32_t crop_version,
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
+    base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+        callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(callback);
 
   std::move(callback).Run(
-      media::mojom::CropRequestResult::kUnsupportedCaptureDevice);
+      media::mojom::ApplySubCaptureTargetResult::kUnsupportedCaptureDevice);
 }
 
 void FrameSinkVideoCaptureDevice::StopAndDeAllocate() {
diff --git a/content/browser/media/capture/frame_sink_video_capture_device.h b/content/browser/media/capture/frame_sink_video_capture_device.h
index e080bbb..b63ad79 100644
--- a/content/browser/media/capture/frame_sink_video_capture_device.h
+++ b/content/browser/media/capture/frame_sink_video_capture_device.h
@@ -88,8 +88,8 @@
   void Resume() final;
   void Crop(const base::Token& crop_id,
             uint32_t crop_version,
-            base::OnceCallback<void(media::mojom::CropRequestResult)> callback)
-      override;
+            base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+                callback) override;
   void StopAndDeAllocate() final;
   void OnUtilizationReport(media::VideoCaptureFeedback feedback) override;
 
diff --git a/content/browser/media/capture/sub_capture_target_id_web_contents_helper.cc b/content/browser/media/capture/sub_capture_target_id_web_contents_helper.cc
index 38bfdefb8..edf91bf 100644
--- a/content/browser/media/capture/sub_capture_target_id_web_contents_helper.cc
+++ b/content/browser/media/capture/sub_capture_target_id_web_contents_helper.cc
@@ -24,7 +24,8 @@
 
 // TODO(crbug.com/1264849): Remove this protected static function.
 // See header for more details.
-base::Token CropIdWebContentsHelper::GUIDToToken(const base::Uuid& guid) {
+base::Token SubCaptureTargetIdWebContentsHelper::GUIDToToken(
+    const base::Uuid& guid) {
   std::string lowercase = guid.AsLowercaseString();
 
   // |lowercase| is either empty, or follows the expected pattern.
@@ -51,67 +52,79 @@
   return base::Token(high, low);
 }
 
-CropIdWebContentsHelper::CropIdWebContentsHelper(WebContents* web_contents)
+SubCaptureTargetIdWebContentsHelper::SubCaptureTargetIdWebContentsHelper(
+    WebContents* web_contents)
     : WebContentsObserver(web_contents),
-      WebContentsUserData<CropIdWebContentsHelper>(*web_contents) {
+      WebContentsUserData<SubCaptureTargetIdWebContentsHelper>(*web_contents) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(web_contents);
 }
 
-CropIdWebContentsHelper::~CropIdWebContentsHelper() = default;
+SubCaptureTargetIdWebContentsHelper::~SubCaptureTargetIdWebContentsHelper() =
+    default;
 
-std::string CropIdWebContentsHelper::ProduceCropId() {
+std::string SubCaptureTargetIdWebContentsHelper::ProduceId(Type type) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  CHECK(type == Type::kCropTarget || type == Type::kRestrictionTarget);
 
-  // Prevent Web-applications from producing an excessive number of crop-IDs.
-  if (crop_ids_.size() >= kMaxCropIdsPerWebContents) {
+  std::vector<base::Token>& ids =
+      (type == Type::kCropTarget) ? crop_ids_ : restriction_ids_;
+
+  // Prevent Web-applications from producing an excessive number of IDs.
+  if (ids.size() >= kMaxIdsPerWebContents) {
     return std::string();
   }
 
   // Given the exceedingly low likelihood of collisions, the check for
   // uniqueness could have theoretically been skipped. But it's cheap
-  // enough to perform, given that `kMaxCropIdsPerWebContents` is so small
+  // enough to perform, given that `kMaxIdsPerWebContents` is so small
   // compared to the space of GUIDs, and it guarantees we never silently fail
-  // the application by cropping to the wrong, duplicate target.
+  // the application by cropping/restricting to the wrong, duplicate target.
   base::Uuid guid;
-  base::Token crop_id;
+  base::Token id;
   do {
     guid = base::Uuid::GenerateRandomV4();
-    crop_id = GUIDToToken(guid);
-  } while (IsAssociatedWithCropId(crop_id));
-  crop_ids_.push_back(crop_id);
+    id = GUIDToToken(guid);
+  } while (IsAssociatedWith(id, type));
+  ids.push_back(id);
 
   return guid.AsLowercaseString();
 }
 
-bool CropIdWebContentsHelper::IsAssociatedWithCropId(
-    const base::Token& crop_id) const {
+bool SubCaptureTargetIdWebContentsHelper::IsAssociatedWith(
+    const base::Token& id,
+    Type type) const {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  CHECK(type == Type::kCropTarget || type == Type::kRestrictionTarget);
 
-  return base::Contains(crop_ids_, crop_id);
+  const std::vector<base::Token>& ids =
+      (type == Type::kCropTarget) ? crop_ids_ : restriction_ids_;
+
+  return base::Contains(ids, id);
 }
 
-void CropIdWebContentsHelper::ReadyToCommitNavigation(
+void SubCaptureTargetIdWebContentsHelper::ReadyToCommitNavigation(
     NavigationHandle* navigation_handle) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   DCHECK(navigation_handle);
 
-  // Cross-document navigation of the top-level frame invalidates all crop-IDs
+  // Cross-document navigation of the top-level frame invalidates all IDs
   // associated with the observed WebContents.
   // Using IsInPrimaryMainFrame is valid here since the browser only caches this
   // state for the active main frame.
   if (!navigation_handle->IsSameDocument() &&
       navigation_handle->IsInPrimaryMainFrame()) {
-    ClearCropIds();
+    ClearIds();
   }
 }
 
-void CropIdWebContentsHelper::ClearCropIds() {
+void SubCaptureTargetIdWebContentsHelper::ClearIds() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   crop_ids_.clear();
+  restriction_ids_.clear();
 }
 
-WEB_CONTENTS_USER_DATA_KEY_IMPL(CropIdWebContentsHelper);
+WEB_CONTENTS_USER_DATA_KEY_IMPL(SubCaptureTargetIdWebContentsHelper);
 
 }  // namespace content
diff --git a/content/browser/media/capture/sub_capture_target_id_web_contents_helper.h b/content/browser/media/capture/sub_capture_target_id_web_contents_helper.h
index 8402540..6ce253a 100644
--- a/content/browser/media/capture/sub_capture_target_id_web_contents_helper.h
+++ b/content/browser/media/capture/sub_capture_target_id_web_contents_helper.h
@@ -17,6 +17,7 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
+#include "third_party/blink/public/mojom/mediastream/media_devices.mojom.h"
 
 #if BUILDFLAG(IS_ANDROID)
 #error Region Capture not supported on Android.
@@ -26,33 +27,37 @@
 
 class NavigationHandle;
 
-class CONTENT_EXPORT CropIdWebContentsHelper final
+class CONTENT_EXPORT SubCaptureTargetIdWebContentsHelper final
     : public WebContentsObserver,
-      public WebContentsUserData<CropIdWebContentsHelper> {
+      public WebContentsUserData<SubCaptureTargetIdWebContentsHelper> {
  public:
-  // Limits the number of crop-IDs a given Web-application can produce
-  // so as to limit the potential for abuse.
+  using Type = blink::mojom::SubCaptureTargetType;
+
+  // Limits the number of SubCaptureTargetIds a given Web-application can
+  // produce of a given type, so as to limit the potential for abuse.
   // Known and accepted issue - embedded iframes can be intentionally disruptive
-  // by producing too many crop-IDs. It's up to the Web-application to not
+  // by producing too many IDs. It's up to the Web-application to not
   // embed such iframes.
-  constexpr static size_t kMaxCropIdsPerWebContents = 100;
+  constexpr static size_t kMaxIdsPerWebContents = 100;
 
-  explicit CropIdWebContentsHelper(WebContents* web_contents);
-  CropIdWebContentsHelper(const CropIdWebContentsHelper&) = delete;
-  CropIdWebContentsHelper& operator=(const CropIdWebContentsHelper&) = delete;
-  ~CropIdWebContentsHelper() final;
+  explicit SubCaptureTargetIdWebContentsHelper(WebContents* web_contents);
+  SubCaptureTargetIdWebContentsHelper(
+      const SubCaptureTargetIdWebContentsHelper&) = delete;
+  SubCaptureTargetIdWebContentsHelper& operator=(
+      const SubCaptureTargetIdWebContentsHelper&) = delete;
+  ~SubCaptureTargetIdWebContentsHelper() final;
 
-  // Produces a new crop-ID, records its association with this WebContents
-  // and returns it.
-  // This method can soft-fail if invoked more than |kMaxCropIdsPerWebContents|
-  // times for a given WebContents. Failure is signaled by returning an
-  // empty string.
-  std::string ProduceCropId();
+  // Produces a new SubCaptureTargetId, records its association with
+  // this WebContents and returns it.
+  // This method can soft-fail if invoked more than |kMaxIdsPerWebContents|
+  // times for a given WebContents.
+  // Failure is signaled by returning an empty string.
+  std::string ProduceId(Type type);
 
-  // Checks whether this WebContents is associated with a crop-ID.
-  // This allows us to check whether a call to cropTo() by the Web-application
-  // is permitted.
-  bool IsAssociatedWithCropId(const base::Token& crop_id) const;
+  // Checks whether this WebContents is associated with a SubCaptureTargetId.
+  // This allows us to check whether a call to cropTo() or restrictTo()
+  // by the Web-application is permitted.
+  bool IsAssociatedWith(const base::Token& id, Type type) const;
 
  protected:
   // TODO(crbug.com/1264849): Remove this local copy of GUIDToToken().
@@ -63,23 +68,24 @@
   static base::Token GUIDToToken(const base::Uuid& guid);
 
  private:
-  friend class WebContentsUserData<CropIdWebContentsHelper>;
-  friend class CropIdWebContentsHelperTest;
+  friend class WebContentsUserData<SubCaptureTargetIdWebContentsHelper>;
+  friend class SubCaptureTargetIdWebContentsHelperTest;
 
   // WebContentsObserver implementation.
-  // Cross-document navigation of the top-level document discards all crop-IDs
-  // associated with the top-level WebContents.
+  // Cross-document navigation of the top-level document discards all
+  // SubCaptureTargetIds associated with the top-level WebContents.
   // TODO(crbug.com/1264849): Record per RFH and treat its navigation.
   void ReadyToCommitNavigation(NavigationHandle* navigation_handle) final;
 
-  // Forgets all associations of crop-IDs to this WebContents.
+  // Forgets all associations of SubCaptureTargetIds to this WebContents.
   // TODO(crbug.com/1264849): Clear per-RFH or throughout.
-  void ClearCropIds();
+  void ClearIds();
 
-  // Records which crop-IDs are associated with this WebContents.
-  // At most |kMaxCropIdsPerWebContents|, as discussed where
-  // |kMaxCropIdsPerWebContents| is defined.
+  // Records which SubCaptureTargetIds are associated with this WebContents.
+  // At most |kMaxIdsPerWebContents| of each type, as discussed where
+  // |kMaxIdsPerWebContents| is defined.
   std::vector<base::Token> crop_ids_;
+  std::vector<base::Token> restriction_ids_;
 
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 };
diff --git a/content/browser/media/capture/video_capture_device_proxy_lacros.cc b/content/browser/media/capture/video_capture_device_proxy_lacros.cc
index 61052d0..21bf10d 100644
--- a/content/browser/media/capture/video_capture_device_proxy_lacros.cc
+++ b/content/browser/media/capture/video_capture_device_proxy_lacros.cc
@@ -147,12 +147,13 @@
 void VideoCaptureDeviceProxyLacros::Crop(
     const base::Token& crop_id,
     uint32_t crop_version,
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
+    base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+        callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(callback);
 
   std::move(callback).Run(
-      media::mojom::CropRequestResult::kUnsupportedCaptureDevice);
+      media::mojom::ApplySubCaptureTargetResult::kUnsupportedCaptureDevice);
 }
 
 void VideoCaptureDeviceProxyLacros::StopAndDeAllocate() {
diff --git a/content/browser/media/capture/video_capture_device_proxy_lacros.h b/content/browser/media/capture/video_capture_device_proxy_lacros.h
index 46e8de70..4912e2c5 100644
--- a/content/browser/media/capture/video_capture_device_proxy_lacros.h
+++ b/content/browser/media/capture/video_capture_device_proxy_lacros.h
@@ -68,8 +68,8 @@
   void Resume() final;
   void Crop(const base::Token& crop_id,
             uint32_t crop_version,
-            base::OnceCallback<void(media::mojom::CropRequestResult)> callback)
-      override;
+            base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+                callback) override;
   void StopAndDeAllocate() final;
   void GetPhotoState(GetPhotoStateCallback callback) final;
   void SetPhotoOptions(media::mojom::PhotoSettingsPtr settings,
diff --git a/content/browser/media/capture/web_contents_frame_tracker.cc b/content/browser/media/capture/web_contents_frame_tracker.cc
index 1460951..ad3f929 100644
--- a/content/browser/media/capture/web_contents_frame_tracker.cc
+++ b/content/browser/media/capture/web_contents_frame_tracker.cc
@@ -434,7 +434,8 @@
 void WebContentsFrameTracker::Crop(
     const base::Token& crop_id,
     uint32_t crop_version,
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
+    base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+        callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(callback);
 
@@ -443,7 +444,7 @@
     // (MediaStreamDispatcherHost knows the capturer, whereas here we know
     // the capturee.)
     std::move(callback).Run(
-        media::mojom::CropRequestResult::kNonIncreasingCropVersion);
+        media::mojom::ApplySubCaptureTargetResult::kNonIncreasingVersion);
     return;
   }
 
@@ -462,15 +463,17 @@
       FROM_HERE,
       base::BindOnce(
           [](const viz::VideoCaptureTarget& target, uint32_t crop_version,
-             base::OnceCallback<void(media::mojom::CropRequestResult)> callback,
+             base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+                 callback,
              base::WeakPtr<WebContentsVideoCaptureDevice> device) {
             if (!device) {
               std::move(callback).Run(
-                  media::mojom::CropRequestResult::kErrorGeneric);
+                  media::mojom::ApplySubCaptureTargetResult::kErrorGeneric);
               return;
             }
             device->OnTargetChanged(target, crop_version);
-            std::move(callback).Run(media::mojom::CropRequestResult::kSuccess);
+            std::move(callback).Run(
+                media::mojom::ApplySubCaptureTargetResult::kSuccess);
           },
           target, crop_version_, std::move(callback), device_));
 }
diff --git a/content/browser/media/capture/web_contents_frame_tracker.h b/content/browser/media/capture/web_contents_frame_tracker.h
index 693ac6e..4137d6af 100644
--- a/content/browser/media/capture/web_contents_frame_tracker.h
+++ b/content/browser/media/capture/web_contents_frame_tracker.h
@@ -138,7 +138,8 @@
   // to the desired target sequence as necessary.
   void Crop(const base::Token& crop_id,
             uint32_t crop_version,
-            base::OnceCallback<void(media::mojom::CropRequestResult)> callback);
+            base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+                callback);
 
   // WebContents are retrieved on the UI thread normally, from the render IDs,
   // so this method is provided for tests to set the web contents directly.
diff --git a/content/browser/media/capture/web_contents_frame_tracker_unittest.cc b/content/browser/media/capture/web_contents_frame_tracker_unittest.cc
index 0160885..cbc28307 100644
--- a/content/browser/media/capture/web_contents_frame_tracker_unittest.cc
+++ b/content/browser/media/capture/web_contents_frame_tracker_unittest.cc
@@ -364,10 +364,11 @@
 
   // Expect the callback handed to Crop() to be invoke with kSuccess.
   bool success = false;
-  base::OnceCallback<void(media::mojom::CropRequestResult)> callback =
+  base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)> callback =
       base::BindOnce(
-          [](bool* success, media::mojom::CropRequestResult result) {
-            *success = (result == media::mojom::CropRequestResult::kSuccess);
+          [](bool* success, media::mojom::ApplySubCaptureTargetResult result) {
+            *success =
+                (result == media::mojom::ApplySubCaptureTargetResult::kSuccess);
           },
           &success);
 
diff --git a/content/browser/media/capture/web_contents_video_capture_device.cc b/content/browser/media/capture/web_contents_video_capture_device.cc
index 70de27ed..3a5cfb92 100644
--- a/content/browser/media/capture/web_contents_video_capture_device.cc
+++ b/content/browser/media/capture/web_contents_video_capture_device.cc
@@ -55,7 +55,8 @@
 void WebContentsVideoCaptureDevice::Crop(
     const base::Token& crop_id,
     uint32_t crop_version,
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
+    base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+        callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(callback);
 
@@ -63,7 +64,7 @@
       .WithArgs(crop_id, crop_version,
                 mojo::WrapCallbackWithDefaultInvokeIfNotRun(
                     std::move(callback),
-                    media::mojom::CropRequestResult::kErrorGeneric));
+                    media::mojom::ApplySubCaptureTargetResult::kErrorGeneric));
 }
 
 void WebContentsVideoCaptureDevice::OnFrameCaptured(
diff --git a/content/browser/media/capture/web_contents_video_capture_device.h b/content/browser/media/capture/web_contents_video_capture_device.h
index 48a4bf4..3cafbfb 100644
--- a/content/browser/media/capture/web_contents_video_capture_device.h
+++ b/content/browser/media/capture/web_contents_video_capture_device.h
@@ -48,10 +48,10 @@
       const std::string& device_id);
 
   // VideoCaptureDevice overrides.
-  void Crop(
-      const base::Token& crop_id,
-      uint32_t crop_version,
-      base::OnceCallback<void(media::mojom::CropRequestResult)> callback) final;
+  void Crop(const base::Token& crop_id,
+            uint32_t crop_version,
+            base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+                callback) final;
 
   // FrameSinkVideoConsumer overrides.
   void OnFrameCaptured(
diff --git a/content/browser/media/media_browsertest.cc b/content/browser/media/media_browsertest.cc
index b4dc619..7ea1d42 100644
--- a/content/browser/media/media_browsertest.cc
+++ b/content/browser/media/media_browsertest.cc
@@ -53,9 +53,14 @@
 #if BUILDFLAG(IS_ANDROID)
     features::kLogJsConsoleMessages,
 #endif
+
 #if BUILDFLAG(IS_CHROMEOS)
     media::kCrOSLegacyMediaFormats,
 #endif
+
+#if BUILDFLAG(ENABLE_HLS_DEMUXER) && BUILDFLAG(USE_PROPRIETARY_CODECS)
+    media::kBuiltInHlsPlayer,
+#endif
   };
 
   std::vector<base::test::FeatureRef> disabled_features = {
@@ -304,6 +309,13 @@
 }
 
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
+#if BUILDFLAG(ENABLE_HLS_DEMUXER)
+IN_PROC_BROWSER_TEST_P(MediaTest, HLSSingleFileBear) {
+  REQUIRE_ACCELERATION_ON_ANDROID();
+  PlayVideo("bear-1280x720-hls-clear-mpl.m3u8");
+}
+#endif  // BUILDFLAG(ENABLE_HLS_DEMUXER)
+
 IN_PROC_BROWSER_TEST_P(MediaTest, VideoBearMp4) {
   REQUIRE_ACCELERATION_ON_ANDROID();
   PlayVideo("bear.mp4");
diff --git a/content/browser/media/session/media_session_controller.cc b/content/browser/media/session/media_session_controller.cc
index 377d1be..f68cc4d 100644
--- a/content/browser/media/session/media_session_controller.cc
+++ b/content/browser/media/session/media_session_controller.cc
@@ -228,6 +228,7 @@
 void MediaSessionController::OnRemotePlaybackMetadataChanged(
     media_session::mojom::RemotePlaybackMetadataPtr metadata) {
   media_session_->SetRemotePlaybackMetadata(std::move(metadata));
+  AddOrRemovePlayer();
 }
 
 bool MediaSessionController::IsMediaSessionNeeded() const {
@@ -237,6 +238,15 @@
   if (!is_playback_in_progress_)
     return false;
 
+  // If the media content has an associated Remote Playback session started, we
+  // should request audio focus regardless of whether the tab is muted.
+  media_session::mojom::MediaSessionInfoPtr session_info =
+      media_session_->GetMediaSessionInfoSync();
+  if (session_info && session_info->remote_playback_metadata &&
+      session_info->remote_playback_metadata->remote_playback_started) {
+    return true;
+  }
+
   // We want to make sure we do not request audio focus on a muted tab as it
   // would break user expectations by pausing/ducking other playbacks.
   return has_audio_ && !web_contents_->IsAudioMuted();
diff --git a/content/browser/media/session/media_session_controller_unittest.cc b/content/browser/media/session/media_session_controller_unittest.cc
index 265f3298..3890d91 100644
--- a/content/browser/media/session/media_session_controller_unittest.cc
+++ b/content/browser/media/session/media_session_controller_unittest.cc
@@ -594,6 +594,23 @@
   EXPECT_FALSE(media_session()->IsActive());
 }
 
+TEST_F(MediaSessionControllerTest,
+       AddPlayerWhenStartingRemotePlaybackWithNoAudio) {
+  controller_->SetMetadata(
+      /* has_audio */ false, /* has_video */ true,
+      media::MediaContentType::kPersistent);
+  ASSERT_TRUE(controller_->OnPlaybackStarted());
+  ASSERT_FALSE(media_session()->IsActive());
+
+  controller_->OnRemotePlaybackMetadataChanged(
+      media_session::mojom::RemotePlaybackMetadata::New(
+          "video_codec", "audio_codec",
+          /* is_remote_playback_disabled */ false,
+          /* is_remote_rendering */ true, "device_friendly_name",
+          /* is_encrypted_media */ false));
+  EXPECT_TRUE(media_session()->IsActive());
+}
+
 TEST_F(MediaSessionControllerTest, EndOfPlaybackWithInPictureInPicture) {
   contents()->SetHasPictureInPictureVideo(true);
   controller_->PictureInPictureStateChanged(true);
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc
index 9606fb6..5a5118b 100644
--- a/content/browser/media/session/media_session_impl.cc
+++ b/content/browser/media/session/media_session_impl.cc
@@ -1074,8 +1074,9 @@
 
   // Disable Remote Playback by passing empty RemotePlaybackMetadata when there
   // are multiple media players.
-  if (normal_players_.size() == 1u) {
-    info->remote_playback_metadata = remote_playback_metadata_.Clone();
+  info->remote_playback_metadata = remote_playback_metadata_.Clone();
+  if (normal_players_.size() > 1u && info->remote_playback_metadata) {
+    info->remote_playback_metadata->remote_playback_disabled = true;
   }
 
   MediaSessionClient* media_session_client = MediaSessionClient::Get();
diff --git a/content/browser/media/session/media_session_impl_unittest.cc b/content/browser/media/session/media_session_impl_unittest.cc
index 0ed68cf..975007c 100644
--- a/content/browser/media/session/media_session_impl_unittest.cc
+++ b/content/browser/media/session/media_session_impl_unittest.cc
@@ -756,8 +756,9 @@
 
   int player2 = player_observer_->StartNewPlayer();
   GetMediaSession()->AddPlayer(player_observer_.get(), player2);
-  EXPECT_FALSE(media_session::test::GetMediaSessionInfoSync(GetMediaSession())
-                   ->remote_playback_metadata);
+
+  EXPECT_TRUE(media_session::test::GetMediaSessionInfoSync(GetMediaSession())
+                  ->remote_playback_metadata->remote_playback_disabled);
 }
 
 TEST_F(MediaSessionImplTest, RaiseActivatesWebContents) {
diff --git a/content/browser/preloading/prefetch/prefetch_document_manager.cc b/content/browser/preloading/prefetch/prefetch_document_manager.cc
index a7a0a1a..712a6ea 100644
--- a/content/browser/preloading/prefetch/prefetch_document_manager.cc
+++ b/content/browser/preloading/prefetch/prefetch_document_manager.cc
@@ -171,13 +171,20 @@
       serving_page_metrics_container->GetWeakPtr());
   prefetch_container->UpdateServingPageMetrics();
 
-  // Inform |PrefetchService| of the navigation to the prefetch.
-  // |navigation_handle->GetURL()| and |prefetched_iter->second->GetURL()|
-  // might be different but be equivalent under No-Vary-Search.
-  PrefetchService* prefetch_service = GetPrefetchService();
-  if (prefetch_service) {
-    prefetch_service->PrepareToServe(navigation_handle->GetURL(),
-                                     *prefetch_container);
+  switch (prefetch_container->GetServableState(PrefetchCacheableDuration())) {
+    case PrefetchContainer::ServableState::kServable:
+      if (PrefetchService* prefetch_service = GetPrefetchService()) {
+        // For prefetches that are already servable, start the process of
+        // copying cookies from the isolated network context used to make the
+        // prefetch to the default network context.
+        prefetch_service->CopyIsolatedCookies(
+            prefetch_container->CreateReader());
+      }
+      break;
+
+    case PrefetchContainer::ServableState::kNotServable:
+    case PrefetchContainer::ServableState::kShouldBlockUntilHeadReceived:
+      break;
   }
 }
 
diff --git a/content/browser/preloading/prefetch/prefetch_document_manager_unittest.cc b/content/browser/preloading/prefetch/prefetch_document_manager_unittest.cc
index 06d96cc..8598a684 100644
--- a/content/browser/preloading/prefetch/prefetch_document_manager_unittest.cc
+++ b/content/browser/preloading/prefetch/prefetch_document_manager_unittest.cc
@@ -42,15 +42,7 @@
     prefetches_.push_back(prefetch_container);
   }
 
-  void PrepareToServe(const GURL& url,
-                      PrefetchContainer& prefetch_container) override {
-    prefetches_prepared_to_serve_.emplace_back(url,
-                                               prefetch_container.GetWeakPtr());
-  }
-
   std::vector<base::WeakPtr<PrefetchContainer>> prefetches_;
-  std::vector<std::pair<GURL, base::WeakPtr<PrefetchContainer>>>
-      prefetches_prepared_to_serve_;
 };
 
 class PrefetchDocumentManagerTest : public RenderViewHostTestHarness {
@@ -111,11 +103,6 @@
     return prefetch_service_->prefetches_;
   }
 
-  const std::vector<std::pair<GURL, base::WeakPtr<PrefetchContainer>>>&
-  GetPrefetchesPreparedToServe() {
-    return prefetch_service_->prefetches_prepared_to_serve_;
-  }
-
   // Used to make sure that No-Vary-Search parsing error/warning message is sent
   // to DevTools console.
   std::string TriggerNoVarySearchParseErrorAndGetConsoleMessage(
@@ -239,143 +226,6 @@
   }
 }
 
-TEST_F(PrefetchDocumentManagerTest, ProcessNoVarySearchResponse) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(
-      network::features::kPrefetchNoVarySearch);
-  // Used to create responses.
-  const net::IsolationInfo info;
-  // Process the candidates with the |PrefetchDocumentManager| for the current
-  // document.
-  auto* prefetch_document_manager =
-      PrefetchDocumentManager::GetOrCreateForCurrentDocument(
-          &GetPrimaryMainFrame());
-  prefetch_document_manager->EnableNoVarySearchSupport();
-  {
-    // Create list of SpeculationCandidatePtrs.
-    std::vector<blink::mojom::SpeculationCandidatePtr> candidates;
-    // Create candidate for private cross-origin prefetch. This candidate should
-    // be prefetched by |PrefetchDocumentManager|.
-    auto candidate1 = blink::mojom::SpeculationCandidate::New();
-    const auto test_url = GetCrossOriginUrl("/candidate1.html?a=2&b=3");
-    candidate1->action = blink::mojom::SpeculationAction::kPrefetch;
-    candidate1->requires_anonymous_client_ip_when_cross_origin = false;
-    candidate1->url = test_url;
-    candidate1->referrer = blink::mojom::Referrer::New();
-
-    candidates.push_back(std::move(candidate1));
-
-    prefetch_document_manager->ProcessCandidates(candidates,
-                                                 /*devtools_observer=*/nullptr);
-
-    // Now call TakePrefetchedResponse
-    network::mojom::URLResponseHeadPtr head =
-        network::mojom::URLResponseHead::New();
-    head->parsed_headers = network::mojom::ParsedHeaders::New();
-    head->parsed_headers->no_vary_search_with_parse_error =
-        network::mojom::NoVarySearchWithParseError::NewNoVarySearch(
-            network::mojom::NoVarySearch::New());
-    head->parsed_headers->no_vary_search_with_parse_error->get_no_vary_search()
-        ->vary_on_key_order = true;
-    head->parsed_headers->no_vary_search_with_parse_error->get_no_vary_search()
-        ->search_variance =
-        network::mojom::SearchParamsVariance::NewVaryParams({"a"});
-
-    MakeServableStreamingURLLoaderForTest(GetPrefetches()[0].get(),
-                                          std::move(head), "empty");
-
-    const auto urls_with_no_vary_search =
-        prefetch_document_manager->GetAllForUrlWithoutRefAndQueryForTesting(
-            test_url);
-    ASSERT_EQ(urls_with_no_vary_search.size(), 1u);
-    EXPECT_EQ(urls_with_no_vary_search.at(0).first, test_url);
-    const absl::optional<net::HttpNoVarySearchData>& nvs =
-        urls_with_no_vary_search.at(0).second->GetNoVarySearchData();
-    ASSERT_TRUE(nvs);
-    EXPECT_THAT(nvs->vary_params(), UnorderedElementsAreArray({"a"}));
-    EXPECT_THAT(nvs->no_vary_params(), IsEmpty());
-    EXPECT_FALSE(nvs->vary_by_default());
-    EXPECT_TRUE(nvs->vary_on_key_order());
-    EXPECT_TRUE(prefetch_document_manager->MatchUrl(
-        GetCrossOriginUrl("/candidate1.html?b=4&a=2&c=5")));
-    EXPECT_TRUE(prefetch_document_manager->MatchUrl(
-        GetCrossOriginUrl("/candidate1.html?a=2")));
-    EXPECT_FALSE(prefetch_document_manager->MatchUrl(
-        GetCrossOriginUrl("/candidate1.html")));
-    EXPECT_FALSE(prefetch_document_manager->MatchUrl(
-        GetCrossOriginUrl("/candidate1.html?b=4")));
-  }
-  {
-    const auto test_url = GetCrossOriginUrl("/candidate2.html?a=2&b=3");
-    auto candidate1 = blink::mojom::SpeculationCandidate::New();
-    candidate1->action = blink::mojom::SpeculationAction::kPrefetch;
-    candidate1->requires_anonymous_client_ip_when_cross_origin = false;
-    candidate1->url = test_url;
-    candidate1->referrer = blink::mojom::Referrer::New();
-
-    // Create list of SpeculationCandidatePtrs.
-    std::vector<blink::mojom::SpeculationCandidatePtr> candidates;
-    candidates.emplace_back(std::move(candidate1));
-    prefetch_document_manager->ProcessCandidates(candidates,
-                                                 /*devtools_observer=*/nullptr);
-
-    network::mojom::URLResponseHeadPtr head =
-        network::mojom::URLResponseHead::New();
-    head->parsed_headers = network::mojom::ParsedHeaders::New();
-
-    MakeServableStreamingURLLoaderForTest(GetPrefetches().back().get(),
-                                          std::move(head), "empty");
-
-    const auto urls_with_no_vary_search =
-        prefetch_document_manager->GetAllForUrlWithoutRefAndQueryForTesting(
-            test_url);
-    ASSERT_EQ(urls_with_no_vary_search.size(), 1u);
-    ASSERT_EQ(urls_with_no_vary_search.at(0).first, test_url);
-  }
-
-  NavigateMainframeRendererTo(GetCrossOriginUrl("/candidate2.html?a=2&b=3"));
-  EXPECT_EQ(GetPrefetchesPreparedToServe()[0].first,
-            GetCrossOriginUrl("/candidate2.html?a=2&b=3"));
-  EXPECT_EQ(GetCrossOriginUrl("/candidate2.html?a=2&b=3"),
-            GetPrefetchesPreparedToServe()[0].second->GetURL());
-
-  NavigateMainframeRendererTo(
-      GetCrossOriginUrl("/candidate1.html?b=4&a=2&c=5"));
-  EXPECT_EQ(GetPrefetchesPreparedToServe()[1].first,
-            GetCrossOriginUrl("/candidate1.html?b=4&a=2&c=5"));
-  EXPECT_EQ(GetPrefetchesPreparedToServe()[1].second->GetURL(),
-            GetCrossOriginUrl("/candidate1.html?a=2&b=3"));
-
-  NavigateMainframeRendererTo(
-      GetCrossOriginUrl("/not_prefetched.html?b=4&a=2&c=5"));
-  EXPECT_EQ(GetPrefetchesPreparedToServe().size(), 2u);
-
-  // Cover the case where we want to navigate again to the same prefetched
-  // Url.
-  // Simulate that we've already navigated to prefetched URL.
-  GetPrefetchesPreparedToServe()[0].second->OnReturnPrefetchToServe(
-      /*served=*/true);
-  // Try to navigate again to the same URL.
-  NavigateMainframeRendererTo(GetCrossOriginUrl("/candidate2.html?a=2&b=3"));
-  EXPECT_EQ(GetPrefetchesPreparedToServe().size(), 3u);
-  // PrepareToServe("/candidate2.html?a=2&b=3") is anyway called, but in
-  // non-test environment this will be merged or ignored later in
-  // PrefetchService.
-  EXPECT_EQ(GetPrefetchesPreparedToServe()[2].first,
-            GetCrossOriginUrl("/candidate2.html?a=2&b=3"));
-  EXPECT_EQ(GetPrefetchesPreparedToServe()[2].second->GetURL(),
-            GetCrossOriginUrl("/candidate2.html?a=2&b=3"));
-
-  // Cover the case where we want to navigate to a URL with No-Vary-Search for
-  // which the PrefetchContainer WeakPtr is not valid anymore.
-  prefetch_document_manager->ReleasePrefetchContainer(
-      GetPrefetchesPreparedToServe()[1].second->GetURL());
-  CHECK(!GetPrefetchesPreparedToServe()[1].second);
-  NavigateMainframeRendererTo(
-      GetCrossOriginUrl("/candidate1.html?b=4&a=2&c=5"));
-  EXPECT_EQ(GetPrefetchesPreparedToServe().size(), 3u);
-}
-
 TEST_F(PrefetchDocumentManagerTest,
        ProcessNoVarySearchResponseWithDefaultValue) {
   EXPECT_THAT(TriggerNoVarySearchParseErrorAndGetConsoleMessage(
diff --git a/content/browser/preloading/prefetch/prefetch_service.cc b/content/browser/preloading/prefetch/prefetch_service.cc
index b755aa5..c491c37 100644
--- a/content/browser/preloading/prefetch/prefetch_service.cc
+++ b/content/browser/preloading/prefetch/prefetch_service.cc
@@ -1012,15 +1012,6 @@
     active_prefetches_.erase(active_prefetch_iter);
   }
 
-  auto prefetches_ready_to_serve_iter = prefetches_ready_to_serve_.find(
-      prefetch_container->GetPrefetchContainerKey());
-  if (prefetches_ready_to_serve_iter != prefetches_ready_to_serve_.end() &&
-      (!prefetches_ready_to_serve_iter->second ||
-       prefetches_ready_to_serve_iter->second->GetPrefetchContainerKey() ==
-           prefetch_container->GetPrefetchContainerKey())) {
-    prefetches_ready_to_serve_.erase(prefetches_ready_to_serve_iter);
-  }
-
   owned_prefetches_.erase(
       owned_prefetches_.find(prefetch_container->GetPrefetchContainerKey()));
 }
@@ -1394,49 +1385,6 @@
   Prefetch();
 }
 
-void PrefetchService::PrepareToServe(const GURL& url,
-                                     PrefetchContainer& prefetch_container) {
-  // Ensure |this| has this prefetch.
-  if (all_prefetches_.find(prefetch_container.GetPrefetchContainerKey()) ==
-      all_prefetches_.end()) {
-    DVLOG(1) << prefetch_container
-             << ": didn't promote to ready (not in all_prefetches_)";
-    return;
-  }
-
-  // `url` might be different from
-  // `prefetch_container->GetPrefetchContainerKey().second` due to
-  // No-Vary-Search.
-  PrefetchContainer::Key ready_key(
-      prefetch_container.GetPrefetchContainerKey().first, url);
-
-  // If there is already a prefetch with the same URL as |prefetch_container| in
-  // |prefetches_ready_to_serve_|, then don't do anything.
-  if (prefetches_ready_to_serve_.find(ready_key) !=
-      prefetches_ready_to_serve_.end()) {
-    DVLOG(1) << prefetch_container
-             << ": didn't promote to ready (another ready prefetch)";
-    return;
-  }
-
-  // Move prefetch into |prefetches_ready_to_serve_|.
-  DVLOG(1) << prefetch_container << ": promoted to ready";
-  prefetches_ready_to_serve_[ready_key] = prefetch_container.GetWeakPtr();
-
-  switch (prefetch_container.GetServableState(PrefetchCacheableDuration())) {
-    case PrefetchContainer::ServableState::kServable:
-      // For prefetches that are already servable, start the process of copying
-      // cookies from the isolated network context used to make the prefetch to
-      // the default network context.
-      CopyIsolatedCookies(prefetch_container.CreateReader());
-      break;
-
-    case PrefetchContainer::ServableState::kNotServable:
-    case PrefetchContainer::ServableState::kShouldBlockUntilHeadReceived:
-      break;
-  }
-}
-
 void PrefetchService::CopyIsolatedCookies(
     const PrefetchContainer::Reader& reader) {
   DCHECK(reader);
@@ -1498,12 +1446,11 @@
     ss << *entry.second.first << std::endl;
   }
 
-  ss << "Ready to serve:" << std::endl;
-  for (const auto& entry : prefetches_ready_to_serve_) {
-    if (PrefetchContainer* prefetch_container = entry.second.get()) {
-      ss << *prefetch_container << std::endl;
-    }
+  ss << "All:" << std::endl;
+  for (const auto& entry : all_prefetches_) {
+    ss << *entry.second << std::endl;
   }
+
   DVLOG(1) << ss.str();
 #endif  // DCHECK_IS_ON()
 }
@@ -1512,26 +1459,16 @@
     const PrefetchContainer::Key& key) {
   std::vector<PrefetchContainer*> matches;
   DVLOG(1) << "PrefetchService::FindPrefetchContainerToServe(" << key << ")";
-  // Search for an exact match first.
-  auto it = prefetches_ready_to_serve_.find(key);
-  if (it != prefetches_ready_to_serve_.end()) {
-    PrefetchContainer* prefetch_container = it->second.get();
-    prefetches_ready_to_serve_.erase(it);
-    if (prefetch_container) {
-      // There are different types of prefetch containers that can be in
-      // `prefetches_ready_to_serve_`:
-      // - matched by URL exactly in `PrefetchService::PrepareToServe` when
-      //   called from `PrefetchDocumentManager::DidStartNavigation`. This
-      //   prefetch already has received head or is waiting for head. In this
-      //   case we need to continue matching.
-      // - matched in `PrefetchService::WaitOnPrefetchToServe` head. In this
-      //   case we know the prefetch is servable.
-      // Even if the prefech is servable, we won't know if Cookies have changed
-      // until `ReturnPrefetchToServe` runs the check. So we need to continue
-      // matching other prefetches.
-      matches.push_back(prefetch_container);
-    }
-  }
+  // Search for an exact or No-Vary-Search match first.
+  no_vary_search::IterateCandidates(
+      key, all_prefetches_,
+      base::BindRepeating(
+          [](std::vector<PrefetchContainer*>* matches,
+             base::WeakPtr<PrefetchContainer> prefetch_container) {
+            matches->push_back(prefetch_container.get());
+            return no_vary_search::IterateCandidateResult::kContinue;
+          },
+          base::Unretained(&matches)));
 
   // Search for an inexact match using the No-Vary-Search hint.
   // It must either be servable now or potentially servable soon.
diff --git a/content/browser/preloading/prefetch/prefetch_service.h b/content/browser/preloading/prefetch/prefetch_service.h
index 98a76419..430a9c1 100644
--- a/content/browser/preloading/prefetch/prefetch_service.h
+++ b/content/browser/preloading/prefetch/prefetch_service.h
@@ -97,13 +97,6 @@
   virtual PrefetchOriginProber* GetPrefetchOriginProber() const;
   virtual void PrefetchUrl(base::WeakPtr<PrefetchContainer> prefetch_container);
 
-  // Called when a navigation to `url` that will be served by
-  // `prefetch_container` is likely to occur in the immediate future.
-  // |url| and |prefetch_container.GetURL()| might not be the same
-  // because of No-Vary-Search non-exact url match.
-  virtual void PrepareToServe(const GURL& url,
-                              PrefetchContainer& prefetch_container);
-
   // Finds the prefetch (if any) that can be used to serve a navigation to
   // |url|, and then calls |on_prefetch_to_serve_ready| with that prefetch.
   using OnPrefetchToServeReady =
@@ -386,19 +379,6 @@
                      std::unique_ptr<base::OneShotTimer>>>
       owned_prefetches_;
 
-  // The set of prefetches that are ready to serve. In order to be in this map,
-  // the prefetch must also be in |owned_prefetches_|, have a valid prefetched
-  // response, and have started the cookie copy process. A prefetch is added to
-  // this map when |PrepareToServe| is called on it, and once in this map, it
-  // can be returned by |GetPrefetchToServe|.
-  // The other way a prefetch could be in this map is if the prefetch matches
-  // exactly by URL and we're waiting for head.
-  //
-  // Unlike other maps, the URL in `PrefetchContainer::Key` can be different
-  // from `PrefetchContainer::GetURL()` due to No-Vary-Search.
-  std::map<PrefetchContainer::Key, base::WeakPtr<PrefetchContainer>>
-      prefetches_ready_to_serve_;
-
 // Protects against Prefetch() being called recursively.
 #if DCHECK_IS_ON()
   bool prefetch_reentrancy_guard_ = false;
diff --git a/content/browser/preloading/prefetch/prefetch_service_unittest.cc b/content/browser/preloading/prefetch/prefetch_service_unittest.cc
index 084a71a..82d1fb91 100644
--- a/content/browser/preloading/prefetch/prefetch_service_unittest.cc
+++ b/content/browser/preloading/prefetch/prefetch_service_unittest.cc
@@ -3120,10 +3120,6 @@
       GetMetricsForMostRecentNavigation();
   EXPECT_FALSE(serving_page_metrics);
 
-  PrefetchContainer::Reader serveable_reader =
-      GetPrefetchToServe(GURL("https://example.com"));
-  EXPECT_FALSE(serveable_reader);
-
   ExpectCorrectUkmLogs({});
 }
 
diff --git a/content/browser/preloading/prerender/prerender_browsertest.cc b/content/browser/preloading/prerender/prerender_browsertest.cc
index 8b07718..194a828 100644
--- a/content/browser/preloading/prerender/prerender_browsertest.cc
+++ b/content/browser/preloading/prerender/prerender_browsertest.cc
@@ -11735,13 +11735,9 @@
 // prediction and the navigation. For this test, we actually simulate the back
 // button press events.
 // TODO(https://crbug.com/1059468): Flaky on ChromeOS.
-#if BUILDFLAG(IS_CHROMEOS)
-#define MAYBE_BackButtonNavigation DISABLED_BackButtonNavigation
-#else
-#define MAYBE_BackButtonNavigation BackButtonNavigation
-#endif
+// TODO(https://crbug.com/1493726): Also flaky on other platforms after r1208618
 IN_PROC_BROWSER_TEST_P(PrerenderSessionHistoryBrowserTest,
-                       MAYBE_BackButtonNavigation) {
+                       DISABLED_BackButtonNavigation) {
   const GURL url1 = GetUrl("/title1.html");
   const GURL url2 = GetCrossSiteUrl("/title2.html");
   PerformInitialNavigations(web_contents_impl(), url1, url2);
diff --git a/content/browser/preloading/prerender/prerender_host.cc b/content/browser/preloading/prerender/prerender_host.cc
index f60c6113..1eee2a3 100644
--- a/content/browser/preloading/prerender/prerender_host.cc
+++ b/content/browser/preloading/prerender/prerender_host.cc
@@ -512,39 +512,7 @@
   // RenderFrameHost.
   CHECK(!page->render_frame_host()->GetParentOrOuterDocumentOrEmbedder());
 
-  // TODO(crbug.com/1470312): Remove the following block (retaining the call to
-  // SetFrameTreeNode) once the issue is resolved.
-  {
-    UrlInfo url_info = navigation_request.GetUrlInfo();
-    std::string url_info_str =
-        "urlOrigin=[" +
-        url_info.url.DeprecatedGetOriginAsURL().possibly_invalid_spec() + "]";
-    if (url_info.is_sandboxed) {
-      url_info_str += " sandboxed";
-    }
-    if (url_info.is_coop_isolation_requested) {
-      url_info_str += " coop";
-    }
-    if (url_info.origin_isolation_request !=
-        UrlInfo::OriginIsolationRequest::kDefault) {
-      url_info_str += " oir=[" +
-                      base::NumberToString(url_info.origin_isolation_request) +
-                      "]";
-    }
-    if (url_info.origin) {
-      url_info_str += " origin=[" +
-                      url_info.origin.value().GetURL().possibly_invalid_spec() +
-                      "]";
-    }
-    SCOPED_CRASH_KEY_STRING256("Bug1470312", "url_info", url_info_str);
-    SCOPED_CRASH_KEY_BOOL(
-        "Bug1470312", "page_has_opener",
-        page->render_frame_host()->frame_tree_node()->opener() != nullptr);
-    SCOPED_CRASH_KEY_BOOL("Bug1470312", "target_has_opener",
-                          target_frame_tree.root()->opener() != nullptr);
-    page->render_frame_host()->SetFrameTreeNode(*(target_frame_tree.root()));
-  }
-
+  page->render_frame_host()->SetFrameTreeNode(*(target_frame_tree.root()));
   page->render_frame_host()->SetRenderFrameHostOwner(target_frame_tree.root());
 
   // Copy frame name into the replication state of the primary main frame to
diff --git a/content/browser/renderer_host/browsing_context_state.cc b/content/browser/renderer_host/browsing_context_state.cc
index 0274d9b..81e1569 100644
--- a/content/browser/renderer_host/browsing_context_state.cc
+++ b/content/browser/renderer_host/browsing_context_state.cc
@@ -50,17 +50,6 @@
 
 BrowsingContextState::~BrowsingContextState() {
   TRACE_EVENT_END("navigation", perfetto::Track::FromPointer(this));
-  // TODO(crbug.com/1470312): if there are any RFPHs remaining at this point,
-  // that's an error. Dump information about them to help debug. Remove this
-  // once the issue is resolved.
-  std::string siteinfo_crashkey_str;
-  for (auto& it : proxy_hosts_) {
-    siteinfo_crashkey_str +=
-        it.second->GetSiteInstanceDeprecated()->GetSiteInfo().GetDebugString() +
-        ";";
-  }
-  SCOPED_CRASH_KEY_STRING256("Bug1470312", "bcs_rfph_siteinfo",
-                             siteinfo_crashkey_str);
   CHECK(proxy_hosts_.empty());
 }
 
diff --git a/content/browser/renderer_host/input/touch_action_browsertest.cc b/content/browser/renderer_host/input/touch_action_browsertest.cc
index b985948..2ef8d4d1 100644
--- a/content/browser/renderer_host/input/touch_action_browsertest.cc
+++ b/content/browser/renderer_host/input/touch_action_browsertest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <string_view>
 #include <tuple>
 #include <utility>
 
@@ -168,8 +169,8 @@
   }
 
  protected:
-  void LoadURL(const char* touch_action_url) {
-    const GURL data_url(touch_action_url);
+  void LoadURL(std::string_view touch_action_url) {
+    const GURL data_url(std::move(touch_action_url));
     EXPECT_TRUE(NavigateToURL(shell(), data_url));
 
     RenderWidgetHostImpl* host = GetWidgetHost();
diff --git a/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc b/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc
index 95937d2d..b036df8b 100644
--- a/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc
+++ b/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc
@@ -47,8 +47,8 @@
   void ResumeDevice() override { device_->Resume(); }
   void Crop(const base::Token& crop_id,
             uint32_t crop_version,
-            base::OnceCallback<void(media::mojom::CropRequestResult)> callback)
-      override {
+            base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+                callback) override {
     device_->Crop(crop_id, crop_version, std::move(callback));
   }
   void RequestRefreshFrame() override { device_->RequestRefreshFrame(); }
diff --git a/content/browser/renderer_host/media/in_process_launched_video_capture_device.cc b/content/browser/renderer_host/media/in_process_launched_video_capture_device.cc
index 18878ec..9277d639 100644
--- a/content/browser/renderer_host/media/in_process_launched_video_capture_device.cc
+++ b/content/browser/renderer_host/media/in_process_launched_video_capture_device.cc
@@ -119,7 +119,8 @@
 void InProcessLaunchedVideoCaptureDevice::Crop(
     const base::Token& crop_id,
     uint32_t crop_version,
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
+    base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+        callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   // Unretained() is safe to use here because |device| would be null if it
   // was scheduled for shutdown and destruction, and because this task is
diff --git a/content/browser/renderer_host/media/in_process_launched_video_capture_device.h b/content/browser/renderer_host/media/in_process_launched_video_capture_device.h
index 5e406e76..5673af6 100644
--- a/content/browser/renderer_host/media/in_process_launched_video_capture_device.h
+++ b/content/browser/renderer_host/media/in_process_launched_video_capture_device.h
@@ -33,8 +33,8 @@
   void ResumeDevice() override;
   void Crop(const base::Token& crop_id,
             uint32_t crop_version,
-            base::OnceCallback<void(media::mojom::CropRequestResult)> callback)
-      override;
+            base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+                callback) override;
   void RequestRefreshFrame() override;
 
   void SetDesktopCaptureWindowIdAsync(gfx::NativeViewId window_id,
diff --git a/content/browser/renderer_host/media/media_devices_dispatcher_host.cc b/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
index 53250822..5cfe0fc5 100644
--- a/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
+++ b/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
@@ -33,6 +33,7 @@
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "third_party/blink/public/common/mediastream/media_devices.h"
 #include "third_party/blink/public/common/mediastream/media_stream_request.h"
+#include "third_party/blink/public/mojom/mediastream/media_devices.mojom.h"
 #include "url/origin.h"
 
 #if !BUILDFLAG(IS_ANDROID)
@@ -319,30 +320,34 @@
       /*is_from_timer=*/false);
 }
 
-void MediaDevicesDispatcherHost::ProduceCropId(ProduceCropIdCallback callback) {
+void MediaDevicesDispatcherHost::ProduceSubCaptureTargetId(
+    blink::mojom::SubCaptureTargetType type,
+    ProduceSubCaptureTargetIdCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(
-          [](int render_process_id, int render_frame_id) {
+          [](int render_process_id, int render_frame_id,
+             blink::mojom::SubCaptureTargetType type) {
             RenderFrameHostImpl* const rfh =
                 RenderFrameHostImpl::FromID(render_process_id, render_frame_id);
             if (!rfh || !rfh->IsActive()) {
               return std::string();  // Might have been asynchronously closed.
             }
 
-            WebContents* const web_contents =
+            WebContents* const wc =
                 WebContents::FromRenderFrameHost(rfh->GetMainFrame());
-            DCHECK(web_contents);
+            DCHECK(wc);
 
             // No-op if already created.
-            CropIdWebContentsHelper::CreateForWebContents(web_contents);
+            SubCaptureTargetIdWebContentsHelper::CreateForWebContents(wc);
 
-            return CropIdWebContentsHelper::FromWebContents(web_contents)
-                ->ProduceCropId();
+            SubCaptureTargetIdWebContentsHelper* const helper =
+                SubCaptureTargetIdWebContentsHelper::FromWebContents(wc);
+            return helper->ProduceId(type);
           },
-          render_process_id_, render_frame_id_),
+          render_process_id_, render_frame_id_, type),
       std::move(callback));
 }
 #endif
diff --git a/content/browser/renderer_host/media/media_devices_dispatcher_host.h b/content/browser/renderer_host/media/media_devices_dispatcher_host.h
index a2d3d497..1fdbe681 100644
--- a/content/browser/renderer_host/media/media_devices_dispatcher_host.h
+++ b/content/browser/renderer_host/media/media_devices_dispatcher_host.h
@@ -73,7 +73,9 @@
       blink::mojom::CaptureHandleConfigPtr config) override;
 #if !BUILDFLAG(IS_ANDROID)
   void CloseFocusWindowOfOpportunity(const std::string& label) override;
-  void ProduceCropId(ProduceCropIdCallback callback) override;
+  void ProduceSubCaptureTargetId(
+      blink::mojom::SubCaptureTargetType type,
+      ProduceSubCaptureTargetIdCallback callback) override;
 #endif
 
  private:
diff --git a/content/browser/renderer_host/media/media_devices_manager_unittest.cc b/content/browser/renderer_host/media/media_devices_manager_unittest.cc
index f50f49c..9978b9d8 100644
--- a/content/browser/renderer_host/media/media_devices_manager_unittest.cc
+++ b/content/browser/renderer_host/media/media_devices_manager_unittest.cc
@@ -40,10 +40,11 @@
 
 using base::HistogramTester;
 using blink::mojom::MediaDeviceType;
+using blink::mojom::SubCaptureTargetType;
 using media::mojom::DeviceEnumerationResult;
-using testing::_;
-using testing::Invoke;
-using testing::SaveArg;
+using ::testing::_;
+using ::testing::Invoke;
+using ::testing::SaveArg;
 
 namespace content {
 
@@ -270,7 +271,10 @@
               (::blink::mojom::CaptureHandleConfigPtr config));
 #if !BUILDFLAG(IS_ANDROID)
   MOCK_METHOD(void, CloseFocusWindowOfOpportunity, (const std::string& label));
-  MOCK_METHOD(void, ProduceCropId, (ProduceCropIdCallback callback));
+  MOCK_METHOD(void,
+              ProduceSubCaptureTargetId,
+              (SubCaptureTargetType type,
+               ProduceSubCaptureTargetIdCallback callback));
 #endif
 };
 
diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
index 040d94b..c35bf6d 100644
--- a/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
+++ b/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -109,8 +109,8 @@
     return false;
   }
 
-  CropIdWebContentsHelper* const helper =
-      CropIdWebContentsHelper::FromWebContents(captured_wc);
+  SubCaptureTargetIdWebContentsHelper* const helper =
+      SubCaptureTargetIdWebContentsHelper::FromWebContents(captured_wc);
   if (!helper) {
     // No crop-IDs were ever produced on this WebContents.
     // Any non-zero crop-ID should be rejected on account of being
@@ -121,7 +121,10 @@
 
   // * crop_id.is_zero() = uncrop-request.
   // * !crop_id.is_zero() = crop-request.
-  return crop_id.is_zero() || helper->IsAssociatedWithCropId(crop_id);
+  // TODO(crbug.com/1418194): Extend to support other types.
+  return crop_id.is_zero() ||
+         helper->IsAssociatedWith(
+             crop_id, SubCaptureTargetIdWebContentsHelper::Type::kCropTarget);
 }
 
 MediaStreamDispatcherHost::CropCallback WrapCropCallback(
@@ -130,9 +133,9 @@
   return base::BindOnce(
       [](MediaStreamDispatcherHost::CropCallback callback,
          mojo::ReportBadMessageCallback bad_message_callback,
-         media::mojom::CropRequestResult result) {
+         media::mojom::ApplySubCaptureTargetResult result) {
         if (result ==
-            media::mojom::CropRequestResult::kNonIncreasingCropVersion) {
+            media::mojom::ApplySubCaptureTargetResult::kNonIncreasingVersion) {
           std::move(bad_message_callback).Run("Non-increasing crop-version.");
           // Intentionally avoid returning. Instead, continue execution and
           // invoke the callback. If the callback were allowed to "drop" that
@@ -693,7 +696,7 @@
 
   if (!crop_id_passed_validation) {
     std::move(callback).Run(
-        media::mojom::CropRequestResult::kInvalidCropTarget);
+        media::mojom::ApplySubCaptureTargetResult::kInvalidTarget);
     return;
   }
 
diff --git a/content/browser/renderer_host/media/mock_video_capture_provider.h b/content/browser/renderer_host/media/mock_video_capture_provider.h
index 6f9ec70..c47cb1a8 100644
--- a/content/browser/renderer_host/media/mock_video_capture_provider.h
+++ b/content/browser/renderer_host/media/mock_video_capture_provider.h
@@ -77,10 +77,12 @@
                void(media::VideoCaptureDevice::TakePhotoCallback* callback));
   MOCK_METHOD0(MaybeSuspendDevice, void());
   MOCK_METHOD0(ResumeDevice, void());
-  MOCK_METHOD3(Crop,
-               void(const base::Token& crop_id,
-                    uint32_t crop_version,
-                    base::OnceCallback<void(media::mojom::CropRequestResult)>));
+  MOCK_METHOD3(
+      Crop,
+      void(
+          const base::Token& crop_id,
+          uint32_t crop_version,
+          base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>));
   MOCK_METHOD0(RequestRefreshFrame, void());
   MOCK_METHOD2(DoSetDesktopCaptureWindowId,
                void(gfx::NativeViewId window_id, base::OnceClosure* done_cb));
diff --git a/content/browser/renderer_host/media/service_launched_video_capture_device.cc b/content/browser/renderer_host/media/service_launched_video_capture_device.cc
index bf90437..8081aec8 100644
--- a/content/browser/renderer_host/media/service_launched_video_capture_device.cc
+++ b/content/browser/renderer_host/media/service_launched_video_capture_device.cc
@@ -81,10 +81,12 @@
 void ServiceLaunchedVideoCaptureDevice::Crop(
     const base::Token& crop_id,
     uint32_t crop_version,
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
+    base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+        callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // TODO(crbug.com/1264849): Implement if necessary.
-  std::move(callback).Run(media::mojom::CropRequestResult::kNotImplemented);
+  std::move(callback).Run(
+      media::mojom::ApplySubCaptureTargetResult::kNotImplemented);
 }
 
 void ServiceLaunchedVideoCaptureDevice::RequestRefreshFrame() {
diff --git a/content/browser/renderer_host/media/service_launched_video_capture_device.h b/content/browser/renderer_host/media/service_launched_video_capture_device.h
index b2b8e3d..1f0e810 100644
--- a/content/browser/renderer_host/media/service_launched_video_capture_device.h
+++ b/content/browser/renderer_host/media/service_launched_video_capture_device.h
@@ -38,8 +38,8 @@
   void ResumeDevice() override;
   void Crop(const base::Token& crop_id,
             uint32_t crop_version,
-            base::OnceCallback<void(media::mojom::CropRequestResult)> callback)
-      override;
+            base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+                callback) override;
   void RequestRefreshFrame() override;
 
   void SetDesktopCaptureWindowIdAsync(gfx::NativeViewId window_id,
diff --git a/content/browser/renderer_host/media/sub_capture_target_id_web_contents_helper_unittest.cc b/content/browser/renderer_host/media/sub_capture_target_id_web_contents_helper_unittest.cc
index 11ab1f5..b618749 100644
--- a/content/browser/renderer_host/media/sub_capture_target_id_web_contents_helper_unittest.cc
+++ b/content/browser/renderer_host/media/sub_capture_target_id_web_contents_helper_unittest.cc
@@ -4,7 +4,10 @@
 
 #include "content/browser/media/capture/sub_capture_target_id_web_contents_helper.h"
 
+#include <map>
 #include <memory>
+#include <string>
+#include <vector>
 
 #include "base/uuid.h"
 #include "build/build_config.h"
@@ -21,21 +24,32 @@
 
 namespace {
 
-MATCHER(IsEmptyCropId, "") {
+using ::testing::Values;
+using ::testing::WithParamInterface;
+
+using Type = SubCaptureTargetIdWebContentsHelper::Type;
+
+constexpr size_t kMaxIdsPerWebContents =
+    SubCaptureTargetIdWebContentsHelper::kMaxIdsPerWebContents;
+
+MATCHER(IsEmptyId, "") {
   static_assert(std::is_same<decltype(arg), const std::string&>::value, "");
   return arg.empty();
 }
 
-MATCHER(IsValidCropId, "") {
+MATCHER(IsValidId, "") {
   static_assert(std::is_same<decltype(arg), const std::string&>::value, "");
   return base::Uuid::ParseLowercase(arg).is_valid();
 }
 
 }  // namespace
 
-class CropIdWebContentsHelperTest : public RenderViewHostImplTestHarness {
+class SubCaptureTargetIdWebContentsHelperTest
+    : public RenderViewHostImplTestHarness,
+      public WithParamInterface<Type> {
  public:
-  ~CropIdWebContentsHelperTest() override = default;
+  SubCaptureTargetIdWebContentsHelperTest() : type_(GetParam()) {}
+  ~SubCaptureTargetIdWebContentsHelperTest() override = default;
 
   void SetUp() override { RenderViewHostImplTestHarness::SetUp(); }
 
@@ -47,171 +61,249 @@
     return TestWebContents::Create(GetBrowserContext(), std::move(instance));
   }
 
-  static CropIdWebContentsHelper* helper(WebContents* web_contents) {
+  static SubCaptureTargetIdWebContentsHelper* MakeHelper(
+      WebContents* web_contents) {
     // No-op if already created.
-    CropIdWebContentsHelper::CreateForWebContents(web_contents);
-    return CropIdWebContentsHelper::FromWebContents(web_contents);
+    SubCaptureTargetIdWebContentsHelper::CreateForWebContents(web_contents);
+    return SubCaptureTargetIdWebContentsHelper::FromWebContents(web_contents);
   }
 
   static base::Token GUIDToToken(const base::Uuid& guid) {
-    return CropIdWebContentsHelper::GUIDToToken(guid);
+    return SubCaptureTargetIdWebContentsHelper::GUIDToToken(guid);
   }
+
+ protected:
+  const Type type_;
 };
 
-TEST_F(CropIdWebContentsHelperTest,
-       IsAssociatedWithCropIdReturnsFalseForUnknownCropId) {
+INSTANTIATE_TEST_SUITE_P(_,
+                         SubCaptureTargetIdWebContentsHelperTest,
+                         Values(Type::kCropTarget, Type::kRestrictionTarget));
+
+TEST_P(SubCaptureTargetIdWebContentsHelperTest,
+       IsAssociatedWithReturnsFalseForUnknownId) {
   const std::unique_ptr<TestWebContents> web_contents = MakeTestWebContents();
-  CropIdWebContentsHelper::CreateForWebContents(web_contents.get());
-  auto* helper = CropIdWebContentsHelper::FromWebContents(web_contents.get());
+  SubCaptureTargetIdWebContentsHelper::CreateForWebContents(web_contents.get());
+  auto* helper =
+      SubCaptureTargetIdWebContentsHelper::FromWebContents(web_contents.get());
   ASSERT_NE(helper, nullptr);
 
   // Test focus.
-  const base::Uuid unknown_crop_id = base::Uuid::GenerateRandomV4();
-  EXPECT_FALSE(helper->IsAssociatedWithCropId(GUIDToToken(unknown_crop_id)));
+  const base::Uuid unknown_id = base::Uuid::GenerateRandomV4();
+  EXPECT_FALSE(helper->IsAssociatedWith(GUIDToToken(unknown_id), type_));
 
   // Extra-test: Ensure the query above did not accidentally record
-  // `unknown_crop_id` as a known crop-ID.
-  EXPECT_FALSE(helper->IsAssociatedWithCropId(GUIDToToken(unknown_crop_id)));
+  // `unknown_id` as a known ID.
+  EXPECT_FALSE(helper->IsAssociatedWith(GUIDToToken(unknown_id), type_));
 }
 
-TEST_F(CropIdWebContentsHelperTest, ProduceCropIdReturnsCropId) {
+TEST_P(SubCaptureTargetIdWebContentsHelperTest, ProduceIdReturnsId) {
   const std::unique_ptr<TestWebContents> web_contents = MakeTestWebContents();
-  CropIdWebContentsHelper::CreateForWebContents(web_contents.get());
-  auto* helper = CropIdWebContentsHelper::FromWebContents(web_contents.get());
+  SubCaptureTargetIdWebContentsHelper::CreateForWebContents(web_contents.get());
+  auto* helper =
+      SubCaptureTargetIdWebContentsHelper::FromWebContents(web_contents.get());
   ASSERT_NE(helper, nullptr);
 
-  EXPECT_THAT(helper->ProduceCropId(), IsValidCropId());
+  EXPECT_THAT(helper->ProduceId(type_), IsValidId());
 }
 
-TEST_F(CropIdWebContentsHelperTest,
-       IsAssociatedWithCropIdReturnsTrueForKnownCropIdIfCorrectWebContents) {
+TEST_P(SubCaptureTargetIdWebContentsHelperTest,
+       IsAssociatedWithReturnsTrueForKnownIdIfCorrectWebContents) {
   const std::unique_ptr<TestWebContents> web_contents = MakeTestWebContents();
-  CropIdWebContentsHelper::CreateForWebContents(web_contents.get());
-  auto* helper = CropIdWebContentsHelper::FromWebContents(web_contents.get());
+  SubCaptureTargetIdWebContentsHelper::CreateForWebContents(web_contents.get());
+  auto* helper =
+      SubCaptureTargetIdWebContentsHelper::FromWebContents(web_contents.get());
   ASSERT_NE(helper, nullptr);
 
   const std::unique_ptr<TestWebContents> other_web_contents =
       MakeTestWebContents();
-  CropIdWebContentsHelper::CreateForWebContents(other_web_contents.get());
-  auto* other_helper =
-      CropIdWebContentsHelper::FromWebContents(other_web_contents.get());
+  SubCaptureTargetIdWebContentsHelper::CreateForWebContents(
+      other_web_contents.get());
+  auto* other_helper = SubCaptureTargetIdWebContentsHelper::FromWebContents(
+      other_web_contents.get());
   ASSERT_NE(other_helper, nullptr);
 
-  const std::string crop_id_str = helper->ProduceCropId();
-  EXPECT_THAT(crop_id_str, IsValidCropId());
+  const std::string id_str = helper->ProduceId(type_);
+  EXPECT_THAT(id_str, IsValidId());
 
-  const base::Token crop_id =
-      GUIDToToken(base::Uuid::ParseLowercase(crop_id_str));
+  const base::Token id = GUIDToToken(base::Uuid::ParseLowercase(id_str));
 
-  EXPECT_TRUE(helper->IsAssociatedWithCropId(crop_id));
-  EXPECT_FALSE(other_helper->IsAssociatedWithCropId(crop_id));
+  EXPECT_TRUE(helper->IsAssociatedWith(id, type_));
+  EXPECT_FALSE(other_helper->IsAssociatedWith(id, type_));
 }
 
-TEST_F(CropIdWebContentsHelperTest, MaxCropIdsPerWebContentsObserved) {
+TEST_P(SubCaptureTargetIdWebContentsHelperTest, IsAssociatedWithObservesType) {
+  const std::unique_ptr<TestWebContents> web_contents = MakeTestWebContents();
+  SubCaptureTargetIdWebContentsHelper* helper = MakeHelper(web_contents.get());
+
+  const std::string id_str = helper->ProduceId(type_);
+  ASSERT_THAT(id_str, IsValidId());
+
+  const base::Token id = GUIDToToken(base::Uuid::ParseLowercase(id_str));
+  ASSERT_TRUE(helper->IsAssociatedWith(id, type_));
+
+  const Type other_type = (type_ == Type::kCropTarget)
+                              ? Type::kRestrictionTarget
+                              : Type::kCropTarget;
+  EXPECT_FALSE(helper->IsAssociatedWith(id, other_type));
+}
+
+// Test that the limit of `kMaxIdsPerWebContents` is applied independently
+// for different WebContents.
+TEST_P(SubCaptureTargetIdWebContentsHelperTest, MaxIdsPerWebContentsObserved) {
   const std::unique_ptr<TestWebContents> web_contents[2] = {
       MakeTestWebContents(), MakeTestWebContents()};
-  CropIdWebContentsHelper::CreateForWebContents(web_contents[0].get());
-  CropIdWebContentsHelper::CreateForWebContents(web_contents[1].get());
-  CropIdWebContentsHelper* helpers[2] = {
-      CropIdWebContentsHelper::FromWebContents(web_contents[0].get()),
-      CropIdWebContentsHelper::FromWebContents(web_contents[1].get())};
+  SubCaptureTargetIdWebContentsHelper::CreateForWebContents(
+      web_contents[0].get());
+  SubCaptureTargetIdWebContentsHelper::CreateForWebContents(
+      web_contents[1].get());
+  SubCaptureTargetIdWebContentsHelper* helpers[2] = {
+      SubCaptureTargetIdWebContentsHelper::FromWebContents(
+          web_contents[0].get()),
+      SubCaptureTargetIdWebContentsHelper::FromWebContents(
+          web_contents[1].get())};
 
-  std::string crop_ids_str[2]
-                          [CropIdWebContentsHelper::kMaxCropIdsPerWebContents];
+  std::string ids_str[2][kMaxIdsPerWebContents];
 
-  // Up to `kMaxCropIdsPerWebContents` allowed on each WebContents.
+  // Up to `kMaxIdsPerWebContents` allowed on each WebContents.
   for (size_t web_contents_idx = 0; web_contents_idx < 2; ++web_contents_idx) {
-    for (size_t i = 0; i < CropIdWebContentsHelper::kMaxCropIdsPerWebContents;
-         ++i) {
-      crop_ids_str[web_contents_idx][i] =
-          helpers[web_contents_idx]->ProduceCropId();
-      EXPECT_THAT(crop_ids_str[web_contents_idx][i], IsValidCropId());
+    for (size_t i = 0; i < kMaxIdsPerWebContents; ++i) {
+      ids_str[web_contents_idx][i] =
+          helpers[web_contents_idx]->ProduceId(type_);
+      EXPECT_THAT(ids_str[web_contents_idx][i], IsValidId());
     }
   }
 
-  // Attempts to produce more crop-IDs on either WebContents fail.
-  for (CropIdWebContentsHelper* helper : helpers) {
-    EXPECT_THAT(helper->ProduceCropId(), IsEmptyCropId());
+  // Attempts to produce more IDs on either WebContents fail.
+  for (SubCaptureTargetIdWebContentsHelper* helper : helpers) {
+    EXPECT_THAT(helper->ProduceId(type_), IsEmptyId());
   }
 
-  // The original crop-IDs are not forgotten.
+  // The original IDs are not forgotten.
   for (size_t web_contents_idx = 0; web_contents_idx < 2; ++web_contents_idx) {
-    for (size_t i = 0; i < CropIdWebContentsHelper::kMaxCropIdsPerWebContents;
-         ++i) {
-      const base::Token crop_id = GUIDToToken(
-          base::Uuid::ParseLowercase(crop_ids_str[web_contents_idx][i]));
-      EXPECT_TRUE(helpers[web_contents_idx]->IsAssociatedWithCropId(crop_id));
+    for (size_t i = 0; i < kMaxIdsPerWebContents; ++i) {
+      const base::Token id =
+          GUIDToToken(base::Uuid::ParseLowercase(ids_str[web_contents_idx][i]));
+      EXPECT_TRUE(helpers[web_contents_idx]->IsAssociatedWith(id, type_));
 
       // Extra-test: They're also still associated *only* with the relevant WC.
       const size_t other_web_contents_idx = 1 - web_contents_idx;
       EXPECT_FALSE(
-          helpers[other_web_contents_idx]->IsAssociatedWithCropId(crop_id));
+          helpers[other_web_contents_idx]->IsAssociatedWith(id, type_));
     }
   }
 }
 
-TEST_F(CropIdWebContentsHelperTest,
-       CrossDocumentNavigationClearsCropIdsAssociation) {
+// Test that the limit of `kMaxIdsPerWebContents` is applied independently
+// for different types (CropTarget, RestrictionTarget).
+TEST_P(SubCaptureTargetIdWebContentsHelperTest, MaxIdsPerTypeObserved) {
+  // This switch is no-op. It's only here to make the compiler emit a warning if
+  // a developer ever adds values to the Type enum without updating this test.
+  // Future developer, please update the container below to cover all types.
+  switch (Type()) {
+    case Type::kCropTarget:
+    case Type::kRestrictionTarget:
+      break;
+  }
+  const std::vector<Type> kAllTypes = {Type::kCropTarget,
+                                       Type::kRestrictionTarget};
+
+  // Note that this test does not need to be parameterized, but the overhead
+  // of separating it from the rest of the suite is not worth the savings.
+  // We therefore skip iterations of this test past the first possible value.
+  if (type_ != kAllTypes[0]) {
+    GTEST_SKIP();
+  }
+
   std::unique_ptr<TestWebContents> web_contents = MakeTestWebContents();
-  CropIdWebContentsHelper::CreateForWebContents(web_contents.get());
-  auto* helper = CropIdWebContentsHelper::FromWebContents(web_contents.get());
+  SubCaptureTargetIdWebContentsHelper* helper = MakeHelper(web_contents.get());
+
+  std::map<Type, std::vector<std::string>> id_strs;
+
+  // Up to `kMaxIdsPerWebContents` allowed on each type.
+  for (Type type : kAllTypes) {
+    std::vector<std::string>& ids = id_strs[type];
+    for (size_t i = 0; i < kMaxIdsPerWebContents; ++i) {
+      ids.push_back(helper->ProduceId(type));
+      EXPECT_THAT(ids.back(), IsValidId());
+    }
+  }
+
+  // Attempts to produce more IDs of either type fail.
+  for (Type type : kAllTypes) {
+    EXPECT_THAT(helper->ProduceId(type), IsEmptyId());
+  }
+
+  // The original IDs are not forgotten.
+  for (Type type : kAllTypes) {
+    for (const std::string& id_str : id_strs[type]) {
+      const base::Token id = GUIDToToken(base::Uuid::ParseLowercase(id_str));
+      EXPECT_TRUE(helper->IsAssociatedWith(id, type));
+    }
+  }
+}
+
+TEST_P(SubCaptureTargetIdWebContentsHelperTest,
+       CrossDocumentNavigationClearsIdAssociation) {
+  std::unique_ptr<TestWebContents> web_contents = MakeTestWebContents();
+  SubCaptureTargetIdWebContentsHelper::CreateForWebContents(web_contents.get());
+  auto* helper =
+      SubCaptureTargetIdWebContentsHelper::FromWebContents(web_contents.get());
   ASSERT_NE(helper, nullptr);
 
-  // Setup - WebContents navigated to a document, crop-ID produced.
+  // Setup - WebContents navigated to a document, ID produced.
   web_contents->NavigateAndCommit(GURL("https://tests-r-us.com/first.html"));
-  base::Token crop_id_1;
+  base::Token id_1;
   {
-    const std::string crop_id_str = helper->ProduceCropId();
-    ASSERT_THAT(crop_id_str, IsValidCropId());
-    crop_id_1 = GUIDToToken(base::Uuid::ParseLowercase(crop_id_str));
+    const std::string id_str = helper->ProduceId(type_);
+    ASSERT_THAT(id_str, IsValidId());
+    id_1 = GUIDToToken(base::Uuid::ParseLowercase(id_str));
   }
-  ASSERT_TRUE(helper->IsAssociatedWithCropId(crop_id_1));  // Sanity-check.
+  ASSERT_TRUE(helper->IsAssociatedWith(id_1, type_));  // Sanity-check.
 
   // Cross-document navigation occurs.
   web_contents->NavigateAndCommit(GURL("https://tests-r-us.com/second.html"));
 
-  // Verification #1: The old crop-ID is forgotten.
-  ASSERT_FALSE(helper->IsAssociatedWithCropId(crop_id_1));
+  // Verification #1: The old ID is forgotten.
+  ASSERT_FALSE(helper->IsAssociatedWith(id_1, type_));
 
-  // Verification #2: New crop-IDs may be recorded.
+  // Verification #2: New IDs may be recorded.
   {
-    const std::string crop_id_str = helper->ProduceCropId();
-    EXPECT_THAT(crop_id_str, IsValidCropId());
-    const base::Token crop_id_2 =
-        GUIDToToken(base::Uuid::ParseLowercase(crop_id_str));
-    ASSERT_TRUE(helper->IsAssociatedWithCropId(crop_id_2));  // Sanity-check.
+    const std::string id_str = helper->ProduceId(type_);
+    EXPECT_THAT(id_str, IsValidId());
+    const base::Token id_2 = GUIDToToken(base::Uuid::ParseLowercase(id_str));
+    ASSERT_TRUE(helper->IsAssociatedWith(id_2, type_));  // Sanity-check.
   }
 
-  // Verification #3: The forgotten crop-ID is not counted against the limit
-  // of crop-IDs applied to a WebContents. (kMaxCropIdsPerWebContents - 1 more
+  // Verification #3: The forgotten ID is not counted against the limit
+  // of IDs applied to a WebContents. (kMaxIdsPerWebContents - 1 more
   // invocations allowed, then the next one fails.)
-  for (size_t i = 0; i < CropIdWebContentsHelper::kMaxCropIdsPerWebContents - 1;
-       ++i) {
-    EXPECT_THAT(helper->ProduceCropId(), IsValidCropId());
+  for (size_t i = 0; i < kMaxIdsPerWebContents - 1; ++i) {
+    EXPECT_THAT(helper->ProduceId(type_), IsValidId());
   }
-  EXPECT_THAT(helper->ProduceCropId(), IsEmptyCropId());
+  EXPECT_THAT(helper->ProduceId(type_), IsEmptyId());
 }
 
-TEST_F(CropIdWebContentsHelperTest,
-       InDocumentNavigationDoesNotClearCropIdsAssociation) {
+TEST_P(SubCaptureTargetIdWebContentsHelperTest,
+       InDocumentNavigationDoesNotClearIdAssociation) {
   std::unique_ptr<TestWebContents> web_contents = MakeTestWebContents();
-  CropIdWebContentsHelper::CreateForWebContents(web_contents.get());
-  auto* helper = CropIdWebContentsHelper::FromWebContents(web_contents.get());
+  SubCaptureTargetIdWebContentsHelper::CreateForWebContents(web_contents.get());
+  auto* helper =
+      SubCaptureTargetIdWebContentsHelper::FromWebContents(web_contents.get());
   ASSERT_NE(helper, nullptr);
 
-  // Setup - WebContents navigated to a document, crop-ID produced.
+  // Setup - WebContents navigated to a document, ID produced.
   web_contents->NavigateAndCommit(GURL("https://tests-r-us.com/first.html"));
-  const std::string crop_id_str = helper->ProduceCropId();
-  ASSERT_THAT(crop_id_str, IsValidCropId());
-  const base::Token crop_id =
-      GUIDToToken(base::Uuid::ParseLowercase(crop_id_str));
+  const std::string id_str = helper->ProduceId(type_);
+  ASSERT_THAT(id_str, IsValidId());
+  const base::Token id = GUIDToToken(base::Uuid::ParseLowercase(id_str));
 
   // Test sanity-check.
-  ASSERT_TRUE(helper->IsAssociatedWithCropId(crop_id));
+  ASSERT_TRUE(helper->IsAssociatedWith(id, type_));
 
-  // In-document navigation occurs. The crop-ID is not forgotten.
+  // In-document navigation occurs. The ID is not forgotten.
   web_contents->NavigateAndCommit(GURL("https://tests-r-us.com/first.html#a"));
-  EXPECT_TRUE(helper->IsAssociatedWithCropId(crop_id));
+  EXPECT_TRUE(helper->IsAssociatedWith(id, type_));
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc
index 8238af4..3ccec532 100644
--- a/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -739,7 +739,8 @@
 void VideoCaptureController::Crop(
     const base::Token& crop_id,
     uint32_t crop_version,
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
+    base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+        callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(launched_device_);
 
@@ -748,7 +749,8 @@
   was_crop_ever_called_ = true;
 
   if (controller_clients_.size() != 1) {
-    std::move(callback).Run(media::mojom::CropRequestResult::kNotImplemented);
+    std::move(callback).Run(
+        media::mojom::ApplySubCaptureTargetResult::kNotImplemented);
     return;
   }
 
diff --git a/content/browser/renderer_host/media/video_capture_controller.h b/content/browser/renderer_host/media/video_capture_controller.h
index f104e41..6d90fcf 100644
--- a/content/browser/renderer_host/media/video_capture_controller.h
+++ b/content/browser/renderer_host/media/video_capture_controller.h
@@ -149,7 +149,8 @@
   void Resume();
   void Crop(const base::Token& crop_id,
             uint32_t crop_version,
-            base::OnceCallback<void(media::mojom::CropRequestResult)> callback);
+            base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+                callback);
   void RequestRefreshFrame();
   void SetDesktopCaptureWindowIdAsync(gfx::NativeViewId window_id,
                                       base::OnceClosure done_cb);
diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc
index 282818e3..cb3274ec 100644
--- a/content/browser/renderer_host/media/video_capture_manager.cc
+++ b/content/browser/renderer_host/media/video_capture_manager.cc
@@ -240,13 +240,15 @@
     const base::UnguessableToken& session_id,
     const base::Token& crop_id,
     uint32_t crop_version,
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
+    base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+        callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
 
   VideoCaptureController* const controller =
       LookupControllerBySessionId(session_id);
   if (!controller || !controller->IsDeviceAlive()) {
-    std::move(callback).Run(media::mojom::CropRequestResult::kErrorGeneric);
+    std::move(callback).Run(
+        media::mojom::ApplySubCaptureTargetResult::kErrorGeneric);
     return;
   }
   controller->Crop(crop_id, crop_version, std::move(callback));
diff --git a/content/browser/renderer_host/media/video_capture_manager.h b/content/browser/renderer_host/media/video_capture_manager.h
index b55770c..9c6aca1 100644
--- a/content/browser/renderer_host/media/video_capture_manager.h
+++ b/content/browser/renderer_host/media/video_capture_manager.h
@@ -101,7 +101,8 @@
   void Crop(const base::UnguessableToken& session_id,
             const base::Token& crop_id,
             uint32_t crop_version,
-            base::OnceCallback<void(media::mojom::CropRequestResult)> callback);
+            base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+                callback);
 
   // Called by VideoCaptureHost to locate a capture device for `capture_params`,
   // adding the Host as a client of the device's controller if successful. The
diff --git a/content/browser/renderer_host/media/video_capture_manager_unittest.cc b/content/browser/renderer_host/media/video_capture_manager_unittest.cc
index af549eb..a82d15c0 100644
--- a/content/browser/renderer_host/media/video_capture_manager_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_manager_unittest.cc
@@ -318,7 +318,10 @@
     ASSERT_GE(devices_.size(), 2u);
   }
 
-  void TearDown() override { task_environment_.RunUntilIdle(); }
+  void TearDown() override {
+    screenlock_monitor_source_ = nullptr;
+    task_environment_.RunUntilIdle();
+  }
 
   void OnGotControllerCallback(
       VideoCaptureControllerID id,
@@ -384,8 +387,7 @@
 #endif
 
   BrowserTaskEnvironment task_environment_;
-  raw_ptr<ScreenlockMonitorTestSource, DanglingUntriaged>
-      screenlock_monitor_source_;
+  raw_ptr<ScreenlockMonitorTestSource> screenlock_monitor_source_;
   std::unique_ptr<ScreenlockMonitor> screenlock_monitor_;
   std::map<VideoCaptureControllerID, VideoCaptureController*> controllers_;
   scoped_refptr<VideoCaptureManager> vcm_;
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
index 9bd3984..2392667b 100644
--- a/content/browser/renderer_host/render_frame_host_impl.cc
+++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -1769,25 +1769,7 @@
   // If this was the last active frame in the SiteInstanceGroup, the
   // DecrementActiveFrameCount call will trigger the deletion of the
   // SiteInstanceGroup's proxies.
-  {
-    SCOPED_CRASH_KEY_BOOL("Bug1470312", "is_main_frame", is_main_frame());
-    SCOPED_CRASH_KEY_BOOL(
-        "Bug1470312", "is_sandboxed",
-        policy_container_host_
-            ? IsSandboxed(network::mojom::WebSandboxFlags::kOrigin)
-            : false);
-    SCOPED_CRASH_KEY_BOOL(
-        "Bug1470312", "sig_is_notifying_observers",
-        GetSiteInstance()->group()->is_notifying_observers_for_debugging());
-    SCOPED_CRASH_KEY_STRING256("Bug1470312", "origin",
-                               GetLastCommittedOrigin().GetDebugString());
-    SCOPED_CRASH_KEY_STRING256("Bug1470312", "origin_from_url",
-                               GetLastCommittedURL().GetWithEmptyPath().spec());
-    SCOPED_CRASH_KEY_STRING256(
-        "Bug1470312", "site_info",
-        GetSiteInstance()->GetSiteInfo().GetDebugString());
-    GetSiteInstance()->group()->DecrementActiveFrameCount();
-  }
+  GetSiteInstance()->group()->DecrementActiveFrameCount();
 
   // Once a RenderFrame is created in the renderer, there are three possible
   // clean-up paths:
diff --git a/content/browser/renderer_host/render_widget_host_view_ios.mm b/content/browser/renderer_host/render_widget_host_view_ios.mm
index ec4a7e4..43dcefb 100644
--- a/content/browser/renderer_host/render_widget_host_view_ios.mm
+++ b/content/browser/renderer_host/render_widget_host_view_ios.mm
@@ -548,6 +548,10 @@
 }
 
 bool RenderWidgetHostViewIOS::IsShowing() {
+  // In testing, `view_` is not attached to the window.
+  if (IsTesting()) {
+    return is_visible_;
+  }
   return is_visible_ && [ui_view_->view_ window];
 }
 
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 6f95c717..64a2ce0f 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -487,6 +487,11 @@
   ns_view_->SetVisible(is_visible_);
   browser_compositor_->SetViewVisible(is_visible_);
   WasOccluded();
+
+  if (base::FeatureList::IsEnabled(::features::kHideDelegatedFrameHostMac)) {
+    browser_compositor_->GetDelegatedFrameHost()->WasHidden(
+        DelegatedFrameHost::HiddenCause::kOther);
+  }
 }
 
 void RenderWidgetHostViewMac::WasUnOccluded() {
diff --git a/content/browser/screenlock_monitor/screenlock_monitor_unittest.cc b/content/browser/screenlock_monitor/screenlock_monitor_unittest.cc
index 156a83c..91427c0 100644
--- a/content/browser/screenlock_monitor/screenlock_monitor_unittest.cc
+++ b/content/browser/screenlock_monitor/screenlock_monitor_unittest.cc
@@ -59,11 +59,10 @@
     screenlock_monitor_ = std::make_unique<ScreenlockMonitor>(
         std::unique_ptr<ScreenlockMonitorSource>(screenlock_monitor_source_));
   }
-  ~ScreenlockMonitorTest() override = default;
+  ~ScreenlockMonitorTest() override { screenlock_monitor_source_ = nullptr; }
 
  protected:
-  raw_ptr<ScreenlockMonitorTestSource, DanglingUntriaged>
-      screenlock_monitor_source_;
+  raw_ptr<ScreenlockMonitorTestSource> screenlock_monitor_source_;
   std::unique_ptr<ScreenlockMonitor> screenlock_monitor_;
 
   base::test::SingleThreadTaskEnvironment task_environment_{
diff --git a/content/browser/service_worker/service_worker_new_script_loader.cc b/content/browser/service_worker/service_worker_new_script_loader.cc
index dc03854..f1b77e4 100644
--- a/content/browser/service_worker/service_worker_new_script_loader.cc
+++ b/content/browser/service_worker/service_worker_new_script_loader.cc
@@ -559,9 +559,8 @@
   CHECK_EQ(WriterState::kWriting, body_writer_state_);
   CHECK(network_consumer_.is_valid());
   scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer;
-  uint32_t bytes_available = 0;
   MojoResult result = network::MojoToNetPendingBuffer::BeginRead(
-      &network_consumer_, &pending_buffer, &bytes_available);
+      &network_consumer_, &pending_buffer);
   TRACE_EVENT_WITH_FLOW1("ServiceWorker",
                          "ServiceWorkerNewScriptLoader::OnNetworkDataAvailable",
                          TRACE_ID_WITH_SCOPE(kServiceWorkerNewScriptLoaderScope,
@@ -569,17 +568,21 @@
                          TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
                          "begin_read_result", result);
   switch (result) {
-    case MOJO_RESULT_OK:
+    case MOJO_RESULT_OK: {
+      const uint32_t bytes_available = pending_buffer->size();
       WriteData(std::move(pending_buffer), bytes_available);
       return;
-    case MOJO_RESULT_FAILED_PRECONDITION:
+    }
+    case MOJO_RESULT_FAILED_PRECONDITION: {
       // Call WriteData() with null buffer to let the cache writer know that
       // body from the network reaches to the end.
       WriteData(/*pending_buffer=*/nullptr, /*bytes_available=*/0);
       return;
-    case MOJO_RESULT_SHOULD_WAIT:
+    }
+    case MOJO_RESULT_SHOULD_WAIT: {
       network_watcher_.ArmOrNotify();
       return;
+    }
   }
   CHECK(false) << static_cast<int>(result);  // NOTREACHED
 }
diff --git a/content/browser/service_worker/service_worker_single_script_update_checker.cc b/content/browser/service_worker/service_worker_single_script_update_checker.cc
index 5f4fa8a1..a8f98c13 100644
--- a/content/browser/service_worker/service_worker_single_script_update_checker.cc
+++ b/content/browser/service_worker/service_worker_single_script_update_checker.cc
@@ -513,9 +513,10 @@
             ServiceWorkerUpdatedScriptLoader::WriterState::kCompleted);
   DCHECK(network_consumer_.is_valid());
   scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer;
-  uint32_t bytes_available = 0;
   MojoResult result = network::MojoToNetPendingBuffer::BeginRead(
-      &network_consumer_, &pending_buffer, &bytes_available);
+      &network_consumer_, &pending_buffer);
+
+  const uint32_t bytes_available = pending_buffer ? pending_buffer->size() : 0;
   TRACE_EVENT_WITH_FLOW2(
       "ServiceWorker",
       "ServiceWorkerSingleScriptUpdateChecker::OnNetworkDataAvailable", this,
diff --git a/content/browser/service_worker/service_worker_test_utils.cc b/content/browser/service_worker/service_worker_test_utils.cc
index 6c5be1f..6d75c1a 100644
--- a/content/browser/service_worker/service_worker_test_utils.cc
+++ b/content/browser/service_worker/service_worker_test_utils.cc
@@ -850,9 +850,9 @@
     base::RunLoop().RunUntilIdle();
 
     // Read the data to make a pending buffer.
-    ASSERT_EQ(MOJO_RESULT_OK,
-              network::MojoToNetPendingBuffer::BeginRead(
-                  &network_consumer, &pending_buffer, &bytes_available));
+    ASSERT_EQ(MOJO_RESULT_OK, network::MojoToNetPendingBuffer::BeginRead(
+                                  &network_consumer, &pending_buffer));
+    bytes_available = pending_buffer->size();
     ASSERT_EQ(diff_data_block.size(), bytes_available);
   }
 
diff --git a/content/browser/service_worker/service_worker_updated_script_loader.cc b/content/browser/service_worker/service_worker_updated_script_loader.cc
index bf2016a..d8c0518 100644
--- a/content/browser/service_worker/service_worker_updated_script_loader.cc
+++ b/content/browser/service_worker/service_worker_updated_script_loader.cc
@@ -366,21 +366,24 @@
   CHECK_EQ(WriterState::kWriting, body_writer_state_);
   CHECK(network_consumer_.is_valid());
   scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer;
-  uint32_t bytes_available = 0;
   MojoResult result = network::MojoToNetPendingBuffer::BeginRead(
-      &network_consumer_, &pending_buffer, &bytes_available);
+      &network_consumer_, &pending_buffer);
   switch (result) {
-    case MOJO_RESULT_OK:
+    case MOJO_RESULT_OK: {
+      const uint32_t bytes_available = pending_buffer->size();
       WriteData(std::move(pending_buffer), bytes_available);
       return;
-    case MOJO_RESULT_FAILED_PRECONDITION:
+    }
+    case MOJO_RESULT_FAILED_PRECONDITION: {
       // Call WriteData() with null buffer to let the cache writer know that
       // body from the network reaches to the end.
       WriteData(/*pending_buffer=*/nullptr, /*bytes_available=*/0);
       return;
-    case MOJO_RESULT_SHOULD_WAIT:
+    }
+    case MOJO_RESULT_SHOULD_WAIT: {
       network_watcher_.ArmOrNotify();
       return;
+    }
   }
   CHECK(false) << static_cast<int>(result);  // NOTREACHED
 }
diff --git a/content/browser/site_instance_group.h b/content/browser/site_instance_group.h
index dfa13aed..ad2ed82 100644
--- a/content/browser/site_instance_group.h
+++ b/content/browser/site_instance_group.h
@@ -165,11 +165,6 @@
   // Write a representation of this object into a trace.
   void WriteIntoTrace(perfetto::TracedProto<TraceProto> proto) const;
 
-  // Used for setting crashkeys for Bug1470312.
-  bool is_notifying_observers_for_debugging() const {
-    return is_notifying_observers_;
-  }
-
  private:
   friend class RefCounted<SiteInstanceGroup>;
   ~SiteInstanceGroup() override;
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc
index f555d7a..132ce9a 100644
--- a/content/browser/site_instance_impl.cc
+++ b/content/browser/site_instance_impl.cc
@@ -1203,6 +1203,12 @@
     return false;
   }
 
+  // Similarly, the common_coop_origin in the UrlInfo and in this
+  // SiteInstance's BrowsingInstance must be compatible.
+  if (url_info.common_coop_origin != GetCommonCoopOrigin()) {
+    return false;
+  }
+
   // If the passed in UrlInfo has a null WebExposedIsolationInfo, meaning that
   // it is compatible with any isolation state, we reuse the isolation state of
   // this SiteInstance's SiteInfo so the member comparison of SiteInfos will
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc
index 17e68c77..b259651 100644
--- a/content/browser/webid/federated_auth_request_impl.cc
+++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -645,10 +645,11 @@
   }
 
   if (idp_get_params_ptrs[0]->providers[0]->is_holder()) {
-    if (!IsWebIdentityMDocsEnabled() ||
+    if (!IsWebIdentityDigitalCredentialsEnabled() ||
         IsFedCmMultipleIdentityProvidersEnabled()) {
-      // TODO(https://crbug.com/1416939): Support calling the MDocs API with the
-      // Multi IdP API support.
+      // TODO(https://crbug.com/1416939): Support calling the Digital
+      // Credentials
+      //  API with the Multi IdP API support.
       std::move(callback).Run(RequestTokenStatus::kError, absl::nullopt, "",
                               /*error=*/nullptr,
                               /*is_identity_credential_auto_selected=*/false);
diff --git a/content/browser/webid/flags.cc b/content/browser/webid/flags.cc
index 94c1fcb..7f5ec56 100644
--- a/content/browser/webid/flags.cc
+++ b/content/browser/webid/flags.cc
@@ -52,8 +52,8 @@
       features::kFedCmWithoutWellKnownEnforcement);
 }
 
-bool IsWebIdentityMDocsEnabled() {
-  return base::FeatureList::IsEnabled(features::kWebIdentityMDocs);
+bool IsWebIdentityDigitalCredentialsEnabled() {
+  return base::FeatureList::IsEnabled(features::kWebIdentityDigitalCredentials);
 }
 
 bool IsFedCmIdentityCredentialAutoSelectedFlagEnabled() {
diff --git a/content/browser/webid/flags.h b/content/browser/webid/flags.h
index 536a891..52badbe5 100644
--- a/content/browser/webid/flags.h
+++ b/content/browser/webid/flags.h
@@ -38,8 +38,8 @@
 // Whether the well-known enforcement is bypassed.
 bool IsFedCmWithoutWellKnownEnforcementEnabled();
 
-// Whether the Web Identity MDocs API is enabled.
-bool IsWebIdentityMDocsEnabled();
+// Whether the Web Identity Digital Credentials API is enabled.
+bool IsWebIdentityDigitalCredentialsEnabled();
 
 // Whether the IdentityCredentialAutoSelected feature is enabled.
 bool IsFedCmIdentityCredentialAutoSelectedFlagEnabled();
diff --git a/content/browser/webid/webid_browsertest.cc b/content/browser/webid/webid_browsertest.cc
index dc15c6c..9ae3e98 100644
--- a/content/browser/webid/webid_browsertest.cc
+++ b/content/browser/webid/webid_browsertest.cc
@@ -646,7 +646,7 @@
   void SetUpCommandLine(base::CommandLine* command_line) override {
     std::vector<base::test::FeatureRef> features;
     features.push_back(net::features::kSplitCacheByNetworkIsolationKey);
-    features.push_back(features::kWebIdentityMDocs);
+    features.push_back(features::kWebIdentityDigitalCredentials);
     scoped_feature_list_.InitWithFeatures(features, {});
 
     command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index 43a2adfc..45cbed8 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -311,8 +311,8 @@
 #if BUILDFLAG(IS_ANDROID)
     {wf::EnableWebNFC, raw_ref(features::kWebNfc), kSetOnlyIfOverridden},
 #endif
-    {wf::EnableWebIdentityMDocs, raw_ref(features::kWebIdentityMDocs),
-     kDefault},
+    {wf::EnableWebIdentityDigitalCredentials,
+     raw_ref(features::kWebIdentityDigitalCredentials), kDefault},
     {wf::EnableWebOTP, raw_ref(features::kWebOTP), kSetOnlyIfOverridden},
     {wf::EnableWebOTPAssertionFeaturePolicy,
      raw_ref(features::kWebOTPAssertionFeaturePolicy), kSetOnlyIfOverridden},
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureList.java b/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureList.java
index ff8ada2b..23afe1a9 100644
--- a/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureList.java
+++ b/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureList.java
@@ -48,5 +48,5 @@
 
     public static final String WEB_NFC = "WebNFC";
 
-    public static final String WEB_IDENTITY_MDOCS = "WebIdentityMDocs";
+    public static final String WEB_IDENTITY_DIGITAL_CREDENTIALS = "WebIdentityDigitalCredentials";
 }
diff --git a/content/public/browser/video_capture_device_launcher.h b/content/public/browser/video_capture_device_launcher.h
index 0ee29d1..2af56b0 100644
--- a/content/public/browser/video_capture_device_launcher.h
+++ b/content/public/browser/video_capture_device_launcher.h
@@ -85,7 +85,8 @@
   virtual void Crop(
       const base::Token& crop_id,
       uint32_t crop_version,
-      base::OnceCallback<void(media::mojom::CropRequestResult)> callback) = 0;
+      base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+          callback) = 0;
   virtual void RequestRefreshFrame() = 0;
 
   // Methods for specific types of devices.
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 02d5e33..d6a922cb 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -414,9 +414,9 @@
              "FencedFramesEnforceFocus",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// Enables the MDocs API in the IdentityCredential.
-BASE_FEATURE(kWebIdentityMDocs,
-             "WebIdentityMDocs",
+// Enables the Digital Credential API.
+BASE_FEATURE(kWebIdentityDigitalCredentials,
+             "WebIdentityDigitalCredentials",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
 // Enables usage of First Party Sets to determine cookie availability.
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 15b1631..9fdfd68c 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -103,7 +103,7 @@
 CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmIdpSigninStatusEnabled);
 CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmWithoutWellKnownEnforcement);
 CONTENT_EXPORT BASE_DECLARE_FEATURE(kFencedFramesEnforceFocus);
-CONTENT_EXPORT BASE_DECLARE_FEATURE(kWebIdentityMDocs);
+CONTENT_EXPORT BASE_DECLARE_FEATURE(kWebIdentityDigitalCredentials);
 CONTENT_EXPORT BASE_DECLARE_FEATURE(kFirstPartySets);
 CONTENT_EXPORT extern const base::FeatureParam<bool>
     kFirstPartySetsClearSiteDataOnChangedSets;
diff --git a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
index 6171497..f8ae1cb 100644
--- a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
@@ -210,12 +210,6 @@
 crbug.com/1201009 [ fuchsia ] WebGLCanvasCaptureTraceTest_VideoStreamFromWebGLCanvas_OneCopy [ Failure ]
 crbug.com/1201009 [ fuchsia ] WebGLCanvasCaptureTraceTest_VideoStreamFromWebGLCanvas_TwoCopy_Accelerated [ Failure ]
 
-# Accelerated canvas capture does not yet work with Graphite.
-crbug.com/1450879 [ mac graphite-enabled ] WebGLCanvasCaptureTraceTest_VideoStreamFromWebGLCanvas_OneCopy [ Failure ]
-crbug.com/1450879 [ mac graphite-enabled ] WebGLCanvasCaptureTraceTest_VideoStreamFromWebGLCanvas_TwoCopy_Accelerated [ Failure ]
-crbug.com/1450879 [ mac no-asan graphite-enabled ] WebGPUTraceTest_WebGPUCanvasOneCopyCapture [ Failure ]
-crbug.com/1450879 [ mac no-asan graphite-enabled ] WebGPUTraceTest_WebGPUCanvasOneCopyCapture_Hidden [ Failure ]
-crbug.com/1450879 [ mac no-asan graphite-enabled ] WebGPUTraceTest_WebGPUCanvasDisableOneCopyCapture_Accelerated [ Failure ]
 
 # WebGL drawingBufferStorage does not work on Pixel 4, Samsung A23, nexus-5x or
 # Lacros FYI x64 Release (Intel) yet.
@@ -254,6 +248,12 @@
 crbug.com/1487723 [ android android-shield-android-tv ] TraceTest_CSS3DBlueBox [ RetryOnFailure ]
 crbug.com/1487723 [ android android-shield-android-tv ] TraceTest_SolidColorBackground [ RetryOnFailure ]
 
+# Canvas capture trace tests on M1 Mac
+crbug.com/1493530 [ mac apple angle-metal ] WebGLCanvasCaptureTraceTest_VideoStreamFromWebGLCanvas_TwoCopy_Accelerated [ RetryOnFailure ]
+crbug.com/1493530 [ mac apple angle-metal ] WebGPUTraceTest_WebGPUCanvasDisableOneCopyCapture_Accelerated [ RetryOnFailure ]
+crbug.com/1493530 [ mac apple angle-metal ] WebGPUTraceTest_WebGPUCanvasOneCopyCapture_Hidden [ RetryOnFailure ]
+crbug.com/1493530 [ mac apple angle-metal no-asan ] WebGPUTraceTest_WebGPUCanvasOneCopyCapture [ RetryOnFailure ]
+
 #######################################################################
 # Automated Entries After This Point - Do Not Manually Add Below Here #
 #######################################################################
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
index 3cbc7e1f..5b616b6 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -547,6 +547,8 @@
 
 ## Mac / M1 / OpenGL ##
 
+crbug.com/1493524 [ mac apple passthrough angle-opengl ] conformance/renderbuffers/stencil-renderbuffer-initialization.html [ RetryOnFailure ]
+
 
 ####################
 # Linux failures   #
diff --git a/content/web_test/browser/web_test_content_browser_client.cc b/content/web_test/browser/web_test_content_browser_client.cc
index 4bb1004a..96429cb 100644
--- a/content/web_test/browser/web_test_content_browser_client.cc
+++ b/content/web_test/browser/web_test_content_browser_client.cc
@@ -86,6 +86,7 @@
 #include "third_party/blink/public/common/web_preferences/web_preferences.h"
 #include "ui/base/ui_base_switches.h"
 #include "url/origin.h"
+#include "url/url_constants.h"
 
 #if BUILDFLAG(IS_WIN)
 #include "base/strings/utf_string_conversions.h"
@@ -476,18 +477,17 @@
 
     // The list of schemes below is based on
     // //third_party/blink/web_tests/external/wpt/config.json
-    const char* kOriginTemplates[] = {
-        "http://%s/",
-        "https://%s/",
+    const char* kSchemes[] = {
+        url::kHttpScheme,
+        url::kHttpsScheme,
     };
 
     origins_to_isolate.reserve(origins_to_isolate.size() +
-                               std::size(kWptHostnames) *
-                                   std::size(kOriginTemplates));
-    for (const char* kWptHostname : kWptHostnames) {
-      for (const char* kOriginTemplate : kOriginTemplates) {
-        std::string origin = base::StringPrintf(kOriginTemplate, kWptHostname);
-        origins_to_isolate.push_back(origin);
+                               std::size(kWptHostnames) * std::size(kSchemes));
+    for (const char* hostname : kWptHostnames) {
+      for (const char* scheme : kSchemes) {
+        origins_to_isolate.push_back(
+            base::StringPrintf("%s://%s/", scheme, hostname));
       }
     }
   }
diff --git a/device/bluetooth/public/mojom/BUILD.gn b/device/bluetooth/public/mojom/BUILD.gn
index 01de33ac..3f701da 100644
--- a/device/bluetooth/public/mojom/BUILD.gn
+++ b/device/bluetooth/public/mojom/BUILD.gn
@@ -8,6 +8,11 @@
   generate_java = true
   sources = [ "uuid.mojom" ]
   webui_module_path = "/"
+  use_typescript_sources = true
+
+  # Indirect dependency of Blink test support so generate legacy bindings for
+  # Blink in JavaScript.
+  generate_legacy_js_bindings = true
 
   cpp_typemaps = [
     {
diff --git a/device/fido/features.cc b/device/fido/features.cc
index 85101da..9270379 100644
--- a/device/fido/features.cc
+++ b/device/fido/features.cc
@@ -222,4 +222,11 @@
              "WebAuthenticationPRFEvalDuringCreate",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+#if BUILDFLAG(IS_CHROMEOS)
+// Not yet enabled by default.
+BASE_FEATURE(kChromeOsPasskeys,
+             "WebAuthenticationCrosPasskeys",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+#endif
+
 }  // namespace device
diff --git a/device/fido/features.h b/device/fido/features.h
index 704ea96..7448df8e 100644
--- a/device/fido/features.h
+++ b/device/fido/features.h
@@ -182,6 +182,12 @@
 COMPONENT_EXPORT(DEVICE_FIDO)
 BASE_DECLARE_FEATURE(kWebAuthnPRFEvalDuringCreate);
 
+#if BUILDFLAG(IS_CHROMEOS)
+// Enable ChromeOS native passkey support.
+COMPONENT_EXPORT(DEVICE_FIDO)
+BASE_DECLARE_FEATURE(kChromeOsPasskeys);
+#endif
+
 }  // namespace device
 
 #endif  // DEVICE_FIDO_FEATURES_H_
diff --git a/docs/enterprise/description_guidelines.md b/docs/enterprise/description_guidelines.md
index 360904a..d8fb5c9 100644
--- a/docs/enterprise/description_guidelines.md
+++ b/docs/enterprise/description_guidelines.md
@@ -13,7 +13,6 @@
 
 * Chrome: `<ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>`
 * ChromeOS: `<ph name="PRODUCT_OS_NAME">$2<ex>Google ChromeOS</ex></ph>`
-* ChromeOS Flex: `<ph name="PRODUCT_OS_FLEX_NAME">Google ChromeOS Flex</ph>`
 * Chrome Browser Cloud Management: `<ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME">Chrome Browser Cloud Management</ph>`
 * Chrome Cleanup: `<ph name="CHROME_CLEANUP_NAME">Chrome Cleanup</ph>`
 * Chrome Sync: `<ph name="CHROME_SYNC_NAME">Chrome Sync</ph>`
diff --git a/docs/lacros/test_instructions.md b/docs/lacros/test_instructions.md
index e028bce..118a5c4 100644
--- a/docs/lacros/test_instructions.md
+++ b/docs/lacros/test_instructions.md
@@ -23,11 +23,11 @@
 *    Lacros browser tests
 *    Lacros Interactive_ui_tests
 *    crosapi tests: lacros_chrome_browsertests,
-lacros_chrome_browsertests_run_in_series
+lacros_chrome_browsertests
 *    Ash browser tests that requires Lacros: Only On Linux ChromeOS.
 (linux-chromeos-rel).
 *    Version skew testing: lacros_chrome_browsertests,
-lacros_chrome_browsertests_run_in_series, interactive_ui_tests.
+lacros_chrome_browsertests, interactive_ui_tests.
 
 ### Building on a Linux workstation and running on a physical ChromeOS device.
 
diff --git a/docs/lacros/test_linux_lacros.md b/docs/lacros/test_linux_lacros.md
index f3a9305..684e7f8 100644
--- a/docs/lacros/test_linux_lacros.md
+++ b/docs/lacros/test_linux_lacros.md
@@ -75,7 +75,7 @@
 ```
 
 You can use this to run Chrome tests, such as browser_tests, unit_tests,
-interactive_ui_tests, lacros_chrome_browsertests_run_in_series etc.
+interactive_ui_tests, lacros_chrome_browsertests etc.
 
 Note: Some tests are disabled by filter file. e.g. This
 [file](https://source.chromium.org/chromium/chromium/src/+/main:testing/buildbot/filters/linux-lacros.browser_tests.filter)
@@ -98,7 +98,7 @@
 By default, //build/lacros/test_runner.py downloads a prebuilt test_ash_chrome.
 If you only change Lacros, this would save your time to not build ash.
 ```
-./build/lacros/test_runner.py test out_linux_lacros/Release/lacros_chrome_browsertests_run_in_series --gtest_filter=ScreenManagerLacrosBrowserTest.*
+./build/lacros/test_runner.py test out_linux_lacros/Release/lacros_chrome_browsertests --gtest_filter=ScreenManagerLacrosBrowserTest.*
 ```
 
 2.  Build linux Ash in a separate folder
@@ -107,15 +107,15 @@
 ```
 ./build/lacros/test_runner.py test \
 --ash-chrome-path=out_linux_ash/Release/test_ash_chrome \
-out_linux_lacros/Release/lacros_chrome_browsertests_run_in_series \
+out_linux_lacros/Release/lacros_chrome_browsertests \
 --gtest_filter=ScreenManagerLacrosBrowserTest.*
 ```
 
 ## Linux version skew testing
 
-If you see a test step name like “lacros_chrome_browsertests_run_in_series_Lacros version skew
+If you see a test step name like “lacros_chrome_browsertests_Lacros version skew
 testing ash 101.0.4951.1 on Ubuntu-18.04”, this means it’s version skew testing
-that “lacros_chrome_browsertests_run_in_series” target is running against a pre-built ash with
+that “lacros_chrome_browsertests” target is running against a pre-built ash with
 version 101.0.4951.13.
 
 There are two ways to run Linux based version skew testing:
@@ -133,7 +133,7 @@
 Then you can use
 ```
 ./build/lacros/test_runner.py test \
-out_linux_lacros_lacros/Release/lacros_chrome_browsertests_run_in_series \
+out_linux_lacros_lacros/Release/lacros_chrome_browsertests \
 --ash-chrome-path-override=lacros_version_skew_tests_v92.0.4515.130/test_ash_chrome
 ```
 to run the test against that version of ash.
diff --git a/docs/transcripts/wuwt-e03-content.md b/docs/transcripts/wuwt-e03-content.md
index cd19812..51234c5 100644
--- a/docs/transcripts/wuwt-e03-content.md
+++ b/docs/transcripts/wuwt-e03-content.md
@@ -16,12 +16,14 @@
 codebase to create the Content layer.
 
 Notes:
+
 - https://docs.google.com/document/d/1EJnG5gK8rQwHkdZTKl8vIwx9oScP8TaKBgwzBafIh9M/edit
 
 Links:
-- [//content/README.md](https://crsrc.org/c/content/README.md)
-- [//content/public/README.md](https://crsrc.org/c/content/public/README.md)
-- [What's Up With Pointers](https://www.youtube.com/watch?v=MpwbWSEDfjM)
+
+- [//content/README.md]
+- [//content/public/README.md]
+- [What's Up With Pointers]
 
 ---
 
@@ -51,7 +53,7 @@
 responsible for the multiprocess sandbox implementation of our platform.
 
 01:24 SHARON: And another term that I had heard a lot tossed around before I
-really understood what was going on was the content public API. So is that the
+really understood what was going on was the content/public API. So is that the
 same as the content layer, or is that different?
 
 01:36 JOHN: It's part of it. So the content component is very large, and so,
@@ -65,10 +67,10 @@
 02:02 JOHN: Sure. The history is - in the beginning, Chrome, like all software
 projects begins nice and easy to understand. But over time, as you add a lot
 more features to go from zero users to billions of users, it becomes harder to
-understand. Small files, small classes become much larger small functions kind
+understand. Small files, small classes become much larger; small functions kind
 of get numerous hooks to talk to every feature, because they want to know when
-something happens. And so, this idea started that let's separate the product.
-Things that make Google Chrome what it is from the platform, which is what any
+something happens. And so, this idea started that let's separate the product -
+things that make Google Chrome what it is - from the platform, which is what any
 browser, any minimal browser doing the latest HTML specs would need to
 implement them in a sandbox, a multiprocess way. And so, content was the lower
 part, and that's how it started.
@@ -76,12 +78,12 @@
 02:58 SHARON: How did we get the name content?
 
 02:58 JOHN: The name is like a pun. And when we started Chrome, one of the
-ideas was, we'll focus on content and not Chrome, and so, the browser will get
+ideas was, we'll focus on content and not chrome, and so, the browser will get
 out of the way. Chrome is a term used to refer to all the user interface parts
-of the browser. And so, we said, it's going to be content and not Chrome. And
+of the browser. And so, we said, it's going to be content and not chrome. And
 so, when you open Chrome, you just see a very small UI. Most of what you see is
 the content. And so, when we split the directory, it was originally called
-Source Chrome, and so, the content part, that's the pun. That's where it came
+src/chrome, and so, the content part, that's the pun. That's where it came
 from.
 
 03:34 SHARON: That's fun. Earlier, you mentioned embedders of content. Can you
@@ -90,7 +92,7 @@
 embedders of content for a long time. Well over a year, and it took me a long
 time to really understand what that was. Because, as you mentioned now,
 Chrome's grown a lot. You work on a very specific thing understanding these
-more general concepts of what is content? What is a content embedder are less
+more general concepts of what is content, what is a content embedder, are less
 important to what you do day-to-day. But can you tell us what an embedder of
 content is?
 
@@ -101,13 +103,13 @@
 you know what? It would be nice for people who work on content and not the
 feature part to build a smaller binary. It builds faster. It debugs faster,
 runs faster. And so, we built this minimal example also to other people called
-content shell. And then, we started running tests against that, and that was
+`content_shell`. And then, we started running tests against that, and that was
 the first - or the second embedder of content. And then since then, what was
 unexpected, what we started for code health reasons turned out to be very
 useful for other projects to restart - or start building their browser from.
-And so, things like Android webview, which was using its own fork of web kit,
+And so, things like Android webview, which was using its own fork of WebKit,
 then started using content. That was one first-party example. But then, other
-projects came along. Things like Electron and content-embedded framework, all
+projects came along. Things like Electron and \[Chromium\] Embedded Framework, all
 started building not just products on top of it, but other frameworks.
 
 05:30 SHARON: That was really surprising to learn about, because it seems
@@ -122,8 +124,8 @@
 else.
 
 06:11 SHARON: That makes sense. You also mentioned that Chrome is dependent on
-content. And when I first started working on Chrome as an intern, I had - it
-told to me so many times because I couldn't remember that Chrome can depend on
+content. And when I first started working on Chrome as an intern, I had it
+told to me so many times, because I couldn't remember, that Chrome can depend on
 content, but not the other way around. So can you tell us a bit about this
 layering, and why it's there?
 
@@ -131,7 +133,7 @@
 content, often what we mean, you embed content. You embed content in everything
 that sits below it in the layer tree. So that includes things like Blink, our
 rendering engine. V8, our JavaScript Engine. Net, our networking library, and
-so on. And there's also you can talk to the content public APIs, but also,
+so on. And there's also you can talk to the content/public APIs, but also,
 sometimes, you talk to the Blink API and the files, and V8, and so on.
 
 07:07 SHARON: So you have this many layer API or product? And, at the bottom,
@@ -139,26 +141,26 @@
 that I don't know about. And on top of that, we have content, and then, on top
 of that, we have Chrome?
 
-07:23 JOHN: Right. And so, Chrome as an embedder content can include directory
-in the content public API. But since content can have multiple embedders, it
+07:23 JOHN: Right. And so, Chrome as an embedder of content can include directory
+in the content/public API. But since content can have multiple embedders, it
 can't include Chrome. If content reached out directly to Chrome, then other
 people wouldn't be able to use it. Because if you try to bring in this code, it
-includes files from a directory that you're not using. So, instead, the content
-public API, it has APIs going two different directions. One direction is going
+includes files from a directory that you're not using. So, instead, the content/public
+API, it has APIs going two different directions. One direction is going
 into content, and then, one direction are these abstract interfaces that go out
 from content. And any embedder has to implement them. And so, these usually end
 up in terms like client or delegate. And these are implemented by Chrome, and
 that's how content is able to call back to it. But then, any other, of course,
 product or embedder can also implement these same interfaces.
 
-08:23 SHARON: You mentioned link and also some things called delegate and
+08:23 SHARON: You mentioned Blink and also some things called delegate and
 whatever. So we have a lot of things called something something host in
 content. Can you talk a bit about what the relationship between content and
 Blink is? Because there's a lot of mirroring in terms of how they might be set
 up, and how they relate to each other.
 
-08:37 JOHN: So Blink was the rendering engine that originally started as Web
-Kit. And we forked, and we named it Blink a number of years ago. And that did
+08:37 JOHN: So Blink was the rendering engine that originally started as WebKit.
+And we forked, and we named it Blink a number of years ago. And that did
 not have any concept of processes. So it was something that you call it in one
 process, and it does its job. And you give it whatever data it needs, and it
 gives you back the rendered data. And you can poke at it or whatever you want
@@ -191,10 +193,10 @@
 
 11:11 SHARON: Can you give an example of -
 
-11:11 JOHN: Yes. So, for example, every renderer process has a class in content
-browser called render process host. And then, every tab object in Blink will
-have this class called render view, and then, in content browser, it will have
-this class called render view host.
+11:11 JOHN: Yes. So, for example, every renderer process has a class in content/browser
+called `RenderProcessHost`. And then, every tab object in Blink will
+have this class called `RenderView`, and then, in content/browser, it will have
+this class called `RenderViewHost`.
 
 11:36 SHARON: Those are classes that, depending on what you work on, you might
 see pop up quite a bit. And there's a lot of them. They're all called render
@@ -224,12 +226,12 @@
 that it could be an embedder of content that has security vulnerability in
 their own Mojo calls. And so, content doesn't know about them, so it can't do
 anything about them. You could write insecure code in content. You can also
-write in secure code in an embedder, and if someone finds a vulnerability - so
+write insecure code in an embedder, and if someone finds a vulnerability - so
 let's say someone finds a vulnerability in Blink, and maybe they're only
 running their code in a minimal content shell. Maybe they can't find any other
 Mojo calls that they can abuse to be able to get access to the browser process.
 But maybe someone else, an embedder, is a more full-featured browser. It has
-more IPC service, and that could be more of an attack surface for that - to
+more IPC surface, and that could be more of an attack surface for that - to
 start with that Blink vulnerability and then to hop into the browser process.
 
 14:38 SHARON: And if you gain control of the browser process, that's a very
@@ -249,19 +251,19 @@
 and everything works great. But then, they'll be like, I just need something
 from Blink. But it's not there. And so, sometimes, they'll have to add an IPC
 between processes, and that might interact. They'll be like, how do I get it?
-It's in Blink. It's in the render view class. so I need an interface that talks
-between each render view host and each render view. And that's how they might
-get - well, that would be how they get interaction with the multiprocessor part
+It's in Blink. It's in the `RenderView` class. so I need an interface that talks
+between each `RenderViewHost` and each `RenderView`. And that's how they might
+get - well, that would be how they get interaction with the multiprocess part
 of it. But if someone is just working on something only in a browser process,
 they might still be trying to get information about the current tab. And that's
-represented by a web content's class and content. So they'll look in content
-public browser, and they'll see web contents. And there will be a lot of
+represented by a `WebContents` class in content. So they'll look in
+content/public/browser, and they'll see `WebContents`. And there will be a lot of
 interfaces that hang off it. So they'll be looking at it, going through a trail
 of interfaces and classes to be able to get more information on what's going on
 in the current tab.
 
-16:29 SHARON: Can you give us a quick overview of the Web Content class?
-Because it is one, massive, and two, called something like web contents. Which
+16:29 SHARON: Can you give us a quick overview of the `WebContents` class?
+Because it is one, massive, and two, called something like `WebContents`. Which
 suggests it's important because content plus the web, and it's also something
 you see all over the place. So can you just give us a quick overview of what
 that class does? What it's for? What it represents?
@@ -269,21 +271,21 @@
 16:46 JOHN: Yes. Things now are a lot more complicated than before, but if you
 go back in a time machine and see how these things started, you can roughly
 think in initial Chrome. Every tab had a class to represent the content in that
-tab, and that was called web contents. And then, it was called web contents
+tab, and that was called `WebContents`. And then, it was called `WebContents`
 because we had other classes. We used to be able to put native stuff in a tab.
-And so, that would be called tab contents. But that's gone now, and we just
-have web contents. So that's where the name comes from. And then even, for
-example, there was render process host, which I mentioned earlier. And then,
-each tab, each web contents roughly translate into one render process. And so,
-now, it's a bit more complicated. There are examples where you can have web
-contents inside of web contents, and that's more esoteric that most people
-don't have to deal with. And then, so that's what web contents is for. It will
+And so, that would be called `TabContents`. But that's gone now, and we just
+have `WebContents`. So that's where the name comes from. And then even, for
+example, there was `RenderProcessHost`, which I mentioned earlier. And then,
+each tab, each `WebContents` roughly translate into one render process. And so,
+now, it's a bit more complicated. There are examples where you can have
+`WebContents` inside of `WebContents`, and that's more esoteric that most people
+don't have to deal with. And then, so that's what `WebContents` is for. It will
 do things like take input and feed it to the page. Every time there's a
-permission prompt, you usually go through that. If a page wants to access to a
-microphone, or video, and so on. It keeps track of this navigation going on.
+permission prompt, you usually go through that. If a page wants access to a
+microphone, or video, and so on. It keeps track if there's navigation going on.
 What's the current URL? What's the pending URL? It uses other classes to drive
 all that stuff as you send out the network request and get it back. And that's
-not inside of web contents itself, but it's driven by other helper classes.
+not inside of `WebContents` itself, but it's driven by other helper classes.
 
 18:28 SHARON: I tend to think of content as being the home of navigation, which
 I think is a decent way to think about it and also is maybe biased because of
@@ -300,14 +302,14 @@
 
 19:32 JOHN: So that happens all over the code, but there's a few critical
 directories. If you look at net at a low level, a lot of IETF - and some
-aspects will be implemented there at that layer. Either net or in the network
+web specs will be implemented there at that layer. Either net or in the network
 service, which is a code that runs inside the network process. Then you've got
 V8, of course, our JavaScript engine, and that has to follow the ECMAScript
 standards. And then, there's a lot of the platform standards. Either some of
 them only don't need multiple processes to be - to implement them, so they'll
 just be completely inside Blink. But some of them require multiple processes,
 things that need access to devices and so on. And so, that implementation will
-be split across Blink and content browser. But then, how do you ensure that,
+be split across Blink and content/browser. But then, how do you ensure that,
 not only do you implement this correctly, but also that you don't regress it?
 So there's a whole slew of tests. There's the Blink tests, which used to be
 called the layout tests. And those run across the simple, simple test cases for
@@ -335,21 +337,21 @@
 
 22:06 SHARON: For sure, and it's a good example of why we have all these tests,
 is to make sure things don't break. So that is pretty much all the questions I
-have written down. Is there anything else generally content layer, content
-public API-ish related that is interesting that maybe we didn't get a chance to
+have written down. Is there anything else generally content layer, content/public
+API-ish related that is interesting that maybe we didn't get a chance to
 cover?
 
 22:31 JOHN: Yes. The most common questions is people will be like, well, does
 this belong in content or not? So I can have a chance to point people towards
-their README files and content/README that describes what's supposed to go in
-or not. And then, there's also a content/public/README that describes the
+their README files and [//content/README.md] that describes what's supposed to go in
+or not. And then, there's also a [//content/public/README.md] that describes the
 guidelines we have for the API to make it consistent.
 
 22:59 SHARON: I've definitely seen those questions before. You're updating one
-of the content public APIs. Does this belong? While we're here, can you give us
+of the content/public APIs. Does this belong? While we're here, can you give us
 a quick breakdown heuristic of what things generally would belong in the
-content public API versus you put it up for review, and the reviewer's like,
-no. This does not belong in content public?
+content/public API versus you put it up for review, and the reviewer's like,
+no. This does not belong in content/public?
 
 23:24 JOHN: So sometimes, for example, for convenience, maybe the Chrome layer
 wants to call other parts of Chrome layer, but they don't have a direct
@@ -357,7 +359,7 @@
 so, they'll be like, we'll add something to the content API, and then, that
 way, Chrome can talk to this other part of Chrome or this other component
 through content as a shortcut. We don't allow that, and the reason for that is
-anybody who's gone through the content public directory, it's already huge. And
+anybody who's gone through the content/public directory, it's already huge. And
 so, we feel that if Chrome wants to talk to Chrome or to another layer, they
 should have their own API to each other directly instead of hopping through
 content. Just because the content API's already very large, very complex, hard
@@ -373,7 +375,7 @@
 
 24:45 JOHN: Well, yes. test-only methods, we try really hard - not just for the
 public API, but inside, because we don't want to bloat the binary. But we do
-have content public tests, which is - gives you a lot more leeway to poke at
+have content/public/test, which is - gives you a lot more leeway to poke at
 things in your browser test, for example, or your unit tests. Another thing is,
 we also have guidelines for how the API should be. We don't have, really,
 concrete classes. It's mostly abstract interfaces. And so, there's a bunch of
@@ -381,7 +383,7 @@
 know the guidelines we have for interfaces there.
 
 25:28 SHARON: On the Chrome binary point, how much is the size of the binary
-dependent on the size of the content public API? Is that a big part of the
+dependent on the size of the content/public API? Is that a big part of the
 binary, or is it small enough where, sure, we want to keep it from being
 unnecessarily large but not too much of an issue?
 
@@ -392,12 +394,12 @@
 megabyte range or 40 megabyte range once you put everything together.
 
 26:12 SHARON: And I guess that's something you have to be more conscious of if
-you're working in content versus another directory even in Chrome. is that you
+you're working in content versus another directory even in Chrome, is that you
 have to be wary of your dependencies more so than anywhere else. Not only for
 Chrome, but also, any other embedders who might want to use content.
 
 26:31 JOHN: Yes. And so, for example, if someone's trying to add something in
-Chrome, we also ask, does this have to be in content? Of can this be part of
+Chrome, we also ask, does this have to be in content? Or can this be part of
 Chrome, so that not every embedder has to pay that cost if they don't need it?
 Maybe we'll have an interface, and the embedder can plug the data in through
 that way but still not have it in content. Another problem, of course, with
@@ -413,9 +415,9 @@
 27:28 JOHN: Well, it's always changing. It's not static, driven by the needs of
 the product. And so, you look at big changes happening today like MPArch to
 support various use cases that we didn't have, or we never thought about
-initially. And that's where the web contents, inside web content, some of that
+initially. And that's where the `WebContents` inside `WebContents`, some of that
 comes in. There are big changes like banning, for example, pointers and
-replacing them with a raw pointer. So we can try to address some of the
+replacing them with a `raw_ptr`. So we can try to address some of the
 security problems we have with Use-After-Frees. So that's where, when you look
 at the content code or the Chrome code in general, too, you might see a little
 bit different than that average C++ project that you see. You'll be like, I'm
@@ -486,3 +488,7 @@
 32:44 JOHN: Same. I've been on it for a long time. I don't touch Blink.
 
 32:50 SHARON: Yes. Yes.
+
+[//content/README.md]: https://crsrc.org/c/content/README.md
+[//content/public/README.md]: https://crsrc.org/c/content/public/README.md
+[What's Up With Pointers]: https://www.youtube.com/watch?v=MpwbWSEDfjM
diff --git a/docs/website b/docs/website
index 6ca9b5d..df59ae1 160000
--- a/docs/website
+++ b/docs/website
@@ -1 +1 @@
-Subproject commit 6ca9b5dcd42207c82e48d0d921742abe1a778815
+Subproject commit df59ae11bb4ef8c7ab3803d84cc7808c2b294030
diff --git a/docs/windows_build_instructions.md b/docs/windows_build_instructions.md
index d7be7f4..fcbb127e 100644
--- a/docs/windows_build_instructions.md
+++ b/docs/windows_build_instructions.md
@@ -59,7 +59,10 @@
 to allow greater-than 4 GiB PDBs. This can be installed after the matching
 Windows SDK version is installed, from: Control Panel -> Programs and Features
 -> Windows Software Development Kit [version] -> Change -> Debugging Tools for
-Windows.
+Windows. If building on ARM64 Windows then you will need to manually copy the
+Debuggers\x64 directory from another machine because it does not get installed
+on ARM64 and is needed, whether you are building Chromium for x64 or ARM64 on
+ARM64.
 
 ## Install `depot_tools`
 
diff --git a/extensions/browser/api/alarms/alarm_manager.cc b/extensions/browser/api/alarms/alarm_manager.cc
index 404aced..376a1f7 100644
--- a/extensions/browser/api/alarms/alarm_manager.cc
+++ b/extensions/browser/api/alarms/alarm_manager.cc
@@ -70,7 +70,7 @@
 }
 
 AlarmManager::AlarmList AlarmsFromValue(const std::string extension_id,
-                                        bool is_unpacked,
+                                        base::TimeDelta min_delay,
                                         const base::Value::List& list) {
   AlarmManager::AlarmList alarms;
   const int max_to_create = std::min(base::saturated_cast<int>(list.size()),
@@ -88,9 +88,7 @@
         // No else branch. It's okay to ignore the failure since we have
         // minimum granularity.
       }
-      alarm.minimum_granularity =
-          is_unpacked ? alarms_api_constants::kDevDelayMinimum
-                      : alarms_api_constants::kReleaseDelayMinimum;
+      alarm.minimum_granularity = min_delay;
       if (alarm.granularity < alarm.minimum_granularity)
         alarm.granularity = alarm.minimum_granularity;
       alarms.emplace_back(std::move(alarm));
@@ -335,11 +333,11 @@
 }
 
 void AlarmManager::ReadFromStorage(const std::string& extension_id,
-                                   bool is_unpacked,
+                                   base::TimeDelta min_delay,
                                    absl::optional<base::Value> value) {
   if (value && value->is_list()) {
     AlarmList alarm_states =
-        AlarmsFromValue(extension_id, is_unpacked, value->GetList());
+        AlarmsFromValue(extension_id, min_delay, value->GetList());
     for (auto& alarm : alarm_states)
       AddAlarmImpl(extension_id, std::move(alarm));
   }
@@ -447,10 +445,12 @@
   if (storage) {
     bool is_unpacked = Manifest::IsUnpackedLocation(extension->location());
     ready_actions_.insert(ReadyMap::value_type(extension->id(), ReadyQueue()));
+    base::TimeDelta min_delay = alarms_api_constants::GetMinimumDelay(
+        is_unpacked, extension->manifest_version());
     storage->GetExtensionValue(extension->id(), kRegisteredAlarms,
                                base::BindOnce(&AlarmManager::ReadFromStorage,
                                               weak_ptr_factory_.GetWeakPtr(),
-                                              extension->id(), is_unpacked));
+                                              extension->id(), min_delay));
   }
 }
 
diff --git a/extensions/browser/api/alarms/alarm_manager.h b/extensions/browser/api/alarms/alarm_manager.h
index c23f78a45..4ea83605 100644
--- a/extensions/browser/api/alarms/alarm_manager.h
+++ b/extensions/browser/api/alarms/alarm_manager.h
@@ -206,7 +206,7 @@
   // Syncs our alarm data for the given extension to/from the state storage.
   void WriteToStorage(const std::string& extension_id);
   void ReadFromStorage(const std::string& extension_id,
-                       bool is_unpacked,
+                       base::TimeDelta min_delay,
                        absl::optional<base::Value> value);
 
   // Set the timer to go off at the specified |time|, and set |next_poll_time|
diff --git a/extensions/browser/api/alarms/alarms_api.cc b/extensions/browser/api/alarms/alarms_api.cc
index 16da573..68f57368 100644
--- a/extensions/browser/api/alarms/alarms_api.cc
+++ b/extensions/browser/api/alarms/alarms_api.cc
@@ -56,27 +56,36 @@
   // compute a long-enough timeout, but then the call into the alarms interface
   // gets delayed past the boundary).  However, it's still worth warning about
   // relative delays that are shorter than we'll honor.
+  // For this minimum delay, we compare to the minimum of a packed extension,
+  // since we want to appropriately warn developers (we take into account the
+  // "real" unpacked state in the phrasing of the warning).
+  const base::TimeDelta min_packed_delay =
+      alarms_api_constants::GetMinimumDelay(/*is_unpacked=*/false,
+                                            extension->manifest_version());
+  const bool is_unpacked = Manifest::IsUnpackedLocation(extension->location());
   if (create_info.delay_in_minutes) {
-    if (base::Minutes(*create_info.delay_in_minutes) <
-        alarms_api_constants::kReleaseDelayMinimum) {
-      if (Manifest::IsUnpackedLocation(extension->location())) {
-        warnings->push_back(ErrorUtils::FormatErrorMessage(
-            alarms_api_constants::kWarningMinimumDevDelay, alarm_name));
+    if (base::Minutes(*create_info.delay_in_minutes) < min_packed_delay) {
+      if (is_unpacked) {
+        warnings->push_back(base::StringPrintf(
+            alarms_api_constants::kWarningMinimumDevDelay, "delay",
+            min_packed_delay.InSeconds(), alarm_name.c_str()));
       } else {
-        warnings->push_back(ErrorUtils::FormatErrorMessage(
-            alarms_api_constants::kWarningMinimumReleaseDelay, alarm_name));
+        warnings->push_back(base::StringPrintf(
+            alarms_api_constants::kWarningMinimumReleaseDelay, "delay",
+            min_packed_delay.InSeconds(), alarm_name.c_str()));
       }
     }
   }
   if (create_info.period_in_minutes) {
-    if (base::Minutes(*create_info.period_in_minutes) <
-        alarms_api_constants::kReleaseDelayMinimum) {
-      if (Manifest::IsUnpackedLocation(extension->location())) {
-        warnings->push_back(ErrorUtils::FormatErrorMessage(
-            alarms_api_constants::kWarningMinimumDevPeriod, alarm_name));
+    if (base::Minutes(*create_info.period_in_minutes) < min_packed_delay) {
+      if (is_unpacked) {
+        warnings->push_back(base::StringPrintf(
+            alarms_api_constants::kWarningMinimumDevDelay, "period",
+            min_packed_delay.InSeconds(), alarm_name.c_str()));
       } else {
-        warnings->push_back(ErrorUtils::FormatErrorMessage(
-            alarms_api_constants::kWarningMinimumReleasePeriod, alarm_name));
+        warnings->push_back(base::StringPrintf(
+            alarms_api_constants::kWarningMinimumReleaseDelay, "period",
+            min_packed_delay.InSeconds(), alarm_name.c_str()));
       }
     }
   }
@@ -119,11 +128,9 @@
     WriteToConsole(blink::mojom::ConsoleMessageLevel::kWarning, warning);
   }
 
-  base::TimeDelta granularity =
-      Manifest::IsUnpackedLocation(extension()->location())
-          ? alarms_api_constants::kDevDelayMinimum
-          : alarms_api_constants::kReleaseDelayMinimum;
-
+  base::TimeDelta granularity = alarms_api_constants::GetMinimumDelay(
+      Manifest::IsUnpackedLocation(extension()->location()),
+      extension()->manifest_version());
   Alarm alarm(alarm_name, params->alarm_info, granularity, clock_->Now());
   alarm_manager->AddAlarm(
       extension_id(), std::move(alarm),
diff --git a/extensions/browser/api/alarms/alarms_api_constants.cc b/extensions/browser/api/alarms/alarms_api_constants.cc
index 385733f..fd0fa558 100644
--- a/extensions/browser/api/alarms/alarms_api_constants.cc
+++ b/extensions/browser/api/alarms/alarms_api_constants.cc
@@ -7,24 +7,15 @@
 namespace extensions {
 namespace alarms_api_constants {
 
-const char kWarningMinimumDevDelay[] =
-    "Alarm delay is less than minimum of 1 minutes. In released .crx, alarm "
-    "\"*\" will fire in approximately 1 minutes.";
-
-const char kWarningMinimumReleaseDelay[] =
-    "Alarm delay is less than minimum of 1 minutes. Alarm \"*\" will fire in "
-    "approximately 1 minutes.";
-
-const char kWarningMinimumDevPeriod[] =
-    "Alarm period is less than minimum of 1 minutes. In released .crx, alarm "
-    "\"*\" will fire approximately every 1 minutes.";
-
-const char kWarningMinimumReleasePeriod[] =
-    "Alarm period is less than minimum of 1 minutes. Alarm \"*\" will fire "
-    "approximately every 1 minutes.";
-
-static_assert(kReleaseDelayMinimum == base::Minutes(1),
-              "warning message must be updated");
+base::TimeDelta GetMinimumDelay(bool is_unpacked, int manifest_version) {
+  if (is_unpacked) {
+    return alarms_api_constants::kDevDelayMinimum;
+  }
+  if (manifest_version >= 3) {
+    return alarms_api_constants::kMV3ReleaseDelayMinimum;
+  }
+  return alarms_api_constants::kMV2ReleaseDelayMinimum;
+}
 
 }  // namespace alarms_api_constants
 }  // namespace extensions
diff --git a/extensions/browser/api/alarms/alarms_api_constants.h b/extensions/browser/api/alarms/alarms_api_constants.h
index 2bd902f0..8da94e2 100644
--- a/extensions/browser/api/alarms/alarms_api_constants.h
+++ b/extensions/browser/api/alarms/alarms_api_constants.h
@@ -5,6 +5,8 @@
 #ifndef EXTENSIONS_BROWSER_API_ALARMS_ALARMS_API_CONSTANTS_H_
 #define EXTENSIONS_BROWSER_API_ALARMS_ALARMS_API_CONSTANTS_H_
 
+#include <cinttypes>
+
 #include "base/time/time.h"
 
 namespace extensions {
@@ -12,13 +14,25 @@
 
 // Minimum specifiable alarm period (in minutes) for unpacked extensions.
 inline constexpr base::TimeDelta kDevDelayMinimum = base::Seconds(1);
-// Minimum specifiable alarm period (in minutes) for packed/crx extensions.
-inline constexpr base::TimeDelta kReleaseDelayMinimum = base::Minutes(1);
+// Minimum specifiable alarm period (in minutes) for packed/crx MV2 extensions.
+inline constexpr base::TimeDelta kMV2ReleaseDelayMinimum = base::Minutes(1);
+// Minimum specifiable alarm period (in minutes) for packed/crx MV3 extensions.
+// This is designed to align with the idle timeout of service workers.
+inline constexpr base::TimeDelta kMV3ReleaseDelayMinimum = base::Seconds(30);
 
-extern const char kWarningMinimumDevDelay[];
-extern const char kWarningMinimumReleaseDelay[];
-extern const char kWarningMinimumDevPeriod[];
-extern const char kWarningMinimumReleasePeriod[];
+// Returns the minimum time delay (either one-time or periodic) for an extension
+// with the given unpacked state and `manifest_version`.
+base::TimeDelta GetMinimumDelay(bool is_unpacked, int manifest_version);
+
+inline constexpr char kWarningMinimumDevDelay[] =
+    "Alarm %s is less than the minimum duration of %" PRId64
+    " seconds."
+    " In packed extensions, alarm \"%s\" will fire after the minimum duration.";
+
+inline constexpr char kWarningMinimumReleaseDelay[] =
+    "Alarm %s is less than the minimum duration of %" PRId64
+    " seconds."
+    " Alarm \"%s\" will fire after the minimum duration.";
 
 }  // namespace alarms_api_constants
 }  // namespace extensions
diff --git a/extensions/browser/api/alarms/alarms_api_unittest.cc b/extensions/browser/api/alarms/alarms_api_unittest.cc
index 73a88df..f7902699 100644
--- a/extensions/browser/api/alarms/alarms_api_unittest.cc
+++ b/extensions/browser/api/alarms/alarms_api_unittest.cc
@@ -340,7 +340,8 @@
   EXPECT_EQ(blink::mojom::ConsoleMessageLevel::kWarning,
             local_frame.last_level());
   EXPECT_THAT(local_frame.last_message(),
-              testing::HasSubstr("delay is less than minimum of 1"));
+              testing::HasSubstr(
+                  "delay is less than the minimum duration of 60 seconds"));
 }
 
 TEST_F(ExtensionAlarmsTest, Get) {
@@ -695,10 +696,14 @@
 TEST_F(ExtensionAlarmsSchedulingTest, PollFrequencyFromStoredAlarm) {
   struct {
     bool is_unpacked;
+    int manifest_version;
     base::TimeDelta delay_minimum;
   } test_data[] = {
-      {true, alarms_api_constants::kDevDelayMinimum},
-      {false, alarms_api_constants::kReleaseDelayMinimum},
+      {true, 2, alarms_api_constants::kDevDelayMinimum},
+      {true, 3, alarms_api_constants::kDevDelayMinimum},
+      {false, 2, alarms_api_constants::kMV2ReleaseDelayMinimum},
+      {false, 3, alarms_api_constants::kMV3ReleaseDelayMinimum},
+      {false, 4, alarms_api_constants::kMV3ReleaseDelayMinimum},
   };
 
   // Test once for unpacked and once for crx extension.
@@ -709,7 +714,10 @@
     std::string alarm_args =
         "[{\"name\": \"hello\", \"scheduledTime\": 10000, "
         "\"periodInMinutes\": 0.0001}]";
-    alarm_manager_->ReadFromStorage(extension()->id(), test_data[i].is_unpacked,
+    base::TimeDelta min_delay = alarms_api_constants::GetMinimumDelay(
+        test_data[i].is_unpacked, test_data[i].manifest_version);
+
+    alarm_manager_->ReadFromStorage(extension()->id(), min_delay,
                                     base::test::ParseJson(alarm_args));
 
     // Let the alarm fire once, we will verify the next polling time afterwards.
@@ -722,11 +730,17 @@
     // alarms_api_constants::kReleaseDelayMinimum). Make sure
     // our next poll time corresponds to our allowed minimum and not to the
     // StateStore specified "periodInMinutes".
-    EXPECT_GE(alarm_manager_->next_poll_time_,
-              // 10s initial clock.
-              base::Time::FromJsTime(10000) +
-                  // 10ms in FrequencyTestGetAlarmsCallback.
-                  base::Milliseconds(10) + test_data[i].delay_minimum);
+    base::Time expected_poll_time =
+        // 10s initial clock.
+        base::Time::FromJsTime(10000) +
+        // 10ms in FrequencyTestGetAlarmsCallback.
+        base::Milliseconds(10) + test_data[i].delay_minimum;
+    // The alarm should not trigger before our expected poll time...
+    EXPECT_GE(alarm_manager_->next_poll_time_, expected_poll_time);
+    // And should trigger within a few seconds of it (to account for test
+    // differences).
+    EXPECT_LT(alarm_manager_->next_poll_time_,
+              expected_poll_time + base::Seconds(10));
     RemoveAlarm("hello");
   }
 }
diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc
index 5189d406..ab35355 100644
--- a/extensions/browser/event_router.cc
+++ b/extensions/browser/event_router.cc
@@ -340,42 +340,46 @@
 }
 
 void EventRouter::AddListenerForMainThread(
-    mojom::EventListenerOwnerPtr listener_owner,
-    const std::string& event_name) {
+    mojom::EventListenerPtr event_listener) {
   auto* process = GetRenderProcessHostForCurrentReceiver();
   if (!process)
     return;
 
-  if (listener_owner->is_extension_id() &&
-      crx_file::id_util::IdIsValid(listener_owner->get_extension_id())) {
-    AddEventListener(event_name, process, listener_owner->get_extension_id());
-  } else if (listener_owner->is_listener_url() &&
-             listener_owner->get_listener_url().is_valid()) {
-    AddEventListenerForURL(event_name, process,
-                           listener_owner->get_listener_url());
+  const mojom::EventListenerOwner& listener_owner =
+      *event_listener->listener_owner;
+  if (listener_owner.is_extension_id() &&
+      crx_file::id_util::IdIsValid(listener_owner.get_extension_id())) {
+    AddEventListener(event_listener->event_name, process,
+                     listener_owner.get_extension_id());
+  } else if (listener_owner.is_listener_url() &&
+             listener_owner.get_listener_url().is_valid()) {
+    AddEventListenerForURL(event_listener->event_name, process,
+                           listener_owner.get_listener_url());
   } else {
     mojo::ReportBadMessage(kAddEventListenerWithInvalidParam);
   }
 }
 
 void EventRouter::AddListenerForServiceWorker(
-    const std::string& extension_id,
-    const std::string& event_name,
-    mojom::ServiceWorkerContextPtr service_worker_context) {
+    mojom::EventListenerPtr event_listener) {
   auto* process = GetRenderProcessHostForCurrentReceiver();
   if (!process)
     return;
 
-  if (crx_file::id_util::IdIsValid(extension_id)) {
-    if (!service_worker_context->scope_url.is_valid()) {
-      mojo::ReportBadMessage(kAddEventListenerWithInvalidWorkerScopeURL);
-      return;
-    }
-    AddServiceWorkerEventListener(event_name, process, extension_id,
-                                  std::move(service_worker_context));
-  } else {
+  const mojom::EventListenerOwner& listener_owner =
+      *event_listener->listener_owner;
+  if (!listener_owner.is_extension_id() ||
+      !crx_file::id_util::IdIsValid(listener_owner.get_extension_id())) {
     mojo::ReportBadMessage(kAddEventListenerWithInvalidExtensionID);
+    return;
   }
+
+  if (!event_listener->service_worker_context->scope_url.is_valid()) {
+    mojo::ReportBadMessage(kAddEventListenerWithInvalidWorkerScopeURL);
+    return;
+  }
+
+  AddServiceWorkerEventListener(std::move(event_listener), process);
 }
 
 void EventRouter::AddLazyListenerForMainThread(const std::string& extension_id,
@@ -434,43 +438,46 @@
 }
 
 void EventRouter::RemoveListenerForMainThread(
-    mojom::EventListenerOwnerPtr listener_owner,
-    const std::string& event_name) {
+    mojom::EventListenerPtr event_listener) {
   auto* process = GetRenderProcessHostForCurrentReceiver();
   if (!process)
     return;
 
-  if (listener_owner->is_extension_id() &&
-      crx_file::id_util::IdIsValid(listener_owner->get_extension_id())) {
-    RemoveEventListener(event_name, process,
-                        listener_owner->get_extension_id());
-  } else if (listener_owner->is_listener_url() &&
-             listener_owner->get_listener_url().is_valid()) {
-    RemoveEventListenerForURL(event_name, process,
-                              listener_owner->get_listener_url());
+  const mojom::EventListenerOwner& listener_owner =
+      *event_listener->listener_owner;
+  if (listener_owner.is_extension_id() &&
+      crx_file::id_util::IdIsValid(listener_owner.get_extension_id())) {
+    RemoveEventListener(event_listener->event_name, process,
+                        listener_owner.get_extension_id());
+  } else if (listener_owner.is_listener_url() &&
+             listener_owner.get_listener_url().is_valid()) {
+    RemoveEventListenerForURL(event_listener->event_name, process,
+                              listener_owner.get_listener_url());
   } else {
     mojo::ReportBadMessage(kRemoveEventListenerWithInvalidParam);
   }
 }
 
 void EventRouter::RemoveListenerForServiceWorker(
-    const std::string& extension_id,
-    const std::string& event_name,
-    mojom::ServiceWorkerContextPtr service_worker_context) {
+    mojom::EventListenerPtr event_listener) {
   auto* process = GetRenderProcessHostForCurrentReceiver();
   if (!process)
     return;
 
-  if (crx_file::id_util::IdIsValid(extension_id)) {
-    if (!service_worker_context->scope_url.is_valid()) {
-      mojo::ReportBadMessage(kRemoveEventListenerWithInvalidWorkerScopeURL);
-      return;
-    }
-    RemoveServiceWorkerEventListener(event_name, process, extension_id,
-                                     std::move(service_worker_context));
-  } else {
+  const mojom::EventListenerOwner& listener_owner =
+      *event_listener->listener_owner;
+  if (!listener_owner.is_extension_id() ||
+      !crx_file::id_util::IdIsValid(listener_owner.get_extension_id())) {
     mojo::ReportBadMessage(kRemoveEventListenerWithInvalidExtensionID);
+    return;
   }
+
+  if (!event_listener->service_worker_context->scope_url.is_valid()) {
+    mojo::ReportBadMessage(kRemoveEventListenerWithInvalidWorkerScopeURL);
+    return;
+  }
+
+  RemoveServiceWorkerEventListener(std::move(event_listener), process);
 }
 
 void EventRouter::RemoveLazyListenerForMainThread(
@@ -537,14 +544,15 @@
 }
 
 void EventRouter::AddServiceWorkerEventListener(
-    const std::string& event_name,
-    RenderProcessHost* process,
-    const ExtensionId& extension_id,
-    mojom::ServiceWorkerContextPtr service_worker_context) {
+    mojom::EventListenerPtr event_listener,
+    RenderProcessHost* process) {
+  const mojom::ServiceWorkerContext& service_worker =
+      *event_listener->service_worker_context;
   listeners_.AddListener(EventListener::ForExtensionServiceWorker(
-      event_name, extension_id, process, process->GetBrowserContext(),
-      service_worker_context->scope_url, service_worker_context->version_id,
-      service_worker_context->thread_id, absl::nullopt));
+      event_listener->event_name,
+      event_listener->listener_owner->get_extension_id(), process,
+      process->GetBrowserContext(), service_worker.scope_url,
+      service_worker.version_id, service_worker.thread_id, absl::nullopt));
   CHECK(base::Contains(observed_process_set_, process));
 }
 
@@ -557,15 +565,16 @@
 }
 
 void EventRouter::RemoveServiceWorkerEventListener(
-    const std::string& event_name,
-    RenderProcessHost* process,
-    const ExtensionId& extension_id,
-    mojom::ServiceWorkerContextPtr service_worker_context) {
+    mojom::EventListenerPtr event_listener,
+    RenderProcessHost* process) {
+  const mojom::ServiceWorkerContext& service_worker =
+      *event_listener->service_worker_context;
   std::unique_ptr<EventListener> listener =
       EventListener::ForExtensionServiceWorker(
-          event_name, extension_id, process, process->GetBrowserContext(),
-          service_worker_context->scope_url, service_worker_context->version_id,
-          service_worker_context->thread_id, absl::nullopt);
+          event_listener->event_name,
+          event_listener->listener_owner->get_extension_id(), process,
+          process->GetBrowserContext(), service_worker.scope_url,
+          service_worker.version_id, service_worker.thread_id, absl::nullopt);
   listeners_.RemoveListener(listener.get());
 }
 
diff --git a/extensions/browser/event_router.h b/extensions/browser/event_router.h
index 37acf675..13debf7 100644
--- a/extensions/browser/event_router.h
+++ b/extensions/browser/event_router.h
@@ -162,13 +162,11 @@
   ~EventRouter() override;
 
   // mojom::EventRouter:
-  void AddListenerForMainThread(mojom::EventListenerOwnerPtr listener_owner,
-                                const std::string& name) override;
+  void AddListenerForMainThread(
+      mojom::EventListenerPtr event_listener) override;
 
   void AddListenerForServiceWorker(
-      const std::string& extension_id,
-      const std::string& name,
-      mojom::ServiceWorkerContextPtr service_worker_context) override;
+      mojom::EventListenerPtr event_listener) override;
 
   void AddLazyListenerForMainThread(const std::string& extension_id,
                                     const std::string& name) override;
@@ -190,13 +188,11 @@
       base::Value::Dict filter,
       bool add_lazy_listener) override;
 
-  void RemoveListenerForMainThread(mojom::EventListenerOwnerPtr listener_owner,
-                                   const std::string& name) override;
+  void RemoveListenerForMainThread(
+      mojom::EventListenerPtr event_listener) override;
 
   void RemoveListenerForServiceWorker(
-      const std::string& extension_id,
-      const std::string& event_name,
-      mojom::ServiceWorkerContextPtr service_worker_context) override;
+      mojom::EventListenerPtr event_listener) override;
 
   void RemoveLazyListenerForMainThread(const std::string& extension_id,
                                        const std::string& name) override;
@@ -226,11 +222,8 @@
   void RemoveEventListener(const std::string& event_name,
                            content::RenderProcessHost* process,
                            const ExtensionId& extension_id);
-  void RemoveServiceWorkerEventListener(
-      const std::string& event_name,
-      content::RenderProcessHost* process,
-      const ExtensionId& extension_id,
-      mojom::ServiceWorkerContextPtr service_worker_context);
+  void RemoveServiceWorkerEventListener(mojom::EventListenerPtr event_listener,
+                                        content::RenderProcessHost* process);
 
   // Add or remove a URL as an event listener for |event_name|.
   void AddEventListenerForURL(const std::string& event_name,
@@ -416,11 +409,8 @@
   void AddEventListener(const std::string& event_name,
                         content::RenderProcessHost* process,
                         const ExtensionId& extension_id);
-  void AddServiceWorkerEventListener(
-      const std::string& event_name,
-      content::RenderProcessHost* process,
-      const ExtensionId& extension_id,
-      mojom::ServiceWorkerContextPtr service_worker_context);
+  void AddServiceWorkerEventListener(mojom::EventListenerPtr event_listener,
+                                     content::RenderProcessHost* process);
 
   // Returns or sets the list of events for which the given extension has
   // registered.
diff --git a/extensions/browser/event_router_unittest.cc b/extensions/browser/event_router_unittest.cc
index e3f232f..39d589a7 100644
--- a/extensions/browser/event_router_unittest.cc
+++ b/extensions/browser/event_router_unittest.cc
@@ -814,8 +814,11 @@
   const int sw_thread_id = 100;
   MockEventDispatcher sw_event_dispatcher;
   event_router()->AddServiceWorkerEventListener(
-      event_name, process4.get(), ext3,
-      mojom::ServiceWorkerContext::New(GURL(), sw_version_id, sw_thread_id));
+      mojom::EventListener::New(
+          mojom::EventListenerOwner::NewExtensionId(ext3), event_name,
+          mojom::ServiceWorkerContext::New(GURL(), sw_version_id, sw_thread_id),
+          /*event_filter=*/absl::nullopt),
+      process4.get());
   event_router()->BindServiceWorkerEventDispatcher(
       process4->GetID(), sw_thread_id, sw_event_dispatcher.BindAndPassRemote());
 
diff --git a/extensions/browser/extension_frame_host.cc b/extensions/browser/extension_frame_host.cc
index 0515dfb..0e7893cd 100644
--- a/extensions/browser/extension_frame_host.cc
+++ b/extensions/browser/extension_frame_host.cc
@@ -118,14 +118,9 @@
     std::vector<mojom::DraggableRegionPtr> regions) {
   content::RenderFrameHost* render_frame_host =
       receivers_.GetCurrentTargetFrame();
-  // This message should come from a primary main frame.
-  if (!render_frame_host->IsInPrimaryMainFrame()) {
-    bad_message::ReceivedBadMessage(
-        render_frame_host->GetProcess(),
-        bad_message::AWCI_INVALID_CALL_FROM_NOT_PRIMARY_MAIN_FRAME);
-    return;
-  }
 
+  // TODO(dtapuska): We should restrict sending the draggable region
+  // only to AppWindows.
   AppWindowRegistry* registry =
       AppWindowRegistry::Get(render_frame_host->GetBrowserContext());
   if (!registry) {
@@ -135,6 +130,14 @@
   if (!app_window) {
     return;
   }
+
+  // This message should come from a primary main frame.
+  if (!render_frame_host->IsInPrimaryMainFrame()) {
+    bad_message::ReceivedBadMessage(
+        render_frame_host->GetProcess(),
+        bad_message::AWCI_INVALID_CALL_FROM_NOT_PRIMARY_MAIN_FRAME);
+    return;
+  }
   app_window->UpdateDraggableRegions(std::move(regions));
 }
 
diff --git a/extensions/browser/file_reader.cc b/extensions/browser/file_reader.cc
index 386c08cc..db4426f 100644
--- a/extensions/browser/file_reader.cc
+++ b/extensions/browser/file_reader.cc
@@ -9,7 +9,7 @@
 #include "base/files/file_util.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
-#include "base/strings/stringprintf.h"
+#include "base/strings/strcat.h"
 #include "base/task/single_thread_task_runner.h"
 #include "extensions/browser/extension_file_task_runner.h"
 
@@ -48,12 +48,9 @@
       // If `file_data` is non-empty, then the file length exceeded
       // `max_resources_length_`. Otherwise, another error was encountered when
       // attempting to read the file.
-      const char* const format_string =
-          file_data->empty()
-              ? "Could not load file: '%s'."
-              : "Could not load file: '%s'. Resource size exceeded.";
-      error = base::StringPrintf(
-          format_string, resource.relative_path().AsUTF8Unsafe().c_str());
+      error = base::StrCat(
+          {"Could not load file: '", resource.relative_path().AsUTF8Unsafe(),
+           "'.", file_data->empty() ? "" : " Resource size exceeded."});
 
       // Clear `data` to avoid passing a partial result.
       data.clear();
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
index be727ed..02f20456 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.cc
@@ -450,7 +450,7 @@
   const GURL& url = navigation_handle->GetURL();
   if (url.SchemeIs(kExtensionScheme) &&
       url.host_piece() == extension_misc::kPdfExtensionId) {
-    // The unseasoned PDF viewer will navigate to the stream URL (using
+    // The PDF viewer will navigate to the stream URL (using
     // PdfNavigtionThrottle), rather than using it as a subresource.
     return;
   }
diff --git a/extensions/common/manifest_handlers/csp_info_unittest.cc b/extensions/common/manifest_handlers/csp_info_unittest.cc
index 367bb8b..ac771312 100644
--- a/extensions/common/manifest_handlers/csp_info_unittest.cc
+++ b/extensions/common/manifest_handlers/csp_info_unittest.cc
@@ -165,6 +165,11 @@
 
 // Tests the requirements for object-src specifications.
 TEST_F(CSPInfoUnitTest, ObjectSrcRequirements) {
+  enum class ManifestVersion {
+    kMV2,
+    kMV3,
+  };
+
   static constexpr char kManifestV3Template[] =
       R"({
            "name": "Test Extension",
@@ -183,31 +188,33 @@
            "content_security_policy": "%s"
          })";
 
-  auto get_manifest = [](const char* manifest_template, const char* input) {
+  auto get_manifest = [](ManifestVersion version, const char* input) {
     return base::test::ParseJsonDict(
-        base::StringPrintf(manifest_template, input));
+        version == ManifestVersion::kMV2
+            ? base::StringPrintf(kManifestV2Template, input)
+            : base::StringPrintf(kManifestV3Template, input));
   };
 
   static constexpr struct {
-    const char* manifest_template;
+    ManifestVersion version;
     const char* csp;
   } kPassingTestcases[] = {
       // object-src doesn't need to be explicitly specified in manifest V3.
-      {kManifestV3Template, "script-src 'self'"},
-      {kManifestV3Template, "default-src 'self'"},
+      {ManifestVersion::kMV3, "script-src 'self'"},
+      {ManifestVersion::kMV3, "default-src 'self'"},
       // Secure object-src specifications are allowed.
-      {kManifestV3Template, "script-src 'self'; object-src 'self'"},
-      {kManifestV3Template, "script-src 'self'; object-src 'none'"},
-      {kManifestV3Template,
-       ("script-src 'self'; object-src 'self'; frame-src 'self'; "
-        "default-src https://google.com")},
+      {ManifestVersion::kMV3, "script-src 'self'; object-src 'self'"},
+      {ManifestVersion::kMV3, "script-src 'self'; object-src 'none'"},
+      {ManifestVersion::kMV3,
+       ("script-src 'self'; object-src 'self'; frame-src 'self'; default-src "
+        "https://google.com")},
       // Even though the object-src in the example below is effectively
       // https://google.com (because it falls back to the default-src), we
       // still allow it so that developers don't need to explicitly specify an
       // object-src just because they specified a default-src. The minimum CSP
       // (which includes `object-src 'self'`) still kicks in and prevents any
       // insecure use.
-      {kManifestV3Template,
+      {ManifestVersion::kMV3,
        "script-src 'self'; default-src https://google.com"},
 
       // In Manifest V2, object-src must be specified (if it's omitted, we add
@@ -215,22 +222,21 @@
       // Note: in MV2, our parsing will implicitly also add a trailing semicolon
       // if one isn't provided, so we always add one here so that the final CSP
       // matches.
-      {kManifestV2Template, "script-src 'self'; object-src 'self';"},
-      {kManifestV2Template, "script-src 'self'; object-src 'none';"},
-      {kManifestV2Template,
-       ("script-src 'self'; object-src 'self'; frame-src 'self'; "
-        "default-src https://google.com;")},
+      {ManifestVersion::kMV2, "script-src 'self'; object-src 'self';"},
+      {ManifestVersion::kMV2, "script-src 'self'; object-src 'none';"},
+      {ManifestVersion::kMV2,
+       ("script-src 'self'; object-src 'self'; frame-src 'self'; default-src "
+        "https://google.com;")},
       // Manifest V2 allows (secure) remote object-src specifications.
-      {kManifestV2Template,
+      {ManifestVersion::kMV2,
        "script-src 'self'; object-src https://google.com;"},
-      {kManifestV2Template,
+      {ManifestVersion::kMV2,
        "script-src 'self'; default-src https://google.com;"},
   };
 
   for (const auto& testcase : kPassingTestcases) {
     SCOPED_TRACE(testcase.csp);
-    ManifestData manifest_data(
-        get_manifest(testcase.manifest_template, testcase.csp));
+    ManifestData manifest_data(get_manifest(testcase.version, testcase.csp));
     scoped_refptr<const Extension> extension =
         LoadAndExpectSuccess(manifest_data);
     ASSERT_TRUE(extension);
@@ -238,39 +244,39 @@
   }
 
   static constexpr struct {
-    const char* manifest_template;
+    ManifestVersion version;
     const char* csp;
     const char* expected_error;
   } kFailingTestcases[] = {
       // If an object-src *is* specified, it must be secure and must not allow
       // remotely-hosted code (in MV3).
-      {kManifestV3Template, "script-src 'self'; object-src https://google.com",
+      {ManifestVersion::kMV3,
+       "script-src 'self'; object-src https://google.com",
        "*Insecure CSP value \"https://google.com\" in directive 'object-src'."},
   };
 
   for (const auto& testcase : kFailingTestcases) {
     SCOPED_TRACE(testcase.csp);
-    ManifestData manifest_data(
-        get_manifest(testcase.manifest_template, testcase.csp));
+    ManifestData manifest_data(get_manifest(testcase.version, testcase.csp));
     LoadAndExpectError(manifest_data, testcase.expected_error);
   }
 
   static constexpr struct {
-    const char* manifest_template;
+    ManifestVersion version;
     const char* csp;
     const char* expected_warning;
     const char* effective_csp;
   } kWarningTestcases[] = {
       // In MV2, if an object-src is not provided, we will warn and synthesize
       // one.
-      {kManifestV2Template, "script-src 'self'",
+      {ManifestVersion::kMV2, "script-src 'self'",
        ("'content_security_policy': CSP directive 'object-src' must be "
         "specified (either explicitly, or implicitly via 'default-src') "
         "and must allowlist only secure resources."),
        "script-src 'self'; object-src 'self';"},
       // Similarly, if an insecure (e.g. http) object-src is provided, we simply
       // ignore it.
-      {kManifestV2Template, "script-src 'self'; object-src http://google.com",
+      {ManifestVersion::kMV2, "script-src 'self'; object-src http://google.com",
        ("'content_security_policy': Ignored insecure CSP value "
         "\"http://google.com\" in directive 'object-src'."),
        "script-src 'self'; object-src;"}};
@@ -278,8 +284,7 @@
   for (const auto& testcase : kWarningTestcases) {
     // Special case: In MV2, if the developer doesn't provide an object-src, we
     // insert one ('self') and emit a warning.
-    ManifestData manifest_data(
-        get_manifest(testcase.manifest_template, testcase.csp));
+    ManifestData manifest_data(get_manifest(testcase.version, testcase.csp));
     scoped_refptr<const Extension> extension =
         LoadAndExpectWarning(manifest_data, testcase.expected_warning);
     ASSERT_TRUE(extension);
diff --git a/extensions/common/mojom/event_router.mojom b/extensions/common/mojom/event_router.mojom
index 4563d931..214b829 100644
--- a/extensions/common/mojom/event_router.mojom
+++ b/extensions/common/mojom/event_router.mojom
@@ -25,21 +25,29 @@
   int32 thread_id;
 };
 
+// Details about a listener for a given event.
+struct EventListener {
+  // The owner of the event listener, either an extension or a web page.
+  EventListenerOwner listener_owner;
+  // The event name for which the listener was added.
+  string event_name;
+  // Details about the service worker context, if and only if this listener was
+  // added by an extension service worker.
+  ServiceWorkerContext? service_worker_context;
+  // The event filter for the listener, if and only if this was for a filtered
+  // event.
+  mojo_base.mojom.DictionaryValue? filter;
+};
+
 // Implemented in the browser, this interface defines methods for handling
 // event router messages from the main thread or service worker.
 interface EventRouter {
-  // Notifies the browser that the given `extension_id` or `listener_url` added
-  // a listener to an event. If it has `extension_id` in `listener_owner`, the
-  // listener is added for the extension. Otherwise, it has a `listener_url` in
-  // `listener_owner` and the listener is added for the URL.
-  AddListenerForMainThread(EventListenerOwner listener_owner,
-                           string event_name);
+  // Notifies the browser that a new `event_listener` has been added.
+  AddListenerForMainThread(EventListener event_listener);
 
   // Notifies the browser that the given extension added a listener to an event
   // in a service worker.
-  AddListenerForServiceWorker(string extension_id,
-                              string event_name,
-                              ServiceWorkerContext service_worker_context);
+  AddListenerForServiceWorker(EventListener event_listener);
 
   // Notifies the browser that the given extension added a listener to an event
   // from a lazy background page.
@@ -72,19 +80,12 @@
       mojo_base.mojom.DictionaryValue filter,
       bool add_lazy_listener);
 
-  // Notifies the browser that the given `extension_id` or `listener_url`
-  // removed a listener to an event. If it has `extension_id` in
-  // `listener_owner`, the listener is removed for the extension. Otherwise, it
-  // has a `listener_url` in `listener_owner` and the listener is removed for
-  // the URL.
-  RemoveListenerForMainThread(EventListenerOwner listener_owner,
-                              string event_name);
+  // Notifies the browser that an `event_listener` has been removed.
+  RemoveListenerForMainThread(EventListener event_listener);
 
   // Notifies the browser that the given extension removed a listener from an
   // event in a service worker.
-  RemoveListenerForServiceWorker(string extension_id,
-                                 string event_name,
-                                 ServiceWorkerContext service_worker_context);
+  RemoveListenerForServiceWorker(EventListener event_listener);
 
   // Notifies the browser that the given extension is no longer interested in
   // receiving the given event from a lazy background page.
diff --git a/extensions/renderer/ipc_message_sender.cc b/extensions/renderer/ipc_message_sender.cc
index c0e7df4b0..f106e281 100644
--- a/extensions/renderer/ipc_message_sender.cc
+++ b/extensions/renderer/ipc_message_sender.cc
@@ -90,8 +90,8 @@
     DCHECK(!context->IsForServiceWorker());
     DCHECK_EQ(kMainThreadId, content::WorkerThread::GetCurrentId());
 
-    GetEventRouter()->AddListenerForMainThread(GetEventListenerOwner(context),
-                                               event_name);
+    GetEventRouter()->AddListenerForMainThread(mojom::EventListener::New(
+        GetEventListenerOwner(context), event_name, nullptr, absl::nullopt));
   }
 
   void SendRemoveUnfilteredEventListenerIPC(
@@ -100,8 +100,8 @@
     DCHECK(!context->IsForServiceWorker());
     DCHECK_EQ(kMainThreadId, content::WorkerThread::GetCurrentId());
 
-    GetEventRouter()->RemoveListenerForMainThread(
-        GetEventListenerOwner(context), event_name);
+    GetEventRouter()->RemoveListenerForMainThread(mojom::EventListener::New(
+        GetEventListenerOwner(context), event_name, nullptr, absl::nullopt));
   }
 
   void SendAddUnfilteredLazyEventListenerIPC(
@@ -392,20 +392,19 @@
     DCHECK_NE(blink::mojom::kInvalidServiceWorkerVersionId,
               context->service_worker_version_id());
 
+    auto event_listener = mojom::EventListener::New(
+        mojom::EventListenerOwner::NewExtensionId(context->GetExtensionID()),
+        event_name,
+        mojom::ServiceWorkerContext::New(context->service_worker_scope(),
+                                         context->service_worker_version_id(),
+                                         content::WorkerThread::GetCurrentId()),
+        /*event_filter=*/absl::nullopt);
 #if BUILDFLAG(ENABLE_EXTENSIONS_LEGACY_IPC)
-    dispatcher_->SendAddEventListener(
-        context->GetExtensionID(), context->service_worker_scope(), event_name,
-        context->service_worker_version_id(),
-        content::WorkerThread::GetCurrentId());
+    dispatcher_->SendAddEventListener(std::move(event_listener));
 #else
     WorkerThreadDispatcher::GetServiceWorkerData()
         ->GetEventRouter()
-        ->AddListenerForServiceWorker(
-            context->GetExtensionID(), event_name,
-            mojom::ServiceWorkerContext::New(
-                context->service_worker_scope(),
-                context->service_worker_version_id(),
-                content::WorkerThread::GetCurrentId()));
+        ->AddListenerForServiceWorker(std::move(event_listener))
 #endif
   }
 
@@ -417,20 +416,20 @@
     DCHECK_NE(blink::mojom::kInvalidServiceWorkerVersionId,
               context->service_worker_version_id());
 
+    auto event_listener = mojom::EventListener::New(
+        mojom::EventListenerOwner::NewExtensionId(context->GetExtensionID()),
+        event_name,
+        mojom::ServiceWorkerContext::New(context->service_worker_scope(),
+                                         context->service_worker_version_id(),
+                                         content::WorkerThread::GetCurrentId()),
+        /*event_filter=*/absl::nullopt);
+
 #if BUILDFLAG(ENABLE_EXTENSIONS_LEGACY_IPC)
-    dispatcher_->SendRemoveEventListener(
-        context->GetExtensionID(), context->service_worker_scope(), event_name,
-        context->service_worker_version_id(),
-        content::WorkerThread::GetCurrentId());
+    dispatcher_->SendRemoveEventListener(std::move(event_listener));
 #else
     WorkerThreadDispatcher::GetServiceWorkerData()
         ->GetEventRouter()
-        ->RemoveListenerForServiceWorker(
-            context->GetExtensionID(), event_name,
-            mojom::ServiceWorkerContext::New(
-                context->service_worker_scope(),
-                context->service_worker_version_id(),
-                content::WorkerThread::GetCurrentId()));
+        ->RemoveListenerForServiceWorker(std::move(event_listener));
 #endif
   }
 
diff --git a/extensions/renderer/worker_thread_dispatcher.cc b/extensions/renderer/worker_thread_dispatcher.cc
index 95123cf4..33819e9 100644
--- a/extensions/renderer/worker_thread_dispatcher.cc
+++ b/extensions/renderer/worker_thread_dispatcher.cc
@@ -53,30 +53,18 @@
 
 // Calls mojom::EventRouter::AddListenerForServiceWorker(). It should be called
 // on the IO thread.
-void AddEventListenerOnIO(const std::string& extension_id,
-                          const GURL& scope,
-                          const std::string& event_name,
-                          int64_t service_worker_version_id,
-                          int worker_thread_id) {
+void AddEventListenerOnIO(mojom::EventListenerPtr event_listener) {
   auto* dispatcher = WorkerThreadDispatcher::Get();
   dispatcher->GetEventRouterOnIO()->AddListenerForServiceWorker(
-      extension_id, event_name,
-      mojom::ServiceWorkerContext::New(scope, service_worker_version_id,
-                                       worker_thread_id));
+      std::move(event_listener));
 }
 
 // Calls mojom::EventRouter::RemoveListenerForServiceWorker(). It should be
 // called on the IO thread.
-void RemoveEventListenerOnIO(const std::string& extension_id,
-                             const GURL& scope,
-                             const std::string& event_name,
-                             int64_t service_worker_version_id,
-                             int worker_thread_id) {
+void RemoveEventListenerOnIO(mojom::EventListenerPtr event_listener) {
   auto* dispatcher = WorkerThreadDispatcher::Get();
   dispatcher->GetEventRouterOnIO()->RemoveListenerForServiceWorker(
-      extension_id, event_name,
-      mojom::ServiceWorkerContext::New(scope, service_worker_version_id,
-                                       worker_thread_id));
+      std::move(event_listener));
 }
 
 // Calls mojom::EventRouter::AddLazyListenerForServiceWorker(). It should be
@@ -132,6 +120,22 @@
                                        worker_thread_id),
       std::move(filter), remove_lazy_listener);
 }
+
+void HandleResponse(int request_id,
+                    bool success,
+                    base::Value::List args,
+                    const std::string& error,
+                    mojom::ExtraResponseDataPtr extra_data) {
+  // If the worker state was already destroyed via
+  // Dispatcher::WillDestroyServiceWorkerContextOnWorkerThread,
+  // then drop this IPC. See https://crbug.com/1008143 for details.
+  if (!service_worker_data) {
+    return;
+  }
+  service_worker_data->bindings_system()->HandleResponse(
+      request_id, success, std::move(args), error, std::move(extra_data));
+}
+
 #endif
 
 }  // namespace
@@ -259,15 +263,10 @@
 
 #if BUILDFLAG(ENABLE_EXTENSIONS_LEGACY_IPC)
 void WorkerThreadDispatcher::SendAddEventListener(
-    const std::string& extension_id,
-    const GURL& scope,
-    const std::string& event_name,
-    int64_t service_worker_version_id,
-    int worker_thread_id) {
+    mojom::EventListenerPtr event_listener) {
   io_task_runner_->PostTask(
       FROM_HERE,
-      base::BindOnce(&AddEventListenerOnIO, extension_id, scope, event_name,
-                     service_worker_version_id, worker_thread_id));
+      base::BindOnce(&AddEventListenerOnIO, std::move(event_listener)));
 }
 
 void WorkerThreadDispatcher::SendAddEventLazyListener(
@@ -302,15 +301,10 @@
 }
 
 void WorkerThreadDispatcher::SendRemoveEventListener(
-    const std::string& extension_id,
-    const GURL& scope,
-    const std::string& event_name,
-    int64_t service_worker_version_id,
-    int worker_thread_id) {
+    mojom::EventListenerPtr event_listener) {
   io_task_runner_->PostTask(
       FROM_HERE,
-      base::BindOnce(&RemoveEventListenerOnIO, extension_id, scope, event_name,
-                     service_worker_version_id, worker_thread_id));
+      base::BindOnce(&RemoveEventListenerOnIO, std::move(event_listener)));
 }
 
 void WorkerThreadDispatcher::SendRemoveEventLazyListener(
@@ -643,19 +637,9 @@
                         auto* dispatcher = WorkerThreadDispatcher::Get();
                         dispatcher->PostTaskToWorkerThread(
                             worker_thread_id,
-                            base::BindOnce(
-                                [](int request_id, bool success,
-                                   base::Value::List args,
-                                   const std::string& error,
-                                   mojom::ExtraResponseDataPtr extra_data) {
-                                  WorkerThreadDispatcher::GetServiceWorkerData()
-                                      ->bindings_system()
-                                      ->HandleResponse(request_id, success,
-                                                       std::move(args), error,
-                                                       std::move(extra_data));
-                                },
-                                request_id, success, std::move(args), error,
-                                std::move(extra_data)));
+                            base::BindOnce(&HandleResponse, request_id, success,
+                                           std::move(args), error,
+                                           std::move(extra_data)));
                       },
                       worker_thread_id, request_id, success, std::move(args),
                       error, std::move(extra_data)));
diff --git a/extensions/renderer/worker_thread_dispatcher.h b/extensions/renderer/worker_thread_dispatcher.h
index 01660ffc..c7ca00d 100644
--- a/extensions/renderer/worker_thread_dispatcher.h
+++ b/extensions/renderer/worker_thread_dispatcher.h
@@ -120,11 +120,7 @@
 #if BUILDFLAG(ENABLE_EXTENSIONS_LEGACY_IPC)
   // Posts mojom::EventRouter::AddListenerForServiceWorker to the IO thread to
   // call it with GetEventRouterOnIO().
-  void SendAddEventListener(const std::string& extension_id,
-                            const GURL& scope,
-                            const std::string& event_name,
-                            int64_t service_worker_version_id,
-                            int worker_thread_id);
+  void SendAddEventListener(mojom::EventListenerPtr event_listener);
 
   // Posts mojom::EventRouter::AddLazyListenerForServiceWorker to the IO thread
   // to call it with GetEventRouterOnIO().
@@ -149,11 +145,7 @@
 
   // Posts mojom::EventRouter::RemoveListenerForServiceWorker to the IO thread
   // to call it with GetEventRouterOnIO().
-  void SendRemoveEventListener(const std::string& extension_id,
-                               const GURL& scope,
-                               const std::string& event_name,
-                               int64_t service_worker_version_id,
-                               int worker_thread_id);
+  void SendRemoveEventListener(mojom::EventListenerPtr event_listener);
 
   // Posts mojom::EventRouter::RemoveLazyListenerForServiceWorker to the IO
   // thread to call it with GetEventRouterOnIO().
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn
index edbca80..209bb84 100644
--- a/gpu/BUILD.gn
+++ b/gpu/BUILD.gn
@@ -483,6 +483,10 @@
   if (is_android && enable_chrome_android_internal) {
     data_deps += [ "//clank/build/bot/filters:gl_tests_filters" ]
   }
+
+  if (is_chromeos) {
+    deps += [ "//ui/gfx/linux:gbm" ]
+  }
 }
 
 test("gpu_unittests") {
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h
index f8110b26..22cb2ef 100644
--- a/gpu/GLES2/gl2chromium_autogen.h
+++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -376,6 +376,8 @@
   GLES2_GET_FUN(ConvertRGBAToYUVAMailboxesINTERNAL)
 #define glConvertYUVAMailboxesToRGBINTERNAL \
   GLES2_GET_FUN(ConvertYUVAMailboxesToRGBINTERNAL)
+#define glConvertYUVAMailboxesToTextureINTERNAL \
+  GLES2_GET_FUN(ConvertYUVAMailboxesToTextureINTERNAL)
 #define glCopySharedImageINTERNAL GLES2_GET_FUN(CopySharedImageINTERNAL)
 #define glCopySharedImageToTextureINTERNAL \
   GLES2_GET_FUN(CopySharedImageToTextureINTERNAL)
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 98a7e3b4..23abb26 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -4083,6 +4083,16 @@
     'unit_test': False,
     'trace_level': 2,
   },
+  'ConvertYUVAMailboxesToTextureINTERNAL': {
+    'decoder_func': 'DoConvertYUVAMailboxesToTextureINTERNAL',
+    'extension': 'CHROMIUM_shared_image',
+    'internal': False,
+    'type': 'PUT',
+    'count': 64, #GL_MAILBOX_SIZE_CHROMIUM x4
+    'impl_func': True,
+    'unit_test': False,
+    'trace_level': 2,
+  },
   'CopySharedImageINTERNAL': {
     'decoder_func': 'DoCopySharedImageINTERNAL',
     'extension': 'CHROMIUM_shared_image',
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index d9cbc30..f0cd8e345 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1679,6 +1679,24 @@
       src_x, src_y, width, height, planes_yuv_color_space, plane_config,
       subsampling, mailboxes);
 }
+void GL_APIENTRY
+GLES2ConvertYUVAMailboxesToTextureINTERNAL(GLuint texture,
+                                           GLenum target,
+                                           GLuint internal_format,
+                                           GLenum type,
+                                           GLint src_x,
+                                           GLint src_y,
+                                           GLsizei width,
+                                           GLsizei height,
+                                           GLboolean flip_y,
+                                           GLenum planes_yuv_color_space,
+                                           GLenum plane_config,
+                                           GLenum subsampling,
+                                           const GLbyte* mailboxes) {
+  gles2::GetGLContext()->ConvertYUVAMailboxesToTextureINTERNAL(
+      texture, target, internal_format, type, src_x, src_y, width, height,
+      flip_y, planes_yuv_color_space, plane_config, subsampling, mailboxes);
+}
 void GL_APIENTRY GLES2CopySharedImageINTERNAL(GLint xoffset,
                                               GLint yoffset,
                                               GLint x,
@@ -3210,6 +3228,11 @@
             glConvertYUVAMailboxesToRGBINTERNAL),
     },
     {
+        "glConvertYUVAMailboxesToTextureINTERNAL",
+        reinterpret_cast<GLES2FunctionPointer>(
+            glConvertYUVAMailboxesToTextureINTERNAL),
+    },
+    {
         "glCopySharedImageINTERNAL",
         reinterpret_cast<GLES2FunctionPointer>(glCopySharedImageINTERNAL),
     },
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index 90693b6f..87c0fb6e 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -3209,6 +3209,32 @@
   }
 }
 
+void ConvertYUVAMailboxesToTextureINTERNALImmediate(
+    GLuint texture,
+    GLenum target,
+    GLuint internal_format,
+    GLenum type,
+    GLint src_x,
+    GLint src_y,
+    GLsizei width,
+    GLsizei height,
+    GLboolean flip_y,
+    GLenum planes_yuv_color_space,
+    GLenum plane_config,
+    GLenum subsampling,
+    const GLbyte* mailboxes) {
+  const uint32_t size = gles2::cmds::
+      ConvertYUVAMailboxesToTextureINTERNALImmediate::ComputeSize();
+  gles2::cmds::ConvertYUVAMailboxesToTextureINTERNALImmediate* c =
+      GetImmediateCmdSpaceTotalSize<
+          gles2::cmds::ConvertYUVAMailboxesToTextureINTERNALImmediate>(size);
+  if (c) {
+    c->Init(texture, target, internal_format, type, src_x, src_y, width, height,
+            flip_y, planes_yuv_color_space, plane_config, subsampling,
+            mailboxes);
+  }
+}
+
 void CopySharedImageINTERNALImmediate(GLint xoffset,
                                       GLint yoffset,
                                       GLint x,
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 0bee7df..24c98b6 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1178,6 +1178,20 @@
                                        GLenum subsampling,
                                        const GLbyte* mailboxes) override;
 
+void ConvertYUVAMailboxesToTextureINTERNAL(GLuint texture,
+                                           GLenum target,
+                                           GLuint internal_format,
+                                           GLenum type,
+                                           GLint src_x,
+                                           GLint src_y,
+                                           GLsizei width,
+                                           GLsizei height,
+                                           GLboolean flip_y,
+                                           GLenum planes_yuv_color_space,
+                                           GLenum plane_config,
+                                           GLenum subsampling,
+                                           const GLbyte* mailboxes) override;
+
 void CopySharedImageINTERNAL(GLint xoffset,
                              GLint yoffset,
                              GLint x,
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
index 0907f178..cd11d1b 100644
--- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -3578,6 +3578,51 @@
   CheckGLError();
 }
 
+void GLES2Implementation::ConvertYUVAMailboxesToTextureINTERNAL(
+    GLuint texture,
+    GLenum target,
+    GLuint internal_format,
+    GLenum type,
+    GLint src_x,
+    GLint src_y,
+    GLsizei width,
+    GLsizei height,
+    GLboolean flip_y,
+    GLenum planes_yuv_color_space,
+    GLenum plane_config,
+    GLenum subsampling,
+    const GLbyte* mailboxes) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG(
+      "[" << GetLogPrefix() << "] glConvertYUVAMailboxesToTextureINTERNAL("
+          << texture << ", " << GLES2Util::GetStringEnum(target) << ", "
+          << internal_format << ", " << GLES2Util::GetStringEnum(type) << ", "
+          << src_x << ", " << src_y << ", " << width << ", " << height << ", "
+          << GLES2Util::GetStringBool(flip_y) << ", "
+          << GLES2Util::GetStringEnum(planes_yuv_color_space) << ", "
+          << GLES2Util::GetStringEnum(plane_config) << ", "
+          << GLES2Util::GetStringEnum(subsampling) << ", "
+          << static_cast<const void*>(mailboxes) << ")");
+  uint32_t count = 64;
+  for (uint32_t ii = 0; ii < count; ++ii) {
+    GPU_CLIENT_LOG("value[" << ii << "]: " << mailboxes[ii]);
+  }
+  if (width < 0) {
+    SetGLError(GL_INVALID_VALUE, "glConvertYUVAMailboxesToTextureINTERNAL",
+               "width < 0");
+    return;
+  }
+  if (height < 0) {
+    SetGLError(GL_INVALID_VALUE, "glConvertYUVAMailboxesToTextureINTERNAL",
+               "height < 0");
+    return;
+  }
+  helper_->ConvertYUVAMailboxesToTextureINTERNALImmediate(
+      texture, target, internal_format, type, src_x, src_y, width, height,
+      flip_y, planes_yuv_color_space, plane_config, subsampling, mailboxes);
+  CheckGLError();
+}
+
 void GLES2Implementation::CopySharedImageINTERNAL(GLint xoffset,
                                                   GLint yoffset,
                                                   GLint x,
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
index e327da5..e43d48b 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -3054,6 +3054,23 @@
   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
 }
 
+TEST_F(GLES2ImplementationTest, ConvertYUVAMailboxesToTextureINTERNAL) {
+  GLbyte data[64] = {0};
+  struct Cmds {
+    cmds::ConvertYUVAMailboxesToTextureINTERNALImmediate cmd;
+    GLbyte data[64];
+  };
+
+  for (int jj = 0; jj < 64; ++jj) {
+    data[jj] = static_cast<GLbyte>(jj);
+  }
+  Cmds expected;
+  expected.cmd.Init(1, 2, 3, 4, 5, 6, 7, 8, true, 10, 11, 12, &data[0]);
+  gl_->ConvertYUVAMailboxesToTextureINTERNAL(1, 2, 3, 4, 5, 6, 7, 8, true, 10,
+                                             11, 12, &data[0]);
+  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
 TEST_F(GLES2ImplementationTest, CopySharedImageINTERNAL) {
   GLbyte data[32] = {0};
   struct Cmds {
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h
index edd260d..845df9d9 100644
--- a/gpu/command_buffer/client/gles2_interface_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -874,6 +874,20 @@
                                                GLenum plane_config,
                                                GLenum subsampling,
                                                const GLbyte* mailboxes) = 0;
+virtual void ConvertYUVAMailboxesToTextureINTERNAL(
+    GLuint texture,
+    GLenum target,
+    GLuint internal_format,
+    GLenum type,
+    GLint src_x,
+    GLint src_y,
+    GLsizei width,
+    GLsizei height,
+    GLboolean flip_y,
+    GLenum planes_yuv_color_space,
+    GLenum plane_config,
+    GLenum subsampling,
+    const GLbyte* mailboxes) = 0;
 virtual void CopySharedImageINTERNAL(GLint xoffset,
                                      GLint yoffset,
                                      GLint x,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
index 8eb7119..541b6f6b 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -846,6 +846,19 @@
                                        GLenum plane_config,
                                        GLenum subsampling,
                                        const GLbyte* mailboxes) override;
+void ConvertYUVAMailboxesToTextureINTERNAL(GLuint texture,
+                                           GLenum target,
+                                           GLuint internal_format,
+                                           GLenum type,
+                                           GLint src_x,
+                                           GLint src_y,
+                                           GLsizei width,
+                                           GLsizei height,
+                                           GLboolean flip_y,
+                                           GLenum planes_yuv_color_space,
+                                           GLenum plane_config,
+                                           GLenum subsampling,
+                                           const GLbyte* mailboxes) override;
 void CopySharedImageINTERNAL(GLint xoffset,
                              GLint yoffset,
                              GLint x,
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
index 69e08a4..7eb42908 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1147,6 +1147,20 @@
     GLenum /* plane_config */,
     GLenum /* subsampling */,
     const GLbyte* /* mailboxes */) {}
+void GLES2InterfaceStub::ConvertYUVAMailboxesToTextureINTERNAL(
+    GLuint /* texture */,
+    GLenum /* target */,
+    GLuint /* internal_format */,
+    GLenum /* type */,
+    GLint /* src_x */,
+    GLint /* src_y */,
+    GLsizei /* width */,
+    GLsizei /* height */,
+    GLboolean /* flip_y */,
+    GLenum /* planes_yuv_color_space */,
+    GLenum /* plane_config */,
+    GLenum /* subsampling */,
+    const GLbyte* /* mailboxes */) {}
 void GLES2InterfaceStub::CopySharedImageINTERNAL(
     GLint /* xoffset */,
     GLint /* yoffset */,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
index 2c3a91e..c8e6b127 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -846,6 +846,19 @@
                                        GLenum plane_config,
                                        GLenum subsampling,
                                        const GLbyte* mailboxes) override;
+void ConvertYUVAMailboxesToTextureINTERNAL(GLuint texture,
+                                           GLenum target,
+                                           GLuint internal_format,
+                                           GLenum type,
+                                           GLint src_x,
+                                           GLint src_y,
+                                           GLsizei width,
+                                           GLsizei height,
+                                           GLboolean flip_y,
+                                           GLenum planes_yuv_color_space,
+                                           GLenum plane_config,
+                                           GLenum subsampling,
+                                           const GLbyte* mailboxes) override;
 void CopySharedImageINTERNAL(GLint xoffset,
                              GLint yoffset,
                              GLint x,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
index 42db133..70aef22 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -2441,6 +2441,27 @@
                                          subsampling, mailboxes);
 }
 
+void GLES2TraceImplementation::ConvertYUVAMailboxesToTextureINTERNAL(
+    GLuint texture,
+    GLenum target,
+    GLuint internal_format,
+    GLenum type,
+    GLint src_x,
+    GLint src_y,
+    GLsizei width,
+    GLsizei height,
+    GLboolean flip_y,
+    GLenum planes_yuv_color_space,
+    GLenum plane_config,
+    GLenum subsampling,
+    const GLbyte* mailboxes) {
+  TRACE_EVENT_BINARY_EFFICIENT0(
+      "gpu", "GLES2Trace::ConvertYUVAMailboxesToTextureINTERNAL");
+  gl_->ConvertYUVAMailboxesToTextureINTERNAL(
+      texture, target, internal_format, type, src_x, src_y, width, height,
+      flip_y, planes_yuv_color_space, plane_config, subsampling, mailboxes);
+}
+
 void GLES2TraceImplementation::CopySharedImageINTERNAL(
     GLint xoffset,
     GLint yoffset,
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index e270e19..633aa51f 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -15772,6 +15772,145 @@
               "offset of ConvertYUVAMailboxesToRGBINTERNALImmediate "
               "subsampling should be 28");
 
+struct ConvertYUVAMailboxesToTextureINTERNALImmediate {
+  typedef ConvertYUVAMailboxesToTextureINTERNALImmediate ValueType;
+  static const CommandId kCmdId =
+      kConvertYUVAMailboxesToTextureINTERNALImmediate;
+  static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
+  static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(2);
+
+  static uint32_t ComputeDataSize() {
+    return static_cast<uint32_t>(sizeof(GLbyte) * 64);
+  }
+
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType) + ComputeDataSize());
+  }
+
+  void SetHeader() { header.SetCmdByTotalSize<ValueType>(ComputeSize()); }
+
+  void Init(GLuint _texture,
+            GLenum _target,
+            GLuint _internal_format,
+            GLenum _type,
+            GLint _src_x,
+            GLint _src_y,
+            GLsizei _width,
+            GLsizei _height,
+            GLboolean _flip_y,
+            GLenum _planes_yuv_color_space,
+            GLenum _plane_config,
+            GLenum _subsampling,
+            const GLbyte* _mailboxes) {
+    SetHeader();
+    texture = _texture;
+    target = _target;
+    internal_format = _internal_format;
+    type = _type;
+    src_x = _src_x;
+    src_y = _src_y;
+    width = _width;
+    height = _height;
+    flip_y = _flip_y;
+    planes_yuv_color_space = _planes_yuv_color_space;
+    plane_config = _plane_config;
+    subsampling = _subsampling;
+    memcpy(ImmediateDataAddress(this), _mailboxes, ComputeDataSize());
+  }
+
+  void* Set(void* cmd,
+            GLuint _texture,
+            GLenum _target,
+            GLuint _internal_format,
+            GLenum _type,
+            GLint _src_x,
+            GLint _src_y,
+            GLsizei _width,
+            GLsizei _height,
+            GLboolean _flip_y,
+            GLenum _planes_yuv_color_space,
+            GLenum _plane_config,
+            GLenum _subsampling,
+            const GLbyte* _mailboxes) {
+    static_cast<ValueType*>(cmd)->Init(_texture, _target, _internal_format,
+                                       _type, _src_x, _src_y, _width, _height,
+                                       _flip_y, _planes_yuv_color_space,
+                                       _plane_config, _subsampling, _mailboxes);
+    const uint32_t size = ComputeSize();
+    return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size);
+  }
+
+  gpu::CommandHeader header;
+  uint32_t texture;
+  uint32_t target;
+  uint32_t internal_format;
+  uint32_t type;
+  int32_t src_x;
+  int32_t src_y;
+  int32_t width;
+  int32_t height;
+  uint32_t flip_y;
+  uint32_t planes_yuv_color_space;
+  uint32_t plane_config;
+  uint32_t subsampling;
+};
+
+static_assert(
+    sizeof(ConvertYUVAMailboxesToTextureINTERNALImmediate) == 52,
+    "size of ConvertYUVAMailboxesToTextureINTERNALImmediate should be 52");
+static_assert(offsetof(ConvertYUVAMailboxesToTextureINTERNALImmediate,
+                       header) == 0,
+              "offset of ConvertYUVAMailboxesToTextureINTERNALImmediate header "
+              "should be 0");
+static_assert(offsetof(ConvertYUVAMailboxesToTextureINTERNALImmediate,
+                       texture) == 4,
+              "offset of ConvertYUVAMailboxesToTextureINTERNALImmediate "
+              "texture should be 4");
+static_assert(offsetof(ConvertYUVAMailboxesToTextureINTERNALImmediate,
+                       target) == 8,
+              "offset of ConvertYUVAMailboxesToTextureINTERNALImmediate target "
+              "should be 8");
+static_assert(offsetof(ConvertYUVAMailboxesToTextureINTERNALImmediate,
+                       internal_format) == 12,
+              "offset of ConvertYUVAMailboxesToTextureINTERNALImmediate "
+              "internal_format should be 12");
+static_assert(offsetof(ConvertYUVAMailboxesToTextureINTERNALImmediate, type) ==
+                  16,
+              "offset of ConvertYUVAMailboxesToTextureINTERNALImmediate type "
+              "should be 16");
+static_assert(offsetof(ConvertYUVAMailboxesToTextureINTERNALImmediate, src_x) ==
+                  20,
+              "offset of ConvertYUVAMailboxesToTextureINTERNALImmediate src_x "
+              "should be 20");
+static_assert(offsetof(ConvertYUVAMailboxesToTextureINTERNALImmediate, src_y) ==
+                  24,
+              "offset of ConvertYUVAMailboxesToTextureINTERNALImmediate src_y "
+              "should be 24");
+static_assert(offsetof(ConvertYUVAMailboxesToTextureINTERNALImmediate, width) ==
+                  28,
+              "offset of ConvertYUVAMailboxesToTextureINTERNALImmediate width "
+              "should be 28");
+static_assert(offsetof(ConvertYUVAMailboxesToTextureINTERNALImmediate,
+                       height) == 32,
+              "offset of ConvertYUVAMailboxesToTextureINTERNALImmediate height "
+              "should be 32");
+static_assert(offsetof(ConvertYUVAMailboxesToTextureINTERNALImmediate,
+                       flip_y) == 36,
+              "offset of ConvertYUVAMailboxesToTextureINTERNALImmediate flip_y "
+              "should be 36");
+static_assert(offsetof(ConvertYUVAMailboxesToTextureINTERNALImmediate,
+                       planes_yuv_color_space) == 40,
+              "offset of ConvertYUVAMailboxesToTextureINTERNALImmediate "
+              "planes_yuv_color_space should be 40");
+static_assert(offsetof(ConvertYUVAMailboxesToTextureINTERNALImmediate,
+                       plane_config) == 44,
+              "offset of ConvertYUVAMailboxesToTextureINTERNALImmediate "
+              "plane_config should be 44");
+static_assert(offsetof(ConvertYUVAMailboxesToTextureINTERNALImmediate,
+                       subsampling) == 48,
+              "offset of ConvertYUVAMailboxesToTextureINTERNALImmediate "
+              "subsampling should be 48");
+
 struct CopySharedImageINTERNALImmediate {
   typedef CopySharedImageINTERNALImmediate ValueType;
   static const CommandId kCmdId = kCopySharedImageINTERNALImmediate;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index 5b18dbce..fc72cc4 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -5475,6 +5475,104 @@
       next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)));
 }
 
+TEST_F(GLES2FormatTest, ConvertYUVAMailboxesToTextureINTERNALImmediate) {
+  const int kSomeBaseValueToTestWith = 51;
+  static GLbyte data[] = {
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 0),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 1),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 2),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 3),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 4),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 5),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 6),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 7),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 8),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 9),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 10),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 11),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 12),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 13),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 14),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 15),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 16),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 17),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 18),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 19),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 20),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 21),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 22),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 23),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 24),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 25),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 26),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 27),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 28),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 29),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 30),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 31),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 32),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 33),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 34),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 35),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 36),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 37),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 38),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 39),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 40),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 41),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 42),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 43),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 44),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 45),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 46),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 47),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 48),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 49),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 50),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 51),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 52),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 53),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 54),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 55),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 56),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 57),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 58),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 59),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 60),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 61),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 62),
+      static_cast<GLbyte>(kSomeBaseValueToTestWith + 63),
+  };
+  cmds::ConvertYUVAMailboxesToTextureINTERNALImmediate& cmd =
+      *GetBufferAs<cmds::ConvertYUVAMailboxesToTextureINTERNALImmediate>();
+  void* next_cmd =
+      cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12),
+              static_cast<GLuint>(13), static_cast<GLenum>(14),
+              static_cast<GLint>(15), static_cast<GLint>(16),
+              static_cast<GLsizei>(17), static_cast<GLsizei>(18),
+              static_cast<GLboolean>(19), static_cast<GLenum>(20),
+              static_cast<GLenum>(21), static_cast<GLenum>(22), data);
+  EXPECT_EQ(static_cast<uint32_t>(
+                cmds::ConvertYUVAMailboxesToTextureINTERNALImmediate::kCmdId),
+            cmd.header.command);
+  EXPECT_EQ(sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)),
+            cmd.header.size * 4u);
+  EXPECT_EQ(static_cast<GLuint>(11), cmd.texture);
+  EXPECT_EQ(static_cast<GLenum>(12), cmd.target);
+  EXPECT_EQ(static_cast<GLuint>(13), cmd.internal_format);
+  EXPECT_EQ(static_cast<GLenum>(14), cmd.type);
+  EXPECT_EQ(static_cast<GLint>(15), cmd.src_x);
+  EXPECT_EQ(static_cast<GLint>(16), cmd.src_y);
+  EXPECT_EQ(static_cast<GLsizei>(17), cmd.width);
+  EXPECT_EQ(static_cast<GLsizei>(18), cmd.height);
+  EXPECT_EQ(static_cast<GLboolean>(19), cmd.flip_y);
+  EXPECT_EQ(static_cast<GLenum>(20), cmd.planes_yuv_color_space);
+  EXPECT_EQ(static_cast<GLenum>(21), cmd.plane_config);
+  EXPECT_EQ(static_cast<GLenum>(22), cmd.subsampling);
+  CheckBytesWrittenMatchesExpectedSize(
+      next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)));
+}
+
 TEST_F(GLES2FormatTest, CopySharedImageINTERNALImmediate) {
   const int kSomeBaseValueToTestWith = 51;
   static GLbyte data[] = {
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index 5408bba..28cd228 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -330,34 +330,35 @@
   OP(EndSharedImageAccessDirectCHROMIUM)                       /* 571 */ \
   OP(ConvertRGBAToYUVAMailboxesINTERNALImmediate)              /* 572 */ \
   OP(ConvertYUVAMailboxesToRGBINTERNALImmediate)               /* 573 */ \
-  OP(CopySharedImageINTERNALImmediate)                         /* 574 */ \
-  OP(CopySharedImageToTextureINTERNALImmediate)                /* 575 */ \
-  OP(ReadbackARGBImagePixelsINTERNAL)                          /* 576 */ \
-  OP(WritePixelsYUVINTERNAL)                                   /* 577 */ \
-  OP(EnableiOES)                                               /* 578 */ \
-  OP(DisableiOES)                                              /* 579 */ \
-  OP(BlendEquationiOES)                                        /* 580 */ \
-  OP(BlendEquationSeparateiOES)                                /* 581 */ \
-  OP(BlendFunciOES)                                            /* 582 */ \
-  OP(BlendFuncSeparateiOES)                                    /* 583 */ \
-  OP(ColorMaskiOES)                                            /* 584 */ \
-  OP(IsEnablediOES)                                            /* 585 */ \
-  OP(ProvokingVertexANGLE)                                     /* 586 */ \
-  OP(FramebufferMemorylessPixelLocalStorageANGLE)              /* 587 */ \
-  OP(FramebufferTexturePixelLocalStorageANGLE)                 /* 588 */ \
-  OP(FramebufferPixelLocalClearValuefvANGLEImmediate)          /* 589 */ \
-  OP(FramebufferPixelLocalClearValueivANGLEImmediate)          /* 590 */ \
-  OP(FramebufferPixelLocalClearValueuivANGLEImmediate)         /* 591 */ \
-  OP(BeginPixelLocalStorageANGLEImmediate)                     /* 592 */ \
-  OP(EndPixelLocalStorageANGLEImmediate)                       /* 593 */ \
-  OP(PixelLocalStorageBarrierANGLE)                            /* 594 */ \
-  OP(FramebufferPixelLocalStorageInterruptANGLE)               /* 595 */ \
-  OP(FramebufferPixelLocalStorageRestoreANGLE)                 /* 596 */ \
-  OP(GetFramebufferPixelLocalStorageParameterfvANGLE)          /* 597 */ \
-  OP(GetFramebufferPixelLocalStorageParameterivANGLE)          /* 598 */ \
-  OP(ClipControlEXT)                                           /* 599 */ \
-  OP(PolygonModeANGLE)                                         /* 600 */ \
-  OP(PolygonOffsetClampEXT)                                    /* 601 */
+  OP(ConvertYUVAMailboxesToTextureINTERNALImmediate)           /* 574 */ \
+  OP(CopySharedImageINTERNALImmediate)                         /* 575 */ \
+  OP(CopySharedImageToTextureINTERNALImmediate)                /* 576 */ \
+  OP(ReadbackARGBImagePixelsINTERNAL)                          /* 577 */ \
+  OP(WritePixelsYUVINTERNAL)                                   /* 578 */ \
+  OP(EnableiOES)                                               /* 579 */ \
+  OP(DisableiOES)                                              /* 580 */ \
+  OP(BlendEquationiOES)                                        /* 581 */ \
+  OP(BlendEquationSeparateiOES)                                /* 582 */ \
+  OP(BlendFunciOES)                                            /* 583 */ \
+  OP(BlendFuncSeparateiOES)                                    /* 584 */ \
+  OP(ColorMaskiOES)                                            /* 585 */ \
+  OP(IsEnablediOES)                                            /* 586 */ \
+  OP(ProvokingVertexANGLE)                                     /* 587 */ \
+  OP(FramebufferMemorylessPixelLocalStorageANGLE)              /* 588 */ \
+  OP(FramebufferTexturePixelLocalStorageANGLE)                 /* 589 */ \
+  OP(FramebufferPixelLocalClearValuefvANGLEImmediate)          /* 590 */ \
+  OP(FramebufferPixelLocalClearValueivANGLEImmediate)          /* 591 */ \
+  OP(FramebufferPixelLocalClearValueuivANGLEImmediate)         /* 592 */ \
+  OP(BeginPixelLocalStorageANGLEImmediate)                     /* 593 */ \
+  OP(EndPixelLocalStorageANGLEImmediate)                       /* 594 */ \
+  OP(PixelLocalStorageBarrierANGLE)                            /* 595 */ \
+  OP(FramebufferPixelLocalStorageInterruptANGLE)               /* 596 */ \
+  OP(FramebufferPixelLocalStorageRestoreANGLE)                 /* 597 */ \
+  OP(GetFramebufferPixelLocalStorageParameterfvANGLE)          /* 598 */ \
+  OP(GetFramebufferPixelLocalStorageParameterivANGLE)          /* 599 */ \
+  OP(ClipControlEXT)                                           /* 600 */ \
+  OP(PolygonModeANGLE)                                         /* 601 */ \
+  OP(PolygonOffsetClampEXT)                                    /* 602 */
 
 enum CommandId {
   kOneBeforeStartPoint =
diff --git a/gpu/command_buffer/gles2_cmd_buffer_functions.txt b/gpu/command_buffer/gles2_cmd_buffer_functions.txt
index 2b8205b..37eda73d 100644
--- a/gpu/command_buffer/gles2_cmd_buffer_functions.txt
+++ b/gpu/command_buffer/gles2_cmd_buffer_functions.txt
@@ -381,6 +381,7 @@
 GL_APICALL void         GL_APIENTRY glEndSharedImageAccessDirectCHROMIUM (GLuint texture);
 GL_APICALL void         GL_APIENTRY glConvertRGBAToYUVAMailboxesINTERNAL (GLenum planes_yuv_color_space, GLenum plane_config, GLenum subsampling, const GLbyte* mailboxes);
 GL_APICALL void         GL_APIENTRY glConvertYUVAMailboxesToRGBINTERNAL (GLint src_x, GLint src_y, GLsizei width, GLsizei height, GLenum planes_yuv_color_space, GLenum plane_config, GLenum subsampling, const GLbyte* mailboxes);
+GL_APICALL void         GL_APIENTRY glConvertYUVAMailboxesToTextureINTERNAL (GLuint texture, GLenum target, GLuint internal_format, GLenum type, GLint src_x, GLint src_y, GLsizei width, GLsizei height, GLboolean flip_y, GLenum planes_yuv_color_space, GLenum plane_config, GLenum subsampling, const GLbyte* mailboxes);
 GL_APICALL void         GL_APIENTRY glCopySharedImageINTERNAL (GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, GLboolean unpack_flip_y, const GLbyte* mailboxes);
 GL_APICALL void         GL_APIENTRY glCopySharedImageToTextureINTERNAL (GLuint texture, GLenum target, GLuint internal_format, GLenum type, GLint src_x, GLint src_y, GLsizei width, GLsizei height, GLboolean flip_y, const GLbyte* src_mailbox);
 GL_APICALL void         GL_APIENTRY glReadbackARGBImagePixelsINTERNAL (const GLbyte* mailbox, const void* dst_color_space, GLuint dst_color_space_size, GLuint dst_size, GLuint dst_width, GLuint dst_height, GLuint dst_color_type, GLuint dst_alpha_type, GLuint dst_row_bytes, GLint src_x, GLint src_y, GLint plane_index, void* pixels);
diff --git a/gpu/command_buffer/service/copy_shared_image_helper.cc b/gpu/command_buffer/service/copy_shared_image_helper.cc
index 3637a6d..4e14c65 100644
--- a/gpu/command_buffer/service/copy_shared_image_helper.cc
+++ b/gpu/command_buffer/service/copy_shared_image_helper.cc
@@ -90,9 +90,10 @@
 }
 
 // Return true if all of `sk_yuv_color_space`, `sk_plane_config`,
-// `sk_subsampling`, `rgba_image, `num_yuva_images`, and `yuva_images` were
-// successfully populated. Return false on error. If this returns false, some
-// of the output arguments may be left populated.
+// `sk_subsampling`, `rgba_image` (if `populate_rgba_image` is true),
+// `num_yuva_images`, and `yuva_images` were successfully populated. Return
+// false on error. If this returns false, some of the output arguments may be
+// left populated.
 base::expected<void, GLError> ConvertYUVACommon(
     const char* function_name,
     GLenum yuv_color_space_in,
@@ -107,7 +108,8 @@
     std::unique_ptr<SkiaImageRepresentation>& rgba_image,
     int& num_yuva_planes,
     std::array<std::unique_ptr<SkiaImageRepresentation>,
-               SkYUVAInfo::kMaxPlanes>& yuva_images) {
+               SkYUVAInfo::kMaxPlanes>& yuva_images,
+    bool populate_rgba_image) {
   if (yuv_color_space_in < 0 ||
       yuv_color_space_in > kLastEnum_SkYUVColorSpace) {
     return base::unexpected(
@@ -141,11 +143,13 @@
         << " with plane config " << plane_config_in;
   }
   gpu::Mailbox rgba_mailbox;
-  rgba_mailbox =
-      Mailbox::FromVolatile(reinterpret_cast<const volatile Mailbox*>(
-          mailboxes_in)[SkYUVAInfo::kMaxPlanes]);
-  DLOG_IF(ERROR, !rgba_mailbox.Verify())
-      << function_name << " was passed an invalid mailbox for RGBA";
+  if (populate_rgba_image) {
+    rgba_mailbox =
+        Mailbox::FromVolatile(reinterpret_cast<const volatile Mailbox*>(
+            mailboxes_in)[SkYUVAInfo::kMaxPlanes]);
+    DLOG_IF(ERROR, !rgba_mailbox.Verify())
+        << function_name << " was passed an invalid mailbox for RGBA";
+  }
 
   for (int i = 0; i < num_yuva_planes; ++i) {
     yuva_images[i] = representation_factory->ProduceSkia(yuva_mailboxes[i],
@@ -159,12 +163,14 @@
           GLError(GL_INVALID_OPERATION, function_name, msg));
     }
   }
-  rgba_image =
-      representation_factory->ProduceSkia(rgba_mailbox, shared_context_state);
-  if (!rgba_image) {
-    return base::unexpected(
-        GLError(GL_INVALID_OPERATION, "ConvertYUVAMailboxesToRGB",
-                "Attempting to operate on unknown dest mailbox."));
+  if (populate_rgba_image) {
+    rgba_image =
+        representation_factory->ProduceSkia(rgba_mailbox, shared_context_state);
+    if (!rgba_image) {
+      return base::unexpected(
+          GLError(GL_INVALID_OPERATION, "ConvertYUVAMailboxesToRGB",
+                  "Attempting to operate on unknown dest mailbox."));
+    }
   }
   return base::ok();
 }
@@ -362,7 +368,7 @@
       "ConvertYUVAMailboxesToRGB", yuv_color_space, plane_config, subsampling,
       mailboxes_in, representation_factory_, shared_context_state_,
       dst_color_space, dst_plane_config, dst_subsampling, rgba_image,
-      num_yuva_planes, yuva_images));
+      num_yuva_planes, yuva_images, /*populate_rgba_image=*/true));
 
   std::vector<GrBackendSemaphore> begin_semaphores;
   std::vector<GrBackendSemaphore> end_semaphores;
@@ -450,7 +456,7 @@
       "ConvertYUVAMailboxesToRGB", planes_yuv_color_space, plane_config,
       subsampling, bytes_in, representation_factory_, shared_context_state_,
       src_yuv_color_space, src_plane_config, src_subsampling, rgba_image,
-      num_src_planes, yuva_images));
+      num_src_planes, yuva_images, /*populate_rgba_image=*/true));
 
   sk_sp<SkColorSpace> src_rgb_color_space = ReadSkColorSpace(
       bytes_in + (SkYUVAInfo::kMaxPlanes + 1) * sizeof(gpu::Mailbox));
diff --git a/gpu/command_buffer/service/dawn_context_provider.cc b/gpu/command_buffer/service/dawn_context_provider.cc
index c3030e5..367eff52c 100644
--- a/gpu/command_buffer/service/dawn_context_provider.cc
+++ b/gpu/command_buffer/service/dawn_context_provider.cc
@@ -220,12 +220,9 @@
 #endif
 
 #if BUILDFLAG(IS_APPLE)
-  if (backend_type == wgpu::BackendType::Vulkan) {
-    // Vulkan doesn't support IOSurface image backing, so we need
-    // MultiPlanarFormatExtendedUsages to copy to/from multiplanar texture.
-    // And this feature is currently experimental.
-    enabled_toggles.push_back("allow_unsafe_apis");
-  }
+  // We need MultiPlanarFormatExtendedUsages to copy to/from multiplanar
+  // texture. And this feature is currently experimental.
+  enabled_toggles.push_back("allow_unsafe_apis");
 #endif  // BUILDFLAG(IS_APPLE)
 
   wgpu::DawnTogglesDescriptor toggles_desc;
@@ -249,6 +246,7 @@
   adapter_options.backendType = backend_type;
   adapter_options.forceFallbackAdapter = force_fallback_adapter;
   adapter_options.powerPreference = wgpu::PowerPreference::LowPower;
+  adapter_options.nextInChain = &toggles_desc;
 
 #if BUILDFLAG(IS_WIN)
   if (adapter_options.backendType == wgpu::BackendType::D3D11) {
@@ -273,6 +271,7 @@
       wgpu::FeatureName::DualSourceBlending,
       wgpu::FeatureName::MultiPlanarFormatExtendedUsages,
       wgpu::FeatureName::MultiPlanarFormatP010,
+      wgpu::FeatureName::MultiPlanarRenderTargets,
       wgpu::FeatureName::Norm16TextureFormats,
       wgpu::FeatureName::TransientAttachments,
   };
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 0d6fa81..2ca7a0c8 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1137,6 +1137,20 @@
                                            GLenum plane_config,
                                            GLenum subsampling,
                                            const volatile GLbyte* mailboxes_in);
+  void DoConvertYUVAMailboxesToTextureINTERNAL(
+      GLuint texture,
+      GLenum target,
+      GLuint internal_format,
+      GLenum type,
+      GLint src_x,
+      GLint src_y,
+      GLsizei width,
+      GLsizei height,
+      GLboolean flip_y,
+      GLenum yuv_color_space,
+      GLenum plane_config,
+      GLenum subsampling,
+      const volatile GLbyte* mailboxes_in);
   void DoCopySharedImageINTERNAL(GLint xoffset,
                                  GLint yoffset,
                                  GLint x,
@@ -17342,6 +17356,23 @@
   NOTIMPLEMENTED_LOG_ONCE();
 }
 
+void GLES2DecoderImpl::DoConvertYUVAMailboxesToTextureINTERNAL(
+    GLuint texture,
+    GLenum target,
+    GLuint internal_format,
+    GLenum type,
+    GLint src_x,
+    GLint src_y,
+    GLsizei width,
+    GLsizei height,
+    GLboolean flip_y,
+    GLenum yuv_color_space,
+    GLenum plane_config,
+    GLenum subsampling,
+    const volatile GLbyte* mailboxes_in) {
+  NOTIMPLEMENTED_LOG_ONCE();
+}
+
 void GLES2DecoderImpl::DoCopySharedImageINTERNAL(
     GLint xoffset,
     GLint yoffset,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 591b59f..44efa58 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -5390,6 +5390,54 @@
   return error::kNoError;
 }
 
+error::Error
+GLES2DecoderImpl::HandleConvertYUVAMailboxesToTextureINTERNALImmediate(
+    uint32_t immediate_data_size,
+    const volatile void* cmd_data) {
+  const volatile gles2::cmds::ConvertYUVAMailboxesToTextureINTERNALImmediate&
+      c = *static_cast<const volatile gles2::cmds::
+                           ConvertYUVAMailboxesToTextureINTERNALImmediate*>(
+          cmd_data);
+  GLuint texture = static_cast<GLuint>(c.texture);
+  GLenum target = static_cast<GLenum>(c.target);
+  GLuint internal_format = static_cast<GLuint>(c.internal_format);
+  GLenum type = static_cast<GLenum>(c.type);
+  GLint src_x = static_cast<GLint>(c.src_x);
+  GLint src_y = static_cast<GLint>(c.src_y);
+  GLsizei width = static_cast<GLsizei>(c.width);
+  GLsizei height = static_cast<GLsizei>(c.height);
+  GLboolean flip_y = static_cast<GLboolean>(c.flip_y);
+  GLenum planes_yuv_color_space = static_cast<GLenum>(c.planes_yuv_color_space);
+  GLenum plane_config = static_cast<GLenum>(c.plane_config);
+  GLenum subsampling = static_cast<GLenum>(c.subsampling);
+  uint32_t mailboxes_size;
+  if (!GLES2Util::ComputeDataSize<GLbyte, 64>(1, &mailboxes_size)) {
+    return error::kOutOfBounds;
+  }
+  if (mailboxes_size > immediate_data_size) {
+    return error::kOutOfBounds;
+  }
+  volatile const GLbyte* mailboxes = GetImmediateDataAs<volatile const GLbyte*>(
+      c, mailboxes_size, immediate_data_size);
+  if (width < 0) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
+                       "glConvertYUVAMailboxesToTextureINTERNAL", "width < 0");
+    return error::kNoError;
+  }
+  if (height < 0) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
+                       "glConvertYUVAMailboxesToTextureINTERNAL", "height < 0");
+    return error::kNoError;
+  }
+  if (mailboxes == nullptr) {
+    return error::kOutOfBounds;
+  }
+  DoConvertYUVAMailboxesToTextureINTERNAL(
+      texture, target, internal_format, type, src_x, src_y, width, height,
+      flip_y, planes_yuv_color_space, plane_config, subsampling, mailboxes);
+  return error::kNoError;
+}
+
 error::Error GLES2DecoderImpl::HandleCopySharedImageINTERNALImmediate(
     uint32_t immediate_data_size,
     const volatile void* cmd_data) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
index 7414f60..e61177c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
@@ -1071,6 +1071,21 @@
     GLenum plane_config,
     GLenum subsampling,
     const volatile GLbyte* mailboxes_in);
+error::Error DoConvertYUVAMailboxesToTextureINTERNAL(
+    GLuint texture,
+    GLenum target,
+    GLuint internal_format,
+    GLenum type,
+    GLint src_x,
+    GLint src_y,
+    GLsizei width,
+    GLsizei height,
+    GLboolean flip_y,
+    GLenum yuv_color_space,
+    GLenum plane_config,
+    GLenum subsampling,
+    const volatile GLbyte* mailboxes_in);
+
 error::Error DoCopySharedImageINTERNAL(GLint xoffset,
                                        GLint yoffset,
                                        GLint x,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
index 78030ed..c896f2f 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -5329,6 +5329,26 @@
   return error::kNoError;
 }
 
+error::Error
+GLES2DecoderPassthroughImpl::DoConvertYUVAMailboxesToTextureINTERNAL(
+    GLuint texture,
+    GLenum target,
+    GLuint internal_format,
+    GLenum type,
+    GLint src_x,
+    GLint src_y,
+    GLsizei width,
+    GLsizei height,
+    GLboolean flip_y,
+    GLenum yuv_color_space,
+    GLenum plane_config,
+    GLenum subsampling,
+    const volatile GLbyte* mailboxes_in) {
+  // TODO(crbug.com/1410164): Implement.
+  NOTIMPLEMENTED_LOG_ONCE();
+  return error::kNoError;
+}
+
 error::Error GLES2DecoderPassthroughImpl::DoCopySharedImageINTERNAL(
     GLint xoffset,
     GLint yoffset,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
index fd8ed05..6dc47d8 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
@@ -4676,6 +4676,47 @@
   return error::kNoError;
 }
 
+error::Error GLES2DecoderPassthroughImpl::
+    HandleConvertYUVAMailboxesToTextureINTERNALImmediate(
+        uint32_t immediate_data_size,
+        const volatile void* cmd_data) {
+  const volatile gles2::cmds::ConvertYUVAMailboxesToTextureINTERNALImmediate&
+      c = *static_cast<const volatile gles2::cmds::
+                           ConvertYUVAMailboxesToTextureINTERNALImmediate*>(
+          cmd_data);
+  GLuint texture = static_cast<GLuint>(c.texture);
+  GLenum target = static_cast<GLenum>(c.target);
+  GLuint internal_format = static_cast<GLuint>(c.internal_format);
+  GLenum type = static_cast<GLenum>(c.type);
+  GLint src_x = static_cast<GLint>(c.src_x);
+  GLint src_y = static_cast<GLint>(c.src_y);
+  GLsizei width = static_cast<GLsizei>(c.width);
+  GLsizei height = static_cast<GLsizei>(c.height);
+  GLboolean flip_y = static_cast<GLboolean>(c.flip_y);
+  GLenum planes_yuv_color_space = static_cast<GLenum>(c.planes_yuv_color_space);
+  GLenum plane_config = static_cast<GLenum>(c.plane_config);
+  GLenum subsampling = static_cast<GLenum>(c.subsampling);
+  uint32_t mailboxes_size;
+  if (!GLES2Util::ComputeDataSize<GLbyte, 64>(1, &mailboxes_size)) {
+    return error::kOutOfBounds;
+  }
+  if (mailboxes_size > immediate_data_size) {
+    return error::kOutOfBounds;
+  }
+  volatile const GLbyte* mailboxes = GetImmediateDataAs<volatile const GLbyte*>(
+      c, mailboxes_size, immediate_data_size);
+  if (mailboxes == nullptr) {
+    return error::kOutOfBounds;
+  }
+  error::Error error = DoConvertYUVAMailboxesToTextureINTERNAL(
+      texture, target, internal_format, type, src_x, src_y, width, height,
+      flip_y, planes_yuv_color_space, plane_config, subsampling, mailboxes);
+  if (error != error::kNoError) {
+    return error;
+  }
+  return error::kNoError;
+}
+
 error::Error
 GLES2DecoderPassthroughImpl::HandleCopySharedImageINTERNALImmediate(
     uint32_t immediate_data_size,
diff --git a/gpu/command_buffer/service/skia_utils.cc b/gpu/command_buffer/service/skia_utils.cc
index c780e73a..33588ad3 100644
--- a/gpu/command_buffer/service/skia_utils.cc
+++ b/gpu/command_buffer/service/skia_utils.cc
@@ -126,15 +126,13 @@
                                             &glyph_cache_max_texture_bytes);
   options.fGlyphCacheTextureMaximumBytes = glyph_cache_max_texture_bytes;
 
-  // Disable multisampled antialiasing when it's slow if the relevant
-  // base::Feature is enabled.
+  // Disable multisampled antialiasing when it's slow.
   // NOTE: `workarounds.msaa_is_slow` is true on all Intel devices.
   // gpu::gles2::MSAAIsSlow() will return true on Intel devices unless the
   // features::kEnableMSAAOnNewIntelGPUs base::Feature is enabled. If rolling
   // out single-sampling for Graphite, we should consider whether to tie the
   // rollout to the features::kEnableMSSAOnNewIntelGPUs experiment.
-  if (workarounds.msaa_is_slow &&
-      base::FeatureList::IsEnabled(features::kDisableSlowMSAAInGraphite)) {
+  if (workarounds.msaa_is_slow) {
     options.fInternalMultisampleCount = 1;
   }
 
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc
index 38bb4737..a3b8658 100644
--- a/gpu/command_buffer/service/webgpu_decoder_impl.cc
+++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -1174,18 +1174,17 @@
   switch (feature) {
     case wgpu::FeatureName::TimestampQuery:
     case wgpu::FeatureName::ChromiumExperimentalTimestampQueryInsidePasses:
-    case wgpu::FeatureName::PipelineStatisticsQuery:
+    case wgpu::FeatureName::ChromiumExperimentalPipelineStatisticsQuery:
     case wgpu::FeatureName::ChromiumExperimentalDp4a:
     case wgpu::FeatureName::ChromiumExperimentalReadWriteStorageTexture:
     case wgpu::FeatureName::ChromiumExperimentalSubgroups:
     case wgpu::FeatureName::ChromiumExperimentalSubgroupUniformControlFlow:
-    // TODO(dawn:1664): Enable Float32Filterable by default once it is tested.
-    case wgpu::FeatureName::Float32Filterable:
     case wgpu::FeatureName::ShaderF16:
       return allow_unsafe_apis_;
     case wgpu::FeatureName::DawnMultiPlanarFormats:
     case wgpu::FeatureName::Depth32FloatStencil8:
     case wgpu::FeatureName::DepthClipControl:
+    case wgpu::FeatureName::Float32Filterable:
     case wgpu::FeatureName::TextureCompressionBC:
     case wgpu::FeatureName::TextureCompressionETC2:
     case wgpu::FeatureName::TextureCompressionASTC:
diff --git a/gpu/command_buffer/tests/gl_tests_main.cc b/gpu/command_buffer/tests/gl_tests_main.cc
index 8553985..8a0183b1 100644
--- a/gpu/command_buffer/tests/gl_tests_main.cc
+++ b/gpu/command_buffer/tests/gl_tests_main.cc
@@ -19,11 +19,23 @@
 #include "base/apple/scoped_nsautorelease_pool.h"
 #endif
 
+#if BUILDFLAG(IS_CHROMEOS)
+#include "ui/gfx/linux/gbm_util.h"  // nogncheck
+#endif
+
 namespace {
 
 class GlTestsSuite : public base::TestSuite {
  public:
-  GlTestsSuite(int argc, char** argv) : base::TestSuite(argc, argv) {}
+  GlTestsSuite(int argc, char** argv) : base::TestSuite(argc, argv) {
+#if BUILDFLAG(IS_CHROMEOS)
+    // TODO(b/271455200): the FeatureList has not been initialized by this
+    // point, so this call will always disable Intel media compression. We may
+    // want to move this to a later point to be able to run GL unit tests with
+    // Intel media compression enabled.
+    ui::EnsureIntelMediaCompressionEnvVarIsSet();
+#endif  // BUILDFLAG(IS_CHROMEOS)
+  }
 
  protected:
   void Initialize() override {
diff --git a/gpu/command_buffer/tests/webgpu_test.cc b/gpu/command_buffer/tests/webgpu_test.cc
index 0f875b2f..3d3013f 100644
--- a/gpu/command_buffer/tests/webgpu_test.cc
+++ b/gpu/command_buffer/tests/webgpu_test.cc
@@ -216,20 +216,11 @@
   // importantly the callbacks will have been called.
   wgpu::Queue queue = device.GetQueue();
   bool done = false;
-#ifdef WGPU_BREAKING_WORK_DONE_SIGNAL_VALUE_CHANGE
   queue.OnSubmittedWorkDone(
       [](WGPUQueueWorkDoneStatus, void* userdata) {
         *static_cast<bool*>(userdata) = true;
       },
       &done);
-#else
-  queue.OnSubmittedWorkDone(
-      0u,
-      [](WGPUQueueWorkDoneStatus, void* userdata) {
-        *static_cast<bool*>(userdata) = true;
-      },
-      &done);
-#endif
 
   while (!done) {
     device.Tick();
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc
index 80c15b5..378507c 100644
--- a/gpu/config/gpu_finch_features.cc
+++ b/gpu/config/gpu_finch_features.cc
@@ -183,11 +183,6 @@
              "DefaultEnableANGLEValidation",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// Disables MSAA in Graphite if MSAA is reported as being slow for the device.
-BASE_FEATURE(kDisableSlowMSAAInGraphite,
-             "DisableSlowMSAAInGraphite",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 // Enables canvas to free its resources by default when it's running in
 // the background.
 BASE_FEATURE(kCanvasContextLostInBackground,
diff --git a/gpu/config/gpu_finch_features.h b/gpu/config/gpu_finch_features.h
index 208463f..7928a7c5 100644
--- a/gpu/config/gpu_finch_features.h
+++ b/gpu/config/gpu_finch_features.h
@@ -47,8 +47,6 @@
 
 GPU_EXPORT BASE_DECLARE_FEATURE(kDefaultEnableANGLEValidation);
 
-GPU_EXPORT BASE_DECLARE_FEATURE(kDisableSlowMSAAInGraphite);
-
 GPU_EXPORT BASE_DECLARE_FEATURE(kCanvasContextLostInBackground);
 
 #if BUILDFLAG(IS_WIN)
diff --git a/gpu/gles2_conform_support/gles2_conform_test.cc b/gpu/gles2_conform_support/gles2_conform_test.cc
index 08b533b..6c5bffc3 100644
--- a/gpu/gles2_conform_support/gles2_conform_test.cc
+++ b/gpu/gles2_conform_support/gles2_conform_test.cc
@@ -39,7 +39,7 @@
 bool RunGLES2ConformTest(const char* path) {
   // Load test expectations, and return early if a test is marked as FAIL.
   base::FilePath src_path;
-  base::PathService::Get(base::DIR_SOURCE_ROOT, &src_path);
+  base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &src_path);
   base::FilePath test_expectations_path =
       src_path.Append(FILE_PATH_LITERAL("gpu")).
       Append(FILE_PATH_LITERAL("gles2_conform_support")).
diff --git a/gpu/khronos_glcts_support/khronos_glcts_test.cc b/gpu/khronos_glcts_support/khronos_glcts_test.cc
index fc6b4997..93f54cf8 100644
--- a/gpu/khronos_glcts_support/khronos_glcts_test.cc
+++ b/gpu/khronos_glcts_support/khronos_glcts_test.cc
@@ -27,7 +27,7 @@
 bool RunKhronosGLCTSTest(const char* test_name) {
   // Load test expectations, and return early if a test is marked as FAIL.
   base::FilePath src_path;
-  base::PathService::Get(base::DIR_SOURCE_ROOT, &src_path);
+  base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &src_path);
   base::FilePath test_expectations_path =
       src_path.Append(FILE_PATH_LITERAL("gpu")).
       Append(FILE_PATH_LITERAL("khronos_glcts_support")).
diff --git a/headless/test/headless_browser_test.cc b/headless/test/headless_browser_test.cc
index e032489..d4b91be 100644
--- a/headless/test/headless_browser_test.cc
+++ b/headless/test/headless_browser_test.cc
@@ -41,7 +41,8 @@
   base::FilePath dir_exe_path;
   CHECK(base::PathService::Get(base::DIR_EXE, &dir_exe_path));
   dir_exe_path = dir_exe_path.Append("../../");
-  CHECK(base::PathService::Override(base::DIR_SOURCE_ROOT, dir_exe_path));
+  CHECK(
+      base::PathService::Override(base::DIR_SRC_TEST_DATA_ROOT, dir_exe_path));
 #endif  // BUILDFLAG(IS_MAC)
   base::FilePath headless_test_data(FILE_PATH_LITERAL("headless/test/data"));
   CreateTestServer(headless_test_data);
diff --git a/headless/test/headless_devtools_client_browsertest.cc b/headless/test/headless_devtools_client_browsertest.cc
index af30b7b..6d953e5 100644
--- a/headless/test/headless_devtools_client_browsertest.cc
+++ b/headless/test/headless_devtools_client_browsertest.cc
@@ -530,7 +530,7 @@
 
     base::ScopedAllowBlockingForTesting allow_blocking;
     base::FilePath source_root_dir;
-    base::PathService::Get(base::DIR_SOURCE_ROOT, &source_root_dir);
+    base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &source_root_dir);
 
     CompareToGolden(
         dom_nodes,
diff --git a/headless/test/headless_protocol_browsertest.cc b/headless/test/headless_protocol_browsertest.cc
index f1e2cfece..3042238 100644
--- a/headless/test/headless_protocol_browsertest.cc
+++ b/headless/test/headless_protocol_browsertest.cc
@@ -106,7 +106,7 @@
 
   base::ScopedAllowBlockingForTesting allow_blocking;
   base::FilePath src_dir;
-  CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &src_dir));
+  CHECK(base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &src_dir));
   base::FilePath test_path =
       src_dir.Append(kTestsDirectory).AppendASCII(script_name_);
   std::string script;
@@ -159,7 +159,7 @@
   base::ScopedAllowBlockingForTesting allow_blocking;
 
   base::FilePath src_dir;
-  CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &src_dir));
+  CHECK(base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &src_dir));
   base::FilePath expectation_path =
       src_dir.Append(kTestsDirectory)
           .AppendASCII(script_name_.substr(0, script_name_.length() - 3) +
@@ -445,7 +445,7 @@
  protected:
   base::Value::Dict GetPageUrlExtraParams() override {
     base::FilePath src_dir;
-    CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &src_dir));
+    CHECK(base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &src_dir));
     base::FilePath path =
         src_dir.Append(kTestsDirectory).AppendASCII(data_path_);
     base::Value::Dict dict;
diff --git a/infra/config/generated/cq-usage/OWNERS b/infra/config/generated/cq-usage/OWNERS
index eb50379..c3b35cc 100644
--- a/infra/config/generated/cq-usage/OWNERS
+++ b/infra/config/generated/cq-usage/OWNERS
@@ -6,4 +6,6 @@
 # only change the paths for some builders, then only full.cfg will be changed.
 # CQ usage secondary owners can approve benign path changes but should defer to
 # above if the path might have a large impact on capacity.
-per-file full.cfg=file://infra/config/groups/cq-usage/CQ_USAGE_SECONDARY_OWNERS
\ No newline at end of file
+per-file full.cfg=file://infra/config/groups/cq-usage/CQ_USAGE_SECONDARY_OWNERS
+
+per-file mega_cq_bots.txt=*
diff --git a/infra/config/generated/cq-usage/mega_cq_bots.txt b/infra/config/generated/cq-usage/mega_cq_bots.txt
new file mode 100644
index 0000000..8799348a
--- /dev/null
+++ b/infra/config/generated/cq-usage/mega_cq_bots.txt
@@ -0,0 +1,349 @@
+chromium/try/android-10-arm64-rel
+chromium/try/android-11-x86-rel
+chromium/try/android-12-x64-dbg
+chromium/try/android-12-x64-dual-coverage-exp-rel
+chromium/try/android-12-x64-rel
+chromium/try/android-12l-x64-dbg
+chromium/try/android-13-x64-rel
+chromium/try/android-angle-chromium-try
+chromium/try/android-arm-compile-dbg
+chromium/try/android-arm64-all-targets-dbg
+chromium/try/android-arm64-rel
+chromium/try/android-arm64-siso-rel
+chromium/try/android-asan-compile-dbg
+chromium/try/android-bfcache-rel
+chromium/try/android-chrome-pie-x86-wpt-android-specific
+chromium/try/android-chrome-pie-x86-wpt-fyi-rel
+chromium/try/android-clobber-rel
+chromium/try/android-code-coverage
+chromium/try/android-code-coverage-native
+chromium/try/android-cronet-arm-dbg
+chromium/try/android-cronet-arm64-dbg
+chromium/try/android-cronet-arm64-rel
+chromium/try/android-cronet-asan-arm-rel
+chromium/try/android-cronet-mainline-clang-arm64-dbg
+chromium/try/android-cronet-mainline-clang-arm64-rel
+chromium/try/android-cronet-mainline-clang-x86-dbg
+chromium/try/android-cronet-mainline-clang-x86-rel
+chromium/try/android-cronet-x64-dbg
+chromium/try/android-cronet-x64-dbg-12-tests
+chromium/try/android-cronet-x64-dbg-13-tests
+chromium/try/android-cronet-x64-rel
+chromium/try/android-cronet-x86-dbg
+chromium/try/android-cronet-x86-dbg-10-tests
+chromium/try/android-cronet-x86-dbg-11-tests
+chromium/try/android-cronet-x86-dbg-lollipop-tests
+chromium/try/android-cronet-x86-dbg-marshmallow-tests
+chromium/try/android-cronet-x86-dbg-nougat-tests
+chromium/try/android-cronet-x86-dbg-oreo-tests
+chromium/try/android-cronet-x86-dbg-pie-tests
+chromium/try/android-cronet-x86-rel
+chromium/try/android-dawn-arm-rel
+chromium/try/android-dawn-arm64-rel
+chromium/try/android-fieldtrial-rel
+chromium/try/android-inverse-fieldtrials-pie-x86-fyi-rel
+chromium/try/android-official
+chromium/try/android-oreo-arm64-dbg
+chromium/try/android-oreo-x86-rel
+chromium/try/android-perfetto-rel
+chromium/try/android-pie-arm64-dbg
+chromium/try/android-pie-x86-rel
+chromium/try/android-rust-arm32-rel
+chromium/try/android-rust-arm64-dbg
+chromium/try/android-rust-arm64-rel
+chromium/try/android-webview-10-x86-rel-tests
+chromium/try/android-webview-12-x64-dbg
+chromium/try/android-webview-13-x64-dbg
+chromium/try/android-webview-oreo-arm64-dbg
+chromium/try/android-webview-pie-arm64-dbg
+chromium/try/android-webview-pie-x86-wpt-fyi-rel
+chromium/try/android-x64-cast
+chromium/try/android-x86-dual-coverage-exp-rel
+chromium/try/android-x86-rel
+chromium/try/android_arm64_dbg_recipe
+chromium/try/android_compile_dbg
+chromium/try/android_compile_x64_dbg
+chromium/try/android_compile_x86_dbg
+chromium/try/android_cronet
+chromium/try/chromeos-amd64-generic-asan-rel
+chromium/try/chromeos-amd64-generic-cfi-thin-lto-rel
+chromium/try/chromeos-amd64-generic-dbg
+chromium/try/chromeos-amd64-generic-lacros-dbg
+chromium/try/chromeos-amd64-generic-rel
+chromium/try/chromeos-amd64-generic-siso-rel
+chromium/try/chromeos-arm-generic-dbg
+chromium/try/chromeos-arm-generic-rel
+chromium/try/chromeos-arm64-generic-rel
+chromium/try/chromeos-jacuzzi-rel
+chromium/try/chromeos-js-code-coverage
+chromium/try/chromeos-js-coverage-rel
+chromium/try/chromeos-octopus-rel
+chromium/try/dawn-android-arm-deps-rel
+chromium/try/dawn-android-arm64-deps-rel
+chromium/try/dawn-linux-x64-deps-rel
+chromium/try/dawn-mac-x64-deps-rel
+chromium/try/dawn-try-linux-tsan-rel
+chromium/try/dawn-try-mac-amd-exp
+chromium/try/dawn-try-mac-arm64-deps-rel
+chromium/try/dawn-try-mac-arm64-rel
+chromium/try/dawn-try-mac-intel-exp
+chromium/try/dawn-try-win-x64-intel-exp
+chromium/try/dawn-try-win-x86-intel-exp
+chromium/try/dawn-try-win10-x64-intel-asan
+chromium/try/dawn-try-win10-x64-nvidia-asan
+chromium/try/dawn-try-win10-x86-rel
+chromium/try/dawn-win10-x64-deps-rel
+chromium/try/dawn-win10-x86-deps-rel
+chromium/try/fuchsia-angle-try
+chromium/try/fuchsia-arm64-cast-receiver-rel
+chromium/try/fuchsia-arm64-rel
+chromium/try/fuchsia-code-coverage
+chromium/try/fuchsia-compile-x64-dbg
+chromium/try/fuchsia-fyi-arm64-dbg
+chromium/try/fuchsia-fyi-x64-asan
+chromium/try/fuchsia-fyi-x64-dbg
+chromium/try/fuchsia-fyi-x64-dbg-persistent-emulator
+chromium/try/fuchsia-official
+chromium/try/fuchsia-x64-accessibility-rel
+chromium/try/fuchsia-x64-cast-receiver-rel
+chromium/try/fuchsia-x64-rel
+chromium/try/gpu-fyi-cq-android-arm64
+chromium/try/gpu-fyi-try-android-m-nexus-5x-64
+chromium/try/gpu-fyi-try-android-nvidia-shield-tv
+chromium/try/gpu-fyi-try-android-p-pixel-2-32
+chromium/try/gpu-fyi-try-android-pixel-6-64
+chromium/try/gpu-fyi-try-android-r-pixel-4-32
+chromium/try/gpu-fyi-try-chromeos-amd64-generic
+chromium/try/gpu-fyi-try-lacros-amd-rel
+chromium/try/gpu-fyi-try-lacros-intel-rel
+chromium/try/gpu-fyi-try-linux-amd-rel
+chromium/try/gpu-fyi-try-linux-intel-exp
+chromium/try/gpu-fyi-try-linux-intel-rel
+chromium/try/gpu-fyi-try-linux-nvidia-dbg
+chromium/try/gpu-fyi-try-linux-nvidia-exp
+chromium/try/gpu-fyi-try-linux-nvidia-rel
+chromium/try/gpu-fyi-try-linux-nvidia-tsn
+chromium/try/gpu-fyi-try-mac-amd-pro-rel
+chromium/try/gpu-fyi-try-mac-amd-retina-asan
+chromium/try/gpu-fyi-try-mac-amd-retina-dbg
+chromium/try/gpu-fyi-try-mac-amd-retina-exp
+chromium/try/gpu-fyi-try-mac-amd-retina-rel
+chromium/try/gpu-fyi-try-mac-arm64-apple-m1-exp
+chromium/try/gpu-fyi-try-mac-arm64-apple-m1-rel
+chromium/try/gpu-fyi-try-mac-arm64-apple-m2-retina-rel
+chromium/try/gpu-fyi-try-mac-intel-asan
+chromium/try/gpu-fyi-try-mac-intel-dbg
+chromium/try/gpu-fyi-try-mac-intel-exp
+chromium/try/gpu-fyi-try-mac-intel-rel
+chromium/try/gpu-fyi-try-mac-nvidia-retina-exp
+chromium/try/gpu-fyi-try-mac-nvidia-retina-rel
+chromium/try/gpu-fyi-try-win10-amd-rel-64
+chromium/try/gpu-fyi-try-win10-intel-exp-64
+chromium/try/gpu-fyi-try-win10-intel-rel-64
+chromium/try/gpu-fyi-try-win10-nvidia-dbg-64
+chromium/try/gpu-fyi-try-win10-nvidia-dx12vk-dbg-64
+chromium/try/gpu-fyi-try-win10-nvidia-dx12vk-rel-64
+chromium/try/gpu-fyi-try-win10-nvidia-exp-64
+chromium/try/gpu-fyi-try-win10-nvidia-rel-32
+chromium/try/gpu-fyi-try-win10-nvidia-rel-64
+chromium/try/gpu-try-android-m-nexus-5x-64
+chromium/try/gpu-try-linux-nvidia-dbg
+chromium/try/gpu-try-linux-nvidia-rel
+chromium/try/gpu-try-mac-amd-retina-dbg
+chromium/try/gpu-try-mac-intel-dbg
+chromium/try/gpu-try-win-nvidia-dbg
+chromium/try/ios-angle-try-intel
+chromium/try/ios-asan
+chromium/try/ios-blink-dbg-fyi
+chromium/try/ios-catalyst
+chromium/try/ios-device
+chromium/try/ios-fieldtrial-rel
+chromium/try/ios-m1-simulator
+chromium/try/ios-m1-simulator-cronet
+chromium/try/ios-simulator
+chromium/try/ios-simulator-code-coverage
+chromium/try/ios-simulator-cronet
+chromium/try/ios-simulator-full-configs
+chromium/try/ios-simulator-inverse-fieldtrials-fyi
+chromium/try/ios-simulator-multi-window
+chromium/try/ios-simulator-noncq
+chromium/try/ios-simulator-siso
+chromium/try/ios-wpt-fyi-rel
+chromium/try/ios16-beta-simulator
+chromium/try/ios16-sdk-simulator
+chromium/try/ios17-beta-simulator
+chromium/try/ios17-sdk-simulator
+chromium/try/lacros-amd64-generic-rel
+chromium/try/lacros-amd64-generic-rel-non-skylab
+chromium/try/lacros-arm-generic-rel
+chromium/try/lacros-arm-generic-rel-skylab
+chromium/try/lacros-arm64-generic-rel
+chromium/try/lacros-arm64-generic-rel-skylab
+chromium/try/layout_test_leak_detection
+chromium/try/leak_detection_linux
+chromium/try/linux-angle-chromium-try
+chromium/try/linux-annotator-rel
+chromium/try/linux-arm64-castos
+chromium/try/linux-arm64-rel-cft
+chromium/try/linux-asan-dbg
+chromium/try/linux-asan-media-rel
+chromium/try/linux-asan-media-v8-arm-rel
+chromium/try/linux-asan-rel
+chromium/try/linux-asan-v8-arm-dbg
+chromium/try/linux-asan-v8-arm-rel
+chromium/try/linux-bfcache-rel
+chromium/try/linux-blink-heap-verification-try
+chromium/try/linux-blink-web-tests-force-accessibility-rel
+chromium/try/linux-cfm-rel
+chromium/try/linux-chromeos-annotator-rel
+chromium/try/linux-chromeos-asan-rel
+chromium/try/linux-chromeos-code-coverage
+chromium/try/linux-chromeos-compile-dbg
+chromium/try/linux-chromeos-dbg
+chromium/try/linux-chromeos-inverse-fieldtrials-fyi-rel
+chromium/try/linux-chromeos-rel
+chromium/try/linux-clobber-rel
+chromium/try/linux-code-coverage
+chromium/try/linux-dawn-rel
+chromium/try/linux-dcheck-off-rel
+chromium/try/linux-exp-asan-lsan-fyi-rel
+chromium/try/linux-exp-msan-fyi-rel
+chromium/try/linux-exp-tsan-fyi-rel
+chromium/try/linux-extended-tracing-rel
+chromium/try/linux-fieldtrial-rel
+chromium/try/linux-gcc-rel
+chromium/try/linux-headless-shell-rel
+chromium/try/linux-inverse-fieldtrials-fyi-rel
+chromium/try/linux-js-code-coverage
+chromium/try/linux-js-coverage-rel
+chromium/try/linux-lacros-asan-lsan-rel
+chromium/try/linux-lacros-code-coverage
+chromium/try/linux-lacros-dbg
+chromium/try/linux-lacros-fyi-rel
+chromium/try/linux-lacros-rel
+chromium/try/linux-lacros-version-skew-fyi
+chromium/try/linux-mbi-mode-per-render-process-host-rel
+chromium/try/linux-mbi-mode-per-site-instance-rel
+chromium/try/linux-msan-chained-origins-rel
+chromium/try/linux-msan-no-origins-rel
+chromium/try/linux-official
+chromium/try/linux-perfetto-rel
+chromium/try/linux-rel
+chromium/try/linux-rel-cft
+chromium/try/linux-rust-x64-dbg
+chromium/try/linux-rust-x64-rel
+chromium/try/linux-siso-rel
+chromium/try/linux-swangle-chromium-try-x64
+chromium/try/linux-swangle-chromium-try-x64-exp
+chromium/try/linux-swangle-try-tot-swiftshader-x64
+chromium/try/linux-swangle-try-x64
+chromium/try/linux-swangle-try-x64-exp
+chromium/try/linux-tsan-dbg
+chromium/try/linux-tsan-rel
+chromium/try/linux-ubsan-fyi-rel
+chromium/try/linux-ubsan-rel
+chromium/try/linux-ubsan-vptr
+chromium/try/linux-ubsan-vptr-rel
+chromium/try/linux-updater-try-builder-dbg
+chromium/try/linux-updater-try-builder-rel
+chromium/try/linux-v4l2-codec-rel
+chromium/try/linux-viz-rel
+chromium/try/linux-wayland-rel
+chromium/try/linux-wayland-siso-rel
+chromium/try/linux-webkit-asan-rel
+chromium/try/linux-webkit-msan-rel
+chromium/try/linux-wpt-content-shell-fyi-rel
+chromium/try/linux-wpt-content-shell-leak-detection
+chromium/try/linux-wpt-fyi-rel
+chromium/try/linux-wpt-identity-fyi-rel
+chromium/try/linux-wpt-input-fyi-rel
+chromium/try/linux-x64-castos
+chromium/try/linux-x64-castos-audio
+chromium/try/linux-x64-castos-dbg
+chromium/try/linux_chromium_archive_rel_ng
+chromium/try/linux_chromium_asan_rel_ng
+chromium/try/linux_chromium_asan_siso_rel_ng
+chromium/try/linux_chromium_cfi_rel_ng
+chromium/try/linux_chromium_chromeos_asan_rel_ng
+chromium/try/linux_chromium_chromeos_msan_rel_ng
+chromium/try/linux_chromium_compile_dbg_ng
+chromium/try/linux_chromium_compile_rel_ng
+chromium/try/linux_chromium_dbg_ng
+chromium/try/linux_chromium_msan_rel_ng
+chromium/try/linux_chromium_tsan_rel_ng
+chromium/try/linux_chromium_tsan_siso_rel_ng
+chromium/try/mac-angle-chromium-try
+chromium/try/mac-arm64-clobber-rel
+chromium/try/mac-arm64-on-arm64-rel
+chromium/try/mac-asan-media-rel
+chromium/try/mac-asan-rel
+chromium/try/mac-builder-next
+chromium/try/mac-clobber-rel
+chromium/try/mac-code-coverage
+chromium/try/mac-dawn-rel
+chromium/try/mac-fieldtrial-tester
+chromium/try/mac-intel-on-arm64-rel
+chromium/try/mac-inverse-fieldtrials-fyi-rel
+chromium/try/mac-official
+chromium/try/mac-osxbeta-rel
+chromium/try/mac-perfetto-rel
+chromium/try/mac-rel
+chromium/try/mac-rel-cft
+chromium/try/mac-rust-x64-dbg
+chromium/try/mac-siso-rel
+chromium/try/mac-swangle-chromium-try-x64
+chromium/try/mac-updater-try-builder-dbg
+chromium/try/mac-updater-try-builder-rel
+chromium/try/mac10.15-wpt-content-shell-fyi-rel
+chromium/try/mac11-arm64-rel
+chromium/try/mac11-arm64-wpt-content-shell-fyi-rel
+chromium/try/mac11-wpt-content-shell-fyi-rel
+chromium/try/mac12-arm64-rel
+chromium/try/mac12-arm64-wpt-content-shell-fyi-rel
+chromium/try/mac12-tests
+chromium/try/mac12-wpt-content-shell-fyi-rel
+chromium/try/mac13-arm64-rel
+chromium/try/mac13-arm64-wpt-content-shell-fyi-rel
+chromium/try/mac13-tests
+chromium/try/mac13-wpt-content-shell-fyi-rel
+chromium/try/mac_chromium_10.15_rel_ng
+chromium/try/mac_chromium_11.0_rel_ng
+chromium/try/mac_chromium_asan_rel_ng
+chromium/try/mac_chromium_compile_dbg_ng
+chromium/try/mac_chromium_compile_rel_ng
+chromium/try/mac_chromium_dbg_ng
+chromium/try/network_service_linux
+chromium/try/win-angle-chromium-x64-try
+chromium/try/win-angle-chromium-x86-try
+chromium/try/win-annotator-rel
+chromium/try/win-asan
+chromium/try/win-asan-media-rel
+chromium/try/win-asan-rel
+chromium/try/win-clobber-rel
+chromium/try/win-dawn-rel
+chromium/try/win-fieldtrial-rel
+chromium/try/win-official
+chromium/try/win-perfetto-rel
+chromium/try/win-rel
+chromium/try/win-rel-cft
+chromium/try/win-rust-x64-dbg
+chromium/try/win-rust-x64-rel
+chromium/try/win-siso-rel
+chromium/try/win-swangle-chromium-try-x86
+chromium/try/win-swangle-try-tot-swiftshader-x64
+chromium/try/win-swangle-try-tot-swiftshader-x86
+chromium/try/win-swangle-try-x64
+chromium/try/win-swangle-try-x86
+chromium/try/win-updater-try-builder-dbg
+chromium/try/win-updater-try-builder-rel
+chromium/try/win10-code-coverage
+chromium/try/win10-wpt-content-shell-fyi-rel
+chromium/try/win10_chromium_inverse_fieldtrials_x64_fyi_rel_ng
+chromium/try/win10_chromium_x64_dbg_ng
+chromium/try/win11-wpt-content-shell-fyi-rel
+chromium/try/win11-x64-fyi-rel
+chromium/try/win32-clobber-rel
+chromium/try/win32-official
+chromium/try/win_chromium_compile_dbg_ng
+chromium/try/win_chromium_compile_rel_ng
+chromium/try/win_chromium_x64_rel_ng
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg
index 97eaf522..1b60c18 100644
--- a/infra/config/generated/luci/commit-queue.cfg
+++ b/infra/config/generated/luci/commit-queue.cfg
@@ -2436,6 +2436,10 @@
         includable_only: true
       }
       builders {
+        name: "chromium/try/gn-args-verifier"
+        includable_only: true
+      }
+      builders {
         name: "chromium/try/gpu-fyi-cq-android-arm64"
         location_filters {
           gerrit_host_regexp: ".*"
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 065c7b45..0b95660 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -62641,6 +62641,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.add_one_test_shard"
+        value: 10
+      }
+      experiments {
         key: "chromium_swarming.expose_merge_script_failures"
         value: 100
       }
@@ -63353,6 +63357,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.add_one_test_shard"
+        value: 10
+      }
+      experiments {
         key: "chromium_swarming.expose_merge_script_failures"
         value: 100
       }
@@ -73857,25 +73865,17 @@
         value: 5
       }
       experiments {
+        key: "chromium.add_one_test_shard"
+        value: 10
+      }
+      experiments {
         key: "chromium_swarming.expose_merge_script_failures"
         value: 100
       }
       experiments {
-        key: "enable_weetbix_queries"
-        value: 100
-      }
-      experiments {
         key: "luci.recipes.use_python3"
         value: 100
       }
-      experiments {
-        key: "weetbix.enable_weetbix_exonerations"
-        value: 100
-      }
-      experiments {
-        key: "weetbix.retry_weak_exonerations"
-        value: 100
-      }
       resultdb {
         enable: true
         bq_exports {
@@ -74105,6 +74105,86 @@
       description_html: "This builder mirrors the following CI builders:<br/><ul><li><a href=\"https://ci.chromium.org/p/chromium/builders/ci/fuchsia-x64-rel\">fuchsia-x64-rel</a></li></ul>"
     }
     builders {
+      name: "gn-args-verifier"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cores:8"
+      dimensions: "cpu:x86-64"
+      dimensions: "os:Ubuntu-22.04"
+      dimensions: "pool:luci.chromium.try"
+      dimensions: "ssd:0"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_config_directory": "infra/config/generated/builders",'
+        '  "recipe": "chromium/gn_args_verifier"'
+        '}'
+      priority: 25
+      execution_timeout_secs: 900
+      expiration_secs: 7200
+      grace_period {
+        seconds: 120
+      }
+      build_numbers: YES
+      service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
+      task_template_canary_percentage {
+        value: 5
+      }
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "try_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "checks that GN args generated by starlark definition match those originally specified in //tools/mb/mb_config.pyl"
+      contact_team_email: "chrome-browser-infra-team@google.com"
+    }
+    builders {
       name: "gpu-fyi-cq-android-arm64"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builder:gpu-fyi-cq-android-arm64"
@@ -85323,6 +85403,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.add_one_test_shard"
+        value: 10
+      }
+      experiments {
         key: "chromium_swarming.expose_merge_script_failures"
         value: 100
       }
@@ -88350,6 +88434,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.add_one_test_shard"
+        value: 10
+      }
+      experiments {
         key: "chromium_swarming.expose_merge_script_failures"
         value: 100
       }
@@ -98647,6 +98735,10 @@
         value: 5
       }
       experiments {
+        key: "chromium.pre_retry_shards_without_patch_compile"
+        value: 100
+      }
+      experiments {
         key: "chromium_swarming.expose_merge_script_failures"
         value: 100
       }
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index ba6d2f08..da4d2a0 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -2110,6 +2110,9 @@
     name: "buildbucket/luci.chromium.try/chromium_presubmit"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/gn-args-verifier"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/reclient-config-deployment-verifier"
   }
   builders {
@@ -3125,6 +3128,9 @@
     name: "buildbucket/luci.chromium.try/fuchsia-x64-rel"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/gn-args-verifier"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/gpu-fyi-cq-android-arm64"
   }
   builders {
@@ -17470,6 +17476,9 @@
     name: "buildbucket/luci.chromium.try/fuchsia-x64-rel"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/gn-args-verifier"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/gpu-fyi-cq-android-arm64"
   }
   builders {
diff --git a/infra/config/generated/testing/mixins.pyl b/infra/config/generated/testing/mixins.pyl
index 2d023d6..5118948 100644
--- a/infra/config/generated/testing/mixins.pyl
+++ b/infra/config/generated/testing/mixins.pyl
@@ -844,7 +844,7 @@
         {
           'cipd_package': 'infra/tools/mac_toolchain/${platform}',
           'location': '.',
-          'revision': 'git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb',
+          'revision': 'git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce',
         },
       ],
     },
diff --git a/infra/config/generated/testing/test_suites.pyl b/infra/config/generated/testing/test_suites.pyl
index 17ec514..b0c64de 100644
--- a/infra/config/generated/testing/test_suites.pyl
+++ b/infra/config/generated/testing/test_suites.pyl
@@ -2637,6 +2637,27 @@
       },
     },
 
+    'gpu_dawn_webgpu_compat_cts': {
+      'webgpu_cts_compat_tests': {
+        'telemetry_test_name': 'webgpu_compat_cts',
+        'mixins': [
+          'has_native_resultdb_integration',
+          'webgpu_telemetry_cts',
+        ],
+        'args': [
+          '--extra-browser-args=--use-angle=gl --use-webgpu-adapter=opengles --enable-webgpu-developer-features',
+        ],
+        'ci_only': True,
+        'swarming': {
+          'shards': 14,
+        },
+        'android_swarming': {
+          'shards': 36,
+        },
+        'experiment_percentage': 100,
+      },
+    },
+
     'gpu_dawn_webgpu_cts': {
       'webgpu_cts_tests': {
         'telemetry_test_name': 'webgpu_cts',
@@ -6239,6 +6260,12 @@
       'gpu_dawn_webgpu_blink_web_tests_force_swiftshader',
     ],
 
+    'gpu_dawn_compat_telemetry_tests': [
+      'gpu_dawn_webgpu_compat_cts',
+      'gpu_dawn_webgpu_cts',
+      'gpu_dawn_web_platform_webgpu_cts_force_swiftshader',
+    ],
+
     'gpu_dawn_integration_asan_gtests_passthrough': [
       'gpu_dawn_gtests',
       'gpu_dawn_gtests_no_dxc',
diff --git a/infra/config/generated/testing/variants.pyl b/infra/config/generated/testing/variants.pyl
index 1510c82..15f415e6 100644
--- a/infra/config/generated/testing/variants.pyl
+++ b/infra/config/generated/testing/variants.pyl
@@ -70,16 +70,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'identifier': 'Lacros version skew testing ash canary',
-    'description': 'Run with ash-chrome version 120.0.6074.0',
+    'description': 'Run with ash-chrome version 120.0.6075.0',
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6074.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6075.0/test_ash_chrome',
     ],
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v120.0.6074.0',
-          'revision': 'version:120.0.6074.0',
+          'location': 'lacros_version_skew_tests_v120.0.6075.0',
+          'revision': 'version:120.0.6075.0',
         },
       ],
     },
@@ -440,7 +440,7 @@
     'identifier': 'BRYA_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'brya',
-      'cros_img': 'brya-release/R120-15642.0.0',
+      'use_lkgm': True,
       'dut_pool': 'chrome',
     },
   },
@@ -472,7 +472,7 @@
     'identifier': 'DEDEDE_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'dedede',
-      'cros_img': 'dedede-release/R120-15645.0.0',
+      'use_lkgm': True,
     },
   },
   'CROS_DEDEDE_RELEASE_DEV': {
@@ -500,7 +500,7 @@
     'identifier': 'FIZZ_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'fizz',
-      'cros_img': 'fizz-release/R120-15645.0.0',
+      'use_lkgm': True,
       'dut_pool': 'chrome',
     },
   },
@@ -532,7 +532,7 @@
     'identifier': 'GUYBRUSH_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'guybrush',
-      'cros_img': 'guybrush-release/R120-15645.0.0',
+      'use_lkgm': True,
       'dut_pool': 'chrome',
     },
   },
@@ -564,7 +564,7 @@
     'identifier': 'PUFF_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'puff',
-      'cros_img': 'puff-release/R120-15645.0.0',
+      'use_lkgm': True,
       'dut_pool': 'chrome',
     },
   },
@@ -596,7 +596,7 @@
     'identifier': 'EVE_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'eve',
-      'cros_img': 'eve-public/R120-15645.0.0',
+      'cros_img': 'eve-public/R120-15650.0.0',
       'bucket': 'chromiumos-image-archive',
       'dut_pool': 'chromium',
       'public_builder': 'cros_test_platform_public',
@@ -607,7 +607,7 @@
     'identifier': 'HANA_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'hana',
-      'cros_img': 'hana-release/R120-15645.0.0',
+      'use_lkgm': True,
     },
   },
   'CROS_HANA_RELEASE_DEV': {
@@ -635,7 +635,7 @@
     'identifier': 'JACUZZI_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_img': 'jacuzzi-release/R120-15645.0.0',
+      'use_lkgm': True,
     },
   },
   'CROS_JACUZZI_RELEASE_DEV': {
@@ -670,7 +670,7 @@
     'identifier': 'JACUZZI_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_img': 'jacuzzi-public/R120-15645.0.0',
+      'cros_img': 'jacuzzi-public/R120-15650.0.0',
       'bucket': 'chromiumos-image-archive',
     },
   },
@@ -678,7 +678,7 @@
     'identifier': 'JACUZZI_CQ_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_img': 'jacuzzi-public/R120-15645.0.0',
+      'cros_img': 'jacuzzi-public/R120-15650.0.0',
       'bucket': 'chromiumos-image-archive',
       'public_builder': 'cros_test_platform_public',
       'public_builder_bucket': 'testplatform-public',
@@ -688,7 +688,7 @@
     'identifier': 'TROGDOR_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'trogdor',
-      'cros_img': 'trogdor-public/R120-15645.0.0',
+      'cros_img': 'trogdor-public/R120-15650.0.0',
       'bucket': 'chromiumos-image-archive',
     },
   },
@@ -696,7 +696,7 @@
     'identifier': 'OCTOPUS_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'octopus',
-      'cros_img': 'octopus-public/R120-15645.0.0',
+      'cros_img': 'octopus-public/R120-15650.0.0',
       'bucket': 'chromiumos-image-archive',
     },
   },
@@ -711,7 +711,7 @@
     'identifier': 'OCTOPUS_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'octopus',
-      'cros_img': 'octopus-release/R120-15645.0.0',
+      'use_lkgm': True,
     },
   },
   'CROS_OCTOPUS_RELEASE_DEV': {
@@ -739,7 +739,7 @@
     'identifier': 'STRONGBAD_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'strongbad',
-      'cros_img': 'strongbad-release/R120-15645.0.0',
+      'use_lkgm': True,
     },
   },
   'CROS_STRONGBAD_RELEASE_DEV': {
@@ -775,7 +775,7 @@
     'skylab': {
       'cros_board': 'volteer',
       'cros_model': 'voxel',
-      'cros_img': 'volteer-public/R120-15645.0.0',
+      'cros_img': 'volteer-public/R120-15650.0.0',
       'bucket': 'chromiumos-image-archive',
       'dut_pool': 'chromium',
       'public_builder': 'cros_test_platform_public',
diff --git a/infra/config/lib/builder_config.star b/infra/config/lib/builder_config.star
index 095039f..a244086 100644
--- a/infra/config/lib/builder_config.star
+++ b/infra/config/lib/builder_config.star
@@ -634,6 +634,7 @@
         fail("There is no buildbucket configuration file to update properties")
 
     bc_state = _bc_state()
+    needs_mega_cq_mode = set()
 
     for bucket in cfg.buckets:
         if not proto.has(bucket, "swarming"):
@@ -766,6 +767,39 @@
             is_excluded = builder.name in excluded_builders or node.props.builder_group in excluded_groups
             if rotations and not mirroring_builders and not is_excluded:
                 fail("{} is on a sheriff/gardener rotation, but lacks a matching trybot".format(builder.name))
+            for m in mirroring_builders:
+                mirror_id = _builder_id(m)
+                cq_identifier = "{}/{}/{}".format(
+                    mirror_id["project"],
+                    mirror_id["bucket"],
+                    mirror_id["builder"],
+                )
+                needs_mega_cq_mode = needs_mega_cq_mode.union([cq_identifier])
+
+    cq_config_groups = []
+    for f in ctx.output:
+        if f == "luci/commit-queue.cfg":
+            cq_config_groups = ctx.output[f].config_groups
+            break
+    for cq_group in cq_config_groups:
+        if cq_group.name != "cq":
+            continue
+        for b in cq_group.verifiers.tryjob.builders:
+            if b.name not in needs_mega_cq_mode:
+                continue
+
+            # TODO(crbug.com/1483511): Uncomment the following when CV actually
+            # supports custom run modes.
+            #if "CQ_MODE_MEGA_DRY_RUN" not in b.mode_allowlist:
+            #    b.mode_allowlist.append("CQ_MODE_MEGA_DRY_RUN")
+            #if "CQ_MODE_MEGA_FULL_RUN" not in b.mode_allowlist:
+            #    b.mode_allowlist.append("CQ_MODE_MEGA_FULL_RUN")
+
+    # Print the mega CQ bots to a txt file for debugging / parsing purposes.
+    # TODO(crbug.com/1483511): Can delete this when CV full supports custom
+    # run modes with all features needed by chrome.
+    mega_cq_bots_file = "cq-usage/mega_cq_bots.txt"
+    ctx.output[mega_cq_bots_file] = "".join(["{}\n".format(b) for b in sorted(needs_mega_cq_mode)])
 
 lucicfg.generator(_set_builder_config_property)
 
diff --git a/infra/config/main.star b/infra/config/main.star
index 5d1a9d6f..4af95ee 100755
--- a/infra/config/main.star
+++ b/infra/config/main.star
@@ -27,6 +27,7 @@
         "cq-builders.md",
         "cq-usage/default.cfg",
         "cq-usage/full.cfg",
+        "cq-usage/mega_cq_bots.txt",
         "health-specs/health-specs.json",
         "luci/commit-queue.cfg",
         "luci/cr-buildbucket.cfg",
diff --git a/infra/config/recipes.star b/infra/config/recipes.star
index 31a5a613..8a43951df 100644
--- a/infra/config/recipes.star
+++ b/infra/config/recipes.star
@@ -165,6 +165,10 @@
 )
 
 build_recipe(
+    name = "recipe:chromium/gn_args_verifier",
+)
+
+build_recipe(
     name = "recipe:chromium/targets_config_verifier",
 )
 
diff --git a/infra/config/subprojects/chromium/try/presubmit.star b/infra/config/subprojects/chromium/try/presubmit.star
index 799b2a0..46dfa053 100644
--- a/infra/config/subprojects/chromium/try/presubmit.star
+++ b/infra/config/subprojects/chromium/try/presubmit.star
@@ -142,6 +142,22 @@
 )
 
 presubmit_builder(
+    name = "gn-args-verifier",
+    description_html = "checks that GN args generated by starlark definition match those originally specified in //tools/mb/mb_config.pyl",
+    executable = "recipe:chromium/gn_args_verifier",
+    contact_team_email = "chrome-browser-infra-team@google.com",
+    properties = {
+        "builder_config_directory": "infra/config/generated/builders",
+    },
+    # TODO(crbug.com/1471251) Once the recipe is working, actually add this to
+    # the CQ
+    # tryjob = try_.job(
+    #     location_filters = ["infra/config/generated/builders/[^/]+/[^/]+/gn-args\.json"],
+    # ),
+    tryjob = None,
+)
+
+presubmit_builder(
     name = "chromium_presubmit",
     branch_selector = branches.selector.ALL_BRANCHES,
     executable = "recipe:presubmit",
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
index 4da3d02..efab611 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
@@ -95,6 +95,10 @@
     ],
     compilator = "android-12-x64-rel-compilator",
     coverage_test_types = ["unit", "overall"],
+    experiments = {
+        # go/nplus1shardsproposal
+        "chromium.add_one_test_shard": 10,
+    },
     main_list_view = "try",
     tryjob = try_.job(),
     # TODO(crbug.com/1372179): Use orchestrator pool once overloaded test pools
@@ -142,6 +146,10 @@
     ],
     compilator = "android-arm64-rel-compilator",
     coverage_test_types = ["unit", "overall"],
+    experiments = {
+        # go/nplus1shardsproposal
+        "chromium.add_one_test_shard": 10,
+    },
     main_list_view = "try",
     tryjob = try_.job(),
     # TODO(crbug.com/1372179): Use orchestrator pool once overloaded test pools
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
index 42a5879..32389e9e 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
@@ -290,6 +290,10 @@
     ],
     compilator = "linux-lacros-rel-compilator",
     coverage_test_types = ["unit", "overall"],
+    experiments = {
+        # go/nplus1shardsproposal
+        "chromium.add_one_test_shard": 10,
+    },
     main_list_view = "try",
     tryjob = try_.job(),
     use_clang_coverage = True,
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star b/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star
index 05cc9ff8..3c134bd 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.fuchsia.star
@@ -153,9 +153,8 @@
     compilator = "fuchsia-x64-cast-receiver-rel-compilator",
     coverage_test_types = ["unit", "overall"],
     experiments = {
-        "enable_weetbix_queries": 100,
-        "weetbix.retry_weak_exonerations": 100,
-        "weetbix.enable_weetbix_exonerations": 100,
+        # go/nplus1shardsproposal
+        "chromium.add_one_test_shard": 10,
     },
     main_list_view = "try",
     tryjob = try_.job(),
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
index 8d221f7..cca2081 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.linux.star
@@ -322,6 +322,10 @@
     ],
     compilator = "linux-wayland-rel-compilator",
     coverage_test_types = ["unit", "overall"],
+    experiments = {
+        # go/nplus1shardsproposal
+        "chromium.add_one_test_shard": 10,
+    },
     main_list_view = "try",
     tryjob = try_.job(),
     use_clang_coverage = True,
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.win.star b/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
index 64f8e7d..e9ca87ed 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.win.star
@@ -91,6 +91,7 @@
     experiments = {
         # go/nplus1shardsproposal
         "chromium.add_one_test_shard": 5,
+        "chromium.pre_retry_shards_without_patch_compile": 100,
     },
     main_list_view = "try",
     tryjob = try_.job(),
diff --git a/infra/config/targets/basic_suites.star b/infra/config/targets/basic_suites.star
index 9272c3db..d0a8df4 100644
--- a/infra/config/targets/basic_suites.star
+++ b/infra/config/targets/basic_suites.star
@@ -3106,6 +3106,30 @@
 )
 
 targets.legacy_basic_suite(
+    name = "gpu_dawn_webgpu_compat_cts",
+    tests = {
+        "webgpu_cts_compat_tests": targets.legacy_test_config(
+            telemetry_test_name = "webgpu_compat_cts",
+            mixins = [
+                "has_native_resultdb_integration",
+                "webgpu_telemetry_cts",
+            ],
+            args = [
+                "--extra-browser-args=--use-angle=gl --use-webgpu-adapter=opengles --enable-webgpu-developer-features",
+            ],
+            ci_only = True,
+            swarming = targets.swarming(
+                shards = 14,
+            ),
+            android_swarming = targets.swarming(
+                shards = 36,
+            ),
+            experiment_percentage = 100,
+        ),
+    },
+)
+
+targets.legacy_basic_suite(
     name = "gpu_dawn_webgpu_cts",
     tests = {
         "webgpu_cts_tests": targets.legacy_test_config(
diff --git a/infra/config/targets/compound_suites.star b/infra/config/targets/compound_suites.star
index 0ca0123..476c09f 100644
--- a/infra/config/targets/compound_suites.star
+++ b/infra/config/targets/compound_suites.star
@@ -777,6 +777,15 @@
 )
 
 targets.legacy_compound_suite(
+    name = "gpu_dawn_compat_telemetry_tests",
+    basic_suites = [
+        "gpu_dawn_webgpu_compat_cts",
+        "gpu_dawn_webgpu_cts",
+        "gpu_dawn_web_platform_webgpu_cts_force_swiftshader",
+    ],
+)
+
+targets.legacy_compound_suite(
     name = "gpu_dawn_integration_asan_gtests_passthrough",
     basic_suites = [
         "gpu_dawn_gtests",
diff --git a/infra/config/targets/cros-skylab-variants.json b/infra/config/targets/cros-skylab-variants.json
index c3aa29d..3d7260c 100644
--- a/infra/config/targets/cros-skylab-variants.json
+++ b/infra/config/targets/cros-skylab-variants.json
@@ -10,8 +10,7 @@
   "CROS_BRYA_RELEASE_LKGM": {
     "skylab": {
       "cros_board": "brya",
-      "cros_chrome_version": "120.0.6057.0",
-      "cros_img": "brya-release/R120-15642.0.0",
+      "use_lkgm": true,
       "dut_pool": "chrome"
     },
     "enabled": true,
@@ -50,8 +49,7 @@
   "CROS_DEDEDE_RELEASE_LKGM": {
     "skylab": {
       "cros_board": "dedede",
-      "cros_chrome_version": "120.0.6062.0",
-      "cros_img": "dedede-release/R120-15645.0.0"
+      "use_lkgm": true
     },
     "enabled": true,
     "identifier": "DEDEDE_RELEASE_LKGM"
@@ -86,8 +84,7 @@
   "CROS_FIZZ_RELEASE_LKGM": {
     "skylab": {
       "cros_board": "fizz",
-      "cros_chrome_version": "120.0.6062.0",
-      "cros_img": "fizz-release/R120-15645.0.0",
+      "use_lkgm": true,
       "dut_pool": "chrome"
     },
     "enabled": true,
@@ -126,8 +123,7 @@
   "CROS_GUYBRUSH_RELEASE_LKGM": {
     "skylab": {
       "cros_board": "guybrush",
-      "cros_chrome_version": "120.0.6062.0",
-      "cros_img": "guybrush-release/R120-15645.0.0",
+      "use_lkgm": true,
       "dut_pool": "chrome"
     },
     "enabled": true,
@@ -166,8 +162,7 @@
   "CROS_PUFF_RELEASE_LKGM": {
     "skylab": {
       "cros_board": "puff",
-      "cros_chrome_version": "120.0.6062.0",
-      "cros_img": "puff-release/R120-15645.0.0",
+      "use_lkgm": true,
       "dut_pool": "chrome"
     },
     "enabled": true,
@@ -206,8 +201,8 @@
   "CROS_EVE_PUBLIC_LKGM": {
     "skylab": {
       "cros_board": "eve",
-      "cros_chrome_version": "120.0.6062.0",
-      "cros_img": "eve-public/R120-15645.0.0",
+      "cros_chrome_version": "120.0.6073.0",
+      "cros_img": "eve-public/R120-15650.0.0",
       "bucket": "chromiumos-image-archive",
       "dut_pool": "chromium",
       "public_builder": "cros_test_platform_public",
@@ -219,8 +214,7 @@
   "CROS_HANA_RELEASE_LKGM": {
     "skylab": {
       "cros_board": "hana",
-      "cros_chrome_version": "120.0.6062.0",
-      "cros_img": "hana-release/R120-15645.0.0"
+      "use_lkgm": true
     },
     "enabled": true,
     "identifier": "HANA_RELEASE_LKGM"
@@ -255,8 +249,7 @@
   "CROS_JACUZZI_RELEASE_LKGM": {
     "skylab": {
       "cros_board": "jacuzzi",
-      "cros_chrome_version": "120.0.6062.0",
-      "cros_img": "jacuzzi-release/R120-15645.0.0"
+      "use_lkgm": true
     },
     "enabled": true,
     "identifier": "JACUZZI_RELEASE_LKGM"
@@ -298,8 +291,8 @@
   "CROS_JACUZZI_PUBLIC_LKGM": {
     "skylab": {
       "cros_board": "jacuzzi",
-      "cros_chrome_version": "120.0.6062.0",
-      "cros_img": "jacuzzi-public/R120-15645.0.0",
+      "cros_chrome_version": "120.0.6073.0",
+      "cros_img": "jacuzzi-public/R120-15650.0.0",
       "bucket": "chromiumos-image-archive"
     },
     "enabled": true,
@@ -308,8 +301,8 @@
   "CROS_JACUZZI_CQ_PUBLIC_LKGM": {
     "skylab": {
       "cros_board": "jacuzzi",
-      "cros_chrome_version": "120.0.6062.0",
-      "cros_img": "jacuzzi-public/R120-15645.0.0",
+      "cros_chrome_version": "120.0.6073.0",
+      "cros_img": "jacuzzi-public/R120-15650.0.0",
       "bucket": "chromiumos-image-archive",
       "public_builder": "cros_test_platform_public",
       "public_builder_bucket": "testplatform-public"
@@ -320,8 +313,8 @@
   "CROS_TROGDOR_PUBLIC_LKGM": {
     "skylab": {
       "cros_board": "trogdor",
-      "cros_chrome_version": "120.0.6062.0",
-      "cros_img": "trogdor-public/R120-15645.0.0",
+      "cros_chrome_version": "120.0.6073.0",
+      "cros_img": "trogdor-public/R120-15650.0.0",
       "bucket": "chromiumos-image-archive"
     },
     "enabled": true,
@@ -330,8 +323,8 @@
   "CROS_OCTOPUS_PUBLIC_LKGM": {
     "skylab": {
       "cros_board": "octopus",
-      "cros_chrome_version": "120.0.6062.0",
-      "cros_img": "octopus-public/R120-15645.0.0",
+      "cros_chrome_version": "120.0.6073.0",
+      "cros_img": "octopus-public/R120-15650.0.0",
       "bucket": "chromiumos-image-archive"
     },
     "enabled": true,
@@ -347,8 +340,7 @@
   "CROS_OCTOPUS_RELEASE_LKGM": {
     "skylab": {
       "cros_board": "octopus",
-      "cros_chrome_version": "120.0.6062.0",
-      "cros_img": "octopus-release/R120-15645.0.0"
+      "use_lkgm": true
     },
     "enabled": true,
     "identifier": "OCTOPUS_RELEASE_LKGM"
@@ -383,8 +375,7 @@
   "CROS_STRONGBAD_RELEASE_LKGM": {
     "skylab": {
       "cros_board": "strongbad",
-      "cros_chrome_version": "120.0.6062.0",
-      "cros_img": "strongbad-release/R120-15645.0.0"
+      "use_lkgm": true
     },
     "enabled": true,
     "identifier": "STRONGBAD_RELEASE_LKGM"
@@ -427,8 +418,8 @@
     "skylab": {
       "cros_board": "volteer",
       "cros_model": "voxel",
-      "cros_chrome_version": "120.0.6062.0",
-      "cros_img": "volteer-public/R120-15645.0.0",
+      "cros_chrome_version": "120.0.6073.0",
+      "cros_img": "volteer-public/R120-15650.0.0",
       "bucket": "chromiumos-image-archive",
       "dut_pool": "chromium",
       "public_builder": "cros_test_platform_public",
diff --git a/infra/config/targets/lacros-version-skew-variants.json b/infra/config/targets/lacros-version-skew-variants.json
index e282fb36..6f3b3cf 100644
--- a/infra/config/targets/lacros-version-skew-variants.json
+++ b/infra/config/targets/lacros-version-skew-variants.json
@@ -1,16 +1,16 @@
 {
   "LACROS_VERSION_SKEW_CANARY": {
     "args": [
-      "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6074.0/test_ash_chrome"
+      "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6075.0/test_ash_chrome"
     ],
-    "description": "Run with ash-chrome version 120.0.6074.0",
+    "description": "Run with ash-chrome version 120.0.6075.0",
     "identifier": "Lacros version skew testing ash canary",
     "swarming": {
       "cipd_packages": [
         {
           "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-          "location": "lacros_version_skew_tests_v120.0.6074.0",
-          "revision": "version:120.0.6074.0"
+          "location": "lacros_version_skew_tests_v120.0.6075.0",
+          "revision": "version:120.0.6075.0"
         }
       ]
     }
diff --git a/infra/config/targets/mixins.star b/infra/config/targets/mixins.star
index bc1cb6b..0559eb5 100644
--- a/infra/config/targets/mixins.star
+++ b/infra/config/targets/mixins.star
@@ -1071,7 +1071,7 @@
             targets.cipd_package(
                 package = "infra/tools/mac_toolchain/${platform}",
                 location = ".",
-                revision = "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb",
+                revision = "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce",
             ),
         ],
     ),
diff --git a/internal b/internal
index d2f1105..6b11058 160000
--- a/internal
+++ b/internal
@@ -1 +1 @@
-Subproject commit d2f1105690202f0c66a12b243f4a7772300fa0e0
+Subproject commit 6b110587054eb66ac230575205a3a948d3d14303
diff --git a/ios/chrome/browser/push_notification/BUILD.gn b/ios/chrome/browser/push_notification/BUILD.gn
index 43c639f..e29b00e 100644
--- a/ios/chrome/browser/push_notification/BUILD.gn
+++ b/ios/chrome/browser/push_notification/BUILD.gn
@@ -94,11 +94,9 @@
     ":test_support",
     "//base",
     "//base/test:test_support",
-    "//components/sync_preferences:test_support",
     "//ios/chrome/browser/shared/model/application_context",
     "//ios/chrome/browser/shared/model/browser_state",
     "//ios/chrome/browser/shared/model/browser_state:test_support",
-    "//ios/chrome/browser/shared/model/prefs:pref_names",
     "//ios/chrome/test:test_support",
     "//ios/web/public/test",
     "//testing/gtest",
diff --git a/ios/chrome/browser/push_notification/push_notification_service.h b/ios/chrome/browser/push_notification/push_notification_service.h
index a5a5183..587a012 100644
--- a/ios/chrome/browser/push_notification/push_notification_service.h
+++ b/ios/chrome/browser/push_notification/push_notification_service.h
@@ -15,7 +15,6 @@
 namespace ios {
 class ChromeBrowserStateManager;
 }
-class PrefRegistrySimple;
 @class PushNotificationAccountContextManager;
 enum class PushNotificationClientId;
 class PushNotificationClientManager;
@@ -74,8 +73,6 @@
   static void RegisterBrowserStatePrefs(
       user_prefs::PrefRegistrySyncable* registry);
 
-  static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
-
  protected:
   PushNotificationService(ios::ChromeBrowserStateManager* manager);
   // Registers the device with the push notification server. By supplying a list
diff --git a/ios/chrome/browser/push_notification/push_notification_service.mm b/ios/chrome/browser/push_notification/push_notification_service.mm
index 68bdc17..8527228 100644
--- a/ios/chrome/browser/push_notification/push_notification_service.mm
+++ b/ios/chrome/browser/push_notification/push_notification_service.mm
@@ -8,11 +8,9 @@
 #import "base/strings/sys_string_conversions.h"
 #import "base/values.h"
 #import "components/pref_registry/pref_registry_syncable.h"
-#import "components/prefs/pref_registry_simple.h"
 #import "ios/chrome/browser/push_notification/push_notification_account_context_manager.h"
 #import "ios/chrome/browser/push_notification/push_notification_client_id.h"
 #import "ios/chrome/browser/push_notification/push_notification_client_manager.h"
-#import "ios/chrome/browser/push_notification/push_notification_util.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
 
@@ -79,15 +77,6 @@
   registry->RegisterDictionaryPref(prefs::kFeaturePushNotificationPermissions);
 }
 
-void PushNotificationService::RegisterLocalStatePrefs(
-    PrefRegistrySimple* registry) {
-  registry->RegisterIntegerPref(
-      prefs::kPushNotificationAuthorizationStatus,
-      static_cast<int>(
-          push_notification::PushNotificationSettingsAuthorizationStatus::
-              NOTDETERMINED));
-}
-
 void PushNotificationService::SetPreferences(
     NSString* account_id,
     PreferenceMap preference_map,
diff --git a/ios/chrome/browser/push_notification/push_notification_util.h b/ios/chrome/browser/push_notification/push_notification_util.h
index 1c51f38..25c2f57 100644
--- a/ios/chrome/browser/push_notification/push_notification_util.h
+++ b/ios/chrome/browser/push_notification/push_notification_util.h
@@ -7,19 +7,6 @@
 
 #import <Foundation/Foundation.h>
 
-// multiple UMA metrics and the local state pref service rely on this enum.
-// Please do not reorder or delete its entries.
-namespace push_notification {
-enum class PushNotificationSettingsAuthorizationStatus : int {
-  NOTDETERMINED,
-  DENIED,
-  AUTHORIZED,
-  PROVISIONAL,
-  EPHEMERAL,
-  kMaxValue = EPHEMERAL
-};
-}
-
 @class UIApplication;
 @class UNNotificationCategory;
 @class UNNotificationSettings;
diff --git a/ios/chrome/browser/push_notification/push_notification_util.mm b/ios/chrome/browser/push_notification/push_notification_util.mm
index f220a2f..95aa7ca 100644
--- a/ios/chrome/browser/push_notification/push_notification_util.mm
+++ b/ios/chrome/browser/push_notification/push_notification_util.mm
@@ -8,9 +8,6 @@
 #import <UserNotifications/UserNotifications.h>
 
 #import "base/metrics/histogram_functions.h"
-#import "components/prefs/pref_service.h"
-#import "ios/chrome/browser/shared/model/application_context/application_context.h"
-#import "ios/chrome/browser/shared/model/prefs/pref_names.h"
 
 namespace {
 
@@ -27,6 +24,15 @@
   kMaxValue = ERROR
 };
 
+enum class PushNotificationSettingsAuthorizationStatus {
+  NOTDETERMINED,
+  DENIED,
+  AUTHORIZED,
+  PROVISIONAL,
+  EPHEMERAL,
+  kMaxValue = EPHEMERAL
+};
+
 // The histogram used to record the outcome of the permission prompt.
 const char kEnabledPermissionsHistogram[] =
     "IOS.PushNotification.EnabledPermisisons";
@@ -35,16 +41,6 @@
 // status.
 const char kAuthorizationStatusHistogram[] =
     "IOS.PushNotification.NotificationSettingsAuthorizationStatus";
-
-// The histogram used to record users changes to an authorized push notification
-// permission status.
-const char kNotificationAutorizationStatusChangedToAuthorized[] =
-    "IOS.PushNotification.NotificationAutorizationStatusChangedToAuthorized";
-
-// The histogram used to record users changes to a denied push notification
-// permission status.
-const char kNotificationAutorizationStatusChangedToDenied[] =
-    "IOS.PushNotification.NotificationAutorizationStatusChangedToDenied";
 }  // namespace
 
 @implementation PushNotificationUtil
@@ -52,12 +48,10 @@
 + (void)registerDeviceWithAPNS {
   [PushNotificationUtil
       getPermissionSettings:^(UNNotificationSettings* settings) {
-        dispatch_async(dispatch_get_main_queue(), ^{
-          // Logs the users iOS settings' push notification permission status
-          // over time.
-          [PushNotificationUtil
-              logPermissionSettingsMetrics:settings.authorizationStatus];
-        });
+        // Logs the users iOS settings' push notification permission status over
+        // time.
+        [PushNotificationUtil
+            logPermissionSettingsMetrics:settings.authorizationStatus];
 
         if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) {
           // iOS instructs that registering the device with APNS must be done on
@@ -145,70 +139,51 @@
 // whether Chrome can receive push notifications on the device to UMA.
 + (void)logPermissionSettingsMetrics:
     (UNAuthorizationStatus)authorizationStatus {
-  push_notification::PushNotificationSettingsAuthorizationStatus status;
   switch (authorizationStatus) {
     case UNAuthorizationStatusNotDetermined:
       // The authorization status is this case when the user has not yet
       // decided to give Chrome push notification permissions.
-      status = push_notification::PushNotificationSettingsAuthorizationStatus::
-          NOTDETERMINED;
+      base::UmaHistogramEnumeration(
+          kAuthorizationStatusHistogram,
+          PushNotificationSettingsAuthorizationStatus::NOTDETERMINED);
       break;
     case UNAuthorizationStatusDenied:
       // The authorization status is this case when the user has denied to
       // give Chrome push notification permissions via the push
       // notification iOS system permission prompt or by navigating to the iOS
       // settings and manually enabling it.
-      status = push_notification::PushNotificationSettingsAuthorizationStatus::
-          DENIED;
+      base::UmaHistogramEnumeration(
+          kAuthorizationStatusHistogram,
+          PushNotificationSettingsAuthorizationStatus::DENIED);
       break;
     case UNAuthorizationStatusAuthorized:
       // The authorization status is this case when the user has
       // authorized to give Chrome push notification permissions via the
       // push notification iOS system permission prompt or by navigating to the
       // iOS settings and manually enabling it.
-      status = push_notification::PushNotificationSettingsAuthorizationStatus::
-          AUTHORIZED;
+      base::UmaHistogramEnumeration(
+          kAuthorizationStatusHistogram,
+          PushNotificationSettingsAuthorizationStatus::AUTHORIZED);
       break;
     case UNAuthorizationStatusProvisional:
       // The authorization status is this case when Chrome has the ability
       // to send provisional push notifications.
-      status = push_notification::PushNotificationSettingsAuthorizationStatus::
-          PROVISIONAL;
+      base::UmaHistogramEnumeration(
+          kAuthorizationStatusHistogram,
+          PushNotificationSettingsAuthorizationStatus::PROVISIONAL);
       break;
     case UNAuthorizationStatusEphemeral:
       // The authorization status is this case Chrome can receive
       // notifications for a limited amount of time.
-      status = push_notification::PushNotificationSettingsAuthorizationStatus::
-          EPHEMERAL;
+      base::UmaHistogramEnumeration(
+          kAuthorizationStatusHistogram,
+          PushNotificationSettingsAuthorizationStatus::EPHEMERAL);
       break;
   }
-  base::UmaHistogramEnumeration(kAuthorizationStatusHistogram, status);
 
-  ApplicationContext* context = GetApplicationContext();
-  PrefService* prefService = context->GetLocalState();
-  int previousAuthorizationStatus =
-      prefService->GetInteger(prefs::kPushNotificationAuthorizationStatus);
-  if (previousAuthorizationStatus != static_cast<int>(status)) {
-    if (status == push_notification::
-                      PushNotificationSettingsAuthorizationStatus::AUTHORIZED) {
-      base::UmaHistogramEnumeration(
-          kNotificationAutorizationStatusChangedToAuthorized,
-          static_cast<
-              push_notification::PushNotificationSettingsAuthorizationStatus>(
-              previousAuthorizationStatus));
-    } else if (status ==
-               push_notification::PushNotificationSettingsAuthorizationStatus::
-                   DENIED) {
-      base::UmaHistogramEnumeration(
-          kNotificationAutorizationStatusChangedToDenied,
-          static_cast<
-              push_notification::PushNotificationSettingsAuthorizationStatus>(
-              previousAuthorizationStatus));
-    }
-
-    prefService->SetInteger(prefs::kPushNotificationAuthorizationStatus,
-                            static_cast<int>(status));
-  }
+  // TODO(crbug.com/1487295): Add metric that tracks when users changes
+  // their push notification permission authorization status to
+  // Authorized/Denied.
 }
 
 @end
diff --git a/ios/chrome/browser/push_notification/push_notification_util_unittest.mm b/ios/chrome/browser/push_notification/push_notification_util_unittest.mm
index 94f8283b..d71a700 100644
--- a/ios/chrome/browser/push_notification/push_notification_util_unittest.mm
+++ b/ios/chrome/browser/push_notification/push_notification_util_unittest.mm
@@ -5,43 +5,26 @@
 #import "ios/chrome/browser/push_notification/push_notification_util.h"
 
 #import "base/test/metrics/histogram_tester.h"
-#import "components/sync_preferences/testing_pref_service_syncable.h"
 #import "ios/chrome/browser/push_notification/push_notification_util+testing.h"
-#import "ios/chrome/browser/push_notification/push_notification_util.h"
-#import "ios/chrome/browser/shared/model/prefs/pref_names.h"
-#import "ios/chrome/test/testing_application_context.h"
 #import "testing/platform_test.h"
 
 namespace {
+enum class PushNotificationSettingsAuthorizationStatus {
+  NOTDETERMINED,
+  DENIED,
+  AUTHORIZED,
+  PROVISIONAL,
+  EPHEMERAL,
+  kMaxValue = EPHEMERAL
+};
+
 const char kAuthorizationStatusHistogramName[] =
     "IOS.PushNotification.NotificationSettingsAuthorizationStatus";
-
-const char kNotificationAutorizationStatusChangedToAuthorized[] =
-    "IOS.PushNotification.NotificationAutorizationStatusChangedToAuthorized";
-
-const char kNotificationAutorizationStatusChangedToDenied[] =
-    "IOS.PushNotification.NotificationAutorizationStatusChangedToDenied";
 }  // namespace
 
 class PushNotificationUtilTest : public PlatformTest {
- public:
-  PushNotificationUtilTest() {
-    pref_service_.registry()->RegisterIntegerPref(
-        prefs::kPushNotificationAuthorizationStatus,
-        static_cast<int>(
-            push_notification::PushNotificationSettingsAuthorizationStatus::
-                NOTDETERMINED));
-    TestingApplicationContext::GetGlobal()->SetLocalState(&pref_service_);
-  }
-
-  void TearDown() override {
-    TestingApplicationContext::GetGlobal()->SetLocalState(nullptr);
-    PlatformTest::TearDown();
-  }
-
  protected:
   base::HistogramTester histogram_tester_;
-  sync_preferences::TestingPrefServiceSyncable pref_service_;
 };
 
 // Ensures that the proper UMA histogram and bucket are logged when
@@ -51,75 +34,34 @@
       logPermissionSettingsMetrics:UNAuthorizationStatusNotDetermined];
   histogram_tester_.ExpectBucketCount(
       kAuthorizationStatusHistogramName,
-      push_notification::PushNotificationSettingsAuthorizationStatus::
-          NOTDETERMINED,
-      1);
+      PushNotificationSettingsAuthorizationStatus::NOTDETERMINED, 1);
   histogram_tester_.ExpectTotalCount(kAuthorizationStatusHistogramName, 1);
 
   [PushNotificationUtil
       logPermissionSettingsMetrics:UNAuthorizationStatusDenied];
   histogram_tester_.ExpectBucketCount(
       kAuthorizationStatusHistogramName,
-      push_notification::PushNotificationSettingsAuthorizationStatus::DENIED,
-      1);
+      PushNotificationSettingsAuthorizationStatus::DENIED, 1);
   histogram_tester_.ExpectTotalCount(kAuthorizationStatusHistogramName, 2);
 
   [PushNotificationUtil
       logPermissionSettingsMetrics:UNAuthorizationStatusAuthorized];
   histogram_tester_.ExpectBucketCount(
       kAuthorizationStatusHistogramName,
-      push_notification::PushNotificationSettingsAuthorizationStatus::
-          AUTHORIZED,
-      1);
+      PushNotificationSettingsAuthorizationStatus::AUTHORIZED, 1);
   histogram_tester_.ExpectTotalCount(kAuthorizationStatusHistogramName, 3);
 
   [PushNotificationUtil
       logPermissionSettingsMetrics:UNAuthorizationStatusProvisional];
   histogram_tester_.ExpectBucketCount(
       kAuthorizationStatusHistogramName,
-      push_notification::PushNotificationSettingsAuthorizationStatus::
-          PROVISIONAL,
-      1);
+      PushNotificationSettingsAuthorizationStatus::PROVISIONAL, 1);
   histogram_tester_.ExpectTotalCount(kAuthorizationStatusHistogramName, 4);
 
   [PushNotificationUtil
       logPermissionSettingsMetrics:UNAuthorizationStatusEphemeral];
   histogram_tester_.ExpectBucketCount(
       kAuthorizationStatusHistogramName,
-      push_notification::PushNotificationSettingsAuthorizationStatus::EPHEMERAL,
-      1);
+      PushNotificationSettingsAuthorizationStatus::EPHEMERAL, 1);
   histogram_tester_.ExpectTotalCount(kAuthorizationStatusHistogramName, 5);
 }
-
-// Ensures that the proper UMA histograms and buckets are logged when
-// changing authorization status' to authorized or denied.
-TEST_F(PushNotificationUtilTest, loggingAuthorizationStatusChange) {
-  [PushNotificationUtil
-      logPermissionSettingsMetrics:UNAuthorizationStatusDenied];
-  histogram_tester_.ExpectBucketCount(
-      kNotificationAutorizationStatusChangedToDenied,
-      push_notification::PushNotificationSettingsAuthorizationStatus::
-          NOTDETERMINED,
-      1);
-  histogram_tester_.ExpectTotalCount(
-      kNotificationAutorizationStatusChangedToDenied, 1);
-  // A repeat request should not be logged to UMA.
-  [PushNotificationUtil
-      logPermissionSettingsMetrics:UNAuthorizationStatusDenied];
-  histogram_tester_.ExpectTotalCount(
-      kNotificationAutorizationStatusChangedToDenied, 1);
-
-  [PushNotificationUtil
-      logPermissionSettingsMetrics:UNAuthorizationStatusAuthorized];
-  histogram_tester_.ExpectBucketCount(
-      kNotificationAutorizationStatusChangedToAuthorized,
-      push_notification::PushNotificationSettingsAuthorizationStatus::DENIED,
-      1);
-  histogram_tester_.ExpectTotalCount(
-      kNotificationAutorizationStatusChangedToAuthorized, 1);
-  // A repeat request should not be logged to UMA.
-  [PushNotificationUtil
-      logPermissionSettingsMetrics:UNAuthorizationStatusAuthorized];
-  histogram_tester_.ExpectTotalCount(
-      kNotificationAutorizationStatusChangedToAuthorized, 1);
-}
diff --git a/ios/chrome/browser/sessions/session_restoration_browser_agent.mm b/ios/chrome/browser/sessions/session_restoration_browser_agent.mm
index db7845fa..1fb5e8b2 100644
--- a/ios/chrome/browser/sessions/session_restoration_browser_agent.mm
+++ b/ios/chrome/browser/sessions/session_restoration_browser_agent.mm
@@ -167,6 +167,9 @@
 
   std::vector<int> items_to_drop;
   NSMutableSet<NSString*>* seen_identifiers = [NSMutableSet set];
+  // Count the number of dropped tabs because they are duplicates, for
+  // reporting.
+  int duplicate_count = 0;
   for (int index = 0; index < sessions_count; ++index) {
     CRWSessionStorage* session = session_window.sessions[index];
     if (session.itemStorages.count == 0) {
@@ -177,10 +180,13 @@
       // somewhere).
       if ([seen_identifiers containsObject:session.stableIdentifier]) {
         items_to_drop.push_back(index);
+        duplicate_count++;
       }
       [seen_identifiers addObject:session.stableIdentifier];
     }
   }
+  base::UmaHistogramCounts100("Tabs.DroppedDuplicatesCountOnSessionRestore",
+                              duplicate_count);
 
   // Nothing to do.
   if (items_to_drop.empty()) {
diff --git a/ios/chrome/browser/sessions/session_restoration_service_impl.mm b/ios/chrome/browser/sessions/session_restoration_service_impl.mm
index f2f082f..27019b7a 100644
--- a/ios/chrome/browser/sessions/session_restoration_service_impl.mm
+++ b/ios/chrome/browser/sessions/session_restoration_service_impl.mm
@@ -9,6 +9,7 @@
 #import "base/files/file_enumerator.h"
 #import "base/files/file_util.h"
 #import "base/functional/bind.h"
+#import "base/metrics/histogram_functions.h"
 #import "ios/chrome/browser/sessions/proto/storage.pb.h"
 #import "ios/chrome/browser/sessions/session_constants.h"
 #import "ios/chrome/browser/sessions/session_internal_util.h"
@@ -216,6 +217,8 @@
   DCHECK(base::Contains(infos_, browser->GetWebStateList()));
   WebStateListInfo& info = *infos_[browser->GetWebStateList()];
 
+  const base::TimeTicks start_time = base::TimeTicks::Now();
+
   // Check that LoadSession is only called once, and before any asynchronous
   // operation where started on that Browser. Then mark the Browser as no
   // longer safe for synchrounous operations.
@@ -269,6 +272,10 @@
   for (auto& observer : observers_) {
     observer.SessionRestorationFinished(browser, restored_web_states);
   }
+
+  // Record the time spent blocking the main thread to load the session.
+  base::UmaHistogramTimes("Session.WebStates.LoadingTimeOnMainThread",
+                          base::TimeTicks::Now() - start_time);
 }
 
 void SessionRestorationServiceImpl::Disconnect(Browser* browser) {
@@ -307,6 +314,8 @@
     return;
   }
 
+  const base::TimeTicks start_time = base::TimeTicks::Now();
+
   ios::sessions::IORequestList requests;
 
   // Create a map of orphaned WebStates (i.e. "unrealized" WebStates detached
@@ -416,4 +425,8 @@
       base::BindOnce(&ios::sessions::ExecuteIORequests, std::move(requests)));
 
   dirty_web_state_lists_.clear();
+
+  // Record the time spent blocking the main thread to save the session.
+  base::UmaHistogramTimes("Session.WebStates.SavingTimeOnMainThread",
+                          base::TimeTicks::Now() - start_time);
 }
diff --git a/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm b/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm
index 99f197e..112a92d5 100644
--- a/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm
+++ b/ios/chrome/browser/sessions/session_restoration_service_impl_unittest.mm
@@ -15,6 +15,7 @@
 #import "base/functional/bind.h"
 #import "base/run_loop.h"
 #import "base/scoped_multi_source_observation.h"
+#import "base/test/metrics/histogram_tester.h"
 #import "base/test/scoped_feature_list.h"
 #import "base/time/time.h"
 #import "ios/chrome/browser/sessions/proto/storage.pb.h"
@@ -764,3 +765,47 @@
   // Disconnect the Browser before destroying it.
   service()->Disconnect(&browser);
 }
+
+// Tests that histograms are correctly recorded.
+TEST_F(SessionRestorationServiceImplTest, RecordHistograms) {
+  {
+    // Create a Browser and add a few WebStates to it and wait for all
+    // pending scheduled tasks to complete.
+    TestBrowser browser = TestBrowser(browser_state());
+    service()->SetSessionID(&browser, kIdentifier0);
+    InsertTabsWithUrls(browser, base::make_span(kURLs));
+    WaitForBackgroundTaskComplete();
+
+    // Check that session is saved and histogram is recorded when making
+    // some changes to the Browser's WebStateList (changing the active
+    // index).
+    base::HistogramTester histogram_tester;
+    ASSERT_NE(browser.GetWebStateList()->active_index(), 0);
+    browser.GetWebStateList()->ActivateWebStateAt(0);
+    WaitForBackgroundTaskComplete();
+
+    // Check that the time spent to record the session was logged.
+    histogram_tester.ExpectTotalCount(
+        "Session.WebStates.SavingTimeOnMainThread", 1);
+
+    // Disconnect the Browser before destroying it.
+    service()->Disconnect(&browser);
+  }
+
+  // Create a Browser.
+  TestBrowser browser = TestBrowser(browser_state());
+  service()->SetSessionID(&browser, kIdentifier0);
+
+  // Load the session and check that the time spent loading was logged.
+  base::HistogramTester histogram_tester;
+  service()->LoadSession(&browser);
+
+  // Check that the expected content was loaded.
+  EXPECT_EQ(browser.GetWebStateList()->count(),
+            static_cast<int>(std::size(kURLs)));
+  histogram_tester.ExpectTotalCount("Session.WebStates.LoadingTimeOnMainThread",
+                                    1);
+
+  // Disconnect the Browser before destroying it.
+  service()->Disconnect(&browser);
+}
diff --git a/ios/chrome/browser/shared/model/prefs/browser_prefs.mm b/ios/chrome/browser/shared/model/prefs/browser_prefs.mm
index 2ca4ad9..0f5429e8 100644
--- a/ios/chrome/browser/shared/model/prefs/browser_prefs.mm
+++ b/ios/chrome/browser/shared/model/prefs/browser_prefs.mm
@@ -245,7 +245,6 @@
   segmentation_platform::SegmentationPlatformService::RegisterLocalStatePrefs(
       registry);
   optimization_guide::prefs::RegisterLocalStatePrefs(registry);
-  PushNotificationService::RegisterLocalStatePrefs(registry);
 
   // Preferences related to the browser state manager.
   registry->RegisterStringPref(prefs::kBrowserStateLastUsed, std::string());
@@ -589,6 +588,8 @@
   // Preferences related to Save to Photos settings.
   registry->RegisterStringPref(prefs::kIosSaveToPhotosDefaultGaiaId,
                                std::string());
+  registry->RegisterBooleanPref(prefs::kIosSaveToPhotosSkipAccountPicker,
+                                false);
 
   // Preferences related to parcel tracking.
   registry->RegisterBooleanPref(
diff --git a/ios/chrome/browser/shared/model/prefs/pref_names.cc b/ios/chrome/browser/shared/model/prefs/pref_names.cc
index 49f82e7..0dadd913 100644
--- a/ios/chrome/browser/shared/model/prefs/pref_names.cc
+++ b/ios/chrome/browser/shared/model/prefs/pref_names.cc
@@ -263,6 +263,11 @@
 const char kIosSaveToPhotosDefaultGaiaId[] =
     "ios.save_to_photos.default_gaia_id";
 
+// Bool preference containing whether to skip the account picker when the user
+// saves an image to Google Photos.
+const char kIosSaveToPhotosSkipAccountPicker[] =
+    "ios.save_to_photos.skip_account_picker";
+
 // Time preference containing the last run time of the Safety Check (via
 // Settings).
 const char kIosSettingsSafetyCheckLastRunTime[] =
@@ -417,11 +422,6 @@
 
 const char kPrintingEnabled[] = "printing.enabled";
 
-// An integer that stores the authorization state push notification permissions
-// are in on a user's device.
-const char kPushNotificationAuthorizationStatus[] =
-    "ios.push_notifications.authorization_status";
-
 // Bool used for the incognito biometric authentication setting.
 const char kIncognitoAuthenticationSetting[] =
     "ios.settings.incognito_authentication_enabled";
diff --git a/ios/chrome/browser/shared/model/prefs/pref_names.h b/ios/chrome/browser/shared/model/prefs/pref_names.h
index d389254..f0bd5304 100644
--- a/ios/chrome/browser/shared/model/prefs/pref_names.h
+++ b/ios/chrome/browser/shared/model/prefs/pref_names.h
@@ -72,6 +72,7 @@
 extern const char kIosSafetyCheckManagerUpdateCheckResult[];
 extern const char kIosSafetyCheckManagerSafeBrowsingCheckResult[];
 extern const char kIosSaveToPhotosDefaultGaiaId[];
+extern const char kIosSaveToPhotosSkipAccountPicker[];
 extern const char kIosSettingsSafetyCheckLastRunTime[];
 extern const char kIosNtpFeedTopPromoAlreadySeen[];
 extern const char kIosNtpFeedTopSigninPromoDisplayedCount[];
@@ -91,7 +92,6 @@
 extern const char kOverflowMenuDestinationBadgeData[];
 extern const char kOverflowMenuActionsOrder[];
 extern const char kPrintingEnabled[];
-extern const char kPushNotificationAuthorizationStatus[];
 extern const char kSearchSuggestEnabled[];
 extern const char kTabPickupEnabled[];
 extern const char kTabPickupLastDisplayedTime[];
diff --git a/ios/chrome/browser/shared/model/url/chrome_url_constants.cc b/ios/chrome/browser/shared/model/url/chrome_url_constants.cc
index 74386d6..b464a145 100644
--- a/ios/chrome/browser/shared/model/url/chrome_url_constants.cc
+++ b/ios/chrome/browser/shared/model/url/chrome_url_constants.cc
@@ -111,10 +111,6 @@
 const char kEmbeddedTermsOfServiceURL[] =
     "https://policies.google.com/terms/embedded";
 
-const char kDoNotTrackLearnMoreURL[] =
-    "https://support.google.com/chrome/answer/"
-    "2942429?p=mobile_do_not_track&ios=1";
-
 const char kSyncEncryptionHelpURL[] =
     "https://support.google.com/chrome/answer/"
     "1181035?p=settings_encryption&ios=1";
diff --git a/ios/chrome/browser/shared/model/url/chrome_url_constants.h b/ios/chrome/browser/shared/model/url/chrome_url_constants.h
index 3b0cc24..4defa090 100644
--- a/ios/chrome/browser/shared/model/url/chrome_url_constants.h
+++ b/ios/chrome/browser/shared/model/url/chrome_url_constants.h
@@ -92,9 +92,6 @@
 // "Terms of service" URL for mobile view.
 extern const char kEmbeddedTermsOfServiceURL[];
 
-// "Learn more" URL for the "Do not track" setting in the privacy section.
-extern const char kDoNotTrackLearnMoreURL[];
-
 // The URL for the "Learn more" page on sync encryption.
 extern const char kSyncEncryptionHelpURL[];
 
diff --git a/ios/chrome/browser/ui/account_picker/account_picker_coordinator.h b/ios/chrome/browser/ui/account_picker/account_picker_coordinator.h
index eb5289ce..f571c13 100644
--- a/ios/chrome/browser/ui/account_picker/account_picker_coordinator.h
+++ b/ios/chrome/browser/ui/account_picker/account_picker_coordinator.h
@@ -9,6 +9,7 @@
 
 @class AccountPickerConfiguration;
 @protocol AccountPickerCoordinatorDelegate;
+@protocol SystemIdentity;
 
 // Presents a bottom sheet that lets the user pick or add an account on the
 // device to perform some action.
@@ -20,6 +21,9 @@
 // on top of the account picker e.g. the AddAccountSigninCoordinator's view.
 @property(nonatomic, readonly) UIViewController* viewController;
 
+// The identity currently presented as selected.
+@property(nonatomic, strong) id<SystemIdentity> selectedIdentity;
+
 // Inits the coordinator.
 - (instancetype)initWithBaseViewController:(UIViewController*)baseViewController
                                    browser:(Browser*)browser
diff --git a/ios/chrome/browser/ui/account_picker/account_picker_coordinator.mm b/ios/chrome/browser/ui/account_picker/account_picker_coordinator.mm
index 33322f04..177a796 100644
--- a/ios/chrome/browser/ui/account_picker/account_picker_coordinator.mm
+++ b/ios/chrome/browser/ui/account_picker/account_picker_coordinator.mm
@@ -38,9 +38,6 @@
     UINavigationControllerDelegate,
     UIViewControllerTransitioningDelegate>
 
-// Returns `_accountPickerConfirmationScreenCoordinator.selectedIdentity`.
-@property(nonatomic, readonly) id<SystemIdentity> selectedIdentity;
-
 @end
 
 @implementation AccountPickerCoordinator {
@@ -137,6 +134,11 @@
   return _accountPickerConfirmationScreenCoordinator.selectedIdentity;
 }
 
+- (void)setSelectedIdentity:(id<SystemIdentity>)selectedIdentity {
+  _accountPickerConfirmationScreenCoordinator.selectedIdentity =
+      selectedIdentity;
+}
+
 - (UIViewController*)viewController {
   return _navigationController;
 }
diff --git a/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator.h b/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator.h
index 1cc133bc..105da9f6 100644
--- a/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator.h
+++ b/ios/chrome/browser/ui/authentication/signout_action_sheet/signout_action_sheet_coordinator.h
@@ -31,12 +31,16 @@
 
 @end
 
-// Displays sign-out action sheet with options to clear or keep user data
-// on the device. The user must be signed-in to use these actions.
-// The owner is responsible to block the UI, when the sign-out flow is in
-// progress.
-// The UI needs to be blocked and unblocked using methods from
+// Initiate a sign-out action.
+// If the sync feature is disabled, directly sign-out, and display a toast.
+// If the sync feature is enabled, displays sign-out action sheet with options
+// to clear or keep user data on the device.
+// The user must be signed-in to use these actions. The owner is responsible to
+// block the UI, when the sign-out flow is in progress. The UI needs to be
+// blocked and unblocked using methods from
 // SignoutActionSheetCoordinatorDelegate.
+// When `kReplaceSyncPromosWithSignInPromos` will be removed, the sync feature
+// won't be enabled anymore.
 @interface SignoutActionSheetCoordinator : ChromeCoordinator
 
 - (instancetype)initWithBaseViewController:(UIViewController*)viewController
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm b/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm
index 35dcb6e5..16f6f61e 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm
@@ -231,8 +231,7 @@
     [toolbarView.heightAnchor
         constraintEqualToConstant:content_suggestions::FakeToolbarHeight()],
     [toolbarView.trailingAnchor constraintEqualToAnchor:self.trailingAnchor],
-    [toolbarView.topAnchor
-        constraintEqualToAnchor:self.safeAreaLayoutGuide.topAnchor],
+    [toolbarView.topAnchor constraintEqualToAnchor:self.topAnchor],
   ]];
 }
 
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm
index 40857bc..d8feedee3 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm
@@ -640,6 +640,7 @@
 - (void)setLogoVendor:(id<LogoVendor>)logoVendor {
   _logoVendor = logoVendor;
   _logoVendor.doodleObserver = self;
+  [self updateLogoAndFakeboxDisplay];
 }
 
 - (void)setVoiceSearchIsEnabled:(BOOL)voiceSearchIsEnabled {
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
index f73a829..f7b02cb 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
@@ -33,6 +33,7 @@
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/elements/gradient_view.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
+#import "ios/chrome/common/ui/util/ui_util.h"
 #import "ui/base/device_form_factor.h"
 
 namespace {
@@ -1263,11 +1264,12 @@
 - (void)handleStickyElementsForScrollPosition:(CGFloat)scrollPosition
                                         force:(BOOL)force {
   // Handles the sticky omnibox. Does not stick for iPads.
+  CGFloat offsetToStickOmnibox = [self offsetToStickOmnibox];
   if ([self shouldPinFakeOmnibox]) {
-    if (scrollPosition > [self offsetToStickOmnibox] &&
+    if (scrollPosition >= offsetToStickOmnibox &&
         (!self.isFakeboxPinned || force)) {
       [self pinFakeOmniboxToTop];
-    } else if (scrollPosition <= [self offsetToStickOmnibox] &&
+    } else if (scrollPosition < offsetToStickOmnibox &&
                (self.isFakeboxPinned || force)) {
       [self resetFakeOmniboxConstraints];
     }
@@ -1554,11 +1556,9 @@
 // The y-position content offset for when the fake omnibox
 // should stick to the top of the NTP.
 - (CGFloat)offsetToStickOmnibox {
-  // Do not need to factor in safeAreaInsets.top because the fake omnibox sticks
-  // below it, so it is effectively just the scroll distance between top of
-  // NTPHeader and the top of the Fake Omnibox.
-  return -([self heightAboveFeed] - [self.headerViewController headerHeight] +
-           [self stickyOmniboxHeight]);
+  return AlignValueToPixel(-([self heightAboveFeed] -
+                             [self.headerViewController headerHeight] +
+                             [self stickyOmniboxHeight]));
 }
 
 // Whether the collection view has attained its minimum height.
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/menu_customization_view.swift b/ios/chrome/browser/ui/popup_menu/overflow_menu/menu_customization_view.swift
index f2402b2..9d79cc4 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/menu_customization_view.swift
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/menu_customization_view.swift
@@ -29,6 +29,11 @@
   /// The namespace for the animation of this view appearing or disappearing.
   let namespace: Namespace.ID
 
+  /// Focus state to allow setting VoiceOver focus to the page header when
+  /// the page appears.
+  @AccessibilityFocusState
+  private var headerFocused: Bool
+
   init(
     actionCustomizationModel: ActionCustomizationModel,
     destinationCustomizationModel: DestinationCustomizationModel,
@@ -94,6 +99,9 @@
     .background(Color(.systemGroupedBackground).edgesIgnoringSafeArea(.all))
     .overflowMenuListStyle()
     .environment(\.editMode, .constant(.active))
+    .onAppear {
+      headerFocused = true
+    }
   }
 
   /// Custom header for this view. This should look like a `NavigationView`'s
@@ -123,6 +131,7 @@
         )
         .fontWeight(.semibold)
         .lineLimit(1)
+        .accessibilityFocused($headerFocused)
         .accessibilityAddTraits(.isHeader)
       }
       .layoutPriority(1000)
diff --git a/ios/chrome/browser/ui/save_to_photos/save_to_photos_coordinator.mm b/ios/chrome/browser/ui/save_to_photos/save_to_photos_coordinator.mm
index e6d9bc3..019941a 100644
--- a/ios/chrome/browser/ui/save_to_photos/save_to_photos_coordinator.mm
+++ b/ios/chrome/browser/ui/save_to_photos/save_to_photos_coordinator.mm
@@ -100,13 +100,20 @@
 #pragma mark - SaveToPhotosMediatorDelegate
 
 - (void)showAccountPickerWithConfiguration:
-    (AccountPickerConfiguration*)configuration {
+            (AccountPickerConfiguration*)configuration
+                          selectedIdentity:
+                              (id<SystemIdentity>)selectedIdentity {
   _accountPickerCoordinator = [[AccountPickerCoordinator alloc]
       initWithBaseViewController:self.baseViewController
                          browser:self.browser
                    configuration:configuration];
   _accountPickerCoordinator.delegate = self;
   [_accountPickerCoordinator start];
+  if (selectedIdentity) {
+    // If the mediator does not want to override the selected identity, leave
+    // the one presented by default by the account picker.
+    _accountPickerCoordinator.selectedIdentity = selectedIdentity;
+  }
 }
 
 - (void)hideAccountPicker {
diff --git a/ios/chrome/browser/ui/save_to_photos/save_to_photos_coordinator_unittest.mm b/ios/chrome/browser/ui/save_to_photos/save_to_photos_coordinator_unittest.mm
index 49bf55d..cbf25d4 100644
--- a/ios/chrome/browser/ui/save_to_photos/save_to_photos_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/save_to_photos/save_to_photos_coordinator_unittest.mm
@@ -358,7 +358,8 @@
       mock_account_picker_coordinator) start]);
 
   [static_cast<id<SaveToPhotosMediatorDelegate>>(coordinator)
-      showAccountPickerWithConfiguration:expected_configuration];
+      showAccountPickerWithConfiguration:expected_configuration
+                        selectedIdentity:nil];
   EXPECT_OCMOCK_VERIFY(mock_account_picker_coordinator);
 
   OCMExpect([base::apple::ObjCCast<AccountPickerCoordinator>(
diff --git a/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator.mm b/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator.mm
index 3ccf66f..ba8a6619 100644
--- a/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator.mm
+++ b/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator.mm
@@ -140,12 +140,12 @@
       SaveToPhotosAccountPickerActions::kSelectedIdentity);
   [self.delegate hideAccountPicker];
 
-  // Memorize the account that was picked if the user does not want to be asked
-  // every time.
-  if (!askEveryTime) {
-    _prefService->SetString(prefs::kIosSaveToPhotosDefaultGaiaId,
-                            base::SysNSStringToUTF8(identity.gaiaID));
-  }
+  // Memorize the account that was picked and whether to ask which account to
+  // use every time.
+  _prefService->SetString(prefs::kIosSaveToPhotosDefaultGaiaId,
+                          base::SysNSStringToUTF8(identity.gaiaID));
+  _prefService->SetBoolean(prefs::kIosSaveToPhotosSkipAccountPicker,
+                           !askEveryTime);
 
   _identity = identity;
 }
@@ -208,10 +208,12 @@
       _prefService->GetString(prefs::kIosSaveToPhotosDefaultGaiaId);
   id<SystemIdentity> defaultIdentity =
       _accountManagerService->GetIdentityWithGaiaID(defaultGaiaId);
+  bool skipAccountPicker =
+      _prefService->GetBoolean(prefs::kIosSaveToPhotosSkipAccountPicker);
 
   // If the user has already selected a default account to save images to
-  // Photos, use that default.
-  if (defaultIdentity) {
+  // Photos and opted to skip the account picker, use that default.
+  if (skipAccountPicker && defaultIdentity) {
     _identity = defaultIdentity;
     base::UmaHistogramEnumeration(kSaveToPhotosAccountPickerActionsHistogram,
                                   SaveToPhotosAccountPickerActions::kSkipped);
@@ -220,8 +222,9 @@
   }
 
   // If the memorized account is not found on the device, unmemorize it.
-  if (!defaultGaiaId.empty()) {
+  if (skipAccountPicker) {
     _prefService->ClearPref(prefs::kIosSaveToPhotosDefaultGaiaId);
+    _prefService->ClearPref(prefs::kIosSaveToPhotosSkipAccountPicker);
   }
 
   // If no default account can be used, present the account picker instead.
@@ -238,7 +241,8 @@
       l10n_util::GetNSString(IDS_IOS_SAVE_TO_PHOTOS_ACCOUNT_PICKER_SUBMIT);
   configuration.askEveryTimeSwitchLabelText = l10n_util::GetNSString(
       IDS_IOS_SAVE_TO_PHOTOS_ACCOUNT_PICKER_ASK_EVERY_TIME);
-  [self.delegate showAccountPickerWithConfiguration:configuration];
+  [self.delegate showAccountPickerWithConfiguration:configuration
+                                   selectedIdentity:defaultIdentity];
 }
 
 // Once the destination account is known, tries to upload the image using the
diff --git a/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator_delegate.h b/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator_delegate.h
index d9c5447..72b476ad 100644
--- a/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator_delegate.h
+++ b/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator_delegate.h
@@ -15,9 +15,12 @@
 // Delegate for the Save to Photos mediator.
 @protocol SaveToPhotosMediatorDelegate
 
-// Show and hide the account picker.
+// Show and hide the account picker with a given configuration. If the
+// `selectedIdentity` is not nil, it will override the value presented by the
+// account picker by default.
 - (void)showAccountPickerWithConfiguration:
-    (AccountPickerConfiguration*)configuration;
+            (AccountPickerConfiguration*)configuration
+                          selectedIdentity:(id<SystemIdentity>)selectedIdentity;
 - (void)hideAccountPicker;
 
 // Show and hide an alert with "Try Again" and "Cancel" options.
diff --git a/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator_unittest.mm b/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator_unittest.mm
index 5052059e..6badb884 100644
--- a/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/save_to_photos/save_to_photos_mediator_unittest.mm
@@ -223,8 +223,9 @@
   SignIn();
 
   // This test assumes there is no default account memorized for Save to Photos.
-  browser_state_->GetPrefs()->SetString(prefs::kIosSaveToPhotosDefaultGaiaId,
-                                        "");
+  browser_state_->GetPrefs()->ClearPref(prefs::kIosSaveToPhotosDefaultGaiaId);
+  browser_state_->GetPrefs()->ClearPref(
+      prefs::kIosSaveToPhotosSkipAccountPicker);
 
   // Create a mediator and set up with mock delegate.
   SaveToPhotosMediator* mediator = CreateSaveToPhotosMediator();
@@ -256,7 +257,8 @@
         EXPECT_NSEQ(expected_ask_every_time_switch_label_text,
                     configuration.askEveryTimeSwitchLabelText);
         return YES;
-      }]]);
+      }]
+                        selectedIdentity:nil]);
 
   // Start the mediator and run until the image has been fetched and
   // processed by the mediator.
@@ -276,10 +278,13 @@
   // The feature requires the user being signed-in.
   SignIn();
 
-  // This test assumes there is no default account memorized for Save to Photos.
+  // This test assumes there is a default account memorized for Save to Photos
+  // and that the user opted-in skipping the account picker.
   browser_state_->GetPrefs()->SetString(
       prefs::kIosSaveToPhotosDefaultGaiaId,
       base::SysNSStringToUTF8(fake_identity_.gaiaID).c_str());
+  browser_state_->GetPrefs()->SetBoolean(
+      prefs::kIosSaveToPhotosSkipAccountPicker, true);
 
   // Create a mediator and set up with mock delegate.
   SaveToPhotosMediator* mediator = CreateSaveToPhotosMediator();
diff --git a/ios/chrome/browser/ui/settings/downloads/downloads_settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/downloads/downloads_settings_table_view_controller.mm
index c495a76..22bc55f 100644
--- a/ios/chrome/browser/ui/settings/downloads/downloads_settings_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/downloads/downloads_settings_table_view_controller.mm
@@ -154,13 +154,13 @@
 #pragma mark - Actions
 
 - (void)saveToPhotosAskEveryTimeSwitchAction:(UISwitch*)sender {
-  NSString* newSelectedIdentityGaiaID = nil;
-  if (!sender.isOn) {
-    newSelectedIdentityGaiaID =
-        self.saveToPhotosDefaultIdentityItem.identityGaiaID;
-  }
   [self.saveToPhotosSettingsMutator
-      setSelectedIdentityGaiaID:newSelectedIdentityGaiaID];
+      setAskWhichAccountToUseEveryTime:sender.isOn];
+  if (!sender.isOn) {
+    [self.saveToPhotosSettingsMutator
+        setSelectedIdentityGaiaID:self.saveToPhotosDefaultIdentityItem
+                                      .identityGaiaID];
+  }
 }
 
 - (void)saveToPhotosIdentityButtonAction:(IdentityButtonControl*)sender {
diff --git a/ios/chrome/browser/ui/settings/downloads/downloads_settings_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/downloads/downloads_settings_table_view_controller_unittest.mm
index c839dde..80d46c0 100644
--- a/ios/chrome/browser/ui/settings/downloads/downloads_settings_table_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/downloads/downloads_settings_table_view_controller_unittest.mm
@@ -133,8 +133,7 @@
   CheckSwitchCellStateAndTextWithId(
       YES, IDS_IOS_SAVE_TO_PHOTOS_ACCOUNT_PICKER_ASK_EVERY_TIME, 0, 1);
 
-  // Test that disabling and re-enabling the switch sets and erases the selected
-  // identity.
+  // Test that disabling and re-enabling the switch updates the mutator.
   EXPECT_FALSE(save_to_photos_mutator_.selectedIdentityGaiaID);
   TableViewSwitchCell* switchCell = base::apple::ObjCCast<TableViewSwitchCell>(
       [controller() tableView:controller().tableView
@@ -143,11 +142,11 @@
   switchCell.switchView.on = NO;
   [switchCell.switchView
       sendActionsForControlEvents:UIControlEventValueChanged];
-  EXPECT_NSEQ(@"mygaiaid", save_to_photos_mutator_.selectedIdentityGaiaID);
+  EXPECT_FALSE(save_to_photos_mutator_.askWhichAccountToUseEveryTime);
   switchCell.switchView.on = YES;
   [switchCell.switchView
       sendActionsForControlEvents:UIControlEventValueChanged];
-  EXPECT_FALSE(save_to_photos_mutator_.selectedIdentityGaiaID);
+  EXPECT_TRUE(save_to_photos_mutator_.askWhichAccountToUseEveryTime);
 
   // Test that tapping the Identity button calls the action delegate.
   EXPECT_FALSE(action_delegate_.selectSaveToPhotosAccountCalled);
diff --git a/ios/chrome/browser/ui/settings/downloads/save_to_photos/fake_save_to_photos_settings_mutator.h b/ios/chrome/browser/ui/settings/downloads/save_to_photos/fake_save_to_photos_settings_mutator.h
index b201bc2..4f7a0b5 100644
--- a/ios/chrome/browser/ui/settings/downloads/save_to_photos/fake_save_to_photos_settings_mutator.h
+++ b/ios/chrome/browser/ui/settings/downloads/save_to_photos/fake_save_to_photos_settings_mutator.h
@@ -13,6 +13,8 @@
 
 @property(nonatomic, copy) NSString* selectedIdentityGaiaID;
 
+@property(nonatomic, assign) BOOL askWhichAccountToUseEveryTime;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_SETTINGS_DOWNLOADS_SAVE_TO_PHOTOS_FAKE_SAVE_TO_PHOTOS_SETTINGS_MUTATOR_H_
diff --git a/ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_mediator.mm b/ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_mediator.mm
index c778a99..9713bd2 100644
--- a/ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_mediator.mm
+++ b/ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_mediator.mm
@@ -37,14 +37,6 @@
   signin::IdentityManager* _identityManager;
   std::unique_ptr<signin::IdentityManagerObserverBridge>
       _identityManagerObserver;
-
-  // Data for the identity presented as default. The data which is presented
-  // will only be updated if it has not been initialized or if there is an
-  // identity that is saved in preferences.
-  UIImage* _presentedIdentityAvatar;
-  NSString* _presentedIdentityGaiaID;
-  NSString* _presentedIdentityEmail;
-  NSString* _presentedIdentityName;
 }
 
 #pragma mark - Initialization
@@ -71,6 +63,8 @@
     _prefServiceObserver = std::make_unique<PrefObserverBridge>(self);
     _prefServiceObserver->ObserveChangesForPreference(
         prefs::kIosSaveToPhotosDefaultGaiaId, _prefChangeRegistrar.get());
+    _prefServiceObserver->ObserveChangesForPreference(
+        prefs::kIosSaveToPhotosSkipAccountPicker, _prefChangeRegistrar.get());
 
     _identityManager = identityManager;
     _identityManagerObserver =
@@ -110,12 +104,14 @@
 #pragma mark - SaveToPhotosSettingsMutator
 
 - (void)setSelectedIdentityGaiaID:(NSString*)gaiaID {
-  if (gaiaID == nil) {
-    _prefService->ClearPref(prefs::kIosSaveToPhotosDefaultGaiaId);
-  } else {
-    _prefService->SetString(prefs::kIosSaveToPhotosDefaultGaiaId,
-                            base::SysNSStringToUTF8(gaiaID).c_str());
-  }
+  CHECK(gaiaID);
+  _prefService->SetString(prefs::kIosSaveToPhotosDefaultGaiaId,
+                          base::SysNSStringToUTF8(gaiaID));
+}
+
+- (void)setAskWhichAccountToUseEveryTime:(BOOL)askEveryTime {
+  _prefService->SetBoolean(prefs::kIosSaveToPhotosSkipAccountPicker,
+                           !askEveryTime);
 }
 
 #pragma mark - ChromeAccountManagerServiceObserver
@@ -131,9 +127,6 @@
 #pragma mark - PrefObserverDelegate
 
 - (void)onPreferenceChanged:(const std::string&)preferenceName {
-  if (preferenceName != prefs::kIosSaveToPhotosDefaultGaiaId) {
-    return;
-  }
   [self updateConsumers];
 }
 
@@ -176,21 +169,16 @@
     return;
   }
 
-  BOOL askEveryTimeSwitchOn = savedIdentity == nil;
-  if (!_presentedIdentityGaiaID || !askEveryTimeSwitchOn) {
-    _presentedIdentityAvatar =
-        _accountManagerService->GetIdentityAvatarWithIdentity(
-            selectedIdentity, IdentityAvatarSize::TableViewIcon);
-    _presentedIdentityName = selectedIdentity.userFullName;
-    _presentedIdentityEmail = selectedIdentity.userEmail;
-    _presentedIdentityGaiaID = selectedIdentity.gaiaID;
-  }
-
+  BOOL askEveryTimeSwitchOn =
+      !_prefService->GetBoolean(prefs::kIosSaveToPhotosSkipAccountPicker);
   [self.accountConfirmationConsumer
-      setIdentityButtonAvatar:_presentedIdentityAvatar
-                         name:_presentedIdentityName
-                        email:_presentedIdentityEmail
-                       gaiaID:_presentedIdentityGaiaID
+      setIdentityButtonAvatar:_accountManagerService
+                                  ->GetIdentityAvatarWithIdentity(
+                                      selectedIdentity,
+                                      IdentityAvatarSize::TableViewIcon)
+                         name:selectedIdentity.userFullName
+                        email:selectedIdentity.userEmail
+                       gaiaID:selectedIdentity.gaiaID
          askEveryTimeSwitchOn:askEveryTimeSwitchOn];
 
   // Update secondary consumer with the list of accounts on the device and which
@@ -208,7 +196,7 @@
     configurator.avatar = _accountManagerService->GetIdentityAvatarWithIdentity(
         systemIdentity, IdentityAvatarSize::TableViewIcon);
     configurator.selected =
-        [systemIdentity.gaiaID isEqual:savedIdentity.gaiaID];
+        [systemIdentity.gaiaID isEqual:selectedIdentity.gaiaID];
     [identityItemConfigurators addObject:configurator];
   }
   [self.accountSelectionConsumer
diff --git a/ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_mediator_unittest.mm b/ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_mediator_unittest.mm
index ed150912..00df686 100644
--- a/ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_mediator_unittest.mm
@@ -135,21 +135,16 @@
   // `askEveryTimeSwitchOn` or `identityEnabled` in `fake_consumer`.
   void CheckFakeConsumerIdentities(
       FakeSaveToPhotosSettingsConsumer* fake_consumer,
-      id<SystemIdentity> expected_presented_identity,
-      bool presented_identity_is_selected) {
-    UIImage* expected_presented_identity_avatar =
+      id<SystemIdentity> saved_identity) {
+    UIImage* saved_identity_avatar =
         GetAccountManagerService()->GetIdentityAvatarWithIdentity(
-            expected_presented_identity, IdentityAvatarSize::TableViewIcon);
+            saved_identity, IdentityAvatarSize::TableViewIcon);
 
     // Test that the presented identity is the expected one.
-    EXPECT_NSEQ(expected_presented_identity_avatar,
-                fake_consumer.identityAvatar);
-    EXPECT_NSEQ(expected_presented_identity.userFullName,
-                fake_consumer.identityName);
-    EXPECT_NSEQ(expected_presented_identity.userEmail,
-                fake_consumer.identityEmail);
-    EXPECT_NSEQ(expected_presented_identity.gaiaID,
-                fake_consumer.identityGaiaID);
+    EXPECT_NSEQ(saved_identity_avatar, fake_consumer.identityAvatar);
+    EXPECT_NSEQ(saved_identity.userFullName, fake_consumer.identityName);
+    EXPECT_NSEQ(saved_identity.userEmail, fake_consumer.identityEmail);
+    EXPECT_NSEQ(saved_identity.gaiaID, fake_consumer.identityGaiaID);
 
     // Tests that if there is at least an element, it matches `fake_identity_a_`
     // and is selected if its GAIA ID matches that of the expected selected
@@ -167,8 +162,7 @@
       EXPECT_NSEQ(fake_identity_a_avatar,
                   fake_consumer.identityConfigurators[0].avatar);
       EXPECT_EQ([fake_consumer.identityConfigurators[0].gaiaID
-                    isEqual:expected_presented_identity.gaiaID] &&
-                    presented_identity_is_selected,
+                    isEqual:saved_identity.gaiaID],
                 fake_consumer.identityConfigurators[0].selected);
     }
 
@@ -187,9 +181,8 @@
                   fake_consumer.identityConfigurators[1].email);
       EXPECT_NSEQ(fake_identity_b_avatar,
                   fake_consumer.identityConfigurators[1].avatar);
-      EXPECT_EQ([fake_identity_b_.gaiaID
-                    isEqual:expected_presented_identity.gaiaID] &&
-                    presented_identity_is_selected,
+      EXPECT_EQ([fake_consumer.identityConfigurators[1].gaiaID
+                    isEqual:saved_identity.gaiaID],
                 fake_consumer.identityConfigurators[1].selected);
     }
   }
@@ -208,7 +201,9 @@
 
   browser_state_->GetPrefs()->SetString(
       prefs::kIosSaveToPhotosDefaultGaiaId,
-      base::SysNSStringToUTF8(fake_identity_a_.gaiaID).c_str());
+      base::SysNSStringToUTF8(fake_identity_a_.gaiaID));
+  browser_state_->GetPrefs()->SetBoolean(
+      prefs::kIosSaveToPhotosSkipAccountPicker, true);
 
   FakeSaveToPhotosSettingsConsumer* fake_consumer =
       [[FakeSaveToPhotosSettingsConsumer alloc] init];
@@ -219,10 +214,15 @@
   EXPECT_EQ(base::SysNSStringToUTF8(fake_identity_b_.gaiaID),
             browser_state_->GetPrefs()->GetString(
                 prefs::kIosSaveToPhotosDefaultGaiaId));
+  EXPECT_TRUE(browser_state_->GetPrefs()->GetBoolean(
+      prefs::kIosSaveToPhotosSkipAccountPicker));
 
-  [mediator setSelectedIdentityGaiaID:nil];
-  EXPECT_EQ("", browser_state_->GetPrefs()->GetString(
-                    prefs::kIosSaveToPhotosDefaultGaiaId));
+  [mediator setAskWhichAccountToUseEveryTime:YES];
+  EXPECT_EQ(base::SysNSStringToUTF8(fake_identity_b_.gaiaID),
+            browser_state_->GetPrefs()->GetString(
+                prefs::kIosSaveToPhotosDefaultGaiaId));
+  EXPECT_FALSE(browser_state_->GetPrefs()->GetBoolean(
+      prefs::kIosSaveToPhotosSkipAccountPicker));
 
   [mediator disconnect];
 }
@@ -234,26 +234,27 @@
 
   browser_state_->GetPrefs()->SetString(
       prefs::kIosSaveToPhotosDefaultGaiaId,
-      base::SysNSStringToUTF8(fake_identity_a_.gaiaID).c_str());
+      base::SysNSStringToUTF8(fake_identity_a_.gaiaID));
+  browser_state_->GetPrefs()->SetBoolean(
+      prefs::kIosSaveToPhotosSkipAccountPicker, true);
 
   FakeSaveToPhotosSettingsConsumer* fake_consumer =
       [[FakeSaveToPhotosSettingsConsumer alloc] init];
   mediator.accountConfirmationConsumer = fake_consumer;
   mediator.accountSelectionConsumer = fake_consumer;
 
-  CheckFakeConsumerIdentities(fake_consumer, fake_identity_a_, true);
+  CheckFakeConsumerIdentities(fake_consumer, fake_identity_a_);
   EXPECT_FALSE(fake_consumer.askEveryTimeSwitchOn);
 
   browser_state_->GetPrefs()->SetString(
       prefs::kIosSaveToPhotosDefaultGaiaId,
-      base::SysNSStringToUTF8(fake_identity_b_.gaiaID).c_str());
-  CheckFakeConsumerIdentities(fake_consumer, fake_identity_b_, true);
+      base::SysNSStringToUTF8(fake_identity_b_.gaiaID));
+  CheckFakeConsumerIdentities(fake_consumer, fake_identity_b_);
   EXPECT_FALSE(fake_consumer.askEveryTimeSwitchOn);
 
-  // The mediator should only push different identity data if the preference is
-  // not cleared.
-  browser_state_->GetPrefs()->ClearPref(prefs::kIosSaveToPhotosDefaultGaiaId);
-  CheckFakeConsumerIdentities(fake_consumer, fake_identity_b_, false);
+  browser_state_->GetPrefs()->ClearPref(
+      prefs::kIosSaveToPhotosSkipAccountPicker);
+  CheckFakeConsumerIdentities(fake_consumer, fake_identity_b_);
   EXPECT_TRUE(fake_consumer.askEveryTimeSwitchOn);
 
   [mediator disconnect];
@@ -267,27 +268,29 @@
 
   browser_state_->GetPrefs()->SetString(
       prefs::kIosSaveToPhotosDefaultGaiaId,
-      base::SysNSStringToUTF8(fake_identity_a_.gaiaID).c_str());
+      base::SysNSStringToUTF8(fake_identity_a_.gaiaID));
+  browser_state_->GetPrefs()->SetBoolean(
+      prefs::kIosSaveToPhotosSkipAccountPicker, true);
 
   FakeSaveToPhotosSettingsConsumer* fake_consumer =
       [[FakeSaveToPhotosSettingsConsumer alloc] init];
   mediator.accountConfirmationConsumer = fake_consumer;
   mediator.accountSelectionConsumer = fake_consumer;
 
-  CheckFakeConsumerIdentities(fake_consumer, fake_identity_a_, true);
+  CheckFakeConsumerIdentities(fake_consumer, fake_identity_a_);
   EXPECT_FALSE(fake_consumer.askEveryTimeSwitchOn);
 
   FakeSystemIdentityManager* system_identity_manager =
       FakeSystemIdentityManager::FromSystemIdentityManager(
           GetApplicationContext()->GetSystemIdentityManager());
   system_identity_manager->ForgetIdentityFromOtherApplication(fake_identity_b_);
-  CheckFakeConsumerIdentities(fake_consumer, fake_identity_a_, true);
+  CheckFakeConsumerIdentities(fake_consumer, fake_identity_a_);
   EXPECT_FALSE(fake_consumer.askEveryTimeSwitchOn);
   EXPECT_EQ(1U, fake_consumer.identityConfigurators.count);
 
   fake_identity_b_ = [FakeSystemIdentity fakeIdentity3];
   system_identity_manager->AddIdentity(fake_identity_b_);
-  CheckFakeConsumerIdentities(fake_consumer, fake_identity_a_, true);
+  CheckFakeConsumerIdentities(fake_consumer, fake_identity_a_);
   EXPECT_FALSE(fake_consumer.askEveryTimeSwitchOn);
   EXPECT_EQ(2U, fake_consumer.identityConfigurators.count);
 
diff --git a/ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_mutator.h b/ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_mutator.h
index 21fb312f..7c75930b 100644
--- a/ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_mutator.h
+++ b/ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_mutator.h
@@ -10,10 +10,13 @@
 @protocol SaveToPhotosSettingsMutator <NSObject>
 
 // Save `gaiaID` to preferences to use the associated identity as a default to
-// save images to Google Photos. If `gaiaID` is nil, then the default identity
-// will be cleared from preferences.
+// save images to Google Photos.
 - (void)setSelectedIdentityGaiaID:(NSString*)gaiaID;
 
+// Opt-in to use the account picker to choose which account to use every time
+// the user saves an image to Google Photos.
+- (void)setAskWhichAccountToUseEveryTime:(BOOL)askWhichAccountToUseEveryTime;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_SETTINGS_DOWNLOADS_SAVE_TO_PHOTOS_SAVE_TO_PHOTOS_SETTINGS_MUTATOR_H_
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_command_handler.h b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_command_handler.h
index 485878c0..4a3b25b 100644
--- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_command_handler.h
+++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_command_handler.h
@@ -15,9 +15,12 @@
 // Opens the "Data from Chrome sync" web page.
 - (void)openDataFromChromeSyncWebPage;
 
-// Presents the data options available when turning off Sync.
-// `targetRect` rect in table view system coordinate to display the signout
-// popover dialog.
+// If the sync feature is disabled, sign-out and display a toast.
+// Otherwise, if the sync feature is enabled, presents the data options
+// available when turning off Sync. `targetRect` rect in table view system
+// coordinate to display the signout popover dialog.
+// When `kReplaceSyncPromosWithSignInPromos` will be removed, the sync feature
+// won't be enabled anymore.
 - (void)signOutFromTargetRect:(CGRect)targetRect;
 
 // Shows a dialog to warn users that addresses are not encrypted by custom
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_menu_item.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_menu_item.h
index f98a42f..b2a9fc5 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_menu_item.h
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_menu_item.h
@@ -7,6 +7,9 @@
 
 #import <UIKit/UIKit.h>
 
+// TODO(crbug.com/1489457): Delete this file when cleaning up deprecation for
+// iOS 15.
+#if !defined(__IPHONE_16_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_16_0
 // Menu item which holds item type. Possible types `website`, `username` or
 // `password`.
 @interface PasswordDetailsMenuItem : UIMenuItem
@@ -15,4 +18,6 @@
 
 @end
 
+#endif
+
 #endif  // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_DETAILS_PASSWORD_DETAILS_MENU_ITEM_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_menu_item.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_menu_item.mm
index 4b15991..691f513 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_menu_item.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_menu_item.mm
@@ -4,6 +4,10 @@
 
 #import "ios/chrome/browser/ui/settings/password/password_details/password_details_menu_item.h"
 
+#if !defined(__IPHONE_16_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_16_0
+
 @implementation PasswordDetailsMenuItem
 
 @end
+
+#endif
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.h b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.h
index 77595d4..a46a333e 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.h
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.h
@@ -18,7 +18,8 @@
 // Screen which shows password details and allows to edit it.
 @interface PasswordDetailsTableViewController
     : AutofillEditTableViewController <PasswordDetailsConsumer,
-                                       SettingsControllerProtocol>
+                                       SettingsControllerProtocol,
+                                       UIEditMenuInteractionDelegate>
 
 // The designated initializer.
 - (instancetype)init;
diff --git a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
index e36946f..2c1308c 100644
--- a/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/password/password_details/password_details_table_view_controller.mm
@@ -189,6 +189,13 @@
 @property(nonatomic, strong)
     NSMutableSet<NSString*>* usernamesWithMoveToAccountOfferRecorded;
 
+// Used to create and show the actions users can execute when they tap on a row
+// in the tableView. These actions are displayed a pop-up.
+// TODO(crbug.com/1489457): Remove available guard when min deployment target is
+// bumped to iOS 16.0.
+@property(nonatomic, strong)
+    UIEditMenuInteraction* interactionMenu API_AVAILABLE(ios(16));
+
 @end
 
 @implementation PasswordDetailsTableViewController
@@ -220,6 +227,12 @@
   self.tableView.accessibilityIdentifier = kPasswordDetailsViewControllerId;
   self.tableView.allowsSelectionDuringEditing = YES;
 
+  if (base::FeatureList::IsEnabled(kEnableUIEditMenuInteraction)) {
+    if (@available(iOS 16.0, *)) {
+      _interactionMenu = [[UIEditMenuInteraction alloc] initWithDelegate:self];
+      [self.tableView addInteraction:self.interactionMenu];
+    }
+  }
   [self setOrExtendAuthValidityTimer];
 }
 
@@ -625,15 +638,31 @@
 - (void)ensureContextMenuShownForItemType:(NSInteger)itemType
                                 tableView:(UITableView*)tableView
                               atIndexPath:(NSIndexPath*)indexPath {
-  // TODO(crbug.com/1481223): Replace UIMenuController with
-  // UIEditMenuInteraction in iOS 16+.
-  UIMenuController* menu = [UIMenuController sharedMenuController];
-  if (![menu isMenuVisible]) {
-    menu.menuItems = [self menuItemsForItemType:itemType];
-
-    [menu showMenuFromView:tableView
-                      rect:[tableView rectForRowAtIndexPath:indexPath]];
+  if (base::FeatureList::IsEnabled(kEnableUIEditMenuInteraction) &&
+      base::ios::IsRunningOnIOS16OrLater()) {
+    if (@available(iOS 16.0, *)) {
+      CGRect row = [tableView rectForRowAtIndexPath:indexPath];
+      CGPoint editMenuLocation =
+          CGPointMake(row.origin.x + row.size.width / 2, row.origin.y);
+      UIEditMenuConfiguration* configuration = [UIEditMenuConfiguration
+          configurationWithIdentifier:[NSNumber numberWithInt:itemType]
+                          sourcePoint:editMenuLocation];
+      [self.interactionMenu presentEditMenuWithConfiguration:configuration];
+    }
   }
+#if !defined(__IPHONE_16_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_16_0
+  else {
+    // TODO(crbug.com/1481223): Replace UIMenuController with
+    // UIEditMenuInteraction in iOS 16+.
+    UIMenuController* menu = [UIMenuController sharedMenuController];
+    if (![menu isMenuVisible]) {
+      menu.menuItems = [self menuItemsForItemType:itemType];
+
+      [menu showMenuFromView:tableView
+                        rect:[tableView rectForRowAtIndexPath:indexPath]];
+    }
+  }
+#endif
 }
 
 - (BOOL)tableView:(UITableView*)tableView
@@ -1268,6 +1297,31 @@
   }
 }
 
+#pragma mark - UIEditMenuInteractionDelegate
+
+// TODO(crbug.com/1489457): Remove available guard when min deployment target is
+// bumped to iOS 16.0.
+- (UIMenu*)editMenuInteraction:(UIEditMenuInteraction*)interaction
+          menuForConfiguration:(UIEditMenuConfiguration*)configuration
+              suggestedActions:(NSArray<UIMenuElement*>*)suggestedActions
+    API_AVAILABLE(ios(16)) {
+  UIAction* copy = [UIAction
+      actionWithTitle:l10n_util::GetNSString(
+                          IDS_IOS_SETTINGS_SITE_COPY_MENU_ITEM)
+                image:nil
+           identifier:nil
+              handler:^(__kindof UIAction* _Nonnull action) {
+                base::RecordAction(
+                    base::UserMetricsAction("MobilePasswordDetailsCopy"));
+
+                [self setOrExtendAuthValidityTimer];
+                NSUInteger itemType = [base::apple::ObjCCastStrict<NSNumber>(
+                    configuration.identifier) intValue];
+                [self copyPasswordDetailsHelper:itemType];
+              }];
+  return [UIMenu menuWithChildren:@[ copy ]];
+}
+
 #pragma mark - Actions
 
 // Called when the user tapped on the show/hide button near password.
@@ -1326,6 +1380,8 @@
   [self presentViewController:errorInfoPopover animated:YES completion:nil];
 }
 
+#if !defined(__IPHONE_16_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_16_0
+
 // Returns an array of UIMenuItems to display in a context menu on the site
 // cell.
 - (NSArray*)menuItemsForItemType:(NSInteger)itemType {
@@ -1348,9 +1404,17 @@
       base::apple::ObjCCastStrict<PasswordDetailsMenuItem>(
           menu.menuItems.firstObject);
 
+  [self copyPasswordDetailsHelper:menuItem.itemType];
+}
+
+#endif
+
+// A helper function that copies the password information to system pasteboard
+// and shows a toast of success/failure.
+- (void)copyPasswordDetailsHelper:(NSInteger)itemType {
   NSString* message = nil;
 
-  switch (menuItem.itemType) {
+  switch (itemType) {
     case PasswordDetailsItemTypeWebsite: {
       PasswordDetails* detailsToCopy;
       detailsToCopy =
diff --git a/ios_internal b/ios_internal
index b78bef8..d40d38d 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit b78bef8066637f477844e27db169a452d4934d5f
+Subproject commit d40d38dc60efd0a1af6d8ed0f6076a44cabe7d95
diff --git a/media/base/android/media_drm_bridge_unittest.cc b/media/base/android/media_drm_bridge_unittest.cc
index 9ef93c0..0d1e7c58 100644
--- a/media/base/android/media_drm_bridge_unittest.cc
+++ b/media/base/android/media_drm_bridge_unittest.cc
@@ -213,8 +213,7 @@
                                       kExternalClearKeyKeySystem);
 }
 
-// See https://crbug.com/1370782.
-TEST_F(MediaDrmBridgeTest, DISABLED_Provision_Widevine) {
+TEST_F(MediaDrmBridgeTest, Provision_Widevine) {
   // Only test this if Widevine is supported. Otherwise
   // CreateWithoutSessionSupport() will return null and it can't be tested.
   if (!MediaDrmBridge::IsKeySystemSupported(kWidevineKeySystem)) {
diff --git a/media/base/mac/color_space_util_mac.mm b/media/base/mac/color_space_util_mac.mm
index 8bc8179..c6632fd1 100644
--- a/media/base/mac/color_space_util_mac.mm
+++ b/media/base/mac/color_space_util_mac.mm
@@ -14,258 +14,10 @@
 #include "base/memory/scoped_policy.h"
 #include "base/no_destructor.h"
 #include "third_party/skia/modules/skcms/skcms.h"
+#include "ui/gfx/mac/color_space_util.h"
 
 namespace media {
 
-namespace {
-
-// Read the value for the key in |key| to CFString and convert it to IdType.
-// Use the list of pairs in |cfstr_id_pairs| to do the conversion (by doing a
-// linear lookup).
-template <typename IdType, typename StringIdPair>
-bool GetImageBufferProperty(CFTypeRef value_untyped,
-                            const std::vector<StringIdPair>& cfstr_id_pairs,
-                            IdType* value_as_id) {
-  CFStringRef value_as_string = base::apple::CFCast<CFStringRef>(value_untyped);
-  if (!value_as_string)
-    return false;
-
-  for (const auto& p : cfstr_id_pairs) {
-    if (p.cfstr_cm)
-      DCHECK(!CFStringCompare(p.cfstr_cv, p.cfstr_cm, 0));
-    if (!CFStringCompare(value_as_string, p.cfstr_cv, 0)) {
-      *value_as_id = p.id;
-      return true;
-    }
-  }
-
-  return false;
-}
-
-struct CVImagePrimary {
-  const CFStringRef cfstr_cv;
-  const CFStringRef cfstr_cm;
-  const gfx::ColorSpace::PrimaryID id;
-};
-const std::vector<CVImagePrimary>& GetSupportedImagePrimaries() {
-  static const base::NoDestructor<std::vector<CVImagePrimary>>
-      kSupportedPrimaries([] {
-        std::vector<CVImagePrimary> supported_primaries;
-        supported_primaries.push_back(
-            {kCVImageBufferColorPrimaries_ITU_R_709_2,
-             kCMFormatDescriptionColorPrimaries_ITU_R_709_2,
-             gfx::ColorSpace::PrimaryID::BT709});
-        supported_primaries.push_back(
-            {kCVImageBufferColorPrimaries_EBU_3213,
-             kCMFormatDescriptionColorPrimaries_EBU_3213,
-             gfx::ColorSpace::PrimaryID::BT470BG});
-        supported_primaries.push_back(
-            {kCVImageBufferColorPrimaries_SMPTE_C,
-             kCMFormatDescriptionColorPrimaries_SMPTE_C,
-             gfx::ColorSpace::PrimaryID::SMPTE170M});
-        supported_primaries.push_back(
-            {kCVImageBufferColorPrimaries_ITU_R_2020,
-             kCMFormatDescriptionColorPrimaries_ITU_R_2020,
-             gfx::ColorSpace::PrimaryID::BT2020});
-        supported_primaries.push_back(
-            {kCVImageBufferColorPrimaries_DCI_P3,
-             kCMFormatDescriptionColorPrimaries_DCI_P3,
-             gfx::ColorSpace::PrimaryID::SMPTEST431_2});
-        supported_primaries.push_back(
-            {kCVImageBufferColorPrimaries_P3_D65,
-             kCMFormatDescriptionColorPrimaries_P3_D65,
-             gfx::ColorSpace::PrimaryID::P3});
-        return supported_primaries;
-      }());
-  return *kSupportedPrimaries;
-}
-
-gfx::ColorSpace::PrimaryID GetCoreVideoPrimary(CFTypeRef primaries_untyped) {
-  auto primary_id = gfx::ColorSpace::PrimaryID::INVALID;
-  if (!GetImageBufferProperty(primaries_untyped, GetSupportedImagePrimaries(),
-                              &primary_id)) {
-    DLOG(ERROR) << "Failed to find CVImageBufferRef primaries: "
-                << primaries_untyped;
-  }
-  return primary_id;
-}
-
-struct CVImageTransferFn {
-  const CFStringRef cfstr_cv;
-  const CFStringRef cfstr_cm;
-  const gfx::ColorSpace::TransferID id;
-};
-const std::vector<CVImageTransferFn>& GetSupportedImageTransferFn() {
-  static const base::NoDestructor<std::vector<CVImageTransferFn>>
-      kSupportedTransferFuncs([] {
-        std::vector<CVImageTransferFn> supported_transfer_funcs;
-        supported_transfer_funcs.push_back(
-            {kCVImageBufferTransferFunction_ITU_R_709_2,
-             kCMFormatDescriptionTransferFunction_ITU_R_709_2,
-             gfx::ColorSpace::TransferID::BT709_APPLE});
-        supported_transfer_funcs.push_back(
-            {kCVImageBufferTransferFunction_ITU_R_709_2,
-             kCMFormatDescriptionTransferFunction_ITU_R_709_2,
-             gfx::ColorSpace::TransferID::BT709});
-        supported_transfer_funcs.push_back(
-            {kCVImageBufferTransferFunction_ITU_R_709_2,
-             kCMFormatDescriptionTransferFunction_ITU_R_709_2,
-             gfx::ColorSpace::TransferID::SMPTE170M});
-        supported_transfer_funcs.push_back(
-            {kCVImageBufferTransferFunction_SMPTE_240M_1995,
-             kCMFormatDescriptionTransferFunction_SMPTE_240M_1995,
-             gfx::ColorSpace::TransferID::SMPTE240M});
-        supported_transfer_funcs.push_back(
-            {kCVImageBufferTransferFunction_UseGamma,
-             kCMFormatDescriptionTransferFunction_UseGamma,
-             gfx::ColorSpace::TransferID::CUSTOM});
-        supported_transfer_funcs.push_back(
-            {kCVImageBufferTransferFunction_ITU_R_2020,
-             kCMFormatDescriptionTransferFunction_ITU_R_2020,
-             gfx::ColorSpace::TransferID::BT2020_10});
-        supported_transfer_funcs.push_back(
-            {kCVImageBufferTransferFunction_SMPTE_ST_428_1,
-             kCMFormatDescriptionTransferFunction_SMPTE_ST_428_1,
-             gfx::ColorSpace::TransferID::SMPTEST428_1});
-        supported_transfer_funcs.push_back(
-            {kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ,
-             kCMFormatDescriptionTransferFunction_SMPTE_ST_2084_PQ,
-             gfx::ColorSpace::TransferID::PQ});
-        supported_transfer_funcs.push_back(
-            {kCVImageBufferTransferFunction_ITU_R_2100_HLG,
-             kCMFormatDescriptionTransferFunction_ITU_R_2100_HLG,
-             gfx::ColorSpace::TransferID::HLG});
-        supported_transfer_funcs.push_back({kCVImageBufferTransferFunction_sRGB,
-                                            nullptr,
-                                            gfx::ColorSpace::TransferID::SRGB});
-        supported_transfer_funcs.push_back(
-            {kCVImageBufferTransferFunction_Linear,
-             kCMFormatDescriptionTransferFunction_Linear,
-             gfx::ColorSpace::TransferID::LINEAR});
-        supported_transfer_funcs.push_back(
-            {kCVImageBufferTransferFunction_sRGB,
-             kCMFormatDescriptionTransferFunction_sRGB,
-             gfx::ColorSpace::TransferID::SRGB});
-
-        return supported_transfer_funcs;
-      }());
-  return *kSupportedTransferFuncs;
-}
-
-gfx::ColorSpace::TransferID GetCoreVideoTransferFn(CFTypeRef transfer_untyped,
-                                                   CFTypeRef gamma_untyped,
-                                                   double* gamma) {
-  // The named transfer function.
-  auto transfer_id = gfx::ColorSpace::TransferID::INVALID;
-  if (!GetImageBufferProperty(transfer_untyped, GetSupportedImageTransferFn(),
-                              &transfer_id)) {
-    DLOG(ERROR) << "Failed to find CVImageBufferRef transfer: "
-                << transfer_untyped;
-  }
-
-  if (transfer_id != gfx::ColorSpace::TransferID::CUSTOM)
-    return transfer_id;
-
-  CFNumberRef gamma_number = base::apple::CFCast<CFNumberRef>(gamma_untyped);
-  if (!gamma_number) {
-    DLOG(ERROR) << "Failed to get gamma level.";
-    return gfx::ColorSpace::TransferID::INVALID;
-  }
-
-  // CGFloat is a double on 64-bit systems.
-  CGFloat gamma_double = 0;
-  if (!CFNumberGetValue(gamma_number, kCFNumberCGFloatType, &gamma_double)) {
-    DLOG(ERROR) << "Failed to get CVImageBufferRef gamma level as float.";
-    return gfx::ColorSpace::TransferID::INVALID;
-  }
-
-  if (gamma_double == 2.2)
-    return gfx::ColorSpace::TransferID::GAMMA22;
-  if (gamma_double == 2.8)
-    return gfx::ColorSpace::TransferID::GAMMA28;
-
-  *gamma = gamma_double;
-  return transfer_id;
-}
-
-struct CVImageMatrix {
-  const CFStringRef cfstr_cv;
-  const CFStringRef cfstr_cm;
-  gfx::ColorSpace::MatrixID id;
-};
-const std::vector<CVImageMatrix>& GetSupportedImageMatrix() {
-  static const base::NoDestructor<std::vector<CVImageMatrix>>
-      kSupportedMatrices([] {
-        std::vector<CVImageMatrix> supported_matrices;
-        supported_matrices.push_back(
-            {kCVImageBufferYCbCrMatrix_ITU_R_709_2,
-             kCMFormatDescriptionYCbCrMatrix_ITU_R_709_2,
-             gfx::ColorSpace::MatrixID::BT709});
-        supported_matrices.push_back(
-            {kCVImageBufferYCbCrMatrix_ITU_R_601_4,
-             kCMFormatDescriptionYCbCrMatrix_ITU_R_601_4,
-             gfx::ColorSpace::MatrixID::SMPTE170M});
-        supported_matrices.push_back(
-            {kCVImageBufferYCbCrMatrix_SMPTE_240M_1995,
-             kCMFormatDescriptionYCbCrMatrix_SMPTE_240M_1995,
-             gfx::ColorSpace::MatrixID::SMPTE240M});
-        supported_matrices.push_back(
-            {kCVImageBufferYCbCrMatrix_ITU_R_2020,
-             kCMFormatDescriptionYCbCrMatrix_ITU_R_2020,
-             gfx::ColorSpace::MatrixID::BT2020_NCL});
-        return supported_matrices;
-      }());
-  return *kSupportedMatrices;
-}
-
-gfx::ColorSpace::MatrixID GetCoreVideoMatrix(CFTypeRef matrix_untyped) {
-  auto matrix_id = gfx::ColorSpace::MatrixID::INVALID;
-  if (!GetImageBufferProperty(matrix_untyped, GetSupportedImageMatrix(),
-                              &matrix_id)) {
-    DLOG(ERROR) << "Failed to find CVImageBufferRef YUV matrix: "
-                << matrix_untyped;
-  }
-  return matrix_id;
-}
-
-gfx::ColorSpace GetCoreVideoColorSpaceInternal(CFTypeRef primaries_untyped,
-                                               CFTypeRef transfer_untyped,
-                                               CFTypeRef gamma_untyped,
-                                               CFTypeRef matrix_untyped) {
-  double gamma;
-  auto primary_id = GetCoreVideoPrimary(primaries_untyped);
-  auto matrix_id = GetCoreVideoMatrix(matrix_untyped);
-  auto transfer_id =
-      GetCoreVideoTransferFn(transfer_untyped, gamma_untyped, &gamma);
-
-  if (primary_id == gfx::ColorSpace::PrimaryID::INVALID ||
-      matrix_id == gfx::ColorSpace::MatrixID::INVALID ||
-      transfer_id == gfx::ColorSpace::TransferID::INVALID) {
-    return gfx::ColorSpace();
-  }
-
-  // It is specified to the decoder to use luma=[16,235] chroma=[16,240] via
-  // the kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange.
-  //
-  // TODO(crbug.com/1103432): We'll probably need support for more than limited
-  // range content if we want this to be used for more than video sites.
-  auto range_id = gfx::ColorSpace::RangeID::LIMITED;
-
-  if (transfer_id == gfx::ColorSpace::TransferID::CUSTOM) {
-    // Transfer functions can also be specified as a gamma value.
-    skcms_TransferFunction custom_tr_fn = {2.2f, 1, 0, 1, 0, 0, 0};
-    if (transfer_id == gfx::ColorSpace::TransferID::CUSTOM)
-      custom_tr_fn.g = gamma;
-
-    return gfx::ColorSpace(primary_id, gfx::ColorSpace::TransferID::CUSTOM,
-                           matrix_id, range_id, nullptr, &custom_tr_fn);
-  }
-
-  return gfx::ColorSpace(primary_id, transfer_id, matrix_id, range_id);
-}
-
-}  // anonymous namespace
-
 gfx::ColorSpace GetImageBufferColorSpace(CVImageBufferRef image_buffer) {
   base::apple::ScopedCFTypeRef<CFTypeRef> color_primaries;
   base::apple::ScopedCFTypeRef<CFTypeRef> transfer_function;
@@ -300,14 +52,14 @@
 #endif
   }
 
-  return GetCoreVideoColorSpaceInternal(color_primaries.get(),
-                                        transfer_function.get(),
-                                        gamma_level.get(), ycbcr_matrix.get());
+  return gfx::ColorSpaceFromCVImageBufferKeys(
+      color_primaries.get(), transfer_function.get(), gamma_level.get(),
+      ycbcr_matrix.get());
 }
 
 gfx::ColorSpace GetFormatDescriptionColorSpace(
     CMFormatDescriptionRef format_description) {
-  return GetCoreVideoColorSpaceInternal(
+  return gfx::ColorSpaceFromCVImageBufferKeys(
       CMFormatDescriptionGetExtension(
           format_description, kCMFormatDescriptionExtension_ColorPrimaries),
       CMFormatDescriptionGetExtension(
@@ -323,38 +75,9 @@
                                CFStringRef* out_primaries,
                                CFStringRef* out_transfer,
                                CFStringRef* out_matrix) {
-  DCHECK(out_primaries);
-  DCHECK(out_transfer);
-  DCHECK(out_matrix);
-
-  bool found_primary = false;
-  for (const auto& primaries : GetSupportedImagePrimaries()) {
-    if (primaries.id == color_space.GetPrimaryID()) {
-      *out_primaries = primaries.cfstr_cv;
-      found_primary = true;
-      break;
-    }
-  }
-
-  bool found_transfer = false;
-  for (const auto& transfer : GetSupportedImageTransferFn()) {
-    if (transfer.id == color_space.GetTransferID()) {
-      *out_transfer = transfer.cfstr_cv;
-      found_transfer = true;
-      break;
-    }
-  }
-
-  bool found_matrix = false;
-  for (const auto& matrix : GetSupportedImageMatrix()) {
-    if (matrix.id == color_space.GetMatrixID()) {
-      *out_matrix = matrix.cfstr_cv;
-      found_matrix = true;
-      break;
-    }
-  }
-
-  return found_primary && found_transfer && found_matrix;
+  return gfx::ColorSpaceToCVImageBufferKeys(
+      color_space,
+      /*prefer_srgb_trfn=*/false, out_primaries, out_transfer, out_matrix);
 }
 
 }  // namespace media
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index 7ac8d55..3c3b13f 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -761,11 +761,6 @@
              "UseMediaHistoryStore",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// Use R16 texture for 9-16 bit channel instead of half-float conversion by CPU.
-BASE_FEATURE(kUseR16Texture,
-             "use-r16-texture",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 // Enables the Unified Autoplay policy by overriding the platform's default
 // autoplay policy.
 BASE_FEATURE(kUnifiedAutoplay,
diff --git a/media/base/media_switches.h b/media/base/media_switches.h
index 4c45308..3f8754f2 100644
--- a/media/base/media_switches.h
+++ b/media/base/media_switches.h
@@ -319,7 +319,6 @@
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseElementInsteadOfRegionCapture);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseFakeDeviceForMediaStream);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseMediaHistoryStore);
-MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseR16Texture);
 #if BUILDFLAG(IS_LINUX)
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kVaapiVideoDecodeLinux);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kVaapiVideoDecodeLinuxGL);
diff --git a/media/base/video_encoder.h b/media/base/video_encoder.h
index 7b72cf5..f3816f7 100644
--- a/media/base/video_encoder.h
+++ b/media/base/video_encoder.h
@@ -63,6 +63,7 @@
   };
 
   enum class LatencyMode { Realtime, Quality };
+  enum class ContentHint { Camera, Screen };
 
   struct MEDIA_EXPORT Options {
     Options();
@@ -79,6 +80,8 @@
 
     absl::optional<SVCScalabilityMode> scalability_mode;
 
+    absl::optional<ContentHint> content_hint;
+
     // Only used for H264 encoding.
     AvcOptions avc;
 
diff --git a/media/capture/mojom/video_capture_types.mojom b/media/capture/mojom/video_capture_types.mojom
index b29f9c7c..0b42428 100644
--- a/media/capture/mojom/video_capture_types.mojom
+++ b/media/capture/mojom/video_capture_types.mojom
@@ -388,15 +388,16 @@
   array<VideoCaptureFormat> supported_formats;
 };
 
-// The result of an attempt by the client to start/stop cropping.
+// The result of an attempt by the client to start/stop cropping,
+// restricting or otherwise applying a sub-capture target.
 // TODO(crbug.com/1264849): Remove kNotImplemented.
-enum CropRequestResult {
+enum ApplySubCaptureTargetResult {
   kSuccess,
   kErrorGeneric,
   kUnsupportedCaptureDevice,
   kNotImplemented,
-  kNonIncreasingCropVersion,
-  kInvalidCropTarget,
+  kNonIncreasingVersion,
+  kInvalidTarget,
 };
 
 enum DeviceEnumerationResult {
diff --git a/media/capture/video/video_capture_device.cc b/media/capture/video/video_capture_device.cc
index 5b20a498..035622f5 100644
--- a/media/capture/video/video_capture_device.cc
+++ b/media/capture/video/video_capture_device.cc
@@ -109,9 +109,10 @@
 void VideoCaptureDevice::Crop(
     const base::Token& crop_id,
     uint32_t crop_version,
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
+    base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+        callback) {
   std::move(callback).Run(
-      media::mojom::CropRequestResult::kUnsupportedCaptureDevice);
+      media::mojom::ApplySubCaptureTargetResult::kUnsupportedCaptureDevice);
 }
 
 void VideoCaptureDevice::GetPhotoState(GetPhotoStateCallback callback) {}
diff --git a/media/capture/video/video_capture_device.h b/media/capture/video/video_capture_device.h
index f5983eef..975e152d 100644
--- a/media/capture/video/video_capture_device.h
+++ b/media/capture/video/video_capture_device.h
@@ -361,7 +361,8 @@
   virtual void Crop(
       const base::Token& crop_id,
       uint32_t crop_version,
-      base::OnceCallback<void(media::mojom::CropRequestResult)> callback);
+      base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+          callback);
 
   // Deallocates the video capturer, possibly asynchronously.
   //
diff --git a/media/gpu/chromeos/video_decoder_pipeline.cc b/media/gpu/chromeos/video_decoder_pipeline.cc
index b918a25..5d3adf1 100644
--- a/media/gpu/chromeos/video_decoder_pipeline.cc
+++ b/media/gpu/chromeos/video_decoder_pipeline.cc
@@ -1027,6 +1027,20 @@
     }
   }
 
+  // TODO(jkardatzke): Remove this when we have protected content rendering on
+  // ARM working. This is temporary so that video will actually decode on HWDRM
+  // ARM devices during development (even though it won't be visible).
+#if BUILDFLAG(USE_V4L2_CODEC) && BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)
+  if (use_protected) {
+    for (const auto& candidate : candidates) {
+      if (candidate.fourcc == Fourcc(Fourcc::MM21)) {
+        LOG(WARNING) << "Forcing MM21 format for V4L2 protected content";
+        viable_candidate = candidate;
+      }
+    }
+  }
+#endif
+
 #if BUILDFLAG(IS_LINUX) && BUILDFLAG(USE_VAAPI)
   // Linux should always use a custom allocator (to allocate buffers using
   // libva) and a PlatformVideoFramePool.
diff --git a/media/gpu/h265_decoder.cc b/media/gpu/h265_decoder.cc
index a2aaab29..e34ef3fa 100644
--- a/media/gpu/h265_decoder.cc
+++ b/media/gpu/h265_decoder.cc
@@ -160,6 +160,7 @@
 
 void H265Decoder::Reset() {
   first_picture_ = true;
+  no_rasl_output_flag_ = true;
 
   curr_pic_ = nullptr;
   curr_nalu_ = nullptr;
@@ -689,8 +690,9 @@
         (curr_nalu_->nal_unit_type >= H265NALU::BLA_W_LP &&
          curr_nalu_->nal_unit_type <= H265NALU::IDR_N_LP) ||
         curr_pic_->first_picture_;
+    no_rasl_output_flag_ = curr_pic_->no_rasl_output_flag_;
   } else {
-    curr_pic_->no_rasl_output_flag_ = false;
+    curr_pic_->no_rasl_output_flag_ = no_rasl_output_flag_;
   }
 
   // C.5.2.2
@@ -1039,6 +1041,7 @@
     if (!PerformDpbOperations(sps)) {
       return H265Accelerator::Status::kFail;
     }
+
     curr_pic_->processed_ = true;
   }
 
diff --git a/media/gpu/h265_decoder.h b/media/gpu/h265_decoder.h
index d50ff58..dccd6c8e 100644
--- a/media/gpu/h265_decoder.h
+++ b/media/gpu/h265_decoder.h
@@ -319,6 +319,10 @@
   // follows an EOS NALU.
   bool first_picture_ = true;
 
+  // Used to keep NoRaslOutputFlag state since last IRAP, to decide if we
+  // drop a RASL picture.
+  bool no_rasl_output_flag_ = true;
+
   // Global state values, needed in decoding. See spec.
   scoped_refptr<H265Picture> prev_tid0_pic_;
   int max_pic_order_cnt_lsb_;
diff --git a/media/gpu/mac/video_toolbox_h265_accelerator.cc b/media/gpu/mac/video_toolbox_h265_accelerator.cc
index 4921b64..c00a1fb8 100644
--- a/media/gpu/mac/video_toolbox_h265_accelerator.cc
+++ b/media/gpu/mac/video_toolbox_h265_accelerator.cc
@@ -167,18 +167,9 @@
 
   ResetFrameData();
 
-  // Handle NoRaslOutputFlag.
-  if (slice_hdr->irap_pic) {
-    // H265Decoder computes this flag, we just need to store it for the rest of
-    // this RAP.
-    no_rasl_output_flag_ = pic->no_rasl_output_flag_;
-  } else if (no_rasl_output_flag_ &&
-             (slice_hdr->nal_unit_type == H265NALU::RASL_N ||
-              slice_hdr->nal_unit_type == H265NALU::RASL_R)) {
-    // H265Decoder attempts to compute this flag, but since it doesn't save the
-    // NoRaslOutputFlag it always thinks RASL frames should be output.
-    // TODO(crbug.com/1331597): Migrate this logic into H265Decoder.
-    pic->pic_output_flag_ = false;
+  if (pic->no_rasl_output_flag_ &&
+      (slice_hdr->nal_unit_type == H265NALU::RASL_N ||
+       slice_hdr->nal_unit_type == H265NALU::RASL_R)) {
     // Drop this RASL frame, otherwise VideoToolbox will fail to decode it.
     drop_frame_ = true;
     return Status::kOk;
@@ -379,7 +370,14 @@
 void VideoToolboxH265Accelerator::Reset() {
   DVLOG(1) << __func__;
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  no_rasl_output_flag_ = false;
+
+  // The decompression session will probably also be reset, so we can't expect
+  // it to know about any parameter sets. https://crbug.com/1493624
+  active_vps_data_.clear();
+  active_sps_data_.clear();
+  active_pps_data_.clear();
+  active_format_.reset();
+
   ResetFrameData();
 }
 
diff --git a/media/gpu/mac/video_toolbox_h265_accelerator.h b/media/gpu/mac/video_toolbox_h265_accelerator.h
index 663ec2a..eb11f42 100644
--- a/media/gpu/mac/video_toolbox_h265_accelerator.h
+++ b/media/gpu/mac/video_toolbox_h265_accelerator.h
@@ -114,9 +114,6 @@
   base::apple::ScopedCFTypeRef<CMFormatDescriptionRef> active_format_;
   VideoToolboxSessionMetadata active_session_metadata_;
 
-  // Tracks NoRaslOutputFlag for the current RAP, used to drop RASL frames.
-  bool no_rasl_output_flag_ = false;
-
   // Accumulated data for the current frame.
   base::flat_set<int> frame_vps_ids_;  // Note: there should be exactly one VPS.
   base::flat_set<int> frame_sps_ids_;
diff --git a/media/gpu/mac/video_toolbox_h265_accelerator_unittest.cc b/media/gpu/mac/video_toolbox_h265_accelerator_unittest.cc
index 4e52ad9d..96e6ce2 100644
--- a/media/gpu/mac/video_toolbox_h265_accelerator_unittest.cc
+++ b/media/gpu/mac/video_toolbox_h265_accelerator_unittest.cc
@@ -201,8 +201,10 @@
   EXPECT_CALL(*this, OnDecode(_, _, _)).WillOnce(SaveArg<0>(&sample1));
   accelerator_->SubmitDecode(pic1);
 
-  // The two samples should still have the same configurations.
-  EXPECT_EQ(CMSampleBufferGetFormatDescription(sample0),
+  // The accelerator should have made a new configuration. (Technically it
+  // should be fine to reuse the old one because the parameter sets did not
+  // change.)
+  EXPECT_NE(CMSampleBufferGetFormatDescription(sample0),
             CMSampleBufferGetFormatDescription(sample1));
 }
 
diff --git a/media/gpu/test/video_decode_accelerator_tests.cc b/media/gpu/test/video_decode_accelerator_tests.cc
index 679abdc..343c7ce 100644
--- a/media/gpu/test/video_decode_accelerator_tests.cc
+++ b/media/gpu/test/video_decode_accelerator_tests.cc
@@ -429,14 +429,14 @@
                                 /*times=*/kNumDecodeBuffers));
 }
 
-// This test case sends all the frames and expects them to be fully decoded
-// (as in, VideoDecoder::OutputCB should be called). Most of them should be
-// decoded as well, but since this test doesn't exercise an End-of-Stream
-// (a.k.a. "a flush"), some will likely be held onto by the VideoDecoder/driver
-// as part of its decoding pipeline. We don't know how many (it depends also on
-// the ImageProcessor, if any), so it's not a good idea to set expectations on
-// the number of kFrameDecoded events.
-TEST_F(VideoDecoderTest, DecodeAndOutputAllFrames) {
+// This test case sends all the frames and expects them to be accepted for
+// decoding (as in, VideoDecoder::OutputCB should be called). Most of them
+// should be decoded as well, but since this test doesn't exercise an
+// End-of-Stream (a.k.a. "a flush"), some will likely be held onto by the
+// VideoDecoder/driver as part of its decoding pipeline. We don't know how
+// many (it depends also on the ImageProcessor, if any), so it's not a good
+// idea to set expectations on the number of kFrameDecoded events.
+TEST_F(VideoDecoderTest, AllDecoderBuffersAcceptedForDecoding) {
   auto tvp = CreateDecoderListener(g_env->Video());
 
   tvp->Play();
diff --git a/media/mojo/mojom/video_frame_mojom_traits.h b/media/mojo/mojom/video_frame_mojom_traits.h
index cc2998ba..9cb8e33 100644
--- a/media/mojo/mojom/video_frame_mojom_traits.h
+++ b/media/mojo/mojom/video_frame_mojom_traits.h
@@ -90,8 +90,6 @@
   static media::mojom::VideoFrameDataPtr data(
       const scoped_refptr<media::VideoFrame>& input);
 
-  // TODO(https://crbug.com/1096727): Change VideoFrame::Metadata() to return a
-  // const &.
   static const media::VideoFrameMetadata& metadata(
       const scoped_refptr<media::VideoFrame>& input) {
     return input->metadata();
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc
index d043705..5bd1d11f 100644
--- a/media/renderers/video_resource_updater.cc
+++ b/media/renderers/video_resource_updater.cc
@@ -621,14 +621,12 @@
     viz::ClientResourceProvider* resource_provider,
     bool use_stream_video_draw_quad,
     bool use_gpu_memory_buffer_resources,
-    bool use_r16_texture,
     int max_resource_size)
     : context_provider_(context_provider),
       shared_bitmap_reporter_(shared_bitmap_reporter),
       resource_provider_(resource_provider),
       use_stream_video_draw_quad_(use_stream_video_draw_quad),
       use_gpu_memory_buffer_resources_(use_gpu_memory_buffer_resources),
-      use_r16_texture_(use_r16_texture),
       max_resource_size_(max_resource_size),
       tracing_id_(g_next_video_resource_updater_id.GetNext()) {
   DCHECK(context_provider_ || shared_bitmap_reporter_);
@@ -845,8 +843,7 @@
            caps.texture_rg);
     return GetSingleChannel8BitFormat(caps, shared_image_caps);
   }
-  if (caps.texture_norm16 &&
-      (shared_image_caps.supports_r16_shared_images || use_r16_texture_)) {
+  if (caps.texture_norm16 && shared_image_caps.supports_r16_shared_images) {
     return viz::SinglePlaneFormat::kR_16;
   }
   if (caps.texture_half_float_linear &&
diff --git a/media/renderers/video_resource_updater.h b/media/renderers/video_resource_updater.h
index 6d4c36d9..11d9cdee 100644
--- a/media/renderers/video_resource_updater.h
+++ b/media/renderers/video_resource_updater.h
@@ -92,7 +92,6 @@
                        viz::ClientResourceProvider* resource_provider,
                        bool use_stream_video_draw_quad,
                        bool use_gpu_memory_buffer_resources,
-                       bool use_r16_texture,
                        int max_resource_size);
 
   VideoResourceUpdater(const VideoResourceUpdater&) = delete;
@@ -211,8 +210,6 @@
       resource_provider_;
   const bool use_stream_video_draw_quad_;
   const bool use_gpu_memory_buffer_resources_;
-  // TODO(crbug.com/759456): Remove after r16 is used without the flag.
-  const bool use_r16_texture_;
   const int max_resource_size_;
   const int tracing_id_;
   std::unique_ptr<PaintCanvasVideoRenderer> video_renderer_;
diff --git a/media/renderers/video_resource_updater_unittest.cc b/media/renderers/video_resource_updater_unittest.cc
index b20748bc..4e276559 100644
--- a/media/renderers/video_resource_updater_unittest.cc
+++ b/media/renderers/video_resource_updater_unittest.cc
@@ -96,19 +96,15 @@
       bool use_stream_video_draw_quad = false) {
     return std::make_unique<VideoResourceUpdater>(
         context_provider_.get(), nullptr, resource_provider_.get(),
-        use_stream_video_draw_quad,
-        /*use_gpu_memory_buffer_resources=*/false,
-        /*use_r16_texture=*/use_r16_texture_, /*max_resource_size=*/10000);
+        use_stream_video_draw_quad, /*use_gpu_memory_buffer_resources=*/false,
+        /*max_resource_size=*/10000);
   }
 
   std::unique_ptr<VideoResourceUpdater> CreateUpdaterForSoftware() {
     return std::make_unique<VideoResourceUpdater>(
         /*context_provider=*/nullptr, &shared_bitmap_reporter_,
-        resource_provider_.get(),
-        /*use_stream_video_draw_quad=*/false,
-        /*use_gpu_memory_buffer_resources=*/false,
-        /*use_r16_texture=*/false,
-        /*max_resource_size=*/10000);
+        resource_provider_.get(), /*use_stream_video_draw_quad=*/false,
+        /*use_gpu_memory_buffer_resources=*/false, /*max_resource_size=*/10000);
   }
 
   // Note that the number of pixels needed for |size| must be less than or equal
@@ -348,7 +344,6 @@
   FakeSharedBitmapReporter shared_bitmap_reporter_;
   std::unique_ptr<viz::ClientResourceProvider> resource_provider_;
   gpu::SyncToken release_sync_token_;
-  bool use_r16_texture_ = false;
 };
 
 const gpu::SyncToken VideoResourceUpdaterTest::kMailboxSyncToken =
@@ -539,7 +534,11 @@
 class VideoResourceUpdaterTestWithR16 : public VideoResourceUpdaterTest {
  public:
   VideoResourceUpdaterTestWithR16() : VideoResourceUpdaterTest() {
-    use_r16_texture_ = true;
+    auto* sii = context_provider_->SharedImageInterface();
+    auto shared_image_caps = sii->GetCapabilities();
+    shared_image_caps.supports_r16_shared_images = true;
+    sii->SetCapabilities(shared_image_caps);
+
     gl_->set_support_texture_norm16(true);
   }
 };
diff --git a/media/test/data/README.md b/media/test/data/README.md
index ba9fc83..4b71b149 100644
--- a/media/test/data/README.md
+++ b/media/test/data/README.md
@@ -851,6 +851,9 @@
 
 ### HLS
 
+#### bear-1280x720-hls-clear-mpl.m3u8
+A single-segment hls media playlist which plays bear-1280x720-hls.ts.
+
 #### bear-1280x720-hls.ts
 Produced using Apple's mediafilesegmenter tool with bear-1280x720.ts as input,
 with no encryption.
diff --git a/media/test/data/bear-1280x720-hls-clear-mpl.m3u8 b/media/test/data/bear-1280x720-hls-clear-mpl.m3u8
new file mode 100644
index 0000000..084b013
--- /dev/null
+++ b/media/test/data/bear-1280x720-hls-clear-mpl.m3u8
@@ -0,0 +1,7 @@
+#EXTM3U
+#EXT-X-VERSION:3
+#EXT-X-TARGETDURATION:3
+#EXT-X-MEDIA-SEQUENCE:0
+#EXTINF:2.79,
+bear-1280x720-hls.ts
+#EXT-X-ENDLIST
diff --git a/media/test/media_bundle_data.filelist b/media/test/media_bundle_data.filelist
index 4236b24b..1c6dacb 100644
--- a/media/test/media_bundle_data.filelist
+++ b/media/test/media_bundle_data.filelist
@@ -73,6 +73,7 @@
 data/bear-1280x720-hevc-8bit-422.mp4
 data/bear-1280x720-hevc-no-audio.mp4
 data/bear-1280x720-hevc.mp4
+data/bear-1280x720-hls-clear-mpl.m3u8
 data/bear-1280x720-hls-sample-aes.ts
 data/bear-1280x720-hls-with-CAT.bin
 data/bear-1280x720-hls.ts
diff --git a/media/unit_tests_bundle_data.filelist b/media/unit_tests_bundle_data.filelist
index bcdf63e..9758754a 100644
--- a/media/unit_tests_bundle_data.filelist
+++ b/media/unit_tests_bundle_data.filelist
@@ -85,6 +85,7 @@
 //media/test/data/bear-1280x720-hevc-8bit-422.mp4
 //media/test/data/bear-1280x720-hevc-no-audio.mp4
 //media/test/data/bear-1280x720-hevc.mp4
+//media/test/data/bear-1280x720-hls-clear-mpl.m3u8
 //media/test/data/bear-1280x720-hls-sample-aes.ts
 //media/test/data/bear-1280x720-hls-with-CAT.bin
 //media/test/data/bear-1280x720-hls.ts
diff --git a/media/video/av1_video_encoder.cc b/media/video/av1_video_encoder.cc
index c99b8ed..a381dec 100644
--- a/media/video/av1_video_encoder.cc
+++ b/media/video/av1_video_encoder.cc
@@ -255,8 +255,13 @@
   CALL_AOM_CONTROL(AV1E_SET_INTRA_DEFAULT_TX_ONLY, 1);
   CALL_AOM_CONTROL(AV1E_SET_SVC_PARAMS, &svc_params_);
 
-  if (config_.rc_end_usage == AOM_CBR)
+  if (config_.rc_end_usage == AOM_CBR) {
     CALL_AOM_CONTROL(AV1E_SET_AQ_MODE, 3);
+  }
+
+  if (options.content_hint == ContentHint::Screen) {
+    CALL_AOM_CONTROL(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN);
+  }
 
   // Keep in mind that AV1E_SET_TILE_[COLUMNS|ROWS] uses log2 units.
   int log2_threads = std::log2(config_.g_threads);
@@ -293,8 +298,7 @@
   // two sides of realtime range for our 'realtime' and 'quality' modes
   // because we don't want encoding speed to drop into single digit fps
   // even in quality mode.
-  const int cpu_speed =
-      (options.latency_mode == VideoEncoder::LatencyMode::Realtime) ? 9 : 7;
+  const int cpu_speed = (options.latency_mode == LatencyMode::Realtime) ? 9 : 7;
   CALL_AOM_CONTROL(AOME_SET_CPUUSED, cpu_speed);
 #undef CALL_AOM_CONTROL
 
diff --git a/media/video/openh264_video_encoder.cc b/media/video/openh264_video_encoder.cc
index e31e3b9..490423a1 100644
--- a/media/video/openh264_video_encoder.cc
+++ b/media/video/openh264_video_encoder.cc
@@ -21,7 +21,7 @@
 
 namespace {
 
-EProfileIdc ToOpenH264Profile(media::VideoCodecProfile profile) {
+EProfileIdc ToOpenH264Profile(VideoCodecProfile profile) {
   switch (profile) {
     case media::H264PROFILE_BASELINE:
       return PRO_BASELINE;
@@ -34,7 +34,7 @@
   }
 }
 
-void SetUpOpenH264Params(media::VideoCodecProfile profile,
+void SetUpOpenH264Params(VideoCodecProfile profile,
                          const VideoEncoder::Options& options,
                          const VideoColorSpace& itu_cs,
                          SEncParamExt* params) {
@@ -42,7 +42,9 @@
   params->bEnableFrameSkip = false;
   params->iPaddingFlag = 0;
   params->iComplexityMode = MEDIUM_COMPLEXITY;
-  params->iUsageType = CAMERA_VIDEO_REAL_TIME;
+  params->iUsageType = options.content_hint == VideoEncoder::ContentHint::Screen
+                           ? SCREEN_CONTENT_REAL_TIME
+                           : CAMERA_VIDEO_REAL_TIME;
   params->bEnableDenoise = false;
   params->eSpsPpsIdStrategy = SPS_LISTING;
   params->iMultipleThreadIdc = threads;
diff --git a/media/video/vpx_video_encoder.cc b/media/video/vpx_video_encoder.cc
index 1f311bf..bc096da 100644
--- a/media/video/vpx_video_encoder.cc
+++ b/media/video/vpx_video_encoder.cc
@@ -385,6 +385,11 @@
     if (codec_config_.rc_end_usage == VPX_CBR) {
       vpx_codec_control(codec.get(), VP9E_SET_AQ_MODE, 3);
     }
+
+    if (options.content_hint == ContentHint::Screen) {
+      vpx_codec_control(codec.get(), VP9E_SET_TUNE_CONTENT,
+                        VP9E_CONTENT_SCREEN);
+    }
   }
 
   options_ = options;
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 08f365b4..731cf77 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -244,6 +244,8 @@
     "base/priority_queue.h",
     "base/privacy_mode.cc",
     "base/privacy_mode.h",
+    "base/proxy_chain.cc",
+    "base/proxy_chain.h",
     "base/proxy_delegate.h",
     "base/proxy_server.cc",
     "base/proxy_server.h",
@@ -2550,6 +2552,7 @@
     "base/prioritized_dispatcher_unittest.cc",
     "base/prioritized_task_runner_unittest.cc",
     "base/priority_queue_unittest.cc",
+    "base/proxy_chain_unittest.cc",
     "base/proxy_server_unittest.cc",
     "base/proxy_string_util_unittest.cc",
     "base/registry_controlled_domains/registry_controlled_domain_unittest.cc",
diff --git a/net/base/features.cc b/net/base/features.cc
index 9fbfd55..44f2e2f 100644
--- a/net/base/features.cc
+++ b/net/base/features.cc
@@ -315,9 +315,10 @@
              "PlatformKeyProbeSHA256",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+// Disabled because of https://crbug.com/1489696.
 BASE_FEATURE(kEnableGetNetworkConnectivityHintAPI,
              "EnableGetNetworkConnectivityHintAPI",
-             base::FEATURE_ENABLED_BY_DEFAULT);
+             base::FEATURE_DISABLED_BY_DEFAULT);
 #endif
 
 // Prefetch to follow normal semantics instead of 5-minute rule
@@ -477,4 +478,10 @@
 
 BASE_FEATURE(kReceiveEcn, "ReceiveEcn", base::FEATURE_DISABLED_BY_DEFAULT);
 
+// TODO(crbug.com/634470): Remove this feature flag in January 2024 if the new
+// limit sticks.
+BASE_FEATURE(kNewCertPathBuilderIterationLimit,
+             "NewCertPathBuilderIterationLimit",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
 }  // namespace net::features
diff --git a/net/base/features.h b/net/base/features.h
index 6d72b85..5923aa0 100644
--- a/net/base/features.h
+++ b/net/base/features.h
@@ -478,6 +478,8 @@
 // Enables receiving ECN bit by sockets in Chrome.
 NET_EXPORT BASE_DECLARE_FEATURE(kReceiveEcn);
 
+NET_EXPORT BASE_DECLARE_FEATURE(kNewCertPathBuilderIterationLimit);
+
 }  // namespace net::features
 
 #endif  // NET_BASE_FEATURES_H_
diff --git a/net/base/load_flags_list.h b/net/base/load_flags_list.h
index 4fc3870..17b1395 100644
--- a/net/base/load_flags_list.h
+++ b/net/base/load_flags_list.h
@@ -110,3 +110,7 @@
 // Indicates that CAN_USE_SHARED_DICTIONARY must be disabled after a redirect to
 // another origin.
 LOAD_FLAG(DISABLE_SHARED_DICTIONARY_AFTER_CROSS_ORIGIN_REDIRECT, 1 << 18)
+
+// This flag is used to bypass HSTS upgrades. This flag must be set for AIA,
+// CRL, and OCSP requests in order to prevent circular dependencies.
+LOAD_FLAG(SHOULD_BYPASS_HSTS, 1 << 19)
diff --git a/net/base/proxy_chain.cc b/net/base/proxy_chain.cc
new file mode 100644
index 0000000..6c7194a4
--- /dev/null
+++ b/net/base/proxy_chain.cc
@@ -0,0 +1,25 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/base/proxy_chain.h"
+
+#include <ostream>
+
+#include "net/base/proxy_string_util.h"
+
+namespace net {
+
+std::string ProxyChain::ToDebugString() const {
+  return ProxyServerToProxyUri(proxy_server());
+}
+
+bool ProxyChain::IsValid() const {
+  return proxy_server().is_valid();
+}
+
+std::ostream& operator<<(std::ostream& os, const ProxyChain& proxy_chain) {
+  return os << proxy_chain.proxy_server();
+}
+
+}  // namespace net
diff --git a/net/base/proxy_chain.h b/net/base/proxy_chain.h
new file mode 100644
index 0000000..9ee7cd21
--- /dev/null
+++ b/net/base/proxy_chain.h
@@ -0,0 +1,109 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_BASE_PROXY_CHAIN_H_
+#define NET_BASE_PROXY_CHAIN_H_
+
+#include <stdint.h>
+
+#include <ostream>
+#include <string>
+#include <tuple>
+
+#include "base/check.h"
+#include "base/strings/string_piece.h"
+#include "net/base/host_port_pair.h"
+#include "net/base/net_export.h"
+#include "net/base/proxy_server.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace net {
+
+// ProxyChain represents a chain of ProxyServers. A chain with multiple proxy
+// servers means that a single connection will go through all of the proxies in
+// order, using a tunnel through the first proxy to connect to the second, etc.
+// A "direct" connection is a chain of length zero.
+//
+// TODO(crbug.com/1491092): Initial implementations of proxy chaining may, in
+// fact, not tunnel through the last proxy in the ProxyChain if the destination
+// is http.
+//
+// TODO(crbug.com/1491092): This does not currently support multi-proxy chains,
+// so a ProxyChain is always inter-convertable to a ProxyServer.
+class NET_EXPORT ProxyChain {
+ public:
+  // Default copy-constructor and assignment operator are OK!
+
+  // Constructs an invalid ProxyChain.
+  ProxyChain() = default;
+
+  ProxyChain(ProxyServer::Scheme scheme, const HostPortPair& host_port_pair)
+      : proxy_server_(scheme, host_port_pair) {}
+
+  explicit ProxyChain(ProxyServer proxy_server) : proxy_server_(proxy_server) {}
+
+  // Creates a single-proxy ProxyChain, validating and canonicalizing input.
+  // Port is optional and, if not provided, will be replaced with the default
+  // port for the given scheme. Accepts IPv6 literal `host`s with surrounding
+  // brackets (URL format) or without (HostPortPair format). On invalid input,
+  // result will be a `SCHEME_INVALID` ProxyChain.
+  //
+  // Must not be called with `SCHEME_INVALID` or `SCHEME_DIRECT`. Use
+  // `ProxyChain()` or `Direct()` respectively to create an invalid or direct
+  // ProxyChain.
+  static ProxyChain FromSchemeHostAndPort(ProxyServer::Scheme scheme,
+                                          base::StringPiece host,
+                                          base::StringPiece port_str) {
+    return ProxyChain(
+        ProxyServer::FromSchemeHostAndPort(scheme, host, port_str));
+  }
+  static ProxyChain FromSchemeHostAndPort(ProxyServer::Scheme scheme,
+                                          base::StringPiece host,
+                                          absl::optional<uint16_t> port) {
+    return ProxyChain(ProxyServer::FromSchemeHostAndPort(scheme, host, port));
+  }
+
+  // Create a "direct" proxy chain, which includes no proxy servers.
+  static ProxyChain Direct() { return ProxyChain(ProxyServer::Direct()); }
+
+  // Returns true if this chain contains more than one proxy.
+  bool is_multi_proxy() const { return false; }
+
+  // Returns true if this is a direct (equivalently, zero-proxy) chain.
+  bool is_direct() const { return proxy_server_.is_direct(); }
+
+  // Returns true if this chain is valid.
+  bool IsValid() const;
+
+  bool operator==(const ProxyChain& other) const {
+    return proxy_server_ == other.proxy_server_;
+  }
+
+  bool operator!=(const ProxyChain& other) const { return !(*this == other); }
+
+  // Comparator function so this can be placed in a std::map.
+  bool operator<(const ProxyChain& other) const {
+    return proxy_server_ < other.proxy_server_;
+  }
+
+  std::string ToDebugString() const;
+
+  // Get the single ProxyServer equivalent to this chain. This must not be
+  // called for multi-proxy chains.
+  // TODO(crbug.com/1491092): Remove this method.
+  const ProxyServer& proxy_server() const {
+    CHECK(!is_multi_proxy());
+    return proxy_server_;
+  }
+
+ private:
+  ProxyServer proxy_server_;
+};
+
+NET_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+                                            const ProxyChain& proxy_chain);
+
+}  // namespace net
+
+#endif  // NET_BASE_PROXY_CHAIN_H_
diff --git a/net/base/proxy_chain_unittest.cc b/net/base/proxy_chain_unittest.cc
new file mode 100644
index 0000000..a15661b
--- /dev/null
+++ b/net/base/proxy_chain_unittest.cc
@@ -0,0 +1,198 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/base/proxy_chain.h"
+
+#include <sstream>
+
+#include "base/strings/string_number_conversions.h"
+#include "net/base/proxy_string_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace net {
+
+namespace {
+
+TEST(ProxyChainTest, DefaultConstructor) {
+  ProxyChain proxy_chain;
+  EXPECT_FALSE(proxy_chain.proxy_server().is_valid());
+}
+
+TEST(ProxyChainTest, Ostream) {
+  ProxyChain proxy_chain =
+      ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTP, "foo", 80);
+  std::ostringstream out;
+  out << proxy_chain;
+  EXPECT_EQ(out.str(), "PROXY foo:80");
+}
+
+TEST(ProxyChainTest, FromSchemeHostAndPort) {
+  const struct {
+    const ProxyServer::Scheme input_scheme;
+    const char* const input_host;
+    const absl::optional<uint16_t> input_port;
+    const char* const input_port_str;
+    const char* const expected_host;
+    const uint16_t expected_port;
+  } tests[] = {
+      {ProxyServer::SCHEME_HTTP, "foopy", 80, "80", "foopy", 80},
+
+      // Non-standard port
+      {ProxyServer::SCHEME_HTTP, "foopy", 10, "10", "foopy", 10},
+      {ProxyServer::SCHEME_HTTP, "foopy", 0, "0", "foopy", 0},
+
+      // Hostname canonicalization
+      {ProxyServer::SCHEME_HTTP, "FoOpY", 80, "80", "foopy", 80},
+      {ProxyServer::SCHEME_HTTP, "f\u00fcpy", 80, "80", "xn--fpy-hoa", 80},
+
+      // IPv4 literal
+      {ProxyServer::SCHEME_HTTP, "1.2.3.4", 80, "80", "1.2.3.4", 80},
+
+      // IPv4 literal canonicalization
+      {ProxyServer::SCHEME_HTTP, "127.1", 80, "80", "127.0.0.1", 80},
+      {ProxyServer::SCHEME_HTTP, "0x7F.0x1", 80, "80", "127.0.0.1", 80},
+      {ProxyServer::SCHEME_HTTP, "0177.01", 80, "80", "127.0.0.1", 80},
+
+      // IPv6 literal
+      {ProxyServer::SCHEME_HTTP, "[3ffe:2a00:100:7031::1]", 80, "80",
+       "[3ffe:2a00:100:7031::1]", 80},
+      {ProxyServer::SCHEME_HTTP, "3ffe:2a00:100:7031::1", 80, "80",
+       "[3ffe:2a00:100:7031::1]", 80},
+
+      // IPv6 literal canonicalization
+      {ProxyServer::SCHEME_HTTP, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", 80,
+       "80", "[fedc:ba98:7654:3210:fedc:ba98:7654:3210]", 80},
+      {ProxyServer::SCHEME_HTTP, "::192.9.5.5", 80, "80", "[::c009:505]", 80},
+
+      // Other schemes
+      {ProxyServer::SCHEME_HTTPS, "foopy", 111, "111", "foopy", 111},
+      {ProxyServer::SCHEME_QUIC, "foopy", 111, "111", "foopy", 111},
+      {ProxyServer::SCHEME_SOCKS4, "foopy", 111, "111", "foopy", 111},
+      {ProxyServer::SCHEME_SOCKS5, "foopy", 111, "111", "foopy", 111},
+
+      // Default ports
+      {ProxyServer::SCHEME_HTTP, "foopy", absl::nullopt, "", "foopy", 80},
+      {ProxyServer::SCHEME_HTTPS, "foopy", absl::nullopt, "", "foopy", 443},
+      {ProxyServer::SCHEME_QUIC, "foopy", absl::nullopt, "", "foopy", 443},
+      {ProxyServer::SCHEME_SOCKS4, "foopy", absl::nullopt, "", "foopy", 1080},
+      {ProxyServer::SCHEME_SOCKS5, "foopy", absl::nullopt, "", "foopy", 1080},
+  };
+
+  for (size_t i = 0; i < std::size(tests); ++i) {
+    SCOPED_TRACE(base::NumberToString(i) + ": " + tests[i].input_host + ":" +
+                 base::NumberToString(tests[i].input_port.value_or(-1)));
+    auto chain = ProxyChain::FromSchemeHostAndPort(
+        tests[i].input_scheme, tests[i].input_host, tests[i].input_port);
+    auto proxy = chain.proxy_server();
+
+    ASSERT_TRUE(proxy.is_valid());
+    EXPECT_EQ(proxy.scheme(), tests[i].input_scheme);
+    EXPECT_EQ(proxy.GetHost(), tests[i].expected_host);
+    EXPECT_EQ(proxy.GetPort(), tests[i].expected_port);
+
+    auto chain_from_string_port = ProxyChain::FromSchemeHostAndPort(
+        tests[i].input_scheme, tests[i].input_host, tests[i].input_port_str);
+    auto proxy_from_string_port = chain_from_string_port.proxy_server();
+    EXPECT_TRUE(proxy_from_string_port.is_valid());
+    EXPECT_EQ(proxy, proxy_from_string_port);
+  }
+}
+
+TEST(ProxyChainTest, InvalidHostname) {
+  const char* const tests[]{
+      "",
+      "[]",
+      "[foo]",
+      "foo:",
+      "foo:80",
+      ":",
+      "http://foo",
+      "3ffe:2a00:100:7031::1]",
+      "[3ffe:2a00:100:7031::1",
+      "foo.80",
+  };
+
+  for (size_t i = 0; i < std::size(tests); ++i) {
+    SCOPED_TRACE(base::NumberToString(i) + ": " + tests[i]);
+    auto proxy = ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTP,
+                                                   tests[i], 80);
+    EXPECT_FALSE(proxy.proxy_server().is_valid());
+  }
+}
+
+TEST(ProxyChainTest, InvalidPort) {
+  const char* const tests[]{
+      "-1",
+      "65536",
+      "foo",
+      "0x35",
+  };
+
+  for (size_t i = 0; i < std::size(tests); ++i) {
+    SCOPED_TRACE(base::NumberToString(i) + ": " + tests[i]);
+    auto proxy = ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTP,
+                                                   "foopy", tests[i]);
+    EXPECT_FALSE(proxy.proxy_server().is_valid());
+  }
+}
+
+TEST(ProxyChainTest, ComparatorAndEquality) {
+  const struct {
+    // Inputs.
+    ProxyChain chain1;
+    ProxyChain chain2;
+
+    // Expectation.
+    //   -1 means chain1 is less than chain2
+    //    0 means chain1 equals chain2
+    //    1 means chain1 is greater than chain2
+    int expected_comparison;
+  } kTests[] = {
+      {// Equal.
+       ProxyUriToProxyChain("foo:11", ProxyServer::SCHEME_HTTP),
+       ProxyUriToProxyChain("http://foo:11", ProxyServer::SCHEME_HTTP), 0},
+      {// Port is different.
+       ProxyUriToProxyChain("foo:333", ProxyServer::SCHEME_HTTP),
+       ProxyUriToProxyChain("foo:444", ProxyServer::SCHEME_HTTP), -1},
+      {// Host is different.
+       ProxyUriToProxyChain("foo:33", ProxyServer::SCHEME_HTTP),
+       ProxyUriToProxyChain("bar:33", ProxyServer::SCHEME_HTTP), 1},
+      {// Scheme is different.
+       ProxyUriToProxyChain("socks4://foo:33", ProxyServer::SCHEME_HTTP),
+       ProxyUriToProxyChain("http://foo:33", ProxyServer::SCHEME_HTTP), 1},
+  };
+
+  for (const auto& test : kTests) {
+    EXPECT_TRUE(test.chain1.proxy_server().is_valid());
+    EXPECT_TRUE(test.chain2.proxy_server().is_valid());
+
+    switch (test.expected_comparison) {
+      case -1:
+        EXPECT_TRUE(test.chain1 < test.chain2);
+        EXPECT_FALSE(test.chain2 < test.chain1);
+        EXPECT_FALSE(test.chain2 == test.chain1);
+        EXPECT_FALSE(test.chain1 == test.chain2);
+        break;
+      case 0:
+        EXPECT_FALSE(test.chain1 < test.chain2);
+        EXPECT_FALSE(test.chain2 < test.chain1);
+        EXPECT_TRUE(test.chain2 == test.chain1);
+        EXPECT_TRUE(test.chain1 == test.chain2);
+        break;
+      case 1:
+        EXPECT_FALSE(test.chain1 < test.chain2);
+        EXPECT_TRUE(test.chain2 < test.chain1);
+        EXPECT_FALSE(test.chain2 == test.chain1);
+        EXPECT_FALSE(test.chain1 == test.chain2);
+        break;
+      default:
+        FAIL() << "Invalid expectation. Can be only -1, 0, 1";
+    }
+  }
+}
+
+}  // namespace
+
+}  // namespace net
diff --git a/net/base/proxy_delegate.h b/net/base/proxy_delegate.h
index c819a7a..8a6c4fe 100644
--- a/net/base/proxy_delegate.h
+++ b/net/base/proxy_delegate.h
@@ -9,6 +9,7 @@
 
 #include "net/base/net_errors.h"
 #include "net/base/net_export.h"
+#include "net/base/proxy_chain.h"
 #include "net/proxy_resolution/proxy_retry_info.h"
 
 class GURL;
@@ -18,7 +19,6 @@
 class HttpRequestHeaders;
 class HttpResponseHeaders;
 class ProxyInfo;
-class ProxyServer;
 
 // Delegate for setting up a connection.
 class NET_EXPORT ProxyDelegate {
@@ -39,25 +39,50 @@
                               const ProxyRetryInfoMap& proxy_retry_info,
                               ProxyInfo* result) = 0;
 
-  // Called when use of |bad_proxy| fails due to |net_error|. |net_error| is
-  // the network error encountered, if any, and OK if the fallback was
-  // for a reason other than a network error (e.g. the proxy service was
-  // explicitly directed to skip a proxy).
-  virtual void OnFallback(const ProxyServer& bad_proxy, int net_error) = 0;
+  // Called when use of a proxy chain failed due to `net_error`, but another
+  // proxy chain in the list succeeded. The failed proxy is within `bad_chain`,
+  // but it is undefined at which proxy in that chain. `net_error` is the
+  // network error encountered, if any, and OK if the fallback was for a reason
+  // other than a network error (e.g. the proxy service was explicitly directed
+  // to skip a proxy).
+  virtual void OnFallback(const ProxyChain& bad_chain, int net_error) = 0;
 
   // Called immediately before a proxy tunnel request is sent. Provides the
   // embedder an opportunity to add extra request headers.
-  virtual void OnBeforeTunnelRequest(const ProxyServer& proxy_server,
+  virtual void OnBeforeTunnelRequest(const ProxyChain& proxy_chain,
+                                     size_t chain_index,
                                      HttpRequestHeaders* extra_headers) = 0;
 
   // Called when the response headers for the proxy tunnel request have been
   // received. Allows the delegate to override the net error code of the tunnel
   // request. Returning OK causes the standard tunnel response handling to be
-  // performed. Implementations should make sure they can trust |proxy_server|
-  // before making decisions based on |response_headers|.
+  // performed. Implementations should make sure they can trust the proxy server
+  // at position `chain_index` in `proxy_chain` before making decisions based on
+  // `response_headers`.
   virtual Error OnTunnelHeadersReceived(
-      const ProxyServer& proxy_server,
+      const ProxyChain& proxy_chain,
+      size_t chain_index,
       const HttpResponseHeaders& response_headers) = 0;
+
+  // Compatibility methods for the transition to using ProxyChain instead of
+  // ProxyServer. TODO(crbug.com/1491092): Remove these methods.
+  void OnFallbackServerOnly(const ProxyServer& bad_server, int net_error) {
+    OnFallback(ProxyChain(bad_server), net_error);
+  }
+
+  void OnBeforeTunnelRequestServerOnly(const ProxyServer& proxy_server,
+                                       HttpRequestHeaders* extra_headers) {
+    DCHECK(!proxy_server.is_direct());
+    OnBeforeTunnelRequest(ProxyChain(proxy_server), /*chain_index=*/0,
+                          extra_headers);
+  }
+
+  Error OnTunnelHeadersReceivedServerOnly(
+      const ProxyServer& proxy_server,
+      const HttpResponseHeaders& response_headers) {
+    return OnTunnelHeadersReceived(ProxyChain(proxy_server),
+                                   /*chain_index=*/0, response_headers);
+  }
 };
 
 }  // namespace net
diff --git a/net/base/proxy_string_util.cc b/net/base/proxy_string_util.cc
index a8e7671..27c907b 100644
--- a/net/base/proxy_string_util.cc
+++ b/net/base/proxy_string_util.cc
@@ -155,6 +155,11 @@
   }
 }
 
+ProxyChain ProxyUriToProxyChain(base::StringPiece uri,
+                                ProxyServer::Scheme default_scheme) {
+  return ProxyChain(ProxyUriToProxyServer(uri, default_scheme));
+}
+
 ProxyServer ProxyUriToProxyServer(base::StringPiece uri,
                                   ProxyServer::Scheme default_scheme) {
   // We will default to |default_scheme| if no scheme specifier was given.
diff --git a/net/base/proxy_string_util.h b/net/base/proxy_string_util.h
index e5c6694..7bb670c 100644
--- a/net/base/proxy_string_util.h
+++ b/net/base/proxy_string_util.h
@@ -9,6 +9,7 @@
 
 #include "base/strings/string_piece.h"
 #include "net/base/net_export.h"
+#include "net/base/proxy_chain.h"
 #include "net/base/proxy_server.h"
 
 namespace net {
@@ -79,6 +80,8 @@
 //   "quic://foopy:17"  {scheme=QUIC, host="foopy", port=17}
 //   "direct://"        {scheme=DIRECT}
 //   "foopy:X"          INVALID -- bad port.
+NET_EXPORT ProxyChain ProxyUriToProxyChain(base::StringPiece uri,
+                                           ProxyServer::Scheme default_scheme);
 NET_EXPORT ProxyServer
 ProxyUriToProxyServer(base::StringPiece uri,
                       ProxyServer::Scheme default_scheme);
diff --git a/net/base/test_proxy_delegate.cc b/net/base/test_proxy_delegate.cc
index 9869a92..5de2dc39 100644
--- a/net/base/test_proxy_delegate.cc
+++ b/net/base/test_proxy_delegate.cc
@@ -20,10 +20,12 @@
 TestProxyDelegate::~TestProxyDelegate() = default;
 
 void TestProxyDelegate::VerifyOnTunnelHeadersReceived(
-    const ProxyServer& proxy_server,
+    const ProxyChain& proxy_chain,
+    size_t chain_index,
     const std::string& response_header_name,
     const std::string& response_header_value) const {
-  EXPECT_EQ(proxy_server, on_tunnel_headers_received_proxy_server_);
+  EXPECT_EQ(proxy_chain, on_tunnel_headers_received_proxy_chain_);
+  EXPECT_EQ(chain_index, on_tunnel_headers_received_chain_index_);
   ASSERT_NE(on_tunnel_headers_received_headers_.get(), nullptr);
   EXPECT_TRUE(on_tunnel_headers_received_headers_->HasHeaderValue(
       response_header_name, response_header_value));
@@ -36,25 +38,31 @@
     const ProxyRetryInfoMap& proxy_retry_info,
     ProxyInfo* result) {}
 
-void TestProxyDelegate::OnFallback(const ProxyServer& bad_proxy,
-                                   int net_error) {}
+void TestProxyDelegate::OnFallback(const ProxyChain& bad_chain, int net_error) {
+}
 
 void TestProxyDelegate::OnBeforeTunnelRequest(
-    const ProxyServer& proxy_server,
+    const ProxyChain& proxy_chain,
+    size_t chain_index,
     HttpRequestHeaders* extra_headers) {
   on_before_tunnel_request_called_ = true;
-  if (extra_headers)
-    extra_headers->SetHeader("Foo", ProxyServerToProxyUri(proxy_server));
+  if (extra_headers) {
+    // TODO(crbug.com/1491092): Include the entire chain in the header.
+    extra_headers->SetHeader("Foo",
+                             ProxyServerToProxyUri(proxy_chain.proxy_server()));
+  }
 }
 
 Error TestProxyDelegate::OnTunnelHeadersReceived(
-    const ProxyServer& proxy_server,
+    const ProxyChain& proxy_chain,
+    size_t chain_index,
     const HttpResponseHeaders& response_headers) {
   EXPECT_EQ(on_tunnel_headers_received_headers_.get(), nullptr);
   on_tunnel_headers_received_headers_ =
       base::MakeRefCounted<HttpResponseHeaders>(response_headers.raw_headers());
 
-  on_tunnel_headers_received_proxy_server_ = proxy_server;
+  on_tunnel_headers_received_proxy_chain_ = proxy_chain;
+  on_tunnel_headers_received_chain_index_ = chain_index;
   return OK;
 }
 
diff --git a/net/base/test_proxy_delegate.h b/net/base/test_proxy_delegate.h
index 7bede51..b5b024e 100644
--- a/net/base/test_proxy_delegate.h
+++ b/net/base/test_proxy_delegate.h
@@ -8,8 +8,8 @@
 #include <string>
 
 #include "base/memory/scoped_refptr.h"
+#include "net/base/proxy_chain.h"
 #include "net/base/proxy_delegate.h"
-#include "net/base/proxy_server.h"
 
 class GURL;
 
@@ -27,7 +27,8 @@
   }
 
   void VerifyOnTunnelHeadersReceived(
-      const ProxyServer& proxy_server,
+      const ProxyChain& proxy_chain,
+      size_t chain_index,
       const std::string& response_header_name,
       const std::string& response_header_value) const;
 
@@ -37,16 +38,19 @@
                       const std::string& method,
                       const ProxyRetryInfoMap& proxy_retry_info,
                       ProxyInfo* result) override;
-  void OnFallback(const ProxyServer& bad_proxy, int net_error) override;
-  void OnBeforeTunnelRequest(const ProxyServer& proxy_server,
+  void OnFallback(const ProxyChain& bad_chain, int net_error) override;
+  void OnBeforeTunnelRequest(const ProxyChain& proxy_chain,
+                             size_t chain_index,
                              HttpRequestHeaders* extra_headers) override;
   Error OnTunnelHeadersReceived(
-      const ProxyServer& proxy_server,
+      const ProxyChain& proxy_chain,
+      size_t chain_index,
       const HttpResponseHeaders& response_headers) override;
 
  private:
   bool on_before_tunnel_request_called_ = false;
-  ProxyServer on_tunnel_headers_received_proxy_server_;
+  ProxyChain on_tunnel_headers_received_proxy_chain_;
+  size_t on_tunnel_headers_received_chain_index_;
   scoped_refptr<HttpResponseHeaders> on_tunnel_headers_received_headers_;
 };
 
diff --git a/net/cert/cert_verify_proc_builtin.cc b/net/cert/cert_verify_proc_builtin.cc
index 5d4bed8..38d8c49 100644
--- a/net/cert/cert_verify_proc_builtin.cc
+++ b/net/cert/cert_verify_proc_builtin.cc
@@ -8,12 +8,14 @@
 #include <string>
 #include <vector>
 
+#include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/memory/raw_ptr.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/strings/string_piece.h"
 #include "base/values.h"
 #include "crypto/sha2.h"
+#include "net/base/features.h"
 #include "net/base/net_errors.h"
 #include "net/cert/cert_net_fetcher.h"
 #include "net/cert/cert_status_flags.h"
@@ -46,8 +48,10 @@
 namespace {
 
 // Very conservative iteration count limit.
-// TODO(https://crbug.com/634470): Make this smaller.
+// TODO(https://crbug.com/634470): Remove this in favor of
+// kPathBuilderIterationLimitNew.
 constexpr uint32_t kPathBuilderIterationLimit = 25000;
+constexpr uint32_t kPathBuilderIterationLimitNew = 20;
 
 constexpr base::TimeDelta kMaxVerificationTime = base::Seconds(60);
 
@@ -622,7 +626,12 @@
     }
   }
 
-  path_builder.SetIterationLimit(kPathBuilderIterationLimit);
+  if (base::FeatureList::IsEnabled(
+          features::kNewCertPathBuilderIterationLimit)) {
+    path_builder.SetIterationLimit(kPathBuilderIterationLimitNew);
+  } else {
+    path_builder.SetIterationLimit(kPathBuilderIterationLimit);
+  }
 
   return path_builder.Run();
 }
diff --git a/net/cert/cert_verify_proc_builtin_unittest.cc b/net/cert/cert_verify_proc_builtin_unittest.cc
index 07ee736..775e1cc 100644
--- a/net/cert/cert_verify_proc_builtin_unittest.cc
+++ b/net/cert/cert_verify_proc_builtin_unittest.cc
@@ -12,8 +12,10 @@
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/thread_pool.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/time/time.h"
+#include "net/base/features.h"
 #include "net/base/test_completion_callback.h"
 #include "net/cert/cert_verify_proc.h"
 #include "net/cert/crl_set.h"
@@ -24,6 +26,7 @@
 #include "net/cert/pki/trust_store_in_memory.h"
 #include "net/cert/time_conversions.h"
 #include "net/cert_net/cert_net_fetcher_url_request.h"
+#include "net/http/transport_security_state.h"
 #include "net/log/net_log_with_source.h"
 #include "net/log/test_net_log.h"
 #include "net/test/cert_builder.h"
@@ -157,8 +160,6 @@
 
 class CertVerifyProcBuiltinTest : public ::testing::Test {
  public:
-  // CertVerifyProcBuiltinTest() {}
-
   void SetUp() override {
     cert_net_fetcher_ = base::MakeRefCounted<CertNetFetcherURLRequest>();
     auto mock_system_trust_store = std::make_unique<MockSystemTrustStore>();
@@ -218,6 +219,8 @@
     mock_system_trust_store_->SetMockIsKnownRoot(is_known_root);
   }
 
+  net::URLRequestContext* context() { return context_.get(); }
+
  private:
   base::test::TaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME,
@@ -234,6 +237,42 @@
   scoped_refptr<CertNetFetcherURLRequest> cert_net_fetcher_;
 };
 
+TEST_F(CertVerifyProcBuiltinTest, ShouldBypassHSTS) {
+  auto [leaf, root] = CertBuilder::CreateSimpleChain2();
+
+  EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP);
+  ASSERT_TRUE(test_server.InitializeAndListen());
+
+  // CRL that marks leaf as revoked.
+  leaf->SetCrlDistributionPointUrl(
+      CreateAndServeCrl(&test_server, root.get(), {leaf->GetSerialNumber()}));
+
+  test_server.StartAcceptingConnections();
+
+  {
+    scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
+    ASSERT_TRUE(chain.get());
+
+    NetLogSource verify_net_log_source;
+    CertVerifyResult verify_result;
+    TestCompletionCallback verify_callback;
+    // Ensure HSTS upgrades for the domain which hosts the CRLs.
+    context()->transport_security_state()->AddHSTS(
+        test_server.base_url().host(), base::Time::Now() + base::Seconds(30),
+        /*include_subdomains=*/true);
+    ASSERT_TRUE(context()->transport_security_state()->ShouldUpgradeToSSL(
+        test_server.base_url().host()));
+    Verify(chain.get(), "www.example.com",
+           CertVerifyProc::VERIFY_REV_CHECKING_ENABLED,
+           /*additional_trust_anchors=*/{root->GetX509Certificate()},
+           &verify_result, &verify_net_log_source, verify_callback.callback());
+
+    int error = verify_callback.WaitForResult();
+    EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
+    EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
+  }
+}
+
 TEST_F(CertVerifyProcBuiltinTest, SimpleSuccess) {
   auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
 
@@ -756,4 +795,102 @@
   EXPECT_THAT(error, IsOk());
 }
 
+class CertVerifyProcBuiltinIterationTest
+    : public CertVerifyProcBuiltinTest,
+      public testing::WithParamInterface<bool> {
+ public:
+  CertVerifyProcBuiltinIterationTest() {
+    if (new_iteration_limit()) {
+      feature_list_.InitAndEnableFeature(
+          features::kNewCertPathBuilderIterationLimit);
+    } else {
+      feature_list_.InitAndDisableFeature(
+          features::kNewCertPathBuilderIterationLimit);
+    }
+  }
+
+  bool new_iteration_limit() const { return GetParam(); }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+TEST_P(CertVerifyProcBuiltinIterationTest, IterationLimit) {
+  // Create a chain which will require many iterations in the path builder.
+  std::vector<std::unique_ptr<CertBuilder>> builders =
+      CertBuilder::CreateSimpleChain(6);
+
+  base::Time not_before = base::Time::Now() - base::Days(1);
+  base::Time not_after = base::Time::Now() + base::Days(1);
+  for (auto& builder : builders) {
+    builder->SetValidity(not_before, not_after);
+  }
+
+  // Generate certificates, making two versions of each intermediate.
+  std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
+  for (size_t i = 1; i < builders.size(); i++) {
+    intermediates.push_back(builders[i]->DupCertBuffer());
+    builders[i]->SetValidity(not_before, not_after + base::Seconds(1));
+    intermediates.push_back(builders[i]->DupCertBuffer());
+  }
+
+  // The above alone is enough to make the path builder explore many paths, but
+  // it will always return the best path it has found, so the error will be the
+  // same. Instead, arrange for all those paths to be invalid (untrusted root),
+  // and add a separate chain that is valid.
+  CertBuilder root_ok(/*orig_cert=*/builders[2]->GetCertBuffer(),
+                      /*issuer=*/nullptr);
+  CertBuilder intermediate_ok(/*orig_cert=*/builders[1]->GetCertBuffer(),
+                              /*issuer=*/&root_ok);
+  // Using the old intermediate as a template does not preserve the subject,
+  // SKID, or key.
+  intermediate_ok.SetSubjectTLV(
+      base::as_bytes(base::make_span(builders[1]->GetSubject())));
+  intermediate_ok.SetKey(bssl::UpRef(builders[1]->GetKey()));
+  intermediate_ok.SetSubjectKeyIdentifier(
+      builders[1]->GetSubjectKeyIdentifier());
+  // Make the valid intermediate older than the invalid ones, so that it is
+  // explored last.
+  intermediate_ok.SetValidity(not_before - base::Seconds(10),
+                              not_after - base::Seconds(10));
+  intermediates.push_back(intermediate_ok.DupCertBuffer());
+
+  // Verify the chain.
+  ScopedTestRoot scoped_root(root_ok.GetX509Certificate().get());
+  scoped_refptr<X509Certificate> chain = X509Certificate::CreateFromBuffer(
+      builders[0]->DupCertBuffer(), std::move(intermediates));
+  ASSERT_TRUE(chain.get());
+
+  RecordingNetLogObserver net_log_observer(NetLogCaptureMode::kDefault);
+  int flags = 0;
+  CertVerifyResult verify_result;
+  NetLogSource verify_net_log_source;
+  TestCompletionCallback callback;
+  Verify(chain.get(), "www.example.com", flags, CertificateList(),
+         &verify_result, &verify_net_log_source, callback.callback());
+  int error = callback.WaitForResult();
+
+  auto events = net_log_observer.GetEntriesForSource(verify_net_log_source);
+  auto event = base::ranges::find_if(events, [](const NetLogEntry& e) {
+    return e.type == NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT &&
+           e.phase == NetLogEventPhase::END;
+  });
+  ASSERT_NE(event, events.end());
+
+  if (new_iteration_limit()) {
+    // The path builder gives up before it finishes all the invalid paths.
+    EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
+    EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
+    EXPECT_EQ(true, event->params.FindBool("exceeded_iteration_limit"));
+  } else {
+    // After exploring many dead ends, the path builder finds the valid path.
+    EXPECT_THAT(error, IsOk());
+    EXPECT_FALSE(event->params.Find("exceeded_iteration_limit"));
+  }
+}
+
+INSTANTIATE_TEST_SUITE_P(NewLimit,
+                         CertVerifyProcBuiltinIterationTest,
+                         testing::Bool());
+
 }  // namespace net
diff --git a/net/cert_net/cert_net_fetcher_url_request.cc b/net/cert_net/cert_net_fetcher_url_request.cc
index 4ca53ce..baae518 100644
--- a/net/cert_net/cert_net_fetcher_url_request.cc
+++ b/net/cert_net/cert_net_fetcher_url_request.cc
@@ -534,6 +534,12 @@
       IsolationInfo::RequestType::kOther, origin /* top_frame_origin */,
       origin /* frame_origin */, SiteForCookies()));
 
+  // Ensure that we bypass HSTS for all requests sent through
+  // CertNetFetcherURLRequest, since AIA/CRL/OCSP requests must be in HTTP to
+  // avoid circular dependencies.
+  url_request_->SetLoadFlags(url_request_->load_flags() |
+                             net::LOAD_SHOULD_BYPASS_HSTS);
+
   url_request_->Start();
 
   // Start a timer to limit how long the job runs for.
diff --git a/net/dns/host_cache.cc b/net/dns/host_cache.cc
index 2a20476..3326d94 100644
--- a/net/dns/host_cache.cc
+++ b/net/dns/host_cache.cc
@@ -278,7 +278,8 @@
   std::unique_ptr<HostResolverInternalResult> error_result;
   std::vector<std::unique_ptr<HostResolverInternalResult>> alias_results;
 
-  absl::optional<base::TimeDelta> smallest_ttl;
+  absl::optional<base::TimeDelta> smallest_ttl =
+      TtlFromInternalResults(results, now, now_ticks);
   absl::optional<Source> source;
   for (auto it = results.cbegin(); it != results.cend();) {
     // Increment iterator now to allow extracting `result` (std::set::extract()
@@ -286,15 +287,6 @@
     // the extracted value).
     const std::unique_ptr<HostResolverInternalResult>& result = *it++;
 
-    if (result->expiration().has_value()) {
-      smallest_ttl = std::min(smallest_ttl.value_or(base::TimeDelta::Max()),
-                              result->expiration().value() - now_ticks);
-    }
-    if (result->timed_expiration().has_value()) {
-      smallest_ttl = std::min(smallest_ttl.value_or(base::TimeDelta::Max()),
-                              result->timed_expiration().value() - now);
-    }
-
     Source result_source;
     switch (result->source()) {
       case HostResolverInternalResult::Source::kDns:
@@ -669,6 +661,25 @@
 }
 
 // static
+absl::optional<base::TimeDelta> HostCache::Entry::TtlFromInternalResults(
+    const std::set<std::unique_ptr<HostResolverInternalResult>>& results,
+    base::Time now,
+    base::TimeTicks now_ticks) {
+  absl::optional<base::TimeDelta> smallest_ttl;
+  for (const std::unique_ptr<HostResolverInternalResult>& result : results) {
+    if (result->expiration().has_value()) {
+      smallest_ttl = std::min(smallest_ttl.value_or(base::TimeDelta::Max()),
+                              result->expiration().value() - now_ticks);
+    }
+    if (result->timed_expiration().has_value()) {
+      smallest_ttl = std::min(smallest_ttl.value_or(base::TimeDelta::Max()),
+                              result->timed_expiration().value() - now);
+    }
+  }
+  return smallest_ttl;
+}
+
+// static
 const HostCache::EntryStaleness HostCache::kNotStale = {base::Seconds(-1), 0,
                                                         0};
 
diff --git a/net/dns/host_cache.h b/net/dns/host_cache.h
index b38a214c..b2d1bfb 100644
--- a/net/dns/host_cache.h
+++ b/net/dns/host_cache.h
@@ -264,6 +264,11 @@
     // set to |port| if the current port is 0. Preserves any non-zero ports.
     HostCache::Entry CopyWithDefaultPort(uint16_t port) const;
 
+    static absl::optional<base::TimeDelta> TtlFromInternalResults(
+        const std::set<std::unique_ptr<HostResolverInternalResult>>& results,
+        base::Time now,
+        base::TimeTicks now_ticks);
+
    private:
     using HttpsRecordPriority = uint16_t;
 
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc
index 4cbbcf9..6b1dc26 100644
--- a/net/dns/host_resolver_manager.cc
+++ b/net/dns/host_resolver_manager.cc
@@ -241,12 +241,10 @@
 
 base::Value::Dict NetLogDnsTaskExtractionFailureParams(
     DnsResponseResultExtractor::ExtractionError extraction_error,
-    DnsQueryType dns_query_type,
-    const HostCache::Entry& results) {
+    DnsQueryType dns_query_type) {
   base::Value::Dict dict;
   dict.Set("extraction_error", base::strict_cast<int>(extraction_error));
   dict.Set("dns_query_type", kDnsQueryTypes.at(dns_query_type));
-  dict.Set("results", results.NetLogParams());
   return dict;
 }
 
@@ -1204,6 +1202,8 @@
   }
 
  private:
+  using Results = std::set<std::unique_ptr<HostResolverInternalResult>>;
+
   enum class TransactionErrorBehavior {
     // Errors lead to task fallback (immediately unless another pending/started
     // transaction has the `kFatalOrEmpty` behavior).
@@ -1477,25 +1477,12 @@
         results.error_or(DnsResponseResultExtractor::ExtractionError::kOk),
         DnsResponseResultExtractor::ExtractionError::kUnexpected);
 
-    // TODO(crbug.com/1381506): Use new results type directly instead of
-    // converting to HostCache::Entry.
-    DnsResponseResultExtractor::ExtractionError extraction_error =
-        results.error_or(DnsResponseResultExtractor::ExtractionError::kOk);
-    HostCache::Entry legacy_results(ERR_DNS_MALFORMED_RESPONSE,
-                                    HostCache::Entry::SOURCE_DNS);
-    if (results.has_value()) {
-      legacy_results = HostCache::Entry(
-          std::move(results).value(), base::Time::Now(),
-          tick_clock_->NowTicks(), HostCache::Entry::SOURCE_DNS);
-    }
-
-    if (legacy_results.error() != OK &&
-        legacy_results.error() != ERR_NAME_NOT_RESOLVED) {
+    if (!results.has_value()) {
       net_log_.AddEvent(
           NetLogEventType::HOST_RESOLVER_MANAGER_DNS_TASK_EXTRACTION_FAILURE,
           [&] {
-            return NetLogDnsTaskExtractionFailureParams(
-                extraction_error, transaction_info.type, legacy_results);
+            return NetLogDnsTaskExtractionFailureParams(results.error(),
+                                                        transaction_info.type);
           });
       if (transaction_info.error_behavior ==
               TransactionErrorBehavior::kFatalOrEmpty ||
@@ -1506,21 +1493,30 @@
         // IsFatalTransactionExtractionError() function.
         DCHECK(!fatal_error);
         DCHECK_EQ(transaction_info.type, DnsQueryType::HTTPS);
-        legacy_results =
-            HostCache::Entry(ERR_NAME_NOT_RESOLVED, std::vector<bool>(),
-                             HostCache::Entry::SOURCE_DNS);
+        results = Results();
       } else {
-        OnFailure(legacy_results.error(), /*allow_fallback=*/true,
-                  legacy_results.GetOptionalTtl(), transaction_info.type);
+        OnFailure(ERR_DNS_MALFORMED_RESPONSE, /*allow_fallback=*/true,
+                  /*ttl=*/absl::nullopt, transaction_info.type);
         return;
       }
     }
+    CHECK(results.has_value());
 
     if (httpssvc_metrics_) {
       if (transaction_info.type == DnsQueryType::HTTPS) {
-        httpssvc_metrics_->SaveForHttps(
-            rcode_for_httpssvc, legacy_results.https_record_compatibility(),
-            elapsed_time);
+        bool has_compatible_https = base::ranges::any_of(
+            results.value(),
+            [](const std::unique_ptr<HostResolverInternalResult>& result) {
+              return result->type() ==
+                     HostResolverInternalResult::Type::kMetadata;
+            });
+        if (has_compatible_https) {
+          httpssvc_metrics_->SaveForHttps(
+              rcode_for_httpssvc, std::vector<bool>{true}, elapsed_time);
+        } else {
+          httpssvc_metrics_->SaveForHttps(rcode_for_httpssvc,
+                                          std::vector<bool>(), elapsed_time);
+        }
       } else {
         httpssvc_metrics_->SaveForAddressQuery(elapsed_time,
                                                rcode_for_httpssvc);
@@ -1530,16 +1526,17 @@
     // Trigger HTTP->HTTPS upgrade if an HTTPS record is received for an "http"
     // or "ws" request.
     if (transaction_info.type == DnsQueryType::HTTPS &&
-        ShouldTriggerHttpToHttpsUpgrade(legacy_results)) {
+        ShouldTriggerHttpToHttpsUpgrade(results.value())) {
       // Disallow fallback. Otherwise DNS could be reattempted without HTTPS
       // queries, and that would hide this error instead of triggering upgrade.
-      OnFailure(ERR_DNS_NAME_HTTPS_ONLY, /*allow_fallback=*/false,
-                legacy_results.GetOptionalTtl(), transaction_info.type);
+      OnFailure(
+          ERR_DNS_NAME_HTTPS_ONLY, /*allow_fallback=*/false,
+          HostCache::Entry::TtlFromInternalResults(
+              results.value(), base::Time::Now(), tick_clock_->NowTicks()),
+          transaction_info.type);
       return;
     }
 
-    HideMetadataResultsIfNotDesired(legacy_results);
-
     switch (transaction_info.type) {
       case DnsQueryType::A:
         a_record_end_time_ = now;
@@ -1568,6 +1565,12 @@
         break;
     }
 
+    // TODO(crbug.com/1381506): Use new results type directly instead of
+    // converting to HostCache::Entry.
+    HostCache::Entry legacy_results(std::move(results).value(),
+                                    base::Time::Now(), tick_clock_->NowTicks(),
+                                    HostCache::Entry::SOURCE_DNS);
+
     // Merge results with saved results from previous transactions.
     if (saved_results_) {
       // If saved result is a deferred failure, try again to complete with that
@@ -1871,31 +1874,19 @@
           base::BindOnce(&DnsTask::OnTimeout, base::Unretained(this)));
   }
 
-  bool ShouldTriggerHttpToHttpsUpgrade(const HostCache::Entry& results) {
+  bool ShouldTriggerHttpToHttpsUpgrade(const Results& results) {
     // Upgrade if at least one HTTPS record was compatible, and the host uses an
     // upgradable scheme.
-    return base::ranges::any_of(results.https_record_compatibility(),
-                                base::identity()) &&
+    return base::ranges::any_of(
+               results,
+               [](const std::unique_ptr<HostResolverInternalResult>& result) {
+                 return result->type() ==
+                        HostResolverInternalResult::Type::kMetadata;
+               }) &&
            (GetScheme(host_) == url::kHttpScheme ||
             GetScheme(host_) == url::kWsScheme);
   }
 
-  // Only keep metadata results (from HTTPS records) for appropriate schemes.
-  // This is needed to ensure metadata isn't included in results if the current
-  // Feature setup allows querying HTTPS for http:// or ws:// but doesn't enable
-  // scheme upgrade to error out on finding an HTTPS record.
-  //
-  // TODO(crbug.com/1206455): Remove once all requests that query HTTPS will
-  // either allow metadata results or error out.
-  void HideMetadataResultsIfNotDesired(HostCache::Entry& results) {
-    if (GetScheme(host_) == url::kHttpsScheme ||
-        GetScheme(host_) == url::kWssScheme) {
-      return;
-    }
-
-    results.ClearMetadatas();
-  }
-
   const raw_ptr<DnsClient> client_;
 
   absl::variant<url::SchemeHostPort, std::string> host_;
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index c553d9e..5bdd7095 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -381,11 +381,13 @@
     if (proxy_server_.is_valid())
       result->UseProxyServer(proxy_server_);
   }
-  void OnFallback(const ProxyServer& bad_proxy, int net_error) override {}
-  void OnBeforeTunnelRequest(const ProxyServer& proxy_server,
+  void OnFallback(const ProxyChain& bad_chain, int net_error) override {}
+  void OnBeforeTunnelRequest(const ProxyChain& proxy_chain,
+                             size_t chain_index,
                              HttpRequestHeaders* extra_headers) override {}
   Error OnTunnelHeadersReceived(
-      const ProxyServer& proxy_server,
+      const ProxyChain& proxy_chain,
+      size_t chain_index,
       const HttpResponseHeaders& response_headers) override {
     return OK;
   }
diff --git a/net/http/http_proxy_client_socket.cc b/net/http/http_proxy_client_socket.cc
index b6bd7f0..60fefa5 100644
--- a/net/http/http_proxy_client_socket.cc
+++ b/net/http/http_proxy_client_socket.cc
@@ -14,6 +14,7 @@
 #include "net/base/auth.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/io_buffer.h"
+#include "net/base/proxy_chain.h"
 #include "net/base/proxy_delegate.h"
 #include "net/base/proxy_server.h"
 #include "net/http/http_basic_stream.h"
@@ -352,8 +353,9 @@
 
     if (proxy_delegate_) {
       HttpRequestHeaders proxy_delegate_headers;
-      proxy_delegate_->OnBeforeTunnelRequest(proxy_server_,
-                                             &proxy_delegate_headers);
+      // TODO(crbug.com/1491092): Provide the full chain with appropriate index.
+      proxy_delegate_->OnBeforeTunnelRequestServerOnly(proxy_server_,
+                                                       &proxy_delegate_headers);
       extra_headers.MergeFrom(proxy_delegate_headers);
     }
 
@@ -404,8 +406,9 @@
       response_.headers.get());
 
   if (proxy_delegate_) {
-    int rv = proxy_delegate_->OnTunnelHeadersReceived(proxy_server_,
-                                                      *response_.headers);
+    // TODO(crbug.com/1491092): Provide the full chain with appropriate index.
+    int rv = proxy_delegate_->OnTunnelHeadersReceivedServerOnly(
+        proxy_server_, *response_.headers);
     if (rv != OK) {
       DCHECK_NE(ERR_IO_PENDING, rv);
       return rv;
diff --git a/net/http/http_proxy_connect_job_unittest.cc b/net/http/http_proxy_connect_job_unittest.cc
index 9f9a9fc7..f2870e5b 100644
--- a/net/http/http_proxy_connect_job_unittest.cc
+++ b/net/http/http_proxy_connect_job_unittest.cc
@@ -532,7 +532,7 @@
   test_delegate.StartJobExpectingResult(connect_job.get(), OK,
                                         false /* expect_sync_result */);
   proxy_delegate_->VerifyOnTunnelHeadersReceived(
-      proxy_server, kResponseHeaderName, kResponseHeaderValue);
+      ProxyChain(proxy_server), 0, kResponseHeaderName, kResponseHeaderValue);
 }
 
 // Test the case where auth credentials are not cached.
diff --git a/net/http/proxy_fallback.h b/net/http/proxy_fallback.h
index e72545f0..f574df48 100644
--- a/net/http/proxy_fallback.h
+++ b/net/http/proxy_fallback.h
@@ -19,7 +19,7 @@
 //         return "PROXY foobar1:8080; HTTPS foobar2:8080; DIRECT";
 //
 //   * Re-ordering the proxy list such that proxies that have recently failed
-//     are given lower priority (ProxyInfo::DeprioritizeBadProxies)
+//     are given lower priority (ProxyInfo::DeprioritizeBadProxyChains)
 //
 //   * Maintaining the expiring cache of proxies that have recently failed.
 //
diff --git a/net/http/transport_security_state_static.pins b/net/http/transport_security_state_static.pins
index 47adf7fd..942e508 100644
--- a/net/http/transport_security_state_static.pins
+++ b/net/http/transport_security_state_static.pins
@@ -43,9 +43,9 @@
 #   hash function for preloaded entries again (we have already done so once).
 #
 
-# Last updated: 2023-10-17 12:54 UTC
+# Last updated: 2023-10-18 12:54 UTC
 PinsListTimestamp
-1697547275
+1697633654
 
 TestSPKI
 sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/net/http/transport_security_state_static_pins.json b/net/http/transport_security_state_static_pins.json
index a3e5d51..98d3cd45 100644
--- a/net/http/transport_security_state_static_pins.json
+++ b/net/http/transport_security_state_static_pins.json
@@ -31,7 +31,7 @@
 // the 'static_spki_hashes' and 'bad_static_spki_hashes' fields in 'pinsets'
 // refer to, and the timestamp at which the pins list was last updated.
 //
-// Last updated: 2023-10-17 12:54 UTC
+// Last updated: 2023-10-18 12:54 UTC
 //
 {
   "pinsets": [
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h
index dd27662..8038dfc 100644
--- a/net/log/net_log_event_type_list.h
+++ b/net/log/net_log_event_type_list.h
@@ -232,7 +232,6 @@
 //   {
 //     "extraction_error": <The DnsResponseResultExtractor::ExtractionError>
 //     "dns_query_type": <The DnsQueryType requested from the extractor>
-//     "results": <The HostCache::Entry returned by the extractor>
 //   }
 EVENT_TYPE(HOST_RESOLVER_MANAGER_DNS_TASK_EXTRACTION_FAILURE)
 
diff --git a/net/proxy_resolution/configured_proxy_resolution_service.cc b/net/proxy_resolution/configured_proxy_resolution_service.cc
index 748e2210..5641f71 100644
--- a/net/proxy_resolution/configured_proxy_resolution_service.cc
+++ b/net/proxy_resolution/configured_proxy_resolution_service.cc
@@ -1137,10 +1137,13 @@
     if (existing == proxy_retry_info_.end()) {
       proxy_retry_info_[iter.first] = iter.second;
       if (proxy_delegate_) {
+        // TODO(crbug.com/1491092): Provide the full chain when that is
+        // available from retry info, and never provide a direct chain.
         const ProxyServer& bad_proxy =
             ProxyUriToProxyServer(iter.first, ProxyServer::SCHEME_HTTP);
         const ProxyRetryInfo& proxy_retry_info = iter.second;
-        proxy_delegate_->OnFallback(bad_proxy, proxy_retry_info.net_error);
+        proxy_delegate_->OnFallbackServerOnly(bad_proxy,
+                                              proxy_retry_info.net_error);
       }
     } else if (existing->second.bad_until < iter.second.bad_until) {
       existing->second.bad_until = iter.second.bad_until;
@@ -1188,7 +1191,7 @@
     // This check is done to only log the NetLog event when necessary, it's
     // not a performance optimization.
     if (!proxy_retry_info_.empty()) {
-      result->DeprioritizeBadProxies(proxy_retry_info_);
+      result->DeprioritizeBadProxyChains(proxy_retry_info_);
       net_log.AddEvent(
           NetLogEventType::PROXY_RESOLUTION_SERVICE_DEPRIORITIZED_BAD_PROXIES,
           [&] { return NetLogFinishedResolvingProxyParams(result); });
diff --git a/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc b/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc
index 4f84654..28a21f3 100644
--- a/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc
+++ b/net/proxy_resolution/configured_proxy_resolution_service_unittest.cc
@@ -233,13 +233,15 @@
     return proxy_retry_info_;
   }
 
-  void OnFallback(const ProxyServer& bad_proxy, int net_error) override {}
+  void OnFallback(const ProxyChain& bad_chain, int net_error) override {}
 
-  void OnBeforeTunnelRequest(const ProxyServer& proxy_server,
+  void OnBeforeTunnelRequest(const ProxyChain& proxy_chain,
+                             size_t chain_index,
                              HttpRequestHeaders* extra_headers) override {}
 
   Error OnTunnelHeadersReceived(
-      const ProxyServer& proxy_server,
+      const ProxyChain& proxy_chain,
+      size_t chain_index,
       const HttpResponseHeaders& response_headers) override {
     return OK;
   }
@@ -262,24 +264,26 @@
                       const ProxyRetryInfoMap& proxy_retry_info,
                       ProxyInfo* result) override {}
 
-  void OnFallback(const ProxyServer& bad_proxy, int net_error) override {
-    proxy_server_ = bad_proxy;
+  void OnFallback(const ProxyChain& bad_chain, int net_error) override {
+    proxy_chain_ = bad_chain;
     last_proxy_fallback_net_error_ = net_error;
     num_proxy_fallback_called_++;
   }
 
-  void OnBeforeTunnelRequest(const ProxyServer& proxy_server,
+  void OnBeforeTunnelRequest(const ProxyChain& proxy_chain,
+                             size_t chain_index,
                              HttpRequestHeaders* extra_headers) override {}
 
   Error OnTunnelHeadersReceived(
-      const ProxyServer& proxy_server,
+      const ProxyChain& proxy_chain,
+      size_t chain_index,
       const HttpResponseHeaders& response_headers) override {
     return OK;
   }
 
   bool num_proxy_fallback_called() const { return num_proxy_fallback_called_; }
 
-  const ProxyServer& proxy_server() const { return proxy_server_; }
+  const ProxyChain& proxy_chain() const { return proxy_chain_; }
 
   int last_proxy_fallback_net_error() const {
     return last_proxy_fallback_net_error_;
@@ -287,7 +291,7 @@
 
  private:
   int num_proxy_fallback_called_ = 0;
-  ProxyServer proxy_server_;
+  ProxyChain proxy_chain_;
   int last_proxy_fallback_net_error_ = OK;
 };
 
@@ -1621,7 +1625,7 @@
   TestProxyFallbackProxyDelegate test_delegate;
   service.SetProxyDelegate(&test_delegate);
   service.ReportSuccess(info);
-  EXPECT_EQ("foopy1:8080", ProxyServerToProxyUri(test_delegate.proxy_server()));
+  EXPECT_EQ("foopy1:8080", test_delegate.proxy_chain().ToDebugString());
   EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED,
             test_delegate.last_proxy_fallback_net_error());
   service.SetProxyDelegate(nullptr);
diff --git a/net/proxy_resolution/proxy_info.cc b/net/proxy_resolution/proxy_info.cc
index 4b45b88..70c5912 100644
--- a/net/proxy_resolution/proxy_info.cc
+++ b/net/proxy_resolution/proxy_info.cc
@@ -43,6 +43,11 @@
   proxy_list_.SetSingleProxyServer(proxy_server);
 }
 
+void ProxyInfo::UseProxyChain(const ProxyChain& proxy_chain) {
+  Reset();
+  proxy_list_.SetSingleProxyChain(proxy_chain);
+}
+
 void ProxyInfo::UsePacString(const std::string& pac_string) {
   Reset();
   proxy_list_.SetFromPacString(pac_string);
@@ -65,9 +70,9 @@
   return proxy_list_.Fallback(&proxy_retry_info_, net_error, net_log);
 }
 
-void ProxyInfo::DeprioritizeBadProxies(
+void ProxyInfo::DeprioritizeBadProxyChains(
     const ProxyRetryInfoMap& proxy_retry_info) {
-  proxy_list_.DeprioritizeBadProxies(proxy_retry_info);
+  proxy_list_.DeprioritizeBadProxyChains(proxy_retry_info);
 }
 
 void ProxyInfo::RemoveProxiesWithoutScheme(int scheme_bit_field) {
diff --git a/net/proxy_resolution/proxy_info.h b/net/proxy_resolution/proxy_info.h
index 7120ef5f..8a3662eb 100644
--- a/net/proxy_resolution/proxy_info.h
+++ b/net/proxy_resolution/proxy_info.h
@@ -19,6 +19,7 @@
 namespace net {
 
 class NetLogWithSource;
+class ProxyChain;
 
 // This object holds proxy information returned by ResolveProxy.
 class NET_EXPORT ProxyInfo {
@@ -45,8 +46,12 @@
   void UseNamedProxy(const std::string& proxy_uri_list);
 
   // Sets the proxy list to a single entry, |proxy_server|.
+  // TODO(crbug.com/1491092): Remove this method, as it is only used in a test.
   void UseProxyServer(const ProxyServer& proxy_server);
 
+  // Sets the proxy list to a single entry, |proxy_chain|.
+  void UseProxyChain(const ProxyChain& proxy_chain);
+
   // Parses from the given PAC result.
   void UsePacString(const std::string& pac_string);
 
@@ -131,10 +136,15 @@
   // Returns true if this proxy info is for IP Protection.
   bool is_for_ip_protection() const { return is_for_ip_protection_; }
 
-  // Returns the first valid proxy server. is_empty() must be false to be able
-  // to call this function.
+  // Returns the first valid proxy server. `is_empty()` must be false to be able
+  // to call this function, and the first chain must not be multi-proxy.
+  // TODO(crbug.com/1491092): Remove this method.
   const ProxyServer& proxy_server() const { return proxy_list_.Get(); }
 
+  // Returns the first valid proxy chain. is_empty() must be false to be able
+  // to call this function.
+  const ProxyChain& proxy_chain() const { return proxy_list_.First(); }
+
   // Returns the full list of proxies to use.
   const ProxyList& proxy_list() const { return proxy_list_; }
 
@@ -150,7 +160,7 @@
 
   // De-prioritizes the proxies that we have cached as not working, by moving
   // them to the end of the proxy list.
-  void DeprioritizeBadProxies(const ProxyRetryInfoMap& proxy_retry_info);
+  void DeprioritizeBadProxyChains(const ProxyRetryInfoMap& proxy_retry_info);
 
   // Deletes any entry which doesn't have one of the specified proxy schemes.
   void RemoveProxiesWithoutScheme(int scheme_bit_field);
diff --git a/net/proxy_resolution/proxy_info_unittest.cc b/net/proxy_resolution/proxy_info_unittest.cc
index 75dd0543..ca422b2 100644
--- a/net/proxy_resolution/proxy_info_unittest.cc
+++ b/net/proxy_resolution/proxy_info_unittest.cc
@@ -5,6 +5,7 @@
 #include "net/proxy_resolution/proxy_info.h"
 
 #include "net/base/net_errors.h"
+#include "net/base/proxy_chain.h"
 #include "net/log/net_log_with_source.h"
 #include "net/proxy_resolution/proxy_config.h"
 #include "net/proxy_resolution/proxy_list.h"
@@ -66,4 +67,12 @@
   EXPECT_FALSE(info.is_for_ip_protection());
 }
 
+TEST(ProxyListTest, UseProxyChain) {
+  ProxyInfo info;
+  ProxyChain proxy_chain =
+      ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTP, "foo", 80);
+  info.UseProxyChain(proxy_chain);
+  EXPECT_EQ("PROXY foo:80", info.proxy_list().ToPacString());
+}
+
 }  // namespace net
diff --git a/net/proxy_resolution/proxy_list.cc b/net/proxy_resolution/proxy_list.cc
index 1343507..7e409ae 100644
--- a/net/proxy_resolution/proxy_list.cc
+++ b/net/proxy_resolution/proxy_list.cc
@@ -10,6 +10,7 @@
 #include "base/strings/string_tokenizer.h"
 #include "base/time/time.h"
 #include "base/values.h"
+#include "net/base/proxy_chain.h"
 #include "net/base/proxy_server.h"
 #include "net/base/proxy_string_util.h"
 #include "net/log/net_log.h"
@@ -30,136 +31,187 @@
 
 ProxyList& ProxyList::operator=(ProxyList&& other) = default;
 
-ProxyList::~ProxyList() = default;
+ProxyList::~ProxyList() {
+#if DCHECK_IS_ON()
+  // Validate that the result of `UpdateProxyServers()` is equivalent to the
+  // incremental updates made in other methods.
+  auto proxy_servers = std::move(proxy_servers_);
+  UpdateProxyServers();
+  CHECK(proxy_servers == proxy_servers_);
+#endif
+}
 
 void ProxyList::Set(const std::string& proxy_uri_list) {
-  proxies_.clear();
+  Clear();
   base::StringTokenizer str_tok(proxy_uri_list, ";");
   while (str_tok.GetNext()) {
-    ProxyServer uri =
-        ProxyUriToProxyServer(str_tok.token_piece(), ProxyServer::SCHEME_HTTP);
-    // Silently discard malformed inputs.
-    if (uri.is_valid())
-      proxies_.push_back(uri);
+    ProxyChain chain =
+        ProxyUriToProxyChain(str_tok.token_piece(), ProxyServer::SCHEME_HTTP);
+    AddProxyChain(chain);
   }
 }
 
+void ProxyList::SetSingleProxyChain(const ProxyChain& proxy_chain) {
+  Clear();
+  AddProxyChain(proxy_chain);
+}
+
 void ProxyList::SetSingleProxyServer(const ProxyServer& proxy_server) {
-  proxies_.clear();
+  Clear();
   AddProxyServer(proxy_server);
 }
 
-void ProxyList::AddProxyServer(const ProxyServer& proxy_server) {
-  if (proxy_server.is_valid())
-    proxies_.push_back(proxy_server);
+void ProxyList::AddProxyChain(const ProxyChain& proxy_chain) {
+  // Silently discard malformed inputs.
+  if (proxy_chain.IsValid()) {
+    if (!proxy_chain.is_multi_proxy() && proxy_servers_.has_value()) {
+      proxy_servers_->push_back(proxy_chain.proxy_server());
+    } else {
+      proxy_servers_ = absl::nullopt;
+    }
+    proxy_chains_.push_back(proxy_chain);
+  }
 }
 
-void ProxyList::DeprioritizeBadProxies(
+void ProxyList::AddProxyServer(const ProxyServer& proxy_server) {
+  AddProxyChain(ProxyChain(proxy_server));
+}
+
+void ProxyList::DeprioritizeBadProxyChains(
     const ProxyRetryInfoMap& proxy_retry_info) {
   // Partition the proxy list in two:
-  //   (1) the known bad proxies
+  //   (1) the known bad proxy chains
   //   (2) everything else
-  std::vector<ProxyServer> good_proxies;
-  std::vector<ProxyServer> bad_proxies_to_try;
+  std::vector<ProxyChain> good_chains;
+  std::vector<ProxyChain> bad_chains_to_try;
 
-  std::vector<ProxyServer>::const_iterator iter = proxies_.begin();
-  for (; iter != proxies_.end(); ++iter) {
-    auto bad_proxy = proxy_retry_info.find(ProxyServerToProxyUri(*iter));
-    if (bad_proxy != proxy_retry_info.end()) {
+  std::vector<ProxyChain>::const_iterator iter = proxy_chains_.begin();
+  for (; iter != proxy_chains_.end(); ++iter) {
+    // TODO(crbug.com/1491092): Store chains in ProxyRetryInfo.
+    auto bad_info =
+        proxy_retry_info.find(ProxyServerToProxyUri(iter->proxy_server()));
+    if (bad_info != proxy_retry_info.end()) {
       // This proxy is bad. Check if it's time to retry.
-      if (bad_proxy->second.bad_until >= TimeTicks::Now()) {
+      if (bad_info->second.bad_until >= TimeTicks::Now()) {
         // still invalid.
-        if (bad_proxy->second.try_while_bad)
-          bad_proxies_to_try.push_back(*iter);
+        if (bad_info->second.try_while_bad) {
+          bad_chains_to_try.push_back(*iter);
+        }
         continue;
       }
     }
-    good_proxies.push_back(*iter);
+    good_chains.push_back(*iter);
   }
 
-  // "proxies_ = good_proxies + bad_proxies"
-  proxies_.swap(good_proxies);
-  proxies_.insert(proxies_.end(), bad_proxies_to_try.begin(),
-                  bad_proxies_to_try.end());
+  // "proxy_chains_ = good_chains + bad_proxies"
+  proxy_chains_.swap(good_chains);
+  proxy_chains_.insert(proxy_chains_.end(), bad_chains_to_try.begin(),
+                       bad_chains_to_try.end());
+
+  UpdateProxyServers();
 }
 
 void ProxyList::RemoveProxiesWithoutScheme(int scheme_bit_field) {
-  for (auto it = proxies_.begin(); it != proxies_.end();) {
-    if (!(scheme_bit_field & it->scheme())) {
-      it = proxies_.erase(it);
+  for (auto it = proxy_chains_.begin(); it != proxy_chains_.end();) {
+    // TODO(crbug.com/1491092): Iterate over all servers in the chain.
+    if (!(scheme_bit_field & it->proxy_server().scheme())) {
+      it = proxy_chains_.erase(it);
       continue;
     }
     ++it;
   }
+
+  UpdateProxyServers();
 }
 
 void ProxyList::Clear() {
-  proxies_.clear();
+  proxy_chains_.clear();
+  UpdateProxyServers();
 }
 
 bool ProxyList::IsEmpty() const {
-  return proxies_.empty();
+  return proxy_chains_.empty();
 }
 
 size_t ProxyList::size() const {
-  return proxies_.size();
+  return proxy_chains_.size();
 }
 
-// Returns true if |*this| lists the same proxies as |other|.
+// Returns true if |*this| lists the same proxy chains as |other|.
 bool ProxyList::Equals(const ProxyList& other) const {
   if (size() != other.size())
     return false;
-  return proxies_ == other.proxies_;
+  // `proxy_servers_` is just a cache, so is not part of the comparison.
+  return proxy_chains_ == other.proxy_chains_;
 }
 
 const ProxyServer& ProxyList::Get() const {
-  CHECK(!proxies_.empty());
-  return proxies_[0];
+  CHECK(!proxy_chains_.empty());
+  return proxy_servers_->front();
+}
+
+const ProxyChain& ProxyList::First() const {
+  CHECK(!proxy_chains_.empty());
+  return proxy_chains_[0];
 }
 
 const std::vector<ProxyServer>& ProxyList::GetAll() const {
-  return proxies_;
+  CHECK(proxy_servers_.has_value())
+      << "ProxyList contains multi-proxy ProxyChains";
+  return *proxy_servers_;
+}
+
+const std::vector<ProxyChain>& ProxyList::AllChains() const {
+  return proxy_chains_;
 }
 
 void ProxyList::SetFromPacString(const std::string& pac_string) {
+  Clear();
   base::StringTokenizer entry_tok(pac_string, ";");
-  proxies_.clear();
   while (entry_tok.GetNext()) {
-    ProxyServer uri = PacResultElementToProxyServer(entry_tok.token_piece());
-    // Silently discard malformed inputs.
-    if (uri.is_valid())
-      proxies_.push_back(uri);
+    // TODO(crbug.com/1491092): Parse multi-proxy chains.
+    ProxyServer proxy_server =
+        PacResultElementToProxyServer(entry_tok.token_piece());
+    if (proxy_server.is_valid()) {
+      proxy_chains_.emplace_back(proxy_server);
+    }
   }
 
   // If we failed to parse anything from the PAC results list, fallback to
   // DIRECT (this basically means an error in the PAC script).
-  if (proxies_.empty()) {
-    proxies_.push_back(ProxyServer::Direct());
+  if (proxy_chains_.empty()) {
+    proxy_chains_.push_back(ProxyChain::Direct());
   }
+
+  UpdateProxyServers();
 }
 
 std::string ProxyList::ToPacString() const {
   std::string proxy_list;
-  auto iter = proxies_.begin();
-  for (; iter != proxies_.end(); ++iter) {
+  auto iter = proxy_chains_.begin();
+  for (; iter != proxy_chains_.end(); ++iter) {
     if (!proxy_list.empty())
       proxy_list += ";";
-    proxy_list += ProxyServerToPacResultElement(*iter);
+    // TODO(crbug.com/1491092): Figure out how to represent a multi-proxy chain.
+    proxy_list += ProxyServerToPacResultElement(iter->proxy_server());
   }
   return proxy_list.empty() ? std::string() : proxy_list;
 }
 
 base::Value ProxyList::ToValue() const {
   base::Value::List list;
-  for (const auto& proxy : proxies_)
-    list.Append(ProxyServerToProxyUri(proxy));
+  for (const auto& proxy_chain : proxy_chains_) {
+    // TODO(crbug.com/1491092): Determine a representation for proxy chains in
+    // Values and use that for chains of length greater than one.
+    list.Append(ProxyServerToProxyUri(proxy_chain.proxy_server()));
+  }
   return base::Value(std::move(list));
 }
 
 bool ProxyList::Fallback(ProxyRetryInfoMap* proxy_retry_info,
                          int net_error,
                          const NetLogWithSource& net_log) {
-  if (proxies_.empty()) {
+  if (proxy_chains_.empty()) {
     NOTREACHED();
     return false;
   }
@@ -168,19 +220,23 @@
                             std::vector<ProxyServer>(), net_error, net_log);
 
   // Remove this proxy from our list.
-  proxies_.erase(proxies_.begin());
-  return !proxies_.empty();
+  proxy_chains_.erase(proxy_chains_.begin());
+  UpdateProxyServers();
+  return !proxy_chains_.empty();
 }
 
-void ProxyList::AddProxyToRetryList(ProxyRetryInfoMap* proxy_retry_info,
-                                    base::TimeDelta retry_delay,
-                                    bool try_while_bad,
-                                    const ProxyServer& proxy_to_retry,
-                                    int net_error,
-                                    const NetLogWithSource& net_log) const {
+void ProxyList::AddProxyChainToRetryList(
+    ProxyRetryInfoMap* proxy_retry_info,
+    base::TimeDelta retry_delay,
+    bool try_while_bad,
+    const ProxyChain& proxy_chain_to_retry,
+    int net_error,
+    const NetLogWithSource& net_log) const {
   // Mark this proxy as bad.
   TimeTicks bad_until = TimeTicks::Now() + retry_delay;
-  std::string proxy_key = ProxyServerToProxyUri(proxy_to_retry);
+  // TODO(crbug.com/1491092): Key retry info by proxy chain.
+  std::string proxy_key =
+      ProxyServerToProxyUri(proxy_chain_to_retry.proxy_server());
   auto iter = proxy_retry_info->find(proxy_key);
   if (iter == proxy_retry_info->end() || bad_until > iter->second.bad_until) {
     ProxyRetryInfo retry_info;
@@ -198,30 +254,46 @@
     ProxyRetryInfoMap* proxy_retry_info,
     base::TimeDelta retry_delay,
     bool reconsider,
+    // TODO(crbug.com/1491092): Take a vector of ProxyChains instead.
     const std::vector<ProxyServer>& additional_proxies_to_bypass,
     int net_error,
     const NetLogWithSource& net_log) const {
   DCHECK(!retry_delay.is_zero());
 
-  if (proxies_.empty()) {
+  if (proxy_chains_.empty()) {
     NOTREACHED();
     return;
   }
 
-  if (!proxies_[0].is_direct()) {
-    AddProxyToRetryList(proxy_retry_info,
-                        retry_delay,
-                        reconsider,
-                        proxies_[0],
-                        net_error,
-                        net_log);
+  auto& first_chain = proxy_chains_[0];
+  if (!first_chain.is_direct()) {
+    AddProxyChainToRetryList(proxy_retry_info, retry_delay, reconsider,
+                             first_chain, net_error, net_log);
     // If any additional proxies to bypass are specified, add to the retry map
     // as well.
     for (const ProxyServer& additional_proxy : additional_proxies_to_bypass) {
-      AddProxyToRetryList(proxy_retry_info, retry_delay, reconsider,
-                          additional_proxy, net_error, net_log);
+      AddProxyChainToRetryList(proxy_retry_info, retry_delay, reconsider,
+                               ProxyChain(additional_proxy), net_error,
+                               net_log);
     }
   }
 }
 
+void ProxyList::UpdateProxyServers() {
+  if (proxy_chains_.empty()) {
+    proxy_servers_ = {{}};
+    return;
+  }
+
+  std::vector<ProxyServer> proxy_servers;
+  for (auto& it : proxy_chains_) {
+    if (it.is_multi_proxy()) {
+      proxy_servers_.reset();
+      return;
+    }
+    proxy_servers.push_back(it.proxy_server());
+  }
+  proxy_servers_ = std::move(proxy_servers);
+}
+
 }  // namespace net
diff --git a/net/proxy_resolution/proxy_list.h b/net/proxy_resolution/proxy_list.h
index 667d341..a99ce33 100644
--- a/net/proxy_resolution/proxy_list.h
+++ b/net/proxy_resolution/proxy_list.h
@@ -12,7 +12,9 @@
 #include <vector>
 
 #include "net/base/net_export.h"
+#include "net/base/proxy_server.h"
 #include "net/proxy_resolution/proxy_retry_info.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class TimeDelta;
@@ -21,12 +23,15 @@
 
 namespace net {
 
-class ProxyServer;
+class ProxyChain;
 class NetLogWithSource;
 
-// This class is used to hold a list of proxies returned by GetProxyForUrl or
-// manually configured. It handles proxy fallback if multiple servers are
-// specified.
+// This class is used to hold a prioritized list of proxy chains. It handles
+// fallback to lower-priority chains if multiple chains are specified.
+//
+// TODO(crbug.com/1491092): For compatibility until proxy chains are used
+// everywhere, this class can also provide a list of ProxyServers only when
+// there are no multi-proxy chains in the list. This support will be removed.
 class NET_EXPORT_PRIVATE ProxyList {
  public:
   ProxyList();
@@ -36,22 +41,32 @@
   ProxyList& operator=(ProxyList&& other);
   ~ProxyList();
 
-  // Initializes the proxy list to a string containing one or more proxy servers
-  // delimited by a semicolon.
+  // Initializes the ProxyList to contain one or more ProxyChains.
+  // `proxy_uri_list` is a semicolon-delimited list of proxy URIs. Note that
+  // multi-proxy chains cannot be represented in this format.
   void Set(const std::string& proxy_uri_list);
 
-  // Set the proxy list to a single entry, |proxy_server|.
+  // Set the proxy list to a single entry, |proxy_chain|.
+  void SetSingleProxyChain(const ProxyChain& proxy_chain);
+
+  // Set the proxy list to a single entry, a chain containing |proxy_server|.
   void SetSingleProxyServer(const ProxyServer& proxy_server);
 
-  // Append a single proxy server to the end of the proxy list.
+  // Append a single proxy chain to the end of the proxy list.
+  void AddProxyChain(const ProxyChain& proxy_chain);
+
+  // Append a single proxy chain containing the given server to the end of the
+  // proxy list.
   void AddProxyServer(const ProxyServer& proxy_server);
 
-  // De-prioritizes the proxies that are cached as not working but are allowed
-  // to be reconsidered, by moving them to the end of the fallback list.
-  void DeprioritizeBadProxies(const ProxyRetryInfoMap& proxy_retry_info);
+  // De-prioritizes the proxy chains that are cached as not working but are
+  // allowed to be reconsidered, by moving them to the end of the fallback list.
+  void DeprioritizeBadProxyChains(const ProxyRetryInfoMap& proxy_retry_info);
 
-  // Delete any entry which doesn't have one of the specified proxy schemes.
-  // |scheme_bit_field| is a bunch of ProxyServer::Scheme bitwise ORed together.
+  // Deletes all chains which don't exclusively consist of proxy servers with
+  // the specified schemes. `scheme_bit_field` is a bunch of
+  // `ProxyServer::Scheme` bitwise ORed together. This is used to remove proxies
+  // that do not support specific functionality such as websockets.
   void RemoveProxiesWithoutScheme(int scheme_bit_field);
 
   // Clear the proxy list.
@@ -66,13 +81,22 @@
   // Returns true if |*this| lists the same proxies as |other|.
   bool Equals(const ProxyList& other) const;
 
-  // Returns the first proxy server in the list. It is only valid to call
-  // this if !IsEmpty().
+  // Returns the single server of the first proxy chain in the list. It is only
+  // valid to call this if !IsEmpty() and no chains in the list are multi-proxy.
+  // TODO(crbug.com/1491092): Remove this method.
   const ProxyServer& Get() const;
 
-  // Returns all proxy servers in the list.
+  // Returns the first proxy chain in the list.
+  const ProxyChain& First() const;
+
+  // Returns all proxy servers in the list. It is only valid to call this
+  // if no chain in the list is multi-proxy.
+  // TODO(crbug.com/1491092): Remove this method in favor of `AllChains()`.
   const std::vector<ProxyServer>& GetAll() const;
 
+  // Returns all proxy chains in the list.
+  const std::vector<ProxyChain>& AllChains() const;
+
   // Sets the list by parsing the PAC result |pac_string|.
   // Some examples for |pac_string|:
   //   "DIRECT"
@@ -88,25 +112,25 @@
   // Returns a serialized value for the list.
   base::Value ToValue() const;
 
-  // Marks the current proxy server as bad and deletes it from the list. The
+  // Marks the current proxy chain as bad and deletes it from the list. The
   // list of known bad proxies is given by |proxy_retry_info|. |net_error|
-  // should contain the network error encountered when this proxy was tried, if
-  // any. If this fallback is not because of a network error, then |OK| should
-  // be passed in (eg. for reasons such as local policy). Returns true if there
-  // is another server available in the list.
+  // should contain the network error encountered when this proxy chain was
+  // tried, if any. If this fallback is not because of a network error, then
+  // |OK| should be passed in (eg. for reasons such as local policy). Returns
+  // true if there is another chain available in the list.
   bool Fallback(ProxyRetryInfoMap* proxy_retry_info,
                 int net_error,
                 const NetLogWithSource& net_log);
 
-  // Updates |proxy_retry_info| to indicate that the first proxy in the list
-  // is bad. This is distinct from Fallback(), above, to allow updating proxy
-  // retry information without modifying a given transction's proxy list. Will
-  // retry after |retry_delay| if positive, and will use the default proxy retry
-  // duration otherwise. It may reconsider the proxy beforehand if |reconsider|
-  // is true. Additionally updates |proxy_retry_info| with
+  // Updates |proxy_retry_info| to indicate that the first proxy chain in the
+  // list is bad. This is distinct from Fallback(), above, to allow updating
+  // proxy retry information without modifying a given transction's proxy list.
+  // Will retry after |retry_delay| if positive, and will use the default proxy
+  // retry duration otherwise. It may reconsider the proxy beforehand if
+  // |reconsider| is true. Additionally updates |proxy_retry_info| with
   // |additional_proxies_to_bypass|. |net_error| should contain the network
-  // error countered when this proxy was tried, or OK if the proxy retry info is
-  // being updated for a non-network related reason (e.g. local policy).
+  // error countered when this proxy chain was tried, or OK if the proxy retry
+  // info is being updated for a non-network related reason (e.g. local policy).
   void UpdateRetryInfoOnFallback(
       ProxyRetryInfoMap* proxy_retry_info,
       base::TimeDelta retry_delay,
@@ -121,15 +145,23 @@
   // |try_while_bad| is true. |net_error| should contain the network error
   // countered when this proxy was tried, or OK if the proxy retry info is
   // being updated for a non-network related reason (e.g. local policy).
-  void AddProxyToRetryList(ProxyRetryInfoMap* proxy_retry_info,
-                           base::TimeDelta retry_delay,
-                           bool try_while_bad,
-                           const ProxyServer& proxy_to_retry,
-                           int net_error,
-                           const NetLogWithSource& net_log) const;
+  void AddProxyChainToRetryList(ProxyRetryInfoMap* proxy_retry_info,
+                                base::TimeDelta retry_delay,
+                                bool try_while_bad,
+                                const ProxyChain& proxy_chain_to_retry,
+                                int net_error,
+                                const NetLogWithSource& net_log) const;
 
-  // List of proxies.
-  std::vector<ProxyServer> proxies_;
+  // Update `proxy_servers_` based on `proxy_chains_`.
+  void UpdateProxyServers();
+
+  // List of proxy chains.
+  std::vector<ProxyChain> proxy_chains_;
+
+  // List of ProxyServers, or nullopt if any chains in `proxy_chains_` are
+  // multi-proxy. This is kept in sync with `proxy_chains_`. This begins as an
+  // empty vector and becomes `nullopt` when a multi-proxy chain is added.
+  absl::optional<std::vector<ProxyServer>> proxy_servers_ = {{}};
 };
 
 }  // namespace net
diff --git a/net/proxy_resolution/proxy_list_unittest.cc b/net/proxy_resolution/proxy_list_unittest.cc
index 0f4fdd889..058eeb0 100644
--- a/net/proxy_resolution/proxy_list_unittest.cc
+++ b/net/proxy_resolution/proxy_list_unittest.cc
@@ -99,24 +99,24 @@
   }
 }
 
-TEST(ProxyListTest, DeprioritizeBadProxies) {
+TEST(ProxyListTest, DeprioritizeBadProxyChains) {
   // Retry info that marks a proxy as being bad for a *very* long time (to avoid
   // the test depending on the current time.)
   ProxyRetryInfo proxy_retry_info;
   proxy_retry_info.bad_until = base::TimeTicks::Now() + base::Days(1);
 
-  // Call DeprioritizeBadProxies with an empty map -- should have no effect.
+  // Call DeprioritizeBadProxyChains with an empty map -- should have no effect.
   {
     ProxyList list;
     list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
 
     ProxyRetryInfoMap retry_info_map;
-    list.DeprioritizeBadProxies(retry_info_map);
+    list.DeprioritizeBadProxyChains(retry_info_map);
     EXPECT_EQ("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80",
               list.ToPacString());
   }
 
-  // Call DeprioritizeBadProxies with 2 of the three proxies marked as bad.
+  // Call DeprioritizeBadProxyChains with 2 of the three chains marked as bad.
   // These proxies should be retried last.
   {
     ProxyList list;
@@ -127,13 +127,13 @@
     retry_info_map["foopy3:80"] = proxy_retry_info;
     retry_info_map["socks5://localhost:1080"] = proxy_retry_info;
 
-    list.DeprioritizeBadProxies(retry_info_map);
+    list.DeprioritizeBadProxyChains(retry_info_map);
 
     EXPECT_EQ("PROXY foopy2:80;PROXY foopy1:80;PROXY foopy3:80",
               list.ToPacString());
   }
 
-  // Call DeprioritizeBadProxies where ALL of the proxies are marked as bad.
+  // Call DeprioritizeBadProxyChains where ALL of the chains are marked as bad.
   // This should have no effect on the order.
   {
     ProxyList list;
@@ -144,14 +144,14 @@
     retry_info_map["foopy2:80"] = proxy_retry_info;
     retry_info_map["foopy3:80"] = proxy_retry_info;
 
-    list.DeprioritizeBadProxies(retry_info_map);
+    list.DeprioritizeBadProxyChains(retry_info_map);
 
     EXPECT_EQ("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80",
               list.ToPacString());
   }
 
-  // Call DeprioritizeBadProxies with 2 of the three proxies marked as bad. Of
-  // the 2 bad proxies, one is to be reconsidered and should be retried last.
+  // Call DeprioritizeBadProxyChains with 2 of the three chains marked as bad.
+  // Of the 2 bad proxies, one is to be reconsidered and should be retried last.
   // The other is not to be reconsidered and should be removed from the list.
   {
     ProxyList list;
@@ -165,7 +165,7 @@
     proxy_retry_info.try_while_bad = true;
     retry_info_map["socks5://localhost:1080"] = proxy_retry_info;
 
-    list.DeprioritizeBadProxies(retry_info_map);
+    list.DeprioritizeBadProxyChains(retry_info_map);
 
     EXPECT_EQ("PROXY foopy2:80;PROXY foopy1:80",
               list.ToPacString());
diff --git a/net/quic/quic_proxy_client_socket.cc b/net/quic/quic_proxy_client_socket.cc
index 5c29e63..e9f1119 100644
--- a/net/quic/quic_proxy_client_socket.cc
+++ b/net/quic/quic_proxy_client_socket.cc
@@ -10,6 +10,7 @@
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/values.h"
+#include "net/base/proxy_chain.h"
 #include "net/base/proxy_delegate.h"
 #include "net/http/http_auth_controller.h"
 #include "net/http/http_log_util.h"
@@ -344,8 +345,9 @@
 
   if (proxy_delegate_) {
     HttpRequestHeaders proxy_delegate_headers;
-    proxy_delegate_->OnBeforeTunnelRequest(proxy_server_,
-                                           &proxy_delegate_headers);
+    // TODO(crbug.com/1491092): Provide the full chain with appropriate index.
+    proxy_delegate_->OnBeforeTunnelRequestServerOnly(proxy_server_,
+                                                     &proxy_delegate_headers);
     request_.extra_headers.MergeFrom(proxy_delegate_headers);
   }
 
@@ -407,8 +409,9 @@
       response_.headers.get());
 
   if (proxy_delegate_) {
-    int rv = proxy_delegate_->OnTunnelHeadersReceived(proxy_server_,
-                                                      *response_.headers);
+    // TODO(crbug.com/1491092): Provide the full chain with appropriate index.
+    int rv = proxy_delegate_->OnTunnelHeadersReceivedServerOnly(
+        proxy_server_, *response_.headers);
     if (rv != OK) {
       DCHECK_NE(ERR_IO_PENDING, rv);
       return rv;
diff --git a/net/quic/quic_proxy_client_socket_unittest.cc b/net/quic/quic_proxy_client_socket_unittest.cc
index 48c89fb0..9c53da6 100644
--- a/net/quic/quic_proxy_client_socket_unittest.cc
+++ b/net/quic/quic_proxy_client_socket_unittest.cc
@@ -687,7 +687,8 @@
   ASSERT_TRUE(response != nullptr);
   ASSERT_EQ(200, response->headers->response_code());
   proxy_delegate_->VerifyOnTunnelHeadersReceived(
-      proxy_server, kResponseHeaderName, kResponseHeaderValue);
+      ProxyChain(proxy_server), /*chain_index=*/0, kResponseHeaderName,
+      kResponseHeaderValue);
 }
 
 TEST_P(QuicProxyClientSocketTest, ConnectWithAuthRequested) {
diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc
index 8956c56..11aceee 100644
--- a/net/spdy/spdy_proxy_client_socket.cc
+++ b/net/spdy/spdy_proxy_client_socket.cc
@@ -17,6 +17,7 @@
 #include "base/values.h"
 #include "net/base/auth.h"
 #include "net/base/io_buffer.h"
+#include "net/base/proxy_chain.h"
 #include "net/base/proxy_delegate.h"
 #include "net/http/http_auth_cache.h"
 #include "net/http/http_auth_handler_factory.h"
@@ -376,8 +377,9 @@
 
   if (proxy_delegate_) {
     HttpRequestHeaders proxy_delegate_headers;
-    proxy_delegate_->OnBeforeTunnelRequest(proxy_server_,
-                                           &proxy_delegate_headers);
+    // TODO(crbug.com/1491092): Provide the full chain with appropriate index.
+    proxy_delegate_->OnBeforeTunnelRequestServerOnly(proxy_server_,
+                                                     &proxy_delegate_headers);
     request_.extra_headers.MergeFrom(proxy_delegate_headers);
   }
 
@@ -422,8 +424,9 @@
       response_.headers.get());
 
   if (proxy_delegate_) {
-    int rv = proxy_delegate_->OnTunnelHeadersReceived(proxy_server_,
-                                                      *response_.headers);
+    // TODO(crbug.com/1491092): Provide the full chain with appropriate index.
+    int rv = proxy_delegate_->OnTunnelHeadersReceivedServerOnly(
+        proxy_server_, *response_.headers);
     if (rv != OK) {
       DCHECK_NE(ERR_IO_PENDING, rv);
       return rv;
diff --git a/net/test/cert_builder.cc b/net/test/cert_builder.cc
index 7b557fa..a3dbccd 100644
--- a/net/test/cert_builder.cc
+++ b/net/test/cert_builder.cc
@@ -1049,14 +1049,12 @@
 
 void CertBuilder::GenerateECKey() {
   auto private_key = crypto::ECPrivateKey::Create();
-  key_ = bssl::UpRef(private_key->key());
-  Invalidate();
+  SetKey(bssl::UpRef(private_key->key()));
 }
 
 void CertBuilder::GenerateRSAKey() {
   auto private_key = crypto::RSAPrivateKey::Create(2048);
-  key_ = bssl::UpRef(private_key->key());
-  Invalidate();
+  SetKey(bssl::UpRef(private_key->key()));
 }
 
 bool CertBuilder::UseKeyFromFile(const base::FilePath& key_file) {
@@ -1064,11 +1062,15 @@
       key_util::LoadEVP_PKEYFromPEM(key_file));
   if (!private_key)
     return false;
-  key_ = std::move(private_key);
-  Invalidate();
+  SetKey(std::move(private_key));
   return true;
 }
 
+void CertBuilder::SetKey(bssl::UniquePtr<EVP_PKEY> key) {
+  key_ = std::move(key);
+  Invalidate();
+}
+
 void CertBuilder::GenerateSubjectKeyIdentifier() {
   // 20 bytes are chosen here for no other reason than it's compatible with
   // systems that assume the SKI is SHA-1(SPKI), which RFC 5280 notes as one
diff --git a/net/test/cert_builder.h b/net/test/cert_builder.h
index 9e02ccc4..5c62c880 100644
--- a/net/test/cert_builder.h
+++ b/net/test/cert_builder.h
@@ -277,6 +277,9 @@
   // Loads the private key for the generated certificate from |key_file|.
   bool UseKeyFromFile(const base::FilePath& key_file);
 
+  // Sets the private key to be |key|.
+  void SetKey(bssl::UniquePtr<EVP_PKEY> key);
+
   // Returns the CertBuilder that issues this certificate. (Will be |this| if
   // certificate is self-signed.)
   CertBuilder* issuer() { return issuer_; }
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index 1fcbb5e..9946945 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -222,14 +222,25 @@
   // Check for reasons not to return a URLRequestHttpJob. These don't apply to
   // https and wss requests.
   if (!url.SchemeIsCryptographic()) {
-    // Check for HSTS upgrade.
-    TransportSecurityState* hsts =
-        request->context()->transport_security_state();
-    if (hsts && hsts->ShouldUpgradeToSSL(url.host(), request->net_log())) {
-      return std::make_unique<URLRequestRedirectJob>(
-          request, UpgradeSchemeToCryptographic(url),
-          // Use status code 307 to preserve the method, so POST requests work.
-          RedirectUtil::ResponseCode::REDIRECT_307_TEMPORARY_REDIRECT, "HSTS");
+    // If the request explicitly has been marked to bypass HSTS, ensure that
+    // the request is in no-credential mode so that the http site can't read
+    // or set cookies which are shared across http/https, then skip the
+    // upgrade.
+    if (((request->load_flags() & net::LOAD_SHOULD_BYPASS_HSTS) ==
+         net::LOAD_SHOULD_BYPASS_HSTS)) {
+      CHECK(request->allow_credentials() == false);
+    } else {
+      // Check for HSTS upgrade.
+      TransportSecurityState* hsts =
+          request->context()->transport_security_state();
+      if (hsts && hsts->ShouldUpgradeToSSL(url.host(), request->net_log())) {
+        return std::make_unique<URLRequestRedirectJob>(
+            request, UpgradeSchemeToCryptographic(url),
+            // Use status code 307 to preserve the method, so POST requests
+            // work.
+            RedirectUtil::ResponseCode::REDIRECT_307_TEMPORARY_REDIRECT,
+            "HSTS");
+      }
     }
 
 #if BUILDFLAG(IS_ANDROID)
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc
index 3de5a08..d14d7f4 100644
--- a/net/url_request/url_request_http_job_unittest.cc
+++ b/net/url_request/url_request_http_job_unittest.cc
@@ -25,6 +25,7 @@
 #include "net/base/auth.h"
 #include "net/base/features.h"
 #include "net/base/isolation_info.h"
+#include "net/base/load_flags.h"
 #include "net/base/proxy_server.h"
 #include "net/base/proxy_string_util.h"
 #include "net/base/request_priority.h"
@@ -1098,6 +1099,178 @@
   }
 }
 
+TEST_F(URLRequestHttpJobTest, ShouldBypassHSTS) {
+  // Setup HSTS state.
+  context_->transport_security_state()->AddHSTS(
+      "upgrade.test", base::Time::Now() + base::Seconds(30), true);
+  ASSERT_TRUE(
+      context_->transport_security_state()->ShouldUpgradeToSSL("upgrade.test"));
+
+  struct TestCase {
+    const char* url;
+    bool bypass_hsts;
+    const char* url_expected;
+  } cases[] = {
+    {"http://upgrade.test/example.crl", true,
+     "http://upgrade.test/example.crl"},
+    // This test ensures that the HSTS check and upgrade happens prior to cache
+    // and socket pool checks
+    {"http://upgrade.test/example.crl", false,
+     "https://upgrade.test/example.crl"},
+    {"http://upgrade.test", false, "https://upgrade.test"},
+    {"http://upgrade.test:1080", false, "https://upgrade.test:1080"},
+#if BUILDFLAG(ENABLE_WEBSOCKETS)
+    {"ws://upgrade.test/example.crl", true, "ws://upgrade.test/example.crl"},
+    {"ws://upgrade.test/example.crl", false, "wss://upgrade.test/example.crl"},
+    {"ws://upgrade.test", false, "wss://upgrade.test"},
+    {"ws://upgrade.test:1080", false, "wss://upgrade.test:1080"},
+#endif  // BUILDFLAG(ENABLE_WEBSOCKETS)
+  };
+
+  for (const auto& test : cases) {
+    SCOPED_TRACE(test.url);
+
+    GURL url = GURL(test.url);
+    // This is needed to bypass logic that rejects using URLRequests directly
+    // for WebSocket requests.
+    bool is_for_websockets = url.SchemeIsWSOrWSS();
+
+    TestDelegate d;
+    TestNetworkDelegate network_delegate;
+    std::unique_ptr<URLRequest> r(context_->CreateRequest(
+        url, DEFAULT_PRIORITY, &d, TRAFFIC_ANNOTATION_FOR_TESTS,
+        is_for_websockets));
+    if (test.bypass_hsts) {
+      r->SetLoadFlags(net::LOAD_SHOULD_BYPASS_HSTS);
+      r->set_allow_credentials(false);
+    }
+
+    net_log_observer_.Clear();
+    r->Start();
+    d.RunUntilComplete();
+
+    if (test.bypass_hsts) {
+      EXPECT_EQ(0, d.received_redirect_count());
+      EXPECT_EQ(1u, r->url_chain().size());
+    } else {
+      auto entries = net_log_observer_.GetEntriesWithType(
+          net::NetLogEventType::URL_REQUEST_REDIRECT_JOB);
+      int redirects = entries.size();
+      for (const auto& entry : entries) {
+        EXPECT_EQ("HSTS", GetStringValueFromParams(entry, "reason"));
+      }
+      EXPECT_EQ(1, redirects);
+      EXPECT_EQ(1, d.received_redirect_count());
+      EXPECT_EQ(2u, r->url_chain().size());
+    }
+    EXPECT_EQ(GURL(test.url_expected), r->url());
+  }
+}
+
+namespace {
+std::unique_ptr<test_server::HttpResponse> HandleRequest(
+    const std::string_view& content,
+    const test_server::HttpRequest& request) {
+  auto response = std::make_unique<test_server::BasicHttpResponse>();
+  response->set_content(content);
+  return std::move(response);
+}
+}  // namespace
+
+// This test checks that if an HTTP connection was made for a request that has
+// the should_bypass_hsts flag set to true, subsequent calls to the exact same
+// URL WITHOUT should_bypass_hsts=true will be upgraded to HTTPS early
+// enough in the process such that the HTTP socket connection is not re-used,
+// and the request does not have a hit in the cache.
+TEST_F(URLRequestHttpJobTest, ShouldBypassHSTSResponseAndConnectionNotReused) {
+  constexpr std::string_view kSecureContent = "Secure: Okay Content";
+  constexpr std::string_view kInsecureContent = "Insecure: Bad Content";
+
+  auto context_builder = CreateTestURLRequestContextBuilder();
+  auto context = context_builder->Build();
+
+  // The host of all EmbeddedTestServer URLs is 127.0.0.1.
+  context->transport_security_state()->AddHSTS(
+      "127.0.0.1", base::Time::Now() + base::Seconds(30), true);
+  ASSERT_TRUE(
+      context->transport_security_state()->ShouldUpgradeToSSL("127.0.0.1"));
+
+  GURL::Replacements replace_scheme;
+  replace_scheme.SetSchemeStr("https");
+  GURL insecure_url;
+  GURL secure_url;
+
+  int common_port = 0;
+
+  // Create an HTTP request that is not upgraded to the should_bypass_hsts flag,
+  // and ensure that the response is stored in the cache.
+  {
+    EmbeddedTestServer http_server(EmbeddedTestServer::TYPE_HTTP);
+    http_server.AddDefaultHandlers(base::FilePath());
+    http_server.RegisterRequestHandler(
+        base::BindRepeating(&HandleRequest, kInsecureContent));
+    ASSERT_TRUE(http_server.Start());
+    common_port = http_server.port();
+
+    insecure_url = http_server.base_url();
+    ASSERT_TRUE(insecure_url.SchemeIs("http"));
+    secure_url = insecure_url.ReplaceComponents(replace_scheme);
+    ASSERT_TRUE(secure_url.SchemeIs("https"));
+
+    net_log_observer_.Clear();
+    TestDelegate delegate;
+    std::unique_ptr<URLRequest> req(
+        context->CreateRequest(insecure_url, DEFAULT_PRIORITY, &delegate,
+                               TRAFFIC_ANNOTATION_FOR_TESTS));
+    req->SetLoadFlags(net::LOAD_SHOULD_BYPASS_HSTS);
+    req->set_allow_credentials(false);
+    req->Start();
+    delegate.RunUntilComplete();
+    EXPECT_EQ(kInsecureContent, delegate.data_received());
+    // There should be 2 cache event entries, one for beginning the read and one
+    // for finishing the read.
+    EXPECT_EQ(2u, net_log_observer_
+                      .GetEntriesWithType(
+                          net::NetLogEventType::HTTP_CACHE_ADD_TO_ENTRY)
+                      .size());
+    ASSERT_TRUE(http_server.ShutdownAndWaitUntilComplete());
+  }
+  // Test that a request with the same URL will be upgraded as long as
+  // should_bypass_hsts flag is not set, and doesn't have an cache hit or
+  // re-use an existing socket connection.
+  {
+    EmbeddedTestServer https_server(EmbeddedTestServer::TYPE_HTTPS);
+    https_server.AddDefaultHandlers(base::FilePath());
+    https_server.RegisterRequestHandler(
+        base::BindRepeating(&HandleRequest, kSecureContent));
+    ASSERT_TRUE(https_server.Start(common_port));
+
+    TestDelegate delegate;
+    std::unique_ptr<URLRequest> req(
+        context->CreateRequest(insecure_url, DEFAULT_PRIORITY, &delegate,
+                               TRAFFIC_ANNOTATION_FOR_TESTS));
+    req->set_allow_credentials(false);
+    req->Start();
+    delegate.RunUntilRedirect();
+    // Ensure that the new URL has an upgraded protocol. This ensures that when
+    // the redirect request continues, the HTTP socket connection from before
+    // will not be re-used, given that "protocol" is one of the fields used to
+    // create a socket connection. Documentation here:
+    // https://chromium.googlesource.com/chromium/src/+/HEAD/net/docs/life-of-a-url-request.md
+    // under "Socket Pools" section.
+    EXPECT_EQ(delegate.redirect_info().new_url, secure_url);
+    EXPECT_TRUE(delegate.redirect_info().new_url.SchemeIs("https"));
+    EXPECT_THAT(delegate.request_status(), net::ERR_IO_PENDING);
+
+    req->FollowDeferredRedirect(absl::nullopt /* removed_headers */,
+                                absl::nullopt /* modified_headers */);
+    delegate.RunUntilComplete();
+    EXPECT_EQ(kSecureContent, delegate.data_received());
+    EXPECT_FALSE(req->was_cached());
+    ASSERT_TRUE(https_server.ShutdownAndWaitUntilComplete());
+  }
+}
+
 TEST_F(URLRequestHttpJobTest, HSTSInternalRedirectCallback) {
   EmbeddedTestServer https_test(EmbeddedTestServer::TYPE_HTTPS);
   https_test.AddDefaultHandlers(base::FilePath());
diff --git a/net/websockets/websocket_end_to_end_test.cc b/net/websockets/websocket_end_to_end_test.cc
index d951793..da5aebb1 100644
--- a/net/websockets/websocket_end_to_end_test.cc
+++ b/net/websockets/websocket_end_to_end_test.cc
@@ -39,6 +39,7 @@
 #include "net/base/ip_endpoint.h"
 #include "net/base/isolation_info.h"
 #include "net/base/net_errors.h"
+#include "net/base/proxy_chain.h"
 #include "net/base/proxy_delegate.h"
 #include "net/base/request_priority.h"
 #include "net/base/url_util.h"
@@ -289,13 +290,15 @@
     resolved_proxy_info_.proxy_info = *result;
   }
 
-  void OnFallback(const ProxyServer& bad_proxy, int net_error) override {}
+  void OnFallback(const ProxyChain& bad_chain, int net_error) override {}
 
-  void OnBeforeTunnelRequest(const ProxyServer& proxy_server,
+  void OnBeforeTunnelRequest(const ProxyChain& proxy_chain,
+                             size_t chain_index,
                              HttpRequestHeaders* extra_headers) override {}
 
   Error OnTunnelHeadersReceived(
-      const ProxyServer& proxy_server,
+      const ProxyChain& proxy_chain,
+      size_t chain_index,
       const HttpResponseHeaders& response_headers) override {
     return OK;
   }
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc
index b8bbc56f..88d32632 100644
--- a/pdf/pdfium/pdfium_engine.cc
+++ b/pdf/pdfium/pdfium_engine.cc
@@ -246,8 +246,8 @@
 
 void SetUpV8() {
   if (!gin::IsolateHolder::Initialized()) {
-    // TODO(crbug.com/1111024): V8 flags for the Unseasoned Viewer need to be
-    // set up as soon as the renderer process is created in the constructor of
+    // TODO(crbug.com/1111024): V8 flags for the PDF Viewer need to be set up as
+    // soon as the renderer process is created in the constructor of
     // `content::RenderProcessImpl`.
     const char* recommended = FPDF_GetRecommendedV8Flags();
     v8::V8::SetFlagsFromString(recommended, strlen(recommended));
diff --git a/remoting/base/hostname.cc b/remoting/base/hostname.cc
index 60e22245..784ec344 100644
--- a/remoting/base/hostname.cc
+++ b/remoting/base/hostname.cc
@@ -19,11 +19,7 @@
 namespace remoting {
 
 std::string GetHostname() {
-// TODO(crbug.com/1052397): Revisit the macro expression once build flag
-// switch of lacros-chrome is complete.
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_LACROS)
-  return net::GetHostName();
-#elif BUILDFLAG(IS_WIN)
+#if BUILDFLAG(IS_WIN)
   wchar_t buffer[MAX_PATH] = {0};
   DWORD size = MAX_PATH;
   if (!::GetComputerNameExW(ComputerNameDnsFullyQualified, buffer, &size)) {
@@ -37,7 +33,7 @@
   }
   return hostname;
 #else
-  return std::string();
+  return net::GetHostName();
 #endif
 }
 
diff --git a/remoting/host/heartbeat_sender_unittest.cc b/remoting/host/heartbeat_sender_unittest.cc
index 35f18aab..22cb79d5 100644
--- a/remoting/host/heartbeat_sender_unittest.cc
+++ b/remoting/host/heartbeat_sender_unittest.cc
@@ -17,8 +17,6 @@
 #include "base/test/mock_callback.h"
 #include "base/test/task_environment.h"
 #include "base/time/time.h"
-#include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 #include "remoting/base/fake_oauth_token_getter.h"
 #include "remoting/base/protobuf_http_status.h"
 #include "remoting/signaling/fake_signal_strategy.h"
@@ -72,14 +70,8 @@
   ASSERT_TRUE(request->has_host_cpu_type());
   ASSERT_EQ(expected_is_initial_heartbeat, request->is_initial_heartbeat());
 
-// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
-// of lacros-chrome is complete.
-#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || \
-    BUILDFLAG(IS_CHROMEOS_LACROS)
+  // We expect hostname (fqdn) to be populated for a Googler-owner host.
   ASSERT_EQ(is_googler, request->has_hostname());
-#else
-  ASSERT_FALSE(request->has_hostname());
-#endif
 }
 
 decltype(auto) DoValidateHeartbeatAndRespondOk(
diff --git a/services/accessibility/fake_service_client.cc b/services/accessibility/fake_service_client.cc
index eb15c50..28c572e3e 100644
--- a/services/accessibility/fake_service_client.cc
+++ b/services/accessibility/fake_service_client.cc
@@ -133,6 +133,12 @@
     highlights_callback_.Run(rects, color);
   }
 }
+
+void FakeServiceClient::SetVirtualKeyboardVisible(bool is_visible) {
+  if (virtual_keyboard_visible_callback_) {
+    virtual_keyboard_visible_callback_.Run(is_visible);
+  }
+}
 #endif  // BUILDFLAG(SUPPORTS_OS_ACCESSIBILITY_SERVICE)
 
 void FakeServiceClient::BindAccessibilityServiceClientForTest() {
@@ -183,6 +189,11 @@
   highlights_callback_ = callback;
 }
 
+void FakeServiceClient::SetVirtualKeyboardVisibleCallback(
+    base::RepeatingCallback<void(bool is_visible)> callback) {
+  virtual_keyboard_visible_callback_ = std::move(callback);
+}
+
 bool FakeServiceClient::UserInterfaceIsBound() const {
   return ux_receivers_.size();
 }
diff --git a/services/accessibility/fake_service_client.h b/services/accessibility/fake_service_client.h
index 62281ae..d390b4e 100644
--- a/services/accessibility/fake_service_client.h
+++ b/services/accessibility/fake_service_client.h
@@ -69,6 +69,7 @@
                      ax::mojom::AssistiveTechnologyType at_type) override;
   void SetHighlights(const std::vector<gfx::Rect>& rects,
                      SkColor color) override;
+  void SetVirtualKeyboardVisible(bool is_visible) override;
 #endif  // BUILDFLAG(SUPPORTS_OS_ACCESSIBILITY_SERVICE)
 
   // Methods for testing.
@@ -94,6 +95,8 @@
   void SetHighlightsCallback(
       base::RepeatingCallback<void(const std::vector<gfx::Rect>& rects,
                                    SkColor color)> callback);
+  void SetVirtualKeyboardVisibleCallback(
+      base::RepeatingCallback<void(bool is_visible)> callback);
 #endif  // BUILDFLAG(SUPPORTS_OS_ACCESSIBILITY_SERVICE)
   base::WeakPtr<FakeServiceClient> GetWeakPtr() {
     return weak_ptr_factory_.GetWeakPtr();
@@ -123,6 +126,8 @@
   base::RepeatingCallback<void(const std::vector<gfx::Rect>& rects,
                                SkColor color)>
       highlights_callback_;
+  base::RepeatingCallback<void(bool is_visible)>
+      virtual_keyboard_visible_callback_;
 #endif  // BUILDFLAG(SUPPORTS_OS_ACCESSIBILITY_SERVICE)
   mojo::Receiver<mojom::AccessibilityServiceClient> a11y_client_receiver_{this};
 
diff --git a/services/accessibility/features/atp_js_api_test.cc b/services/accessibility/features/atp_js_api_test.cc
index a3ac992..8c9b469 100644
--- a/services/accessibility/features/atp_js_api_test.cc
+++ b/services/accessibility/features/atp_js_api_test.cc
@@ -110,6 +110,103 @@
   base::RunLoop test_waiter_;
 };
 
+// Tests for generic ChromeEvents.
+class ChromeEventTest : public AtpJSApiTest {
+ public:
+  ChromeEventTest() = default;
+  ChromeEventTest(const ChromeEventTest&) = delete;
+  ChromeEventTest& operator=(const ChromeEventTest&) = delete;
+  ~ChromeEventTest() override = default;
+
+  mojom::AssistiveTechnologyType GetATTypeForTest() const override {
+    // Any type is fine.
+    return mojom::AssistiveTechnologyType::kChromeVox;
+  }
+
+  const std::vector<std::string> GetJSFilePathsToLoad() const override {
+    // TODO(b:266856702): Eventually ATP will load its own JS instead of us
+    // doing it in the test. Right now the service doesn't have enough
+    // permissions so we load support JS within the test.
+    return std::vector<std::string>{
+        "services/accessibility/features/mojo/test/mojom_test_support.js",
+        "services/accessibility/features/javascript/chrome_event.js",
+    };
+  }
+};
+
+TEST_F(ChromeEventTest, AddsRemovesAndCallsListeners) {
+  ExecuteJS(R"JS(
+    const remote = axtest.mojom.TestBindingInterface.getRemote();
+    let listenerAddedCallbackCount = 0;
+    const chromeEvent = new ChromeEvent(() => {
+      listenerAddedCallbackCount++;
+    });
+
+    let firstCallCount = 0;
+    const firstListener = (a, b) => {
+      if (a !== 'hello' && b !== 'world') {
+        remote.testComplete(/*success=*/false);
+      }
+      firstCallCount++;
+    };
+
+    // Add one listener and call it.
+    chromeEvent.addListener(firstListener);
+    if (listenerAddedCallbackCount !== 1) {
+      remote.testComplete(/*success=*/false);
+    }
+    chromeEvent.callListeners('hello', 'world');
+    if (firstCallCount !== 1) {
+      remote.testComplete(/*success=*/false);
+    }
+
+    let secondCallCount = 0;
+    const secondListener = (a, b) => {
+      if (a !== 'hello' && b !== 'world') {
+        remote.testComplete(/*success=*/false);
+      }
+      secondCallCount++;
+    };
+
+    // Add another listener and call all the listeners.
+    chromeEvent.addListener(secondListener);
+    if (listenerAddedCallbackCount !== 1) {
+      // Listener added callback should only be used once.
+      remote.testComplete(/*success=*/false);
+    }
+    chromeEvent.callListeners('hello', 'world');
+    if (firstCallCount !== 2) {
+      remote.testComplete(/*success=*/false);
+    }
+    if (secondCallCount !== 1) {
+      remote.testComplete(/*success=*/false);
+    }
+
+    // Remove a listener and call the listeners.
+    chromeEvent.removeListener(secondListener);
+    chromeEvent.callListeners('hello', 'world');
+    if (firstCallCount !== 3) {
+      remote.testComplete(/*success=*/false);
+    }
+    if (secondCallCount !== 1) {
+      remote.testComplete(/*success=*/false);
+    }
+
+    // Remove the first listener and call.
+    chromeEvent.removeListener(firstListener);
+    chromeEvent.callListeners('no one', 'is listening');
+    if (firstCallCount !== 3) {
+      remote.testComplete(/*success=*/false);
+    }
+    if (secondCallCount !== 1) {
+      remote.testComplete(/*success=*/false);
+    }
+
+    remote.testComplete(/*success=*/true);
+  )JS");
+  WaitForJSTestComplete();
+}
+
 class TtsJSApiTest : public AtpJSApiTest {
  public:
   TtsJSApiTest() = default;
@@ -605,4 +702,30 @@
   waiter.Run();
 }
 
+TEST_F(AccessibilityPrivateJSApiTest, SetVirtualKeyboardVisible) {
+  base::RunLoop waiter;
+  client_->SetVirtualKeyboardVisibleCallback(
+      base::BindLambdaForTesting([&waiter](bool is_visible) {
+        waiter.Quit();
+        ASSERT_EQ(is_visible, true);
+      }));
+  ExecuteJS(R"JS(
+    chrome.accessibilityPrivate.setVirtualKeyboardVisible(true);
+  )JS");
+  waiter.Run();
+}
+
+TEST_F(AccessibilityPrivateJSApiTest, SetVirtualKeyboardInvisible) {
+  base::RunLoop waiter;
+  client_->SetVirtualKeyboardVisibleCallback(
+      base::BindLambdaForTesting([&waiter](bool is_visible) {
+        waiter.Quit();
+        ASSERT_EQ(is_visible, false);
+      }));
+  ExecuteJS(R"JS(
+    chrome.accessibilityPrivate.setVirtualKeyboardVisible(false);
+  )JS");
+  waiter.Run();
+}
+
 }  // namespace ax
diff --git a/services/accessibility/features/javascript/BUILD.gn b/services/accessibility/features/javascript/BUILD.gn
index b89d3e3..575b571 100644
--- a/services/accessibility/features/javascript/BUILD.gn
+++ b/services/accessibility/features/javascript/BUILD.gn
@@ -5,6 +5,7 @@
 copy("js_api_copied_files") {
   sources = [
     "accessibility_private.js",
+    "chrome_event.js",
     "tts.js",
   ]
   outputs = [ "$target_gen_dir/{{source_file_part}}" ]
@@ -12,8 +13,9 @@
 
 group("js_api_files") {
   data = [
-    "$target_gen_dir/tts.js",
     "$target_gen_dir/accessibility_private.js",
+    "$target_gen_dir/chrome_event.js",
+    "$target_gen_dir/tts.js",
   ]
   deps = [ ":js_api_copied_files" ]
 }
diff --git a/services/accessibility/features/javascript/accessibility_private.js b/services/accessibility/features/javascript/accessibility_private.js
index d3d8b851..e4618817 100644
--- a/services/accessibility/features/javascript/accessibility_private.js
+++ b/services/accessibility/features/javascript/accessibility_private.js
@@ -166,6 +166,14 @@
   }
 
   /**
+   * Shows or hides the virtual keyboard.
+   * @param {boolean} is_visible
+   */
+  setVirtualKeyboardVisible(is_visible) {
+    this.userInterfaceRemote_.setVirtualKeyboardVisible(is_visible);
+  }
+
+  /**
    * Convert array of accessibilityPrivate.ScreenRect to gfx.mojom.Rects.
    * @param {!Array<!chrome.accessibilityPrivate.ScreenRect>} rects
    * @return {!Array<!gfx.mojom.Rect>}
diff --git a/services/accessibility/features/javascript/chrome_event.js b/services/accessibility/features/javascript/chrome_event.js
new file mode 100644
index 0000000..df31f3e
--- /dev/null
+++ b/services/accessibility/features/javascript/chrome_event.js
@@ -0,0 +1,48 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Class that can be used by ATP ChromeEvents. Consumers can set
+// up any required state in the `listenerAddedCallback`, which is
+// run the first time a listener is added to this ChromeEvent.
+class ChromeEvent {
+  /**
+   * @param {?function<>} listenerAddedCallback Callback to run the first
+   *     time a listener is added.
+   */
+  constructor(listenerAddedCallback) {
+    /** @type {!Set<!Function>} */
+    this.listeners_ = new Set();
+    this.listenerAddedCallback_ = listenerAddedCallback;
+  }
+
+  /**
+   * Adds a listener to this event.
+   * @param {!Function} listener
+   */
+  addListener(listener) {
+    this.listeners_.add(listener);
+    if (this.listenerAddedCallback_) {
+      this.listenerAddedCallback_();
+      this.listenerAddedCallback_ = null;
+    }
+  }
+
+  /**
+   * Removes a listener from this event.
+   * @param {Function} listener
+   */
+  removeListener(listener) {
+    this.listeners_.delete(listener);
+  }
+
+  /**
+   * Calls all listeners of this event with the given args.
+   * @param  {...any} args Args to pass to listeners.
+   */
+  callListeners(...args) {
+    this.listeners_.forEach(listener => {
+      listener(...args);
+    });
+  }
+}
diff --git a/services/accessibility/public/mojom/user_interface.mojom b/services/accessibility/public/mojom/user_interface.mojom
index 386eaf0..90abe1ef 100644
--- a/services/accessibility/public/mojom/user_interface.mojom
+++ b/services/accessibility/public/mojom/user_interface.mojom
@@ -71,4 +71,7 @@
 
     // Sets the bounds and color of the accessibility highlight.
     SetHighlights(array<gfx.mojom.Rect> rects, skia.mojom.SkColor color);
+
+    // Shows or hides the virtual keyboard.
+    SetVirtualKeyboardVisible(bool is_visible);
 };
diff --git a/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.cc b/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.cc
index 7f9d5b9..73ddf538 100644
--- a/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.cc
+++ b/services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.cc
@@ -527,6 +527,10 @@
   request->trusted_params = network::ResourceRequest::TrustedParams();
   request->trusted_params->disable_secure_dns = true;
   request->credentials_mode = network::mojom::CredentialsMode::kOmit;
+  // Ensure that we bypass HSTS for all requests sent through
+  // CertNetFetcherURLLoader, since AIA/CRL/OCSP requests must be in HTTP to
+  // avoid circular dependencies.
+  request->load_flags |= net::LOAD_SHOULD_BYPASS_HSTS;
   url_loader_ =
       network::SimpleURLLoader::Create(std::move(request), traffic_annotation);
   // base::Unretained(this) is safe because |this| owns |url_loader_|, which
diff --git a/services/device/nfc/android/junit/src/org/chromium/device/nfc/NFCTest.java b/services/device/nfc/android/junit/src/org/chromium/device/nfc/NFCTest.java
index 002a0347..a5e8848 100644
--- a/services/device/nfc/android/junit/src/org/chromium/device/nfc/NFCTest.java
+++ b/services/device/nfc/android/junit/src/org/chromium/device/nfc/NFCTest.java
@@ -29,7 +29,6 @@
 import android.nfc.NfcManager;
 import android.nfc.Tag;
 import android.nfc.TagLostException;
-import android.nfc.tech.TagTechnology;
 import android.os.Bundle;
 
 import org.junit.Before;
@@ -1451,8 +1450,7 @@
 
         // Mocks blocked 'NFC tag found' event.
         NfcBlocklist.getInstance().setIsTagBlockedForTesting(true);
-        Tag tag = Tag.createMockTag(
-                new byte[] {0x00}, new int[] {TagTechnology.NDEF}, new Bundle[] {});
+        Tag tag = mock(Tag.class);
         NfcTagHandler nfcTagHandler = NfcTagHandler.create(tag);
         nfc.processPendingOperationsForTesting(nfcTagHandler);
 
diff --git a/services/network/ip_protection_config_cache.h b/services/network/ip_protection_config_cache.h
index 66cf064..506833fe 100644
--- a/services/network/ip_protection_config_cache.h
+++ b/services/network/ip_protection_config_cache.h
@@ -27,18 +27,18 @@
   // Initializes the proxy list and token managers for the cache.
   virtual void SetUp() = 0;
 
-  // Check whether tokens are available.
+  // Check whether tokens are available in all token caches.
   //
   // This function is called on every URL load, so it should complete quickly.
-  virtual bool IsAuthTokenAvailable() = 0;
+  virtual bool AreAuthTokensAvailable() = 0;
 
   // Get a token, if one is available.
   //
   // Returns `nullopt` if no token is available, whether for a transient or
   // permanent reason. This method may return `nullopt` even if
   // `IsAuthTokenAvailable()` recently returned `true`.
-  virtual absl::optional<network::mojom::BlindSignedAuthTokenPtr>
-  GetAuthToken() = 0;
+  virtual absl::optional<network::mojom::BlindSignedAuthTokenPtr> GetAuthToken(
+      network::mojom::IpProtectionProxyLayer proxy_layer) = 0;
 
   // Invalidate any previous instruction that token requests should not be
   // made until after a specified time.
@@ -46,12 +46,14 @@
 
   // Set the token cache manager for the cache.
   virtual void SetIpProtectionTokenCacheManagerForTesting(
+      network::mojom::IpProtectionProxyLayer proxy_layer,
       std::unique_ptr<IpProtectionTokenCacheManager>
           ipp_token_cache_manager) = 0;
 
   // Fetch the token cache manager.
   virtual IpProtectionTokenCacheManager*
-  GetIpProtectionTokenCacheManagerForTesting() = 0;
+  GetIpProtectionTokenCacheManagerForTesting(
+      network::mojom::IpProtectionProxyLayer proxy_layer) = 0;
 
   // Set the proxy list manager for the cache.
   virtual void SetIpProtectionProxyListManagerForTesting(
diff --git a/services/network/ip_protection_config_cache_impl.cc b/services/network/ip_protection_config_cache_impl.cc
index e5c829e..b09a6bf 100644
--- a/services/network/ip_protection_config_cache_impl.cc
+++ b/services/network/ip_protection_config_cache_impl.cc
@@ -12,15 +12,15 @@
 #include "services/network/ip_protection_proxy_list_manager_impl.h"
 #include "services/network/ip_protection_token_cache_manager.h"
 #include "services/network/ip_protection_token_cache_manager_impl.h"
+#include "services/network/public/mojom/network_context.mojom.h"
 
 namespace network {
 
 IpProtectionConfigCacheImpl::IpProtectionConfigCacheImpl(
     mojo::PendingRemote<network::mojom::IpProtectionConfigGetter>
         config_getter) {
-  // Proxy list and token cache managers are null upon cache creation.
+  // Proxy list is null upon cache creation.
   ipp_proxy_list_manager_ = nullptr;
-  ipp_token_cache_manager_ = nullptr;
 
   if (config_getter.is_valid()) {
     config_getter_.Bind(std::move(config_getter));
@@ -32,39 +32,48 @@
 void IpProtectionConfigCacheImpl::SetUp() {
   ipp_proxy_list_manager_ =
       std::make_unique<IpProtectionProxyListManagerImpl>(&config_getter_);
-  ipp_token_cache_manager_ =
-      std::make_unique<IpProtectionTokenCacheManagerImpl>(&config_getter_);
+  // TODO(@ciaramcmullin) Initialize kProxyB cache manager when fetching tokens
+  // for proxy B is supported.
+  ipp_token_cache_managers_[network::mojom::IpProtectionProxyLayer::kProxyA] =
+      std::make_unique<IpProtectionTokenCacheManagerImpl>(
+          &config_getter_, network::mojom::IpProtectionProxyLayer::kProxyA);
 }
 
-bool IpProtectionConfigCacheImpl::IsAuthTokenAvailable() {
-  return ipp_token_cache_manager_ != nullptr
-             ? ipp_token_cache_manager_->IsAuthTokenAvailable()
-             : false;
+bool IpProtectionConfigCacheImpl::AreAuthTokensAvailable() {
+  for (const auto& manager : ipp_token_cache_managers_) {
+    if (!manager.second->IsAuthTokenAvailable()) {
+      return false;
+    }
+  }
+  return !ipp_token_cache_managers_.empty();
 }
 
 absl::optional<network::mojom::BlindSignedAuthTokenPtr>
-IpProtectionConfigCacheImpl::GetAuthToken() {
+IpProtectionConfigCacheImpl::GetAuthToken(
+    network::mojom::IpProtectionProxyLayer proxy_layer) {
   absl::optional<network::mojom::BlindSignedAuthTokenPtr> result;
-  if (ipp_token_cache_manager_ != nullptr) {
-    result = ipp_token_cache_manager_->GetAuthToken();
+  if (ipp_token_cache_managers_.count(proxy_layer) > 0) {
+    result = ipp_token_cache_managers_[proxy_layer]->GetAuthToken();
   }
   return result;
 }
 
 void IpProtectionConfigCacheImpl::InvalidateTryAgainAfterTime() {
-  if (ipp_token_cache_manager_ != nullptr) {
-    ipp_token_cache_manager_->InvalidateTryAgainAfterTime();
+  for (const auto& manager : ipp_token_cache_managers_) {
+    manager.second->InvalidateTryAgainAfterTime();
   }
 }
 
 void IpProtectionConfigCacheImpl::SetIpProtectionTokenCacheManagerForTesting(
+    network::mojom::IpProtectionProxyLayer proxy_layer,
     std::unique_ptr<IpProtectionTokenCacheManager> ipp_token_cache_manager) {
-  ipp_token_cache_manager_ = std::move(ipp_token_cache_manager);
+  ipp_token_cache_managers_[proxy_layer] = std::move(ipp_token_cache_manager);
 }
 
 IpProtectionTokenCacheManager*
-IpProtectionConfigCacheImpl::GetIpProtectionTokenCacheManagerForTesting() {
-  return ipp_token_cache_manager_.get();
+IpProtectionConfigCacheImpl::GetIpProtectionTokenCacheManagerForTesting(
+    network::mojom::IpProtectionProxyLayer proxy_layer) {
+  return ipp_token_cache_managers_[proxy_layer].get();
 }
 
 void IpProtectionConfigCacheImpl::SetIpProtectionProxyListManagerForTesting(
diff --git a/services/network/ip_protection_config_cache_impl.h b/services/network/ip_protection_config_cache_impl.h
index 90b0e3d..3084b74 100644
--- a/services/network/ip_protection_config_cache_impl.h
+++ b/services/network/ip_protection_config_cache_impl.h
@@ -6,6 +6,7 @@
 #define SERVICES_NETWORK_IP_PROTECTION_CONFIG_CACHE_IMPL_H_
 
 #include <deque>
+#include <map>
 
 #include "base/component_export.h"
 #include "base/functional/callback.h"
@@ -33,15 +34,16 @@
 
   // IpProtectionConfigCache implementation.
   void SetUp() override;
-  bool IsAuthTokenAvailable() override;
-  absl::optional<network::mojom::BlindSignedAuthTokenPtr> GetAuthToken()
-      override;
+  bool AreAuthTokensAvailable() override;
+  absl::optional<network::mojom::BlindSignedAuthTokenPtr> GetAuthToken(
+      network::mojom::IpProtectionProxyLayer proxy_layer) override;
   void InvalidateTryAgainAfterTime() override;
   void SetIpProtectionTokenCacheManagerForTesting(
+      network::mojom::IpProtectionProxyLayer proxy_layer,
       std::unique_ptr<IpProtectionTokenCacheManager> ipp_token_cache_manager)
       override;
-  IpProtectionTokenCacheManager* GetIpProtectionTokenCacheManagerForTesting()
-      override;
+  IpProtectionTokenCacheManager* GetIpProtectionTokenCacheManagerForTesting(
+      network::mojom::IpProtectionProxyLayer proxy_layer) override;
   void SetIpProtectionProxyListManagerForTesting(
       std::unique_ptr<IpProtectionProxyListManager> ipp_proxy_list_manager)
       override;
@@ -56,8 +58,10 @@
   // A manager for the list of currently cached proxy hostnames.
   std::unique_ptr<IpProtectionProxyListManager> ipp_proxy_list_manager_;
 
-  // A manager for cache of blind-signed auth tokens.
-  std::unique_ptr<IpProtectionTokenCacheManager> ipp_token_cache_manager_;
+  // Proxy layer managers for cache of blind-signed auth tokens.
+  std::map<network::mojom::IpProtectionProxyLayer,
+           std::unique_ptr<IpProtectionTokenCacheManager>>
+      ipp_token_cache_managers_;
 
   base::WeakPtrFactory<IpProtectionConfigCacheImpl> weak_ptr_factory_{this};
 };
diff --git a/services/network/ip_protection_config_cache_impl_unittest.cc b/services/network/ip_protection_config_cache_impl_unittest.cc
index bf69a791..46a9c21 100644
--- a/services/network/ip_protection_config_cache_impl_unittest.cc
+++ b/services/network/ip_protection_config_cache_impl_unittest.cc
@@ -94,10 +94,12 @@
       std::make_unique<MockIpProtectionTokenCacheManager>();
   ipp_token_cache_manager_->SetAuthToken(std::move(exp_token));
   ipp_config_cache_->SetIpProtectionTokenCacheManagerForTesting(
+      network::mojom::IpProtectionProxyLayer::kProxyA,
       std::move(ipp_token_cache_manager_));
 
-  ASSERT_TRUE(ipp_config_cache_->IsAuthTokenAvailable());
-  ASSERT_TRUE(ipp_config_cache_->GetAuthToken());
+  ASSERT_TRUE(ipp_config_cache_->AreAuthTokensAvailable());
+  ASSERT_TRUE(ipp_config_cache_->GetAuthToken(
+      network::mojom::IpProtectionProxyLayer::kProxyA));
 }
 
 // Proxy list manager returns currently cached proxy hostnames.
diff --git a/services/network/ip_protection_proxy_list_manager_impl_unittest.cc b/services/network/ip_protection_proxy_list_manager_impl_unittest.cc
index 9a47925..b47af72 100644
--- a/services/network/ip_protection_proxy_list_manager_impl_unittest.cc
+++ b/services/network/ip_protection_proxy_list_manager_impl_unittest.cc
@@ -11,6 +11,7 @@
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "services/network/ip_protection_proxy_list_manager.h"
 #include "services/network/ip_protection_proxy_list_manager_impl.h"
+#include "services/network/public/mojom/network_context.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -56,6 +57,7 @@
   void Reset() { expected_get_proxy_list_calls_.clear(); }
 
   void TryGetAuthTokens(uint32_t batch_size,
+                        network::mojom::IpProtectionProxyLayer proxy_layer,
                         TryGetAuthTokensCallback callback) override {
     NOTREACHED_NORETURN();
   }
diff --git a/services/network/ip_protection_token_cache_manager_impl.cc b/services/network/ip_protection_token_cache_manager_impl.cc
index f2c1ad5..b85f51d3 100644
--- a/services/network/ip_protection_token_cache_manager_impl.cc
+++ b/services/network/ip_protection_token_cache_manager_impl.cc
@@ -8,6 +8,7 @@
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
 #include "base/time/time.h"
+#include "services/network/public/mojom/network_context.mojom.h"
 
 namespace network {
 
@@ -24,11 +25,13 @@
 
 IpProtectionTokenCacheManagerImpl::IpProtectionTokenCacheManagerImpl(
     mojo::Remote<network::mojom::IpProtectionConfigGetter>* config_getter,
+    network::mojom::IpProtectionProxyLayer proxy_layer,
     bool disable_cache_management_for_testing)
     : batch_size_(net::features::kIpPrivacyAuthTokenCacheBatchSize.Get()),
       cache_low_water_mark_(
           net::features::kIpPrivacyAuthTokenCacheLowWaterMark.Get()),
       config_getter_(config_getter),
+      proxy_layer_(proxy_layer),
       disable_cache_management_for_testing_(
           disable_cache_management_for_testing) {
   last_token_rate_measurement_ = base::TimeTicks::Now();
@@ -77,7 +80,7 @@
     fetching_auth_tokens_ = true;
     VLOG(2) << "IPPATC::MaybeRefillCache calling TryGetAuthTokens";
     config_getter_->get()->TryGetAuthTokens(
-        batch_size_,
+        batch_size_, proxy_layer_,
         base::BindOnce(&IpProtectionTokenCacheManagerImpl::OnGotAuthTokens,
                        weak_ptr_factory_.GetWeakPtr()));
   }
@@ -234,7 +237,7 @@
   CHECK(config_getter_);
   CHECK(on_try_get_auth_tokens_completed_for_testing_);
   config_getter_->get()->TryGetAuthTokens(
-      batch_size_,
+      batch_size_, proxy_layer_,
       base::BindOnce(&IpProtectionTokenCacheManagerImpl::OnGotAuthTokens,
                      weak_ptr_factory_.GetWeakPtr()));
 }
diff --git a/services/network/ip_protection_token_cache_manager_impl.h b/services/network/ip_protection_token_cache_manager_impl.h
index c45af3ae..52b53930 100644
--- a/services/network/ip_protection_token_cache_manager_impl.h
+++ b/services/network/ip_protection_token_cache_manager_impl.h
@@ -26,6 +26,7 @@
  public:
   explicit IpProtectionTokenCacheManagerImpl(
       mojo::Remote<network::mojom::IpProtectionConfigGetter>* config_getter,
+      network::mojom::IpProtectionProxyLayer proxy_layer,
       bool disable_cache_management_for_testing = false);
   ~IpProtectionTokenCacheManagerImpl() override;
 
@@ -96,6 +97,9 @@
   raw_ptr<mojo::Remote<network::mojom::IpProtectionConfigGetter>>
       config_getter_;
 
+  // The proxy layer which the cache of tokens will be used for.
+  network::mojom::IpProtectionProxyLayer proxy_layer_;
+
   // True if an invocation of `config_getter_.TryGetAuthTokens()` is
   // outstanding.
   bool fetching_auth_tokens_ = false;
diff --git a/services/network/ip_protection_token_cache_manager_impl_unittest.cc b/services/network/ip_protection_token_cache_manager_impl_unittest.cc
index c09b4ee..37197ff6 100644
--- a/services/network/ip_protection_token_cache_manager_impl_unittest.cc
+++ b/services/network/ip_protection_token_cache_manager_impl_unittest.cc
@@ -13,6 +13,7 @@
 #include "services/network/ip_protection_config_cache_impl.h"
 #include "services/network/ip_protection_token_cache_manager.h"
 #include "services/network/ip_protection_token_cache_manager_impl.h"
+#include "services/network/public/mojom/network_context.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -76,6 +77,7 @@
   void Reset() { expected_try_get_auth_token_calls_.clear(); }
 
   void TryGetAuthTokens(uint32_t batch_size,
+                        network::mojom::IpProtectionProxyLayer proxy_layer,
                         TryGetAuthTokensCallback callback) override {
     ASSERT_FALSE(expected_try_get_auth_token_calls_.empty())
         << "Unexpected call to TryGetAuthTokens";
@@ -112,7 +114,7 @@
     remote_.Bind(receiver_.BindNewPipeAndPassRemote());
     ipp_token_cache_manager_ =
         std::make_unique<IpProtectionTokenCacheManagerImpl>(
-            &remote_,
+            &remote_, network::mojom::IpProtectionProxyLayer::kProxyA,
             /* disable_cache_management_for_testing=*/true);
   }
 
@@ -273,7 +275,7 @@
 // but things don't crash.
 TEST_F(IpProtectionTokenCacheManagerImplTest, NullGetter) {
   auto ipp_token_cache_manager = IpProtectionTokenCacheManagerImpl(
-      nullptr,
+      nullptr, network::mojom::IpProtectionProxyLayer::kProxyA,
       /* disable_cache_management_for_testing=*/true);
   EXPECT_FALSE(ipp_token_cache_manager_->IsAuthTokenAvailable());
   auto token = ipp_token_cache_manager.GetAuthToken();
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index c60bbab..ad15222c 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -2040,7 +2040,8 @@
   auto* ipp_token_cache_manager_impl =
       static_cast<IpProtectionTokenCacheManagerImpl*>(
           ipp_config_cache
-              ->GetIpProtectionTokenCacheManagerForTesting());  // IN-TEST
+              ->GetIpProtectionTokenCacheManagerForTesting(  // IN-TEST
+                  network::mojom::IpProtectionProxyLayer::kProxyA));
   CHECK(ipp_token_cache_manager_impl);
 
   // If active cache management is enabled (the default), disable it and do a
@@ -2061,8 +2062,9 @@
               auto* ipp_config_cache =
                   weak_ptr->proxy_delegate_->GetIpProtectionConfigCache();
               ipp_config_cache->InvalidateTryAgainAfterTime();
-              while (ipp_config_cache->IsAuthTokenAvailable()) {
-                ipp_config_cache->GetAuthToken();
+              while (ipp_config_cache->AreAuthTokensAvailable()) {
+                ipp_config_cache->GetAuthToken(
+                    network::mojom::IpProtectionProxyLayer::kProxyA);
               }
               // Call `PostTask()` instead of invoking the Verify method again
               // directly so that if `DisableCacheManagementForTesting()` needed
@@ -2103,10 +2105,12 @@
   auto* ipp_token_cache_manager_impl =
       static_cast<IpProtectionTokenCacheManagerImpl*>(
           ipp_config_cache
-              ->GetIpProtectionTokenCacheManagerForTesting());  // IN-TEST
+              ->GetIpProtectionTokenCacheManagerForTesting(  // IN-TEST
+                  network::mojom::IpProtectionProxyLayer::kProxyA));
 
   absl::optional<network::mojom::BlindSignedAuthTokenPtr> result =
-      ipp_config_cache->GetAuthToken();
+      ipp_config_cache->GetAuthToken(
+          network::mojom::IpProtectionProxyLayer::kProxyA);
   if (result.has_value()) {
     std::move(callback).Run(std::move(result).value(), absl::nullopt);
     return;
diff --git a/services/network/network_service_proxy_delegate.cc b/services/network/network_service_proxy_delegate.cc
index 8673c94..96f3c54 100644
--- a/services/network/network_service_proxy_delegate.cc
+++ b/services/network/network_service_proxy_delegate.cc
@@ -8,6 +8,8 @@
 #include "base/functional/bind.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/strings/strcat.h"
+#include "net/base/proxy_chain.h"
+#include "net/base/proxy_server.h"
 #include "net/base/url_util.h"
 #include "net/http/http_request_headers.h"
 #include "net/http/http_util.h"
@@ -31,7 +33,7 @@
   }
 
   rules.Apply(url, proxy_info);
-  proxy_info->DeprioritizeBadProxies(proxy_retry_info);
+  proxy_info->DeprioritizeBadProxyChains(proxy_retry_info);
   return !proxy_info->is_empty() && !proxy_info->proxy_server().is_direct();
 }
 
@@ -153,7 +155,7 @@
       vlog("proxy allow list did not match");
       return;
     }
-    if (!ipp_config_cache_->IsAuthTokenAvailable()) {
+    if (!ipp_config_cache_->AreAuthTokensAvailable()) {
       vlog("no auth token available from cache");
       return;
     }
@@ -183,7 +185,7 @@
     result->set_is_for_ip_protection(true);
     result->OverrideProxyList(
         MergeProxyRules(result->proxy_list(), proxy_list));
-    result->DeprioritizeBadProxies(proxy_retry_info);
+    result->DeprioritizeBadProxyChains(proxy_retry_info);
     return;
   }
 
@@ -207,8 +209,11 @@
   }
 }
 
-void NetworkServiceProxyDelegate::OnFallback(const net::ProxyServer& bad_proxy,
+void NetworkServiceProxyDelegate::OnFallback(const net::ProxyChain& bad_chain,
                                              int net_error) {
+  // TODO(crbug.com/1491092): Handle proxy chains.
+  const net::ProxyServer& bad_proxy = bad_chain.proxy_server();
+
   // If the bad proxy was an IP Protection proxy, refresh the list of IP
   // protection proxies immediately.
   if (IsProxyForIpProtection(bad_proxy) && ipp_config_cache_) {
@@ -221,8 +226,13 @@
 }
 
 void NetworkServiceProxyDelegate::OnBeforeTunnelRequest(
-    const net::ProxyServer& proxy_server,
+    const net::ProxyChain& proxy_chain,
+    size_t chain_index,
     net::HttpRequestHeaders* extra_headers) {
+  // TODO(crbug.com/1491092): Handle proxy chains.
+  CHECK(chain_index == 0);
+  const net::ProxyServer& proxy_server = proxy_chain.proxy_server();
+
   auto vlog = [](std::string message) {
     VLOG(2) << "NSPD::OnBeforeTunnelRequest() - " << message;
   };
@@ -231,7 +241,8 @@
   }
   if (IsForIpProtection() && IsProxyForIpProtection(proxy_server)) {
     if (ipp_config_cache_) {
-      auto token = ipp_config_cache_->GetAuthToken();
+      auto token = ipp_config_cache_->GetAuthToken(
+          network::mojom::IpProtectionProxyLayer::kProxyA);
       if (token) {
         vlog("adding auth token");
         std::string encoded_token;
@@ -251,8 +262,13 @@
 }
 
 net::Error NetworkServiceProxyDelegate::OnTunnelHeadersReceived(
-    const net::ProxyServer& proxy_server,
+    const net::ProxyChain& proxy_chain,
+    size_t chain_index,
     const net::HttpResponseHeaders& response_headers) {
+  // TODO(crbug.com/1491092): Handle proxy chains.
+  CHECK_EQ(chain_index, 0u);
+  const net::ProxyServer& proxy_server = proxy_chain.proxy_server();
+
   if (observer_) {
     // Copy the response headers since mojo expects a ref counted object.
     observer_->OnTunnelHeadersReceived(
diff --git a/services/network/network_service_proxy_delegate.h b/services/network/network_service_proxy_delegate.h
index e406d6d..64b62467 100644
--- a/services/network/network_service_proxy_delegate.h
+++ b/services/network/network_service_proxy_delegate.h
@@ -59,11 +59,13 @@
                       const std::string& method,
                       const net::ProxyRetryInfoMap& proxy_retry_info,
                       net::ProxyInfo* result) override;
-  void OnFallback(const net::ProxyServer& bad_proxy, int net_error) override;
-  void OnBeforeTunnelRequest(const net::ProxyServer& proxy_server,
+  void OnFallback(const net::ProxyChain& bad_chain, int net_error) override;
+  void OnBeforeTunnelRequest(const net::ProxyChain& proxy_chain,
+                             size_t chain_index,
                              net::HttpRequestHeaders* extra_headers) override;
   net::Error OnTunnelHeadersReceived(
-      const net::ProxyServer& proxy_server,
+      const net::ProxyChain& proxy_chain,
+      size_t chain_index,
       const net::HttpResponseHeaders& response_headers) override;
 
   IpProtectionConfigCache* GetIpProtectionConfigCache() {
diff --git a/services/network/network_service_proxy_delegate_unittest.cc b/services/network/network_service_proxy_delegate_unittest.cc
index d493218..e6ca9b74 100644
--- a/services/network/network_service_proxy_delegate_unittest.cc
+++ b/services/network/network_service_proxy_delegate_unittest.cc
@@ -14,7 +14,7 @@
 #include "base/test/task_environment.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
-#include "net/base/proxy_server.h"
+#include "net/base/proxy_chain.h"
 #include "net/base/proxy_string_util.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "net/url_request/url_request_context.h"
@@ -38,10 +38,10 @@
 
 class MockIpProtectionConfigCache : public IpProtectionConfigCache {
  public:
-  bool IsAuthTokenAvailable() override { return auth_token_.has_value(); }
+  bool AreAuthTokensAvailable() override { return auth_token_.has_value(); }
   void InvalidateTryAgainAfterTime() override {}
-  absl::optional<network::mojom::BlindSignedAuthTokenPtr> GetAuthToken()
-      override {
+  absl::optional<network::mojom::BlindSignedAuthTokenPtr> GetAuthToken(
+      network::mojom::IpProtectionProxyLayer proxy_layer) override {
     return std::move(auth_token_);
   }
 
@@ -60,12 +60,13 @@
     NOTREACHED_NORETURN();
   }
 
-  IpProtectionTokenCacheManager* GetIpProtectionTokenCacheManagerForTesting()
-      override {
+  IpProtectionTokenCacheManager* GetIpProtectionTokenCacheManagerForTesting(
+      network::mojom::IpProtectionProxyLayer proxy_layer) override {
     NOTREACHED_NORETURN();
   }
 
   void SetIpProtectionTokenCacheManagerForTesting(
+      network::mojom::IpProtectionProxyLayer proxy_layer,
       std::unique_ptr<IpProtectionTokenCacheManager> ipp_token_cache_manager)
       override {
     NOTREACHED_NORETURN();
@@ -227,8 +228,9 @@
   auto delegate = CreateDelegate(std::move(config));
 
   net::HttpRequestHeaders headers;
-  auto proxy_server = net::PacResultElementToProxyServer("HTTPS proxy");
-  delegate->OnBeforeTunnelRequest(proxy_server, &headers);
+  auto proxy_chain =
+      net::ProxyChain(net::PacResultElementToProxyServer("HTTPS proxy"));
+  delegate->OnBeforeTunnelRequest(proxy_chain, /*chain_index=*/0, &headers);
 
   EXPECT_THAT(headers, Contain("connect", "baz"));
 }
@@ -244,9 +246,9 @@
   delegate->SetIpProtectionConfigCache(std::move(ipp_config_cache));
 
   net::HttpRequestHeaders headers;
-  auto proxy_server = net::ProxyServer::FromSchemeHostAndPort(
+  auto proxy_chain = net::ProxyChain::FromSchemeHostAndPort(
       net::ProxyServer::SCHEME_HTTPS, "proxy", absl::nullopt);
-  delegate->OnBeforeTunnelRequest(proxy_server, &headers);
+  delegate->OnBeforeTunnelRequest(proxy_chain, /*chain_index=*/0, &headers);
 
   std::string encoded_token;
   base::Base64Encode("a-token", &encoded_token);
@@ -264,8 +266,9 @@
   delegate->SetIpProtectionConfigCache(std::move(ipp_config_cache));
 
   net::HttpRequestHeaders headers;
-  auto proxy_server = net::PacResultElementToProxyServer("HTTPS proxy");
-  delegate->OnBeforeTunnelRequest(proxy_server, &headers);
+  auto proxy_chain =
+      net::ProxyChain(net::PacResultElementToProxyServer("HTTPS proxy"));
+  delegate->OnBeforeTunnelRequest(proxy_chain, /*chain_index=*/0, &headers);
 
   std::string value;
   EXPECT_FALSE(headers.GetHeader("Authorization", &value));
@@ -925,23 +928,25 @@
 }
 
 TEST_F(NetworkServiceProxyDelegateTest, OnFallbackObserved) {
-  net::ProxyServer proxy(net::ProxyServer::SCHEME_HTTP,
-                         net::HostPortPair("proxy.com", 80));
+  net::ProxyChain proxy_chain(net::ProxyServer::SCHEME_HTTP,
+                              net::HostPortPair("proxy.com", 80));
 
   auto config = mojom::CustomProxyConfig::New();
   config->rules.ParseFromString("http=foo");
   auto delegate = CreateDelegate(std::move(config));
 
   EXPECT_FALSE(TestObserver()->FallbackArgs());
-  delegate->OnFallback(proxy, net::ERR_FAILED);
+  delegate->OnFallback(proxy_chain, net::ERR_FAILED);
   RunUntilIdle();
   ASSERT_TRUE(TestObserver()->FallbackArgs());
-  EXPECT_EQ(TestObserver()->FallbackArgs()->first, proxy);
+  // TODO(crbug.com/1491092): When Observer supports chain, test that it
+  // receives the full chain and chain index.
+  EXPECT_EQ(TestObserver()->FallbackArgs()->first, proxy_chain.proxy_server());
   EXPECT_EQ(TestObserver()->FallbackArgs()->second, net::ERR_FAILED);
 }
 
 TEST_F(NetworkServiceProxyDelegateTest, OnFallback_IpProtection) {
-  auto proxy = net::ProxyServer::FromSchemeHostAndPort(
+  auto proxy_chain = net::ProxyChain::FromSchemeHostAndPort(
       net::ProxyServer::SCHEME_HTTPS, "proxy.com", absl::nullopt);
   bool force_refresh_called = false;
 
@@ -954,13 +959,13 @@
   ipp_config_cache->SetProxyList({"proxy.com"});
   delegate->SetIpProtectionConfigCache(std::move(ipp_config_cache));
 
-  delegate->OnFallback(proxy, net::ERR_FAILED);
+  delegate->OnFallback(proxy_chain, net::ERR_FAILED);
   EXPECT_TRUE(force_refresh_called);
 }
 
 TEST_F(NetworkServiceProxyDelegateTest, OnTunnelHeadersReceivedObserved) {
-  net::ProxyServer proxy(net::ProxyServer::SCHEME_HTTP,
-                         net::HostPortPair("proxy.com", 80));
+  net::ProxyChain proxy_chain(net::ProxyServer::SCHEME_HTTP,
+                              net::HostPortPair("proxy.com", 80));
   scoped_refptr<net::HttpResponseHeaders> headers =
       base::MakeRefCounted<net::HttpResponseHeaders>(
           "HTTP/1.1 200\nHello: World\n\n");
@@ -970,10 +975,14 @@
   auto delegate = CreateDelegate(std::move(config));
 
   EXPECT_FALSE(TestObserver()->HeadersReceivedArgs());
-  EXPECT_EQ(net::OK, delegate->OnTunnelHeadersReceived(proxy, *headers));
+  EXPECT_EQ(net::OK, delegate->OnTunnelHeadersReceived(
+                         proxy_chain, /*chain_index=*/0, *headers));
   RunUntilIdle();
   ASSERT_TRUE(TestObserver()->HeadersReceivedArgs());
-  EXPECT_EQ(TestObserver()->HeadersReceivedArgs()->first, proxy);
+  // TODO(crbug.com/1491092): When Observer supports chain, test that it
+  // receives the full chain and chain index.
+  EXPECT_EQ(TestObserver()->HeadersReceivedArgs()->first,
+            proxy_chain.proxy_server());
   // Compare raw header strings since the headers pointer is copied.
   EXPECT_EQ(TestObserver()->HeadersReceivedArgs()->second->raw_headers(),
             headers->raw_headers());
diff --git a/services/network/public/cpp/net_adapters.cc b/services/network/public/cpp/net_adapters.cc
index 39f7fc5..77067c2 100644
--- a/services/network/public/cpp/net_adapters.cc
+++ b/services/network/public/cpp/net_adapters.cc
@@ -4,6 +4,9 @@
 
 #include "services/network/public/cpp/net_adapters.h"
 
+#include <limits>
+
+#include "base/check_op.h"
 #include "net/base/net_errors.h"
 #include "services/network/public/cpp/features.h"
 
@@ -54,28 +57,34 @@
 
 MojoToNetPendingBuffer::MojoToNetPendingBuffer(
     mojo::ScopedDataPipeConsumerHandle handle,
-    const void* buffer)
-    : handle_(std::move(handle)), buffer_(buffer) {}
+    base::span<const char> buffer)
+    : handle_(std::move(handle)), buffer_(buffer) {
+  CHECK_LE(buffer_.size(), std::numeric_limits<uint32_t>::max());
+}
 
-MojoToNetPendingBuffer::~MojoToNetPendingBuffer() {}
+MojoToNetPendingBuffer::~MojoToNetPendingBuffer() = default;
 
 // static
 MojoResult MojoToNetPendingBuffer::BeginRead(
     mojo::ScopedDataPipeConsumerHandle* handle,
-    scoped_refptr<MojoToNetPendingBuffer>* pending,
-    uint32_t* num_bytes) {
+    scoped_refptr<MojoToNetPendingBuffer>* pending) {
   const void* buffer = nullptr;
-  *num_bytes = 0;
+  uint32_t num_bytes = 0;
   MojoResult result =
-      (*handle)->BeginReadData(&buffer, num_bytes, MOJO_READ_DATA_FLAG_NONE);
-  if (result == MOJO_RESULT_OK)
-    *pending = new MojoToNetPendingBuffer(std::move(*handle), buffer);
-  return result;
+      (*handle)->BeginReadData(&buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
+  if (result != MOJO_RESULT_OK) {
+    *pending = nullptr;
+    return result;
+  }
+  *pending = new MojoToNetPendingBuffer(
+      std::move(*handle),
+      {static_cast<const char*>(buffer), static_cast<size_t>(num_bytes)});
+  return MOJO_RESULT_OK;
 }
 
 void MojoToNetPendingBuffer::CompleteRead(uint32_t num_bytes) {
   handle_->EndReadData(num_bytes);
-  buffer_ = nullptr;
+  buffer_ = base::span<const char>();
 }
 
 mojo::ScopedDataPipeConsumerHandle MojoToNetPendingBuffer::ReleaseHandle() {
@@ -84,7 +93,7 @@
 }
 
 bool MojoToNetPendingBuffer::IsComplete() const {
-  return buffer_ == nullptr;
+  return buffer_.empty();
 }
 
 MojoToNetIOBuffer::MojoToNetIOBuffer(MojoToNetPendingBuffer* pending_buffer,
diff --git a/services/network/public/cpp/net_adapters.h b/services/network/public/cpp/net_adapters.h
index b84ab64..23b3f417 100644
--- a/services/network/public/cpp/net_adapters.h
+++ b/services/network/public/cpp/net_adapters.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include "base/component_export.h"
+#include "base/containers/span.h"
 #include "base/memory/raw_ptr_exclusion.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "net/base/io_buffer.h"
@@ -90,14 +91,12 @@
   //
   // On success, MOJO_RESULT_OK will be returned. The ownership of the given
   // consumer handle will be transferred to the new MojoToNetPendingBuffer that
-  // will be placed into *pending, and the size of the buffer will be in
-  // *num_bytes.
+  // will be placed into *pending.
   //
   // On failure or MOJO_RESULT_SHOULD_WAIT, there will be no change to the
-  // handle, and *pending and *num_bytes will be unused.
+  // handle, and *pending will be nulled out.
   static MojoResult BeginRead(mojo::ScopedDataPipeConsumerHandle* handle,
-                              scoped_refptr<MojoToNetPendingBuffer>* pending,
-                              uint32_t* num_bytes);
+                              scoped_refptr<MojoToNetPendingBuffer>* pending);
 
   // Indicates the buffer is done being read from. The argument is the number
   // of bytes actually read, since net may do partial writes, which will result
@@ -111,22 +110,23 @@
   // assume that if the buffer_ is null, data was read from the pipe.
   bool IsComplete() const;
 
-  const char* buffer() { return static_cast<const char*>(buffer_); }
+  const char* buffer() const { return buffer_.data(); }
+  uint32_t size() const { return static_cast<uint32_t>(buffer_.size()); }
 
  private:
   friend class base::RefCountedThreadSafe<MojoToNetPendingBuffer>;
 
   // Takes ownership of the handle.
-  explicit MojoToNetPendingBuffer(mojo::ScopedDataPipeConsumerHandle handle,
-                                  const void* buffer);
+  MojoToNetPendingBuffer(mojo::ScopedDataPipeConsumerHandle handle,
+                         base::span<const char> buffer);
   ~MojoToNetPendingBuffer();
 
   mojo::ScopedDataPipeConsumerHandle handle_;
 
-  // `buffer_` is not a raw_ptr<...> for performance reasons: pointee is never
-  // protected by BackupRefPtr, because the pointer comes either from using
-  // `mmap`, MapViewOfFile or base::AllocPages directly.
-  RAW_PTR_EXCLUSION const void* buffer_;
+  // `buffer_` is not a raw_span<...> for performance reasons (also, pointee
+  // would never be protected under BackupRefPtr, because the pointer comes
+  // either from using `mmap`, MapViewOfFile or base::AllocPages directly).
+  base::span<const char> buffer_;
 };
 
 // Net side of a Mojo -> Net copy. The data will already be in the
diff --git a/services/network/public/cpp/url_request_mojom_traits_unittest.cc b/services/network/public/cpp/url_request_mojom_traits_unittest.cc
index e10ab09..f29f19e 100644
--- a/services/network/public/cpp/url_request_mojom_traits_unittest.cc
+++ b/services/network/public/cpp/url_request_mojom_traits_unittest.cc
@@ -9,6 +9,7 @@
 #include "mojo/public/cpp/base/unguessable_token_mojom_traits.h"
 #include "mojo/public/cpp/test_support/test_utils.h"
 #include "net/base/isolation_info.h"
+#include "net/base/load_flags.h"
 #include "net/filter/source_stream.h"
 #include "net/log/net_log.h"
 #include "net/log/net_log_source.h"
@@ -68,7 +69,8 @@
       net::ReferrerPolicy::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN;
   original.headers.SetHeader("Accept", "text/xml");
   original.cors_exempt_headers.SetHeader("X-Requested-With", "ForTesting");
-  original.load_flags = 3;
+  original.load_flags = net::LOAD_VALIDATE_CACHE | net::LOAD_BYPASS_CACHE |
+                        net::LOAD_SHOULD_BYPASS_HSTS;
   original.resource_type = 2;
   original.priority = net::IDLE;
   original.priority_incremental = net::kDefaultPriorityIncremental;
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index 9826919..64fc19a 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -908,6 +908,9 @@
   mojo_base.mojom.Time expiration;
 };
 
+// The proxy layer to fetch batches of tokens for.
+enum IpProtectionProxyLayer {kProxyA, kProxyB};
+
 // A source for new BlindSignedAuthTokens.
 interface IpProtectionConfigGetter {
   // Try to get a batch of new tokens.
@@ -919,7 +922,7 @@
   //
   // It is forbidden for two calls to this method to be outstanding at the same
   // time.
-  TryGetAuthTokens(uint32 batch_size) =>
+  TryGetAuthTokens(uint32 batch_size, IpProtectionProxyLayer proxy_layer) =>
     (array<BlindSignedAuthToken>? bsa_tokens,
      mojo_base.mojom.Time? try_again_after);
 
diff --git a/services/network/socket_data_pump.cc b/services/network/socket_data_pump.cc
index 13c7bbcc..2febc26 100644
--- a/services/network/socket_data_pump.cc
+++ b/services/network/socket_data_pump.cc
@@ -156,9 +156,8 @@
   DCHECK(send_stream_.is_valid());
   DCHECK(!pending_send_buffer_);
 
-  uint32_t num_bytes = 0;
-  MojoResult result = MojoToNetPendingBuffer::BeginRead(
-      &send_stream_, &pending_send_buffer_, &num_bytes);
+  MojoResult result =
+      MojoToNetPendingBuffer::BeginRead(&send_stream_, &pending_send_buffer_);
   if (result == MOJO_RESULT_SHOULD_WAIT) {
     send_stream_watcher_.ArmOrNotify();
     return;
@@ -167,13 +166,12 @@
     ShutdownSend();
     return;
   }
-  DCHECK_EQ(MOJO_RESULT_OK, result);
-  DCHECK(pending_send_buffer_);
+  const int num_bytes = static_cast<int>(pending_send_buffer_->size());
   scoped_refptr<net::IOBuffer> buf = base::MakeRefCounted<net::WrappedIOBuffer>(
       pending_send_buffer_->buffer());
   // Use WeakPtr here because |this| doesn't outlive |socket_|.
   int write_result =
-      socket_->Write(buf.get(), static_cast<int>(num_bytes),
+      socket_->Write(buf.get(), num_bytes,
                      base::BindOnce(&SocketDataPump::OnNetworkWriteCompleted,
                                     weak_factory_.GetWeakPtr()),
                      traffic_annotation_);
diff --git a/services/viz/privileged/mojom/compositing/renderer_settings_mojom_traits.cc b/services/viz/privileged/mojom/compositing/renderer_settings_mojom_traits.cc
index 686e24b4a..c43fd8a 100644
--- a/services/viz/privileged/mojom/compositing/renderer_settings_mojom_traits.cc
+++ b/services/viz/privileged/mojom/compositing/renderer_settings_mojom_traits.cc
@@ -5,7 +5,6 @@
 #include "services/viz/privileged/mojom/compositing/renderer_settings_mojom_traits.h"
 
 #include "build/build_config.h"
-#include "services/viz/public/cpp/compositing/resource_settings_mojom_traits.h"
 
 #if BUILDFLAG(IS_ANDROID)
 #include "ui/gfx/mojom/color_space_mojom_traits.h"
diff --git a/services/viz/public/cpp/compositing/mojom_traits_unittest.cc b/services/viz/public/cpp/compositing/mojom_traits_unittest.cc
index e152c7b..13dbcb69 100644
--- a/services/viz/public/cpp/compositing/mojom_traits_unittest.cc
+++ b/services/viz/public/cpp/compositing/mojom_traits_unittest.cc
@@ -15,7 +15,6 @@
 #include "components/viz/common/quads/debug_border_draw_quad.h"
 #include "components/viz/common/quads/solid_color_draw_quad.h"
 #include "components/viz/common/quads/texture_draw_quad.h"
-#include "components/viz/common/resources/resource_settings.h"
 #include "components/viz/common/resources/returned_resource.h"
 #include "components/viz/common/resources/shared_image_format.h"
 #include "components/viz/common/resources/transferable_resource.h"
@@ -42,7 +41,6 @@
 #include "services/viz/public/cpp/compositing/filter_operations_mojom_traits.h"
 #include "services/viz/public/cpp/compositing/frame_sink_id_mojom_traits.h"
 #include "services/viz/public/cpp/compositing/local_surface_id_mojom_traits.h"
-#include "services/viz/public/cpp/compositing/resource_settings_mojom_traits.h"
 #include "services/viz/public/cpp/compositing/returned_resource_mojom_traits.h"
 #include "services/viz/public/cpp/compositing/selection_mojom_traits.h"
 #include "services/viz/public/cpp/compositing/shared_quad_state_mojom_traits.h"
@@ -409,18 +407,6 @@
   EXPECT_EQ(1, n_called);
 }
 
-TEST_F(StructTraitsTest, ResourceSettings) {
-  constexpr bool kArbitraryBool = true;
-  ResourceSettings input;
-  input.use_gpu_memory_buffer_resources = kArbitraryBool;
-
-  ResourceSettings output;
-  mojo::test::SerializeAndDeserialize<mojom::ResourceSettings>(input, output);
-
-  EXPECT_EQ(input.use_gpu_memory_buffer_resources,
-            output.use_gpu_memory_buffer_resources);
-}
-
 TEST_F(StructTraitsTest, Selection) {
   gfx::SelectionBound start;
   start.SetEdge(gfx::PointF(1234.5f, 67891.f), gfx::PointF(5432.1f, 1987.6f));
diff --git a/services/viz/public/cpp/compositing/resource_settings_mojom_traits.cc b/services/viz/public/cpp/compositing/resource_settings_mojom_traits.cc
deleted file mode 100644
index d15b70d..0000000
--- a/services/viz/public/cpp/compositing/resource_settings_mojom_traits.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "services/viz/public/cpp/compositing/resource_settings_mojom_traits.h"
-
-namespace mojo {
-
-// static
-bool StructTraits<viz::mojom::ResourceSettingsDataView, viz::ResourceSettings>::
-    Read(viz::mojom::ResourceSettingsDataView data,
-         viz::ResourceSettings* out) {
-  out->use_gpu_memory_buffer_resources = data.use_gpu_memory_buffer_resources();
-
-  return true;
-}
-
-}  // namespace mojo
diff --git a/services/viz/public/cpp/compositing/resource_settings_mojom_traits.h b/services/viz/public/cpp/compositing/resource_settings_mojom_traits.h
deleted file mode 100644
index d994d0d6..0000000
--- a/services/viz/public/cpp/compositing/resource_settings_mojom_traits.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_RESOURCE_SETTINGS_MOJOM_TRAITS_H_
-#define SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_RESOURCE_SETTINGS_MOJOM_TRAITS_H_
-
-#include "components/viz/common/resources/resource_settings.h"
-#include "services/viz/public/mojom/compositing/resource_settings.mojom.h"
-#include "ui/gfx/mojom/buffer_types.mojom.h"
-#include "ui/gfx/mojom/buffer_types_mojom_traits.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<viz::mojom::ResourceSettingsDataView,
-                    viz::ResourceSettings> {
-  static bool use_gpu_memory_buffer_resources(
-      const viz::ResourceSettings& input) {
-    return input.use_gpu_memory_buffer_resources;
-  }
-
-  static bool Read(viz::mojom::ResourceSettingsDataView data,
-                   viz::ResourceSettings* out);
-};
-
-}  // namespace mojo
-
-#endif  // SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_RESOURCE_SETTINGS_MOJOM_TRAITS_H_
diff --git a/services/viz/public/mojom/BUILD.gn b/services/viz/public/mojom/BUILD.gn
index 091f9c2..be0b09c 100644
--- a/services/viz/public/mojom/BUILD.gn
+++ b/services/viz/public/mojom/BUILD.gn
@@ -31,7 +31,6 @@
     "compositing/quads.mojom",
     "compositing/region_capture_bounds.mojom",
     "compositing/resource_id.mojom",
-    "compositing/resource_settings.mojom",
     "compositing/returned_resource.mojom",
     "compositing/selection.mojom",
     "compositing/shared_quad_state.mojom",
@@ -461,24 +460,6 @@
     {
       types = [
         {
-          mojom = "viz.mojom.BufferUsageAndFormat"
-          cpp = "::std::pair<::gfx::BufferUsage, gfx::BufferFormat>"
-        },
-        {
-          mojom = "viz.mojom.ResourceSettings"
-          cpp = "::viz::ResourceSettings"
-        },
-      ]
-      traits_sources = [ "//services/viz/public/cpp/compositing/resource_settings_mojom_traits.cc" ]
-      traits_headers = [ "//services/viz/public/cpp/compositing/resource_settings_mojom_traits.h" ]
-      traits_public_deps = [
-        "//components/viz/common",
-        "//ui/gfx/mojom",
-      ]
-    },
-    {
-      types = [
-        {
           mojom = "viz.mojom.SharedQuadState"
           cpp = "::viz::SharedQuadState"
         },
diff --git a/services/viz/public/mojom/compositing/resource_settings.mojom b/services/viz/public/mojom/compositing/resource_settings.mojom
deleted file mode 100644
index 2cc6d58..0000000
--- a/services/viz/public/mojom/compositing/resource_settings.mojom
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2017 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module viz.mojom;
-
-// Corresponds to |viz::ResourceSettings| in
-// components/viz/common/resources/resource_settings.h
-struct ResourceSettings {
-  bool use_gpu_memory_buffer_resources;
-};
diff --git a/testing/android/proguard_for_test.flags b/testing/android/proguard_for_test.flags
index dcf083d..03133af 100644
--- a/testing/android/proguard_for_test.flags
+++ b/testing/android/proguard_for_test.flags
@@ -24,12 +24,6 @@
   *;
 }
 
-# This matches how we keep @CalledByNative.
--keep @interface org.chromium.base.annotations.CalledByNativeForTesting
--keepclasseswithmembers,includedescriptorclasses,allowaccessmodification class ** {
-  @org.chromium.base.annotations.CalledByNativeForTesting <methods>;
-}
-
 # Keep all classes that are in test packages. There is no benefit in testing
 # Proguarding of test classes, but this is as close as we can get to selecting
 # all classes from the test apk.
diff --git a/testing/buildbot/chrome.gpu.fyi.json b/testing/buildbot/chrome.gpu.fyi.json
index c0688ee..d750814f 100644
--- a/testing/buildbot/chrome.gpu.fyi.json
+++ b/testing/buildbot/chrome.gpu.fyi.json
@@ -19,7 +19,6 @@
         ],
         "autotest_name": "chromium_Graphics",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R120-15645.0.0",
         "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
         "name": "context_lost_passthrough_tests JACUZZI_RELEASE_LKGM",
         "resultdb": {
@@ -29,6 +28,7 @@
         "test": "telemetry_gpu_integration_test",
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "JACUZZI_RELEASE_LKGM"
       },
       {
@@ -48,7 +48,6 @@
         ],
         "autotest_name": "chromium_Graphics",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R120-15645.0.0",
         "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
         "name": "expected_color_pixel_passthrough_test JACUZZI_RELEASE_LKGM",
         "precommit_args": [
@@ -63,6 +62,7 @@
         "test": "telemetry_gpu_integration_test",
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "JACUZZI_RELEASE_LKGM"
       },
       {
@@ -77,7 +77,6 @@
         ],
         "autotest_name": "chromium_Graphics",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R120-15645.0.0",
         "extra_browser_args": "--log-level=0 --js-flags=--expose-gc",
         "name": "gpu_process_launch_tests JACUZZI_RELEASE_LKGM",
         "resultdb": {
@@ -87,6 +86,7 @@
         "test": "telemetry_gpu_integration_test",
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "JACUZZI_RELEASE_LKGM"
       },
       {
@@ -101,7 +101,6 @@
         ],
         "autotest_name": "chromium_Graphics",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R120-15645.0.0",
         "extra_browser_args": "--log-level=0 --js-flags=--expose-gc",
         "name": "hardware_accelerated_feature_tests JACUZZI_RELEASE_LKGM",
         "resultdb": {
@@ -111,6 +110,7 @@
         "test": "telemetry_gpu_integration_test",
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "JACUZZI_RELEASE_LKGM"
       },
       {
@@ -129,7 +129,6 @@
         ],
         "autotest_name": "chromium_Graphics",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R120-15645.0.0",
         "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --force_high_performance_gpu",
         "name": "info_collection_tests JACUZZI_RELEASE_LKGM",
         "resultdb": {
@@ -139,6 +138,7 @@
         "test": "telemetry_gpu_integration_test",
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "JACUZZI_RELEASE_LKGM"
       },
       {
@@ -153,7 +153,6 @@
         ],
         "autotest_name": "chromium_Graphics",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R120-15645.0.0",
         "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --force_higher_performance_gpu --use-cmd-decoder=passthrough --use-gl=angle",
         "name": "mediapipe_passthrough_tests JACUZZI_RELEASE_LKGM",
         "resultdb": {
@@ -163,6 +162,7 @@
         "test": "telemetry_gpu_integration_test",
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "JACUZZI_RELEASE_LKGM"
       },
       {
@@ -183,7 +183,6 @@
         ],
         "autotest_name": "chromium_Graphics",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R120-15645.0.0",
         "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
         "name": "pixel_skia_gold_passthrough_test JACUZZI_RELEASE_LKGM",
         "precommit_args": [
@@ -198,6 +197,7 @@
         "test": "telemetry_gpu_integration_test",
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "JACUZZI_RELEASE_LKGM"
       },
       {
@@ -213,7 +213,6 @@
         ],
         "autotest_name": "chromium_Graphics",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R120-15645.0.0",
         "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle",
         "name": "screenshot_sync_passthrough_tests JACUZZI_RELEASE_LKGM",
         "resultdb": {
@@ -223,6 +222,7 @@
         "test": "telemetry_gpu_integration_test",
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "JACUZZI_RELEASE_LKGM"
       },
       {
@@ -238,7 +238,6 @@
         ],
         "autotest_name": "chromium_Graphics",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R120-15645.0.0",
         "extra_browser_args": "--log-level=0 --js-flags=--expose-gc",
         "name": "trace_test JACUZZI_RELEASE_LKGM",
         "resultdb": {
@@ -248,6 +247,7 @@
         "test": "telemetry_gpu_integration_test",
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "JACUZZI_RELEASE_LKGM"
       },
       {
@@ -263,7 +263,6 @@
         ],
         "autotest_name": "chromium_Graphics",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R120-15645.0.0",
         "extra_browser_args": "--log-level=0 --js-flags=--expose-gc",
         "name": "webcodecs_tests JACUZZI_RELEASE_LKGM",
         "resultdb": {
@@ -273,6 +272,7 @@
         "test": "telemetry_gpu_integration_test",
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "JACUZZI_RELEASE_LKGM"
       },
       {
@@ -290,7 +290,6 @@
         ],
         "autotest_name": "chromium_Graphics",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R120-15645.0.0",
         "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --use-gl=angle --use-angle=gles --use-cmd-decoder=passthrough --force_high_performance_gpu",
         "name": "webgl2_conformance_gles_passthrough_tests JACUZZI_RELEASE_LKGM",
         "resultdb": {
@@ -300,6 +299,7 @@
         "test": "telemetry_gpu_integration_test",
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "JACUZZI_RELEASE_LKGM"
       },
       {
@@ -316,7 +316,6 @@
         ],
         "autotest_name": "chromium_Graphics",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R120-15645.0.0",
         "extra_browser_args": "--log-level=0 --js-flags=--expose-gc --use-gl=angle --use-angle=gles --use-cmd-decoder=passthrough --force_high_performance_gpu",
         "name": "webgl_conformance_gles_passthrough_tests JACUZZI_RELEASE_LKGM",
         "resultdb": {
@@ -326,6 +325,7 @@
         "test": "telemetry_gpu_integration_test",
         "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "JACUZZI_RELEASE_LKGM"
       }
     ]
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json
index 85d4fea..b9b3c34 100644
--- a/testing/buildbot/chrome.json
+++ b/testing/buildbot/chrome.json
@@ -1684,7 +1684,6 @@
       {
         "autotest_name": "tast.lacros-from-gcs",
         "cros_board": "brya",
-        "cros_img": "brya-release/R120-15642.0.0",
         "dut_pool": "chrome",
         "name": "lacros_all_tast_tests BRYA_RELEASE_LKGM",
         "resultdb": {
@@ -1697,6 +1696,7 @@
         "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests/",
         "test_level_retries": 2,
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "BRYA_RELEASE_LKGM"
       },
       {
@@ -1754,7 +1754,6 @@
       {
         "autotest_name": "tast.lacros-from-gcs",
         "cros_board": "dedede",
-        "cros_img": "dedede-release/R120-15645.0.0",
         "name": "lacros_all_tast_tests DEDEDE_RELEASE_LKGM",
         "resultdb": {
           "enable": true,
@@ -1766,6 +1765,7 @@
         "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests/",
         "test_level_retries": 2,
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "DEDEDE_RELEASE_LKGM"
       },
       {
@@ -1824,7 +1824,6 @@
       {
         "autotest_name": "tast.lacros-from-gcs",
         "cros_board": "fizz",
-        "cros_img": "fizz-release/R120-15645.0.0",
         "dut_pool": "chrome",
         "name": "lacros_all_tast_tests FIZZ_RELEASE_LKGM",
         "resultdb": {
@@ -1837,6 +1836,7 @@
         "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests/",
         "test_level_retries": 2,
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "FIZZ_RELEASE_LKGM"
       },
       {
@@ -1896,7 +1896,6 @@
       {
         "autotest_name": "tast.lacros-from-gcs",
         "cros_board": "guybrush",
-        "cros_img": "guybrush-release/R120-15645.0.0",
         "dut_pool": "chrome",
         "name": "lacros_all_tast_tests GUYBRUSH_RELEASE_LKGM",
         "resultdb": {
@@ -1909,6 +1908,7 @@
         "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests/",
         "test_level_retries": 2,
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "GUYBRUSH_RELEASE_LKGM"
       },
       {
@@ -1968,7 +1968,6 @@
       {
         "autotest_name": "tast.lacros-from-gcs",
         "cros_board": "puff",
-        "cros_img": "puff-release/R120-15645.0.0",
         "dut_pool": "chrome",
         "name": "lacros_all_tast_tests PUFF_RELEASE_LKGM",
         "resultdb": {
@@ -1981,6 +1980,7 @@
         "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests/",
         "test_level_retries": 2,
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "PUFF_RELEASE_LKGM"
       },
       {
@@ -2070,7 +2070,6 @@
       {
         "autotest_name": "tast.lacros-from-gcs",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-release/R120-15645.0.0",
         "name": "lacros_all_tast_tests JACUZZI_RELEASE_LKGM",
         "resultdb": {
           "enable": true,
@@ -2082,6 +2081,7 @@
         "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests/",
         "test_level_retries": 2,
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "JACUZZI_RELEASE_LKGM"
       },
       {
@@ -2136,7 +2136,6 @@
       {
         "autotest_name": "tast.lacros-from-gcs",
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R120-15645.0.0",
         "name": "lacros_all_tast_tests STRONGBAD_RELEASE_LKGM",
         "resultdb": {
           "enable": true,
@@ -2148,6 +2147,7 @@
         "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests/",
         "test_level_retries": 2,
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "STRONGBAD_RELEASE_LKGM"
       }
     ]
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index 144044f..30289bce 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -7776,7 +7776,7 @@
         "args": [
           "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
           "--test-list",
-          "../../third_party/blink/web_tests/TestLists/Default.txt"
+          "../../third_party/blink/web_tests/TestLists/android.filter"
         ],
         "merge": {
           "args": [
@@ -7820,7 +7820,7 @@
         "args": [
           "--avd-config=../../tools/android/avd/proto/generic_android28.textpb",
           "--test-list",
-          "../../third_party/blink/web_tests/TestLists/Default.txt"
+          "../../third_party/blink/web_tests/TestLists/android.filter"
         ],
         "merge": {
           "args": [
diff --git a/testing/buildbot/chromium.angle.json b/testing/buildbot/chromium.angle.json
index 30d377b..f4fd68a 100644
--- a/testing/buildbot/chromium.angle.json
+++ b/testing/buildbot/chromium.angle.json
@@ -79,7 +79,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "containment_type": "AUTO",
@@ -133,7 +133,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "containment_type": "AUTO",
@@ -187,7 +187,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "containment_type": "AUTO",
@@ -241,7 +241,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "containment_type": "AUTO",
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 9e5cfb2..7be5233b 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -1133,7 +1133,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "volteer",
-        "cros_img": "volteer-public/R120-15645.0.0",
+        "cros_img": "volteer-public/R120-15650.0.0",
         "cros_model": "voxel",
         "dut_pool": "chromium",
         "name": "lacros_all_tast_tests VOLTEER_PUBLIC_LKGM",
@@ -1478,7 +1478,7 @@
         "autotest_name": "chromium",
         "bucket": "chromiumos-image-archive",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-public/R120-15645.0.0",
+        "cros_img": "jacuzzi-public/R120-15650.0.0",
         "name": "chromeos_integration_tests JACUZZI_PUBLIC_LKGM",
         "test": "chromeos_integration_tests",
         "test_id_prefix": "ninja://chrome/test:chromeos_integration_tests/",
@@ -1488,7 +1488,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-public/R120-15645.0.0",
+        "cros_img": "jacuzzi-public/R120-15650.0.0",
         "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -1518,7 +1518,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "trogdor",
-        "cros_img": "trogdor-public/R120-15645.0.0",
+        "cros_img": "trogdor-public/R120-15650.0.0",
         "name": "lacros_all_tast_tests TROGDOR_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -5045,9 +5045,9 @@
       {
         "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_v120.0.6074.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6075.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 120.0.6074.0",
+        "description": "Run with ash-chrome version 120.0.6075.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5057,8 +5057,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v120.0.6074.0",
-              "revision": "version:120.0.6074.0"
+              "location": "lacros_version_skew_tests_v120.0.6075.0",
+              "revision": "version:120.0.6075.0"
             }
           ],
           "dimensions": {
@@ -5195,9 +5195,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6074.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6075.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 120.0.6074.0",
+        "description": "Run with ash-chrome version 120.0.6075.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5207,8 +5207,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v120.0.6074.0",
-              "revision": "version:120.0.6074.0"
+              "location": "lacros_version_skew_tests_v120.0.6075.0",
+              "revision": "version:120.0.6075.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json
index 303f365..ea1c87a 100644
--- a/testing/buildbot/chromium.clang.json
+++ b/testing/buildbot/chromium.clang.json
@@ -2084,7 +2084,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -2152,7 +2152,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json
index 6b40c63..efebd46 100644
--- a/testing/buildbot/chromium.coverage.json
+++ b/testing/buildbot/chromium.coverage.json
@@ -9374,7 +9374,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9424,7 +9424,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9474,7 +9474,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9524,7 +9524,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9574,7 +9574,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9624,7 +9624,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9674,7 +9674,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9724,7 +9724,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9774,7 +9774,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9824,7 +9824,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9874,7 +9874,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9924,7 +9924,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9974,7 +9974,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10024,7 +10024,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10074,7 +10074,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10124,7 +10124,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10174,7 +10174,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10224,7 +10224,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10274,7 +10274,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10324,7 +10324,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10374,7 +10374,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10424,7 +10424,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10474,7 +10474,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10524,7 +10524,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10574,7 +10574,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10624,7 +10624,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10674,7 +10674,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10724,7 +10724,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10774,7 +10774,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10824,7 +10824,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10874,7 +10874,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10924,7 +10924,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10974,7 +10974,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11024,7 +11024,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11074,7 +11074,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11124,7 +11124,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11174,7 +11174,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11224,7 +11224,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11274,7 +11274,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11324,7 +11324,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11374,7 +11374,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11424,7 +11424,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11474,7 +11474,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11524,7 +11524,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11574,7 +11574,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11624,7 +11624,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11674,7 +11674,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11724,7 +11724,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11774,7 +11774,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11824,7 +11824,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11874,7 +11874,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11924,7 +11924,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11974,7 +11974,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12024,7 +12024,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12074,7 +12074,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12124,7 +12124,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12174,7 +12174,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12225,7 +12225,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12276,7 +12276,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12327,7 +12327,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12378,7 +12378,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12429,7 +12429,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12480,7 +12480,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12531,7 +12531,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12582,7 +12582,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12635,7 +12635,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12689,7 +12689,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12743,7 +12743,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12797,7 +12797,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12851,7 +12851,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12905,7 +12905,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12959,7 +12959,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13013,7 +13013,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13067,7 +13067,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13121,7 +13121,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13175,7 +13175,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13229,7 +13229,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13283,7 +13283,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13337,7 +13337,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13391,7 +13391,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13445,7 +13445,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13497,7 +13497,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13549,7 +13549,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13601,7 +13601,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13653,7 +13653,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13705,7 +13705,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13757,7 +13757,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13809,7 +13809,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13861,7 +13861,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13913,7 +13913,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13964,7 +13964,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14015,7 +14015,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14066,7 +14066,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14117,7 +14117,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14168,7 +14168,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14219,7 +14219,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14270,7 +14270,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14323,7 +14323,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14377,7 +14377,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14431,7 +14431,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14485,7 +14485,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14539,7 +14539,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14593,7 +14593,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14647,7 +14647,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14701,7 +14701,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14752,7 +14752,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14802,7 +14802,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14852,7 +14852,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14902,7 +14902,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14952,7 +14952,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15002,7 +15002,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15052,7 +15052,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15102,7 +15102,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15152,7 +15152,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15202,7 +15202,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15252,7 +15252,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15303,7 +15303,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15355,7 +15355,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15407,7 +15407,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15459,7 +15459,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15511,7 +15511,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15563,7 +15563,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15615,7 +15615,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15667,7 +15667,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15718,7 +15718,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15768,7 +15768,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15818,7 +15818,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15868,7 +15868,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15918,7 +15918,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15969,7 +15969,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16020,7 +16020,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16071,7 +16071,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16122,7 +16122,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16172,7 +16172,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16222,7 +16222,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16272,7 +16272,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16323,7 +16323,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16374,7 +16374,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16425,7 +16425,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16476,7 +16476,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16527,7 +16527,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16578,7 +16578,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16629,7 +16629,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16680,7 +16680,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16730,7 +16730,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16780,7 +16780,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16830,7 +16830,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16880,7 +16880,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16930,7 +16930,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16980,7 +16980,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17030,7 +17030,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17080,7 +17080,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17130,7 +17130,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17180,7 +17180,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17230,7 +17230,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17280,7 +17280,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17330,7 +17330,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17380,7 +17380,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17430,7 +17430,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17481,7 +17481,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17532,7 +17532,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17583,7 +17583,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17634,7 +17634,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17685,7 +17685,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17736,7 +17736,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17787,7 +17787,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17838,7 +17838,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17888,7 +17888,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17938,7 +17938,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17988,7 +17988,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18038,7 +18038,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18088,7 +18088,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18138,7 +18138,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18188,7 +18188,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18238,7 +18238,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18288,7 +18288,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18338,7 +18338,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18388,7 +18388,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18438,7 +18438,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18488,7 +18488,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18538,7 +18538,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18588,7 +18588,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18638,7 +18638,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18688,7 +18688,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18738,7 +18738,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18788,7 +18788,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18838,7 +18838,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18888,7 +18888,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18938,7 +18938,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18988,7 +18988,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19038,7 +19038,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19088,7 +19088,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19138,7 +19138,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19188,7 +19188,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19238,7 +19238,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19288,7 +19288,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19338,7 +19338,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19388,7 +19388,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19438,7 +19438,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19488,7 +19488,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19538,7 +19538,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19588,7 +19588,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19638,7 +19638,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19688,7 +19688,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19738,7 +19738,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19788,7 +19788,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19838,7 +19838,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19888,7 +19888,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19938,7 +19938,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19988,7 +19988,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20038,7 +20038,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20088,7 +20088,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20138,7 +20138,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20188,7 +20188,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20238,7 +20238,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20288,7 +20288,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20338,7 +20338,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20388,7 +20388,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20438,7 +20438,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20488,7 +20488,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20538,7 +20538,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20588,7 +20588,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20638,7 +20638,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20688,7 +20688,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20738,7 +20738,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20788,7 +20788,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20838,7 +20838,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20888,7 +20888,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20938,7 +20938,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20988,7 +20988,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21038,7 +21038,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21088,7 +21088,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21138,7 +21138,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21188,7 +21188,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21238,7 +21238,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21288,7 +21288,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21338,7 +21338,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21388,7 +21388,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25401,9 +25401,9 @@
       {
         "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_v120.0.6074.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6075.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 120.0.6074.0",
+        "description": "Run with ash-chrome version 120.0.6075.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25413,8 +25413,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v120.0.6074.0",
-              "revision": "version:120.0.6074.0"
+              "location": "lacros_version_skew_tests_v120.0.6075.0",
+              "revision": "version:120.0.6075.0"
             }
           ],
           "dimensions": {
@@ -25551,9 +25551,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6074.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6075.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 120.0.6074.0",
+        "description": "Run with ash-chrome version 120.0.6075.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25563,8 +25563,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v120.0.6074.0",
-              "revision": "version:120.0.6074.0"
+              "location": "lacros_version_skew_tests_v120.0.6075.0",
+              "revision": "version:120.0.6075.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.dawn.json b/testing/buildbot/chromium.dawn.json
index 112b953..7a2fb921 100644
--- a/testing/buildbot/chromium.dawn.json
+++ b/testing/buildbot/chromium.dawn.json
@@ -1217,6 +1217,44 @@
       },
       {
         "args": [
+          "webgpu_compat_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=gl --use-webgpu-adapter=opengles --enable-webgpu-developer-features --force_high_performance_gpu --enable-features=Vulkan",
+          "--enforce-browser-version",
+          "--use-webgpu-power-preference=default-high-performance",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "experiment_percentage": 100,
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_compat_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "dimensions": {
+            "gpu": "8086:9bc5-20.0.8",
+            "os": "Ubuntu-18.04.6",
+            "pool": "chromium.tests.gpu"
+          },
+          "hard_timeout": 1800,
+          "idempotent": false,
+          "io_timeout": 1800,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 14
+        },
+        "test": "telemetry_gpu_integration_test",
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
           "webgpu_cts",
           "--show-stdout",
           "--browser=release",
@@ -1728,6 +1766,44 @@
       },
       {
         "args": [
+          "webgpu_compat_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=gl --use-webgpu-adapter=opengles --enable-webgpu-developer-features --force_high_performance_gpu --enable-features=Vulkan",
+          "--enforce-browser-version",
+          "--use-webgpu-power-preference=default-high-performance",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "experiment_percentage": 100,
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_compat_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "dimensions": {
+            "gpu": "10de:2184-440.100",
+            "os": "Ubuntu-18.04.5|Ubuntu-18.04.6",
+            "pool": "chromium.tests.gpu"
+          },
+          "hard_timeout": 1800,
+          "idempotent": false,
+          "io_timeout": 1800,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 14
+        },
+        "test": "telemetry_gpu_integration_test",
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
           "webgpu_cts",
           "--show-stdout",
           "--browser=release",
@@ -2237,6 +2313,44 @@
       },
       {
         "args": [
+          "webgpu_compat_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=gl --use-webgpu-adapter=opengles --enable-webgpu-developer-features --force_high_performance_gpu --enable-features=Vulkan",
+          "--enforce-browser-version",
+          "--use-webgpu-power-preference=default-high-performance",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "experiment_percentage": 100,
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_compat_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "dimensions": {
+            "gpu": "8086:9bc5-20.0.8",
+            "os": "Ubuntu-18.04.6",
+            "pool": "chromium.tests.gpu"
+          },
+          "hard_timeout": 1800,
+          "idempotent": false,
+          "io_timeout": 1800,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 14
+        },
+        "test": "telemetry_gpu_integration_test",
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
           "webgpu_cts",
           "--show-stdout",
           "--browser=release",
@@ -2748,6 +2862,44 @@
       },
       {
         "args": [
+          "webgpu_compat_cts",
+          "--show-stdout",
+          "--browser=release",
+          "--passthrough",
+          "-v",
+          "--stable-jobs",
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-angle=gl --use-webgpu-adapter=opengles --enable-webgpu-developer-features --force_high_performance_gpu --enable-features=Vulkan",
+          "--enforce-browser-version",
+          "--use-webgpu-power-preference=default-high-performance",
+          "--jobs=4"
+        ],
+        "ci_only": true,
+        "experiment_percentage": 100,
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "webgpu_cts_compat_tests",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "dimensions": {
+            "gpu": "10de:2184-440.100",
+            "os": "Ubuntu-18.04.5|Ubuntu-18.04.6",
+            "pool": "chromium.tests.gpu"
+          },
+          "hard_timeout": 1800,
+          "idempotent": false,
+          "io_timeout": 1800,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 14
+        },
+        "test": "telemetry_gpu_integration_test",
+        "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/"
+      },
+      {
+        "args": [
           "webgpu_cts",
           "--show-stdout",
           "--browser=release",
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 80f34b9..b55921c 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -4563,7 +4563,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -4611,7 +4611,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -4660,7 +4660,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -4708,7 +4708,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -4756,7 +4756,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -4804,7 +4804,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -4852,7 +4852,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -4900,7 +4900,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -4948,7 +4948,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -4996,7 +4996,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5044,7 +5044,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5092,7 +5092,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5140,7 +5140,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5188,7 +5188,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5236,7 +5236,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5286,7 +5286,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5338,7 +5338,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5386,7 +5386,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5434,7 +5434,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5482,7 +5482,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5530,7 +5530,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5578,7 +5578,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5626,7 +5626,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5674,7 +5674,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5722,7 +5722,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5770,7 +5770,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5818,7 +5818,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5866,7 +5866,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5914,7 +5914,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -5962,7 +5962,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6010,7 +6010,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6058,7 +6058,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6106,7 +6106,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6154,7 +6154,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6202,7 +6202,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6250,7 +6250,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6298,7 +6298,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6346,7 +6346,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6394,7 +6394,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6442,7 +6442,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6490,7 +6490,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6538,7 +6538,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6586,7 +6586,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6634,7 +6634,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6682,7 +6682,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6730,7 +6730,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6779,7 +6779,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6827,7 +6827,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6875,7 +6875,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6923,7 +6923,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -6971,7 +6971,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7019,7 +7019,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7067,7 +7067,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7121,7 +7121,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7172,7 +7172,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7225,7 +7225,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7279,7 +7279,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7333,7 +7333,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7387,7 +7387,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7439,7 +7439,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7491,7 +7491,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7543,7 +7543,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7594,7 +7594,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7647,7 +7647,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7701,7 +7701,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7753,7 +7753,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7805,7 +7805,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7857,7 +7857,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7908,7 +7908,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7959,7 +7959,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8010,7 +8010,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8066,7 +8066,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8114,7 +8114,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8162,7 +8162,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8210,7 +8210,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8258,7 +8258,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8306,7 +8306,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8354,7 +8354,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8402,7 +8402,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8450,7 +8450,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8498,7 +8498,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8546,7 +8546,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8594,7 +8594,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8642,7 +8642,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8690,7 +8690,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8738,7 +8738,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8786,7 +8786,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8834,7 +8834,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8882,7 +8882,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8930,7 +8930,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8978,7 +8978,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9026,7 +9026,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9074,7 +9074,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9122,7 +9122,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9170,7 +9170,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9218,7 +9218,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9266,7 +9266,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9314,7 +9314,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9362,7 +9362,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9410,7 +9410,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9458,7 +9458,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9506,7 +9506,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9554,7 +9554,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9602,7 +9602,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9650,7 +9650,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9698,7 +9698,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9746,7 +9746,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9797,7 +9797,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9848,7 +9848,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9901,7 +9901,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9955,7 +9955,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10009,7 +10009,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10063,7 +10063,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10117,7 +10117,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10171,7 +10171,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10225,7 +10225,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10279,7 +10279,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10333,7 +10333,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10387,7 +10387,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10439,7 +10439,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10491,7 +10491,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10543,7 +10543,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10594,7 +10594,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10647,7 +10647,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10701,7 +10701,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10750,7 +10750,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10798,7 +10798,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10846,7 +10846,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10894,7 +10894,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10942,7 +10942,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10990,7 +10990,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11038,7 +11038,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11086,7 +11086,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11137,7 +11137,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11189,7 +11189,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11238,7 +11238,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11286,7 +11286,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11334,7 +11334,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11383,7 +11383,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11432,7 +11432,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11480,7 +11480,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11531,7 +11531,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11582,7 +11582,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11630,7 +11630,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11678,7 +11678,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11726,7 +11726,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11774,7 +11774,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11822,7 +11822,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11870,7 +11870,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11918,7 +11918,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11966,7 +11966,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12014,7 +12014,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12062,7 +12062,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12113,7 +12113,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12164,7 +12164,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12215,7 +12215,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12266,7 +12266,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12317,7 +12317,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12368,7 +12368,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12419,7 +12419,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12470,7 +12470,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12518,7 +12518,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12566,7 +12566,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12614,7 +12614,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12662,7 +12662,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12710,7 +12710,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12758,7 +12758,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12806,7 +12806,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12854,7 +12854,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12902,7 +12902,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12950,7 +12950,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12998,7 +12998,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13046,7 +13046,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13094,7 +13094,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13142,7 +13142,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13190,7 +13190,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13238,7 +13238,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13286,7 +13286,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13334,7 +13334,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13382,7 +13382,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13430,7 +13430,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13478,7 +13478,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13526,7 +13526,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13574,7 +13574,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13622,7 +13622,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13670,7 +13670,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13718,7 +13718,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13766,7 +13766,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13814,7 +13814,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13862,7 +13862,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13910,7 +13910,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13958,7 +13958,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14006,7 +14006,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14054,7 +14054,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14102,7 +14102,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14150,7 +14150,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14198,7 +14198,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14246,7 +14246,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14294,7 +14294,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14342,7 +14342,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14390,7 +14390,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14438,7 +14438,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14486,7 +14486,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14534,7 +14534,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14582,7 +14582,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14630,7 +14630,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14678,7 +14678,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14726,7 +14726,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14774,7 +14774,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14826,7 +14826,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14878,7 +14878,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14930,7 +14930,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14978,7 +14978,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15026,7 +15026,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15074,7 +15074,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15122,7 +15122,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15170,7 +15170,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15218,7 +15218,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15266,7 +15266,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15314,7 +15314,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15362,7 +15362,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15410,7 +15410,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15458,7 +15458,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15506,7 +15506,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15554,7 +15554,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15602,7 +15602,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15650,7 +15650,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15698,7 +15698,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15746,7 +15746,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15795,7 +15795,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15844,7 +15844,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15895,7 +15895,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15947,7 +15947,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15999,7 +15999,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16051,7 +16051,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16101,7 +16101,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16151,7 +16151,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16201,7 +16201,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16250,7 +16250,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16301,7 +16301,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16353,7 +16353,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16402,7 +16402,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16450,7 +16450,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16499,7 +16499,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16549,7 +16549,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16598,7 +16598,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16646,7 +16646,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16694,7 +16694,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16743,7 +16743,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16792,7 +16792,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16840,7 +16840,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16889,7 +16889,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16938,7 +16938,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16986,7 +16986,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17034,7 +17034,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17082,7 +17082,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17130,7 +17130,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17179,7 +17179,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17228,7 +17228,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17276,7 +17276,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17324,7 +17324,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17372,7 +17372,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17420,7 +17420,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17468,7 +17468,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17516,7 +17516,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17564,7 +17564,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17612,7 +17612,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17660,7 +17660,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17708,7 +17708,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17756,7 +17756,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17804,7 +17804,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17852,7 +17852,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17900,7 +17900,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17948,7 +17948,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17996,7 +17996,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18044,7 +18044,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18092,7 +18092,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18146,7 +18146,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18196,7 +18196,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18246,7 +18246,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18296,7 +18296,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18346,7 +18346,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18396,7 +18396,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18446,7 +18446,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18496,7 +18496,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18546,7 +18546,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18596,7 +18596,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18646,7 +18646,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18696,7 +18696,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18746,7 +18746,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18796,7 +18796,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18846,7 +18846,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18896,7 +18896,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18946,7 +18946,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18996,7 +18996,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19046,7 +19046,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19096,7 +19096,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19146,7 +19146,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19196,7 +19196,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19246,7 +19246,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19296,7 +19296,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19346,7 +19346,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19396,7 +19396,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19446,7 +19446,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19496,7 +19496,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19546,7 +19546,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19596,7 +19596,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19646,7 +19646,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19696,7 +19696,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19746,7 +19746,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19796,7 +19796,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19846,7 +19846,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19896,7 +19896,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19947,7 +19947,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19998,7 +19998,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20049,7 +20049,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20100,7 +20100,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20153,7 +20153,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20207,7 +20207,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20261,7 +20261,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20315,7 +20315,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20369,7 +20369,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20423,7 +20423,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20477,7 +20477,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20531,7 +20531,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20583,7 +20583,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20635,7 +20635,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20687,7 +20687,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20739,7 +20739,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20791,7 +20791,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20842,7 +20842,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20893,7 +20893,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20944,7 +20944,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20997,7 +20997,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21051,7 +21051,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21105,7 +21105,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21159,7 +21159,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21210,7 +21210,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21260,7 +21260,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21310,7 +21310,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21360,7 +21360,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21411,7 +21411,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21463,7 +21463,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21515,7 +21515,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21567,7 +21567,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21618,7 +21618,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21668,7 +21668,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21718,7 +21718,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21768,7 +21768,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21818,7 +21818,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21869,7 +21869,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21920,7 +21920,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21971,7 +21971,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22022,7 +22022,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22072,7 +22072,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22122,7 +22122,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22172,7 +22172,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22223,7 +22223,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22274,7 +22274,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22325,7 +22325,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22376,7 +22376,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22426,7 +22426,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22476,7 +22476,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22526,7 +22526,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22576,7 +22576,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22626,7 +22626,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22676,7 +22676,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22726,7 +22726,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22776,7 +22776,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22827,7 +22827,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22878,7 +22878,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22929,7 +22929,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22980,7 +22980,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23030,7 +23030,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23080,7 +23080,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23130,7 +23130,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23180,7 +23180,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23230,7 +23230,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23280,7 +23280,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23330,7 +23330,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23380,7 +23380,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23430,7 +23430,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23480,7 +23480,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23530,7 +23530,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23580,7 +23580,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23630,7 +23630,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23680,7 +23680,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23730,7 +23730,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23780,7 +23780,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23830,7 +23830,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23880,7 +23880,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23930,7 +23930,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23980,7 +23980,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24030,7 +24030,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24080,7 +24080,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24130,7 +24130,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24180,7 +24180,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24230,7 +24230,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24280,7 +24280,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24330,7 +24330,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24380,7 +24380,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24430,7 +24430,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24480,7 +24480,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24530,7 +24530,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24580,7 +24580,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24630,7 +24630,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24680,7 +24680,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24730,7 +24730,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24780,7 +24780,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24831,7 +24831,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24885,7 +24885,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24933,7 +24933,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -24981,7 +24981,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25029,7 +25029,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25077,7 +25077,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25125,7 +25125,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25173,7 +25173,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25221,7 +25221,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25269,7 +25269,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25317,7 +25317,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25365,7 +25365,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25413,7 +25413,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25461,7 +25461,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25509,7 +25509,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25557,7 +25557,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25605,7 +25605,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25653,7 +25653,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25701,7 +25701,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25752,7 +25752,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25803,7 +25803,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25854,7 +25854,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25905,7 +25905,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -25958,7 +25958,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26012,7 +26012,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26066,7 +26066,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26120,7 +26120,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26174,7 +26174,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26228,7 +26228,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26282,7 +26282,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26334,7 +26334,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26386,7 +26386,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26438,7 +26438,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26490,7 +26490,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26542,7 +26542,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26593,7 +26593,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26644,7 +26644,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26695,7 +26695,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26748,7 +26748,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26802,7 +26802,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26856,7 +26856,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26910,7 +26910,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -26959,7 +26959,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27007,7 +27007,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27055,7 +27055,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27103,7 +27103,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27154,7 +27154,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27206,7 +27206,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27258,7 +27258,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27310,7 +27310,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27359,7 +27359,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27408,7 +27408,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27456,7 +27456,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27505,7 +27505,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27556,7 +27556,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27607,7 +27607,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27658,7 +27658,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27709,7 +27709,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27757,7 +27757,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27805,7 +27805,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27853,7 +27853,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27901,7 +27901,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -27949,7 +27949,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28000,7 +28000,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28051,7 +28051,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28102,7 +28102,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28150,7 +28150,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28198,7 +28198,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28246,7 +28246,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28294,7 +28294,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28342,7 +28342,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28390,7 +28390,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28438,7 +28438,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28486,7 +28486,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28534,7 +28534,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28582,7 +28582,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28630,7 +28630,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28678,7 +28678,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28726,7 +28726,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28774,7 +28774,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28822,7 +28822,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28870,7 +28870,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28918,7 +28918,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -28966,7 +28966,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29014,7 +29014,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29062,7 +29062,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29110,7 +29110,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29158,7 +29158,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29206,7 +29206,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29254,7 +29254,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29314,7 +29314,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29362,7 +29362,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29410,7 +29410,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29458,7 +29458,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29506,7 +29506,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29554,7 +29554,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29602,7 +29602,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29650,7 +29650,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29698,7 +29698,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29746,7 +29746,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29794,7 +29794,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29842,7 +29842,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29890,7 +29890,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29938,7 +29938,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -29986,7 +29986,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30034,7 +30034,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30082,7 +30082,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30130,7 +30130,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30181,7 +30181,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30232,7 +30232,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30283,7 +30283,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30336,7 +30336,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30390,7 +30390,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30444,7 +30444,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30498,7 +30498,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30552,7 +30552,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30606,7 +30606,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30658,7 +30658,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30710,7 +30710,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30762,7 +30762,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30814,7 +30814,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30865,7 +30865,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30916,7 +30916,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -30969,7 +30969,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31023,7 +31023,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31077,7 +31077,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31126,7 +31126,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31174,7 +31174,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31222,7 +31222,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31270,7 +31270,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31321,7 +31321,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31373,7 +31373,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31425,7 +31425,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31474,7 +31474,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31523,7 +31523,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31571,7 +31571,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31620,7 +31620,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31671,7 +31671,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31722,7 +31722,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31773,7 +31773,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31821,7 +31821,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31869,7 +31869,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31917,7 +31917,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -31965,7 +31965,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32013,7 +32013,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32064,7 +32064,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32115,7 +32115,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32166,7 +32166,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32214,7 +32214,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32262,7 +32262,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32310,7 +32310,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32358,7 +32358,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32406,7 +32406,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32454,7 +32454,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32502,7 +32502,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32550,7 +32550,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32598,7 +32598,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32646,7 +32646,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32694,7 +32694,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32742,7 +32742,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32790,7 +32790,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32838,7 +32838,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32886,7 +32886,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32934,7 +32934,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -32982,7 +32982,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33030,7 +33030,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33078,7 +33078,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33126,7 +33126,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33174,7 +33174,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33222,7 +33222,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33270,7 +33270,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33318,7 +33318,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33373,7 +33373,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33421,7 +33421,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33469,7 +33469,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33517,7 +33517,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33565,7 +33565,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33613,7 +33613,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33661,7 +33661,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33709,7 +33709,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33757,7 +33757,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33805,7 +33805,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33853,7 +33853,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33901,7 +33901,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33949,7 +33949,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -33997,7 +33997,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34045,7 +34045,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34093,7 +34093,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34141,7 +34141,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34189,7 +34189,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34237,7 +34237,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34285,7 +34285,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34333,7 +34333,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34384,7 +34384,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34435,7 +34435,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34488,7 +34488,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34542,7 +34542,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34596,7 +34596,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34650,7 +34650,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34702,7 +34702,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34754,7 +34754,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34806,7 +34806,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34857,7 +34857,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34910,7 +34910,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -34964,7 +34964,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35013,7 +35013,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35061,7 +35061,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35109,7 +35109,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35160,7 +35160,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35212,7 +35212,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35261,7 +35261,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35309,7 +35309,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35358,7 +35358,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35407,7 +35407,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35455,7 +35455,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35504,7 +35504,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35553,7 +35553,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35601,7 +35601,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35652,7 +35652,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35703,7 +35703,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35751,7 +35751,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35799,7 +35799,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35847,7 +35847,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35895,7 +35895,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35943,7 +35943,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -35994,7 +35994,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36045,7 +36045,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36093,7 +36093,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36141,7 +36141,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36189,7 +36189,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36237,7 +36237,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36285,7 +36285,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36333,7 +36333,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36381,7 +36381,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36429,7 +36429,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36477,7 +36477,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36525,7 +36525,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36573,7 +36573,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36621,7 +36621,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36669,7 +36669,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36717,7 +36717,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36765,7 +36765,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36813,7 +36813,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36861,7 +36861,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36909,7 +36909,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -36957,7 +36957,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37005,7 +37005,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37053,7 +37053,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37101,7 +37101,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37149,7 +37149,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37204,7 +37204,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37252,7 +37252,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37300,7 +37300,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37348,7 +37348,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37396,7 +37396,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37444,7 +37444,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37492,7 +37492,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37540,7 +37540,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37588,7 +37588,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37636,7 +37636,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37684,7 +37684,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37732,7 +37732,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37780,7 +37780,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37828,7 +37828,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37876,7 +37876,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37924,7 +37924,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -37972,7 +37972,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38020,7 +38020,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38068,7 +38068,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38116,7 +38116,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38164,7 +38164,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38213,7 +38213,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38262,7 +38262,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38313,7 +38313,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38365,7 +38365,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38417,7 +38417,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38469,7 +38469,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38519,7 +38519,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38569,7 +38569,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38619,7 +38619,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38668,7 +38668,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38719,7 +38719,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38771,7 +38771,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38820,7 +38820,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38868,7 +38868,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38916,7 +38916,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -38965,7 +38965,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39015,7 +39015,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39064,7 +39064,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39112,7 +39112,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39160,7 +39160,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39209,7 +39209,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39258,7 +39258,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39306,7 +39306,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39355,7 +39355,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39404,7 +39404,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39452,7 +39452,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39500,7 +39500,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39548,7 +39548,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39596,7 +39596,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39644,7 +39644,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39693,7 +39693,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39742,7 +39742,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39790,7 +39790,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39838,7 +39838,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39886,7 +39886,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39934,7 +39934,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -39982,7 +39982,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40030,7 +40030,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40078,7 +40078,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40126,7 +40126,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40174,7 +40174,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40222,7 +40222,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40270,7 +40270,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40318,7 +40318,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40366,7 +40366,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40414,7 +40414,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40462,7 +40462,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40510,7 +40510,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40558,7 +40558,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40606,7 +40606,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40654,7 +40654,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40702,7 +40702,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40750,7 +40750,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40798,7 +40798,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -40846,7 +40846,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -41153,7 +41153,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "eve",
-        "cros_img": "eve-public/R120-15645.0.0",
+        "cros_img": "eve-public/R120-15650.0.0",
         "dut_pool": "chromium",
         "name": "lacros_all_tast_tests EVE_PUBLIC_LKGM",
         "public_builder": "cros_test_platform_public",
@@ -41174,7 +41174,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "octopus",
-        "cros_img": "octopus-public/R120-15645.0.0",
+        "cros_img": "octopus-public/R120-15650.0.0",
         "name": "lacros_all_tast_tests OCTOPUS_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -41199,7 +41199,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-public/R120-15645.0.0",
+        "cros_img": "jacuzzi-public/R120-15650.0.0",
         "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -41217,7 +41217,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "trogdor",
-        "cros_img": "trogdor-public/R120-15645.0.0",
+        "cros_img": "trogdor-public/R120-15650.0.0",
         "name": "lacros_all_tast_tests TROGDOR_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -41242,7 +41242,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-public/R120-15645.0.0",
+        "cros_img": "jacuzzi-public/R120-15650.0.0",
         "name": "lacros_all_tast_tests JACUZZI_CQ_PUBLIC_LKGM",
         "public_builder": "cros_test_platform_public",
         "public_builder_bucket": "testplatform-public",
@@ -41262,7 +41262,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-public/R120-15645.0.0",
+        "cros_img": "jacuzzi-public/R120-15650.0.0",
         "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -41280,7 +41280,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "trogdor",
-        "cros_img": "trogdor-public/R120-15645.0.0",
+        "cros_img": "trogdor-public/R120-15650.0.0",
         "name": "lacros_all_tast_tests TROGDOR_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -43505,9 +43505,9 @@
       {
         "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_v120.0.6074.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6075.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 120.0.6074.0",
+        "description": "Run with ash-chrome version 120.0.6075.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -43516,8 +43516,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v120.0.6074.0",
-              "revision": "version:120.0.6074.0"
+              "location": "lacros_version_skew_tests_v120.0.6075.0",
+              "revision": "version:120.0.6075.0"
             }
           ],
           "dimensions": {
@@ -43655,9 +43655,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6074.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6075.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 120.0.6074.0",
+        "description": "Run with ash-chrome version 120.0.6075.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -43666,8 +43666,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v120.0.6074.0",
-              "revision": "version:120.0.6074.0"
+              "location": "lacros_version_skew_tests_v120.0.6075.0",
+              "revision": "version:120.0.6075.0"
             }
           ],
           "dimensions": {
@@ -44964,9 +44964,9 @@
       {
         "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_v120.0.6074.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6075.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 120.0.6074.0",
+        "description": "Run with ash-chrome version 120.0.6075.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -44975,8 +44975,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v120.0.6074.0",
-              "revision": "version:120.0.6074.0"
+              "location": "lacros_version_skew_tests_v120.0.6075.0",
+              "revision": "version:120.0.6075.0"
             }
           ],
           "dimensions": {
@@ -45114,9 +45114,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6074.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6075.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 120.0.6074.0",
+        "description": "Run with ash-chrome version 120.0.6075.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -45125,8 +45125,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v120.0.6074.0",
-              "revision": "version:120.0.6074.0"
+              "location": "lacros_version_skew_tests_v120.0.6075.0",
+              "revision": "version:120.0.6075.0"
             }
           ],
           "dimensions": {
@@ -45809,9 +45809,9 @@
       {
         "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_v120.0.6074.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6075.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 120.0.6074.0",
+        "description": "Run with ash-chrome version 120.0.6075.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -45820,8 +45820,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v120.0.6074.0",
-              "revision": "version:120.0.6074.0"
+              "location": "lacros_version_skew_tests_v120.0.6075.0",
+              "revision": "version:120.0.6075.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index 6d051ff1..5db2f92 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -7799,7 +7799,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7848,7 +7848,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7897,7 +7897,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7946,7 +7946,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -7995,7 +7995,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8044,7 +8044,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8093,7 +8093,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8142,7 +8142,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8191,7 +8191,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8240,7 +8240,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8289,7 +8289,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8338,7 +8338,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8387,7 +8387,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8436,7 +8436,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8485,7 +8485,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8534,7 +8534,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8583,7 +8583,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8632,7 +8632,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8681,7 +8681,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8730,7 +8730,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8779,7 +8779,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8828,7 +8828,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8877,7 +8877,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8926,7 +8926,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -8978,7 +8978,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9031,7 +9031,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9081,7 +9081,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9130,7 +9130,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9179,7 +9179,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9228,7 +9228,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9277,7 +9277,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9326,7 +9326,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9375,7 +9375,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9425,7 +9425,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9475,7 +9475,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9524,7 +9524,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9573,7 +9573,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9622,7 +9622,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9671,7 +9671,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9720,7 +9720,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9769,7 +9769,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9818,7 +9818,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9868,7 +9868,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9918,7 +9918,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -9967,7 +9967,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10016,7 +10016,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10065,7 +10065,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10114,7 +10114,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10163,7 +10163,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10212,7 +10212,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10261,7 +10261,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10310,7 +10310,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10359,7 +10359,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10408,7 +10408,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10457,7 +10457,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10506,7 +10506,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10555,7 +10555,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10604,7 +10604,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10653,7 +10653,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10702,7 +10702,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10751,7 +10751,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10800,7 +10800,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10849,7 +10849,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10898,7 +10898,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10947,7 +10947,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -10996,7 +10996,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11045,7 +11045,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11094,7 +11094,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11143,7 +11143,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11192,7 +11192,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11241,7 +11241,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11290,7 +11290,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11346,7 +11346,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11395,7 +11395,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11444,7 +11444,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11493,7 +11493,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11542,7 +11542,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11591,7 +11591,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11640,7 +11640,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11689,7 +11689,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11738,7 +11738,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11787,7 +11787,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11836,7 +11836,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11885,7 +11885,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11934,7 +11934,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -11983,7 +11983,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12032,7 +12032,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12081,7 +12081,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12130,7 +12130,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12179,7 +12179,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12228,7 +12228,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12277,7 +12277,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12326,7 +12326,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12375,7 +12375,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12424,7 +12424,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12473,7 +12473,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12523,7 +12523,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12573,7 +12573,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12623,7 +12623,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12673,7 +12673,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12725,7 +12725,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12778,7 +12778,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12831,7 +12831,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12884,7 +12884,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12937,7 +12937,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -12990,7 +12990,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13043,7 +13043,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13096,7 +13096,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13149,7 +13149,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13202,7 +13202,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13253,7 +13253,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13304,7 +13304,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13355,7 +13355,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13406,7 +13406,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13457,7 +13457,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13507,7 +13507,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13557,7 +13557,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13607,7 +13607,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13659,7 +13659,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13712,7 +13712,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13765,7 +13765,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13818,7 +13818,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13868,7 +13868,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13917,7 +13917,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13966,7 +13966,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14015,7 +14015,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14065,7 +14065,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14116,7 +14116,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14167,7 +14167,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14218,7 +14218,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14268,7 +14268,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14317,7 +14317,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14366,7 +14366,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14416,7 +14416,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14466,7 +14466,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14515,7 +14515,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14565,7 +14565,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14615,7 +14615,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14665,7 +14665,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14715,7 +14715,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14764,7 +14764,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14813,7 +14813,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14862,7 +14862,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14911,7 +14911,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14960,7 +14960,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15009,7 +15009,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15059,7 +15059,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15109,7 +15109,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15159,7 +15159,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15209,7 +15209,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15259,7 +15259,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15309,7 +15309,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15358,7 +15358,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15407,7 +15407,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15456,7 +15456,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15505,7 +15505,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15554,7 +15554,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15603,7 +15603,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15652,7 +15652,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15701,7 +15701,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15750,7 +15750,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15799,7 +15799,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15848,7 +15848,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15897,7 +15897,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15946,7 +15946,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15995,7 +15995,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16044,7 +16044,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16093,7 +16093,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16142,7 +16142,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16191,7 +16191,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16240,7 +16240,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16289,7 +16289,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16338,7 +16338,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16387,7 +16387,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16436,7 +16436,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16485,7 +16485,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16534,7 +16534,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16583,7 +16583,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16632,7 +16632,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16681,7 +16681,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16736,7 +16736,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16784,7 +16784,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16832,7 +16832,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16880,7 +16880,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16928,7 +16928,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16976,7 +16976,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17024,7 +17024,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17072,7 +17072,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17120,7 +17120,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17168,7 +17168,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17216,7 +17216,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17264,7 +17264,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17312,7 +17312,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17360,7 +17360,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17408,7 +17408,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17456,7 +17456,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17504,7 +17504,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17552,7 +17552,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17600,7 +17600,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17648,7 +17648,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17696,7 +17696,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17744,7 +17744,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17792,7 +17792,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17840,7 +17840,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17888,7 +17888,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17936,7 +17936,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -17984,7 +17984,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18032,7 +18032,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18080,7 +18080,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18128,7 +18128,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18179,7 +18179,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18230,7 +18230,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18281,7 +18281,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18334,7 +18334,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18388,7 +18388,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18442,7 +18442,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18496,7 +18496,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18550,7 +18550,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18604,7 +18604,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18656,7 +18656,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18708,7 +18708,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18760,7 +18760,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18812,7 +18812,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18863,7 +18863,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18914,7 +18914,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -18967,7 +18967,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19021,7 +19021,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19075,7 +19075,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19124,7 +19124,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19172,7 +19172,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19220,7 +19220,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19268,7 +19268,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19316,7 +19316,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19364,7 +19364,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19412,7 +19412,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19460,7 +19460,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19508,7 +19508,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19556,7 +19556,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19607,7 +19607,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19659,7 +19659,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19711,7 +19711,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19761,7 +19761,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19810,7 +19810,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19859,7 +19859,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19910,7 +19910,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -19961,7 +19961,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20012,7 +20012,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20060,7 +20060,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20108,7 +20108,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20156,7 +20156,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20204,7 +20204,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20252,7 +20252,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20300,7 +20300,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20348,7 +20348,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20396,7 +20396,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20444,7 +20444,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20492,7 +20492,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20543,7 +20543,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20594,7 +20594,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20645,7 +20645,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20693,7 +20693,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20741,7 +20741,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20789,7 +20789,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20837,7 +20837,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20885,7 +20885,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20933,7 +20933,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -20981,7 +20981,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21029,7 +21029,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21077,7 +21077,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21125,7 +21125,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21173,7 +21173,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21221,7 +21221,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21269,7 +21269,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21317,7 +21317,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21365,7 +21365,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21413,7 +21413,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21461,7 +21461,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21509,7 +21509,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21557,7 +21557,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21605,7 +21605,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21653,7 +21653,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21701,7 +21701,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21749,7 +21749,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21797,7 +21797,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21845,7 +21845,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21893,7 +21893,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21941,7 +21941,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -21989,7 +21989,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22037,7 +22037,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22085,7 +22085,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22133,7 +22133,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22181,7 +22181,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22229,7 +22229,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22277,7 +22277,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22325,7 +22325,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22373,7 +22373,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22421,7 +22421,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22469,7 +22469,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22517,7 +22517,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22565,7 +22565,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22613,7 +22613,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22661,7 +22661,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22709,7 +22709,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22757,7 +22757,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22805,7 +22805,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22853,7 +22853,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22901,7 +22901,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22949,7 +22949,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -22997,7 +22997,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -23045,7 +23045,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index aa4d49cf..585feab5 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -13113,7 +13113,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13161,7 +13161,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13209,7 +13209,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13257,7 +13257,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13305,7 +13305,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13353,7 +13353,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13401,7 +13401,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13449,7 +13449,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13497,7 +13497,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13545,7 +13545,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13593,7 +13593,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13641,7 +13641,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13689,7 +13689,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13737,7 +13737,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13785,7 +13785,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13833,7 +13833,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13881,7 +13881,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13929,7 +13929,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -13977,7 +13977,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14025,7 +14025,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14073,7 +14073,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14121,7 +14121,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14169,7 +14169,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14218,7 +14218,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14267,7 +14267,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14315,7 +14315,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14363,7 +14363,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14411,7 +14411,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14459,7 +14459,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14507,7 +14507,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14555,7 +14555,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14603,7 +14603,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14651,7 +14651,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14699,7 +14699,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14747,7 +14747,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14795,7 +14795,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14843,7 +14843,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14891,7 +14891,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14939,7 +14939,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -14987,7 +14987,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15035,7 +15035,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15083,7 +15083,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15131,7 +15131,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15179,7 +15179,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15227,7 +15227,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15275,7 +15275,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15323,7 +15323,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -15371,7 +15371,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -16245,12 +16245,12 @@
       {
         "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_v120.0.6074.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6075.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 120.0.6074.0",
+        "description": "Run with ash-chrome version 120.0.6075.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -16260,8 +16260,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v120.0.6074.0",
-              "revision": "version:120.0.6074.0"
+              "location": "lacros_version_skew_tests_v120.0.6075.0",
+              "revision": "version:120.0.6075.0"
             }
           ],
           "dimensions": {
@@ -16415,12 +16415,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6074.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6075.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 120.0.6074.0",
+        "description": "Run with ash-chrome version 120.0.6075.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -16430,8 +16430,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v120.0.6074.0",
-              "revision": "version:120.0.6074.0"
+              "location": "lacros_version_skew_tests_v120.0.6075.0",
+              "revision": "version:120.0.6075.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.webrtc.fyi.json b/testing/buildbot/chromium.webrtc.fyi.json
index 260453a..e39a62f 100644
--- a/testing/buildbot/chromium.webrtc.fyi.json
+++ b/testing/buildbot/chromium.webrtc.fyi.json
@@ -657,7 +657,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -705,7 +705,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -753,7 +753,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
@@ -801,7 +801,7 @@
             {
               "cipd_package": "infra/tools/mac_toolchain/${platform}",
               "location": ".",
-              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+              "revision": "git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/filters/ios.content_browsertests.filter b/testing/buildbot/filters/ios.content_browsertests.filter
index 25a8998..8c83964 100644
--- a/testing/buildbot/filters/ios.content_browsertests.filter
+++ b/testing/buildbot/filters/ios.content_browsertests.filter
@@ -91,7 +91,6 @@
 -NoCompositingRenderWidgetHostViewBrowserTest.NoFallbackAfterHiddenNavigationFails
 -NoCompositingRenderWidgetHostViewBrowserTest.NoFallbackIfSwapFailedBeforeNavigation
 -NoCompositingRenderWidgetHostViewBrowserTest.ValidLocalSurfaceIdAfterHiddenNavigation
--NoCompositingRenderWidgetHostViewBrowserTest.ValidLocalSurfaceIdAfterInitialNavigation
 -NoGPUCaptureScreenshotTest.LargeScreenshot
 -PointerLockBrowserTest.PointerLockRequestUnadjustedMovement
 -PointerLockBrowserTest.PointerLockWheelEventRouting
diff --git a/testing/buildbot/filters/linux-lacros.browser_tests.filter b/testing/buildbot/filters/linux-lacros.browser_tests.filter
index 92db91cf..a3b77c5a 100644
--- a/testing/buildbot/filters/linux-lacros.browser_tests.filter
+++ b/testing/buildbot/filters/linux-lacros.browser_tests.filter
@@ -84,6 +84,3 @@
 -ProfileHelperTest.OpenNewWindowForProfile
 -WebAppBrowserTest.WindowsOffsetForMultiWindowPWA
 -WebAppTabStripBrowserTest.ActiveTabColorIsBackgroundColor
-
-# crbug.com/1493211
--SafeBrowsingBlockingPageBrowserTestWithThreatTypeAndIsolationSetting.*
diff --git a/testing/buildbot/internal.chromeos.fyi.json b/testing/buildbot/internal.chromeos.fyi.json
index e5b1135..6b72d3a 100644
--- a/testing/buildbot/internal.chromeos.fyi.json
+++ b/testing/buildbot/internal.chromeos.fyi.json
@@ -1291,12 +1291,12 @@
       {
         "autotest_name": "tast.lacros-from-gcs",
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R120-15645.0.0",
         "name": "lacros_fyi_tast_tests OCTOPUS_RELEASE_LKGM",
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
         "test": "lacros_fyi_tast_tests",
         "test_id_prefix": "ninja://chromeos/lacros:lacros_fyi_tast_tests/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "OCTOPUS_RELEASE_LKGM"
       },
       {
@@ -1333,11 +1333,11 @@
       {
         "autotest_name": "chromium",
         "cros_board": "octopus",
-        "cros_img": "octopus-release/R120-15645.0.0",
         "name": "ozone_unittests OCTOPUS_RELEASE_LKGM",
         "test": "ozone_unittests",
         "test_id_prefix": "ninja://ui/ozone:ozone_unittests/",
         "timeout_sec": 3600,
+        "use_lkgm": true,
         "variant_id": "OCTOPUS_RELEASE_LKGM"
       },
       {
@@ -1382,12 +1382,12 @@
       {
         "autotest_name": "tast.lacros-from-gcs",
         "cros_board": "hana",
-        "cros_img": "hana-release/R120-15645.0.0",
         "name": "lacros_all_tast_tests HANA_RELEASE_LKGM",
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
         "test": "lacros_all_tast_tests",
         "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "HANA_RELEASE_LKGM"
       },
       {
@@ -1415,12 +1415,12 @@
       {
         "autotest_name": "tast.lacros-from-gcs",
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R120-15645.0.0",
         "name": "lacros_all_tast_tests STRONGBAD_RELEASE_LKGM",
         "tast_expr": "(\"group:mainline\" && \"dep:lacros\" && !informational)",
         "test": "lacros_all_tast_tests",
         "test_id_prefix": "ninja://chromeos/lacros:lacros_all_tast_tests/",
         "timeout_sec": 10800,
+        "use_lkgm": true,
         "variant_id": "STRONGBAD_RELEASE_LKGM"
       },
       {
@@ -1468,11 +1468,11 @@
       {
         "autotest_name": "chromium",
         "cros_board": "hana",
-        "cros_img": "hana-release/R120-15645.0.0",
         "name": "ozone_unittests HANA_RELEASE_LKGM",
         "test": "ozone_unittests",
         "test_id_prefix": "ninja://ui/ozone:ozone_unittests/",
         "timeout_sec": 3600,
+        "use_lkgm": true,
         "variant_id": "HANA_RELEASE_LKGM"
       },
       {
@@ -1498,11 +1498,11 @@
       {
         "autotest_name": "chromium",
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R120-15645.0.0",
         "name": "ozone_unittests STRONGBAD_RELEASE_LKGM",
         "test": "ozone_unittests",
         "test_id_prefix": "ninja://ui/ozone:ozone_unittests/",
         "timeout_sec": 3600,
+        "use_lkgm": true,
         "variant_id": "STRONGBAD_RELEASE_LKGM"
       },
       {
@@ -1548,11 +1548,11 @@
       {
         "autotest_name": "chromium",
         "cros_board": "hana",
-        "cros_img": "hana-release/R120-15645.0.0",
         "name": "viz_unittests HANA_RELEASE_LKGM",
         "test": "viz_unittests",
         "test_id_prefix": "ninja://components/viz:viz_unittests/",
         "timeout_sec": 3600,
+        "use_lkgm": true,
         "variant_id": "HANA_RELEASE_LKGM"
       },
       {
@@ -1578,11 +1578,11 @@
       {
         "autotest_name": "chromium",
         "cros_board": "strongbad",
-        "cros_img": "strongbad-release/R120-15645.0.0",
         "name": "viz_unittests STRONGBAD_RELEASE_LKGM",
         "test": "viz_unittests",
         "test_id_prefix": "ninja://components/viz:viz_unittests/",
         "timeout_sec": 3600,
+        "use_lkgm": true,
         "variant_id": "STRONGBAD_RELEASE_LKGM"
       },
       {
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl
index 2d023d6..5118948 100644
--- a/testing/buildbot/mixins.pyl
+++ b/testing/buildbot/mixins.pyl
@@ -844,7 +844,7 @@
         {
           'cipd_package': 'infra/tools/mac_toolchain/${platform}',
           'location': '.',
-          'revision': 'git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb',
+          'revision': 'git_revision:32d81d877ee07af07bf03b7f70ce597e323b80ce',
         },
       ],
     },
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 49f6425..2418fe47 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1634,7 +1634,7 @@
       'android-chrome-pie-x86-wpt-android-specific': {
         'args': [
           '--test-list',
-          '../../third_party/blink/web_tests/TestLists/Default.txt'
+          '../../third_party/blink/web_tests/TestLists/android.filter'
         ]
       },
       'android-chrome-pie-x86-wpt-fyi-rel': {
@@ -4176,7 +4176,7 @@
       'android-chrome-pie-x86-wpt-android-specific': {
         'args': [
           '--test-list',
-          '../../third_party/blink/web_tests/TestLists/Default.txt'
+          '../../third_party/blink/web_tests/TestLists/android.filter'
         ]
       },
       'android-webview-pie-x86-wpt-fyi-rel': {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 17ec514..b0c64de 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -2637,6 +2637,27 @@
       },
     },
 
+    'gpu_dawn_webgpu_compat_cts': {
+      'webgpu_cts_compat_tests': {
+        'telemetry_test_name': 'webgpu_compat_cts',
+        'mixins': [
+          'has_native_resultdb_integration',
+          'webgpu_telemetry_cts',
+        ],
+        'args': [
+          '--extra-browser-args=--use-angle=gl --use-webgpu-adapter=opengles --enable-webgpu-developer-features',
+        ],
+        'ci_only': True,
+        'swarming': {
+          'shards': 14,
+        },
+        'android_swarming': {
+          'shards': 36,
+        },
+        'experiment_percentage': 100,
+      },
+    },
+
     'gpu_dawn_webgpu_cts': {
       'webgpu_cts_tests': {
         'telemetry_test_name': 'webgpu_cts',
@@ -6239,6 +6260,12 @@
       'gpu_dawn_webgpu_blink_web_tests_force_swiftshader',
     ],
 
+    'gpu_dawn_compat_telemetry_tests': [
+      'gpu_dawn_webgpu_compat_cts',
+      'gpu_dawn_webgpu_cts',
+      'gpu_dawn_web_platform_webgpu_cts_force_swiftshader',
+    ],
+
     'gpu_dawn_integration_asan_gtests_passthrough': [
       'gpu_dawn_gtests',
       'gpu_dawn_gtests_no_dxc',
diff --git a/testing/buildbot/tryserver.chromium.chromiumos.json b/testing/buildbot/tryserver.chromium.chromiumos.json
index d876eaf..7374b45 100644
--- a/testing/buildbot/tryserver.chromium.chromiumos.json
+++ b/testing/buildbot/tryserver.chromium.chromiumos.json
@@ -10,7 +10,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "volteer",
-        "cros_img": "volteer-public/R120-15645.0.0",
+        "cros_img": "volteer-public/R120-15650.0.0",
         "cros_model": "voxel",
         "dut_pool": "chromium",
         "name": "lacros_all_tast_tests VOLTEER_PUBLIC_LKGM",
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 1510c82..15f415e6 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -70,16 +70,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'identifier': 'Lacros version skew testing ash canary',
-    'description': 'Run with ash-chrome version 120.0.6074.0',
+    'description': 'Run with ash-chrome version 120.0.6075.0',
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6074.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v120.0.6075.0/test_ash_chrome',
     ],
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v120.0.6074.0',
-          'revision': 'version:120.0.6074.0',
+          'location': 'lacros_version_skew_tests_v120.0.6075.0',
+          'revision': 'version:120.0.6075.0',
         },
       ],
     },
@@ -440,7 +440,7 @@
     'identifier': 'BRYA_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'brya',
-      'cros_img': 'brya-release/R120-15642.0.0',
+      'use_lkgm': True,
       'dut_pool': 'chrome',
     },
   },
@@ -472,7 +472,7 @@
     'identifier': 'DEDEDE_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'dedede',
-      'cros_img': 'dedede-release/R120-15645.0.0',
+      'use_lkgm': True,
     },
   },
   'CROS_DEDEDE_RELEASE_DEV': {
@@ -500,7 +500,7 @@
     'identifier': 'FIZZ_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'fizz',
-      'cros_img': 'fizz-release/R120-15645.0.0',
+      'use_lkgm': True,
       'dut_pool': 'chrome',
     },
   },
@@ -532,7 +532,7 @@
     'identifier': 'GUYBRUSH_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'guybrush',
-      'cros_img': 'guybrush-release/R120-15645.0.0',
+      'use_lkgm': True,
       'dut_pool': 'chrome',
     },
   },
@@ -564,7 +564,7 @@
     'identifier': 'PUFF_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'puff',
-      'cros_img': 'puff-release/R120-15645.0.0',
+      'use_lkgm': True,
       'dut_pool': 'chrome',
     },
   },
@@ -596,7 +596,7 @@
     'identifier': 'EVE_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'eve',
-      'cros_img': 'eve-public/R120-15645.0.0',
+      'cros_img': 'eve-public/R120-15650.0.0',
       'bucket': 'chromiumos-image-archive',
       'dut_pool': 'chromium',
       'public_builder': 'cros_test_platform_public',
@@ -607,7 +607,7 @@
     'identifier': 'HANA_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'hana',
-      'cros_img': 'hana-release/R120-15645.0.0',
+      'use_lkgm': True,
     },
   },
   'CROS_HANA_RELEASE_DEV': {
@@ -635,7 +635,7 @@
     'identifier': 'JACUZZI_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_img': 'jacuzzi-release/R120-15645.0.0',
+      'use_lkgm': True,
     },
   },
   'CROS_JACUZZI_RELEASE_DEV': {
@@ -670,7 +670,7 @@
     'identifier': 'JACUZZI_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_img': 'jacuzzi-public/R120-15645.0.0',
+      'cros_img': 'jacuzzi-public/R120-15650.0.0',
       'bucket': 'chromiumos-image-archive',
     },
   },
@@ -678,7 +678,7 @@
     'identifier': 'JACUZZI_CQ_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_img': 'jacuzzi-public/R120-15645.0.0',
+      'cros_img': 'jacuzzi-public/R120-15650.0.0',
       'bucket': 'chromiumos-image-archive',
       'public_builder': 'cros_test_platform_public',
       'public_builder_bucket': 'testplatform-public',
@@ -688,7 +688,7 @@
     'identifier': 'TROGDOR_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'trogdor',
-      'cros_img': 'trogdor-public/R120-15645.0.0',
+      'cros_img': 'trogdor-public/R120-15650.0.0',
       'bucket': 'chromiumos-image-archive',
     },
   },
@@ -696,7 +696,7 @@
     'identifier': 'OCTOPUS_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'octopus',
-      'cros_img': 'octopus-public/R120-15645.0.0',
+      'cros_img': 'octopus-public/R120-15650.0.0',
       'bucket': 'chromiumos-image-archive',
     },
   },
@@ -711,7 +711,7 @@
     'identifier': 'OCTOPUS_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'octopus',
-      'cros_img': 'octopus-release/R120-15645.0.0',
+      'use_lkgm': True,
     },
   },
   'CROS_OCTOPUS_RELEASE_DEV': {
@@ -739,7 +739,7 @@
     'identifier': 'STRONGBAD_RELEASE_LKGM',
     'skylab': {
       'cros_board': 'strongbad',
-      'cros_img': 'strongbad-release/R120-15645.0.0',
+      'use_lkgm': True,
     },
   },
   'CROS_STRONGBAD_RELEASE_DEV': {
@@ -775,7 +775,7 @@
     'skylab': {
       'cros_board': 'volteer',
       'cros_model': 'voxel',
-      'cros_img': 'volteer-public/R120-15645.0.0',
+      'cros_img': 'volteer-public/R120-15650.0.0',
       'bucket': 'chromiumos-image-archive',
       'dut_pool': 'chromium',
       'public_builder': 'cros_test_platform_public',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index e935de0..9488562 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -2494,7 +2494,7 @@
           'linux_intel_uhd_630_stable',
         ],
         'test_suites': {
-          'gpu_telemetry_tests': 'gpu_dawn_telemetry_tests',
+          'gpu_telemetry_tests': 'gpu_dawn_compat_telemetry_tests',
           'gtest_tests': 'gpu_dawn_integration_gtests_passthrough',
           'isolated_scripts': 'gpu_dawn_isolated_scripts',
         },
@@ -2506,7 +2506,7 @@
           'linux_nvidia_gtx_1660_stable',
         ],
         'test_suites': {
-          'gpu_telemetry_tests': 'gpu_dawn_telemetry_tests',
+          'gpu_telemetry_tests': 'gpu_dawn_compat_telemetry_tests',
           'gtest_tests': 'gpu_dawn_integration_gtests_passthrough',
           'isolated_scripts': 'gpu_dawn_isolated_scripts',
         },
@@ -2518,7 +2518,7 @@
           'linux_intel_uhd_630_stable',
         ],
         'test_suites': {
-          'gpu_telemetry_tests': 'gpu_dawn_telemetry_tests',
+          'gpu_telemetry_tests': 'gpu_dawn_compat_telemetry_tests',
           'gtest_tests': 'gpu_dawn_integration_gtests_passthrough',
           'isolated_scripts': 'gpu_dawn_isolated_scripts',
         },
@@ -2534,7 +2534,7 @@
           'linux_nvidia_gtx_1660_stable',
         ],
         'test_suites': {
-          'gpu_telemetry_tests': 'gpu_dawn_telemetry_tests',
+          'gpu_telemetry_tests': 'gpu_dawn_compat_telemetry_tests',
           'gtest_tests': 'gpu_dawn_integration_gtests_passthrough',
           'isolated_scripts': 'gpu_dawn_isolated_scripts',
         },
diff --git a/testing/rust_gtest_interop/rust_gtest_interop.cc b/testing/rust_gtest_interop/rust_gtest_interop.cc
index 4cb06ac..0815c0a 100644
--- a/testing/rust_gtest_interop/rust_gtest_interop.cc
+++ b/testing/rust_gtest_interop/rust_gtest_interop.cc
@@ -8,24 +8,25 @@
 
 namespace rust_gtest_interop {
 
-testing::Test* rust_gtest_default_factory(void (*body)(testing::Test*)) {
+extern "C" testing::Test* rust_gtest_default_factory(
+    void (*body)(testing::Test*)) {
   return rust_gtest_factory_for_subclass<testing::Test>(body);
 }
 
-void rust_gtest_add_test(GtestFactoryFunction gtest_factory,
-                         void (*test_function)(testing::Test*),
-                         const char* test_suite_name,
-                         const char* test_name,
-                         const char* file,
-                         int32_t line) {
+extern "C" void rust_gtest_add_test(GtestFactoryFunction gtest_factory,
+                                    void (*test_function)(testing::Test*),
+                                    const char* test_suite_name,
+                                    const char* test_name,
+                                    const char* file,
+                                    int32_t line) {
   auto factory = [=]() { return gtest_factory(test_function); };
   testing::RegisterTest(test_suite_name, test_name, nullptr, nullptr, file,
                         line, factory);
 }
 
-void rust_gtest_add_failure_at(const char* file,
-                               int32_t line,
-                               const char* message) {
+extern "C" void rust_gtest_add_failure_at(const char* file,
+                                          int32_t line,
+                                          const char* message) {
   ADD_FAILURE_AT(reinterpret_cast<const char*>(file), line) << message;
 }
 
diff --git a/testing/rust_gtest_interop/rust_gtest_interop.h b/testing/rust_gtest_interop/rust_gtest_interop.h
index 9b6d37a..e0fe740 100644
--- a/testing/rust_gtest_interop/rust_gtest_interop.h
+++ b/testing/rust_gtest_interop/rust_gtest_interop.h
@@ -8,8 +8,6 @@
 #include <stdint.h>
 #include <type_traits>
 
-#include "base/memory/raw_ptr_exclusion.h"
-
 namespace testing {
 class Test;
 }
@@ -43,13 +41,8 @@
   void TestBody() override { test_fn_(this); }
 
  private:
-  // Not a `raw_ref<T>`, because the pointee (a function) is never
-  // heap/PartitionAlloc-allocated.
-  //
-  // TODO(https://crbug.com/1451571): An explicit exclusion shouldn't be needed
-  // for function pointers. Remove the //base dependency when RAW_PTR_EXCLUSION
-  // isn't needed.
-  void(RAW_PTR_EXCLUSION& test_fn_)(Subclass*);
+  // Not a `raw_ref<T>` because this is a function reference.
+  void (&test_fn_)(Subclass*);
 };
 
 // The TestSuite factory function which will construct a testing::Test subclass
@@ -67,7 +60,8 @@
 
 // Returns a factory that will run the test function. Used for any Rust tests
 // that don't need a specific C++ testing::Test subclass.
-testing::Test* rust_gtest_default_factory(void (*body)());
+extern "C" testing::Test* rust_gtest_default_factory(
+    void (*body)(testing::Test*));
 
 // Register a test to be run via GTest. This must be called before main(), as
 // there's no calls from C++ into Rust to collect tests. Any function given to
@@ -86,12 +80,12 @@
 //
 // SAFETY: This function makes copies of the strings so the pointers do not need
 // to outlive the function call.
-void rust_gtest_add_test(GtestFactoryFunction gtest_factory,
-                         void (*test_function)(testing::Test*),
-                         const char* test_suite_name,
-                         const char* test_name,
-                         const char* file,
-                         int32_t line);
+extern "C" void rust_gtest_add_test(GtestFactoryFunction gtest_factory,
+                                    void (*test_function)(testing::Test*),
+                                    const char* test_suite_name,
+                                    const char* test_name,
+                                    const char* file,
+                                    int32_t line);
 
 // Report a test failure at a given file and line tuple, with a provided
 // message.
@@ -105,9 +99,9 @@
 //
 // SAFETY: This function makes copies of the strings so the pointers do not need
 // to outlive the function call.
-void rust_gtest_add_failure_at(const char* file,
-                               int32_t line,
-                               const char* message);
+extern "C" void rust_gtest_add_failure_at(const char* file,
+                                          int32_t line,
+                                          const char* message);
 
 }  // namespace rust_gtest_interop
 
diff --git a/testing/rust_gtest_interop/rust_gtest_interop.rs b/testing/rust_gtest_interop/rust_gtest_interop.rs
index 26047ef..adab2b1 100644
--- a/testing/rust_gtest_interop/rust_gtest_interop.rs
+++ b/testing/rust_gtest_interop/rust_gtest_interop.rs
@@ -114,14 +114,6 @@
         let null_term_message = std::ffi::CString::new(message).unwrap();
 
         extern "C" {
-            #[cfg_attr(
-                windows,
-                link_name = "?rust_gtest_add_failure_at@rust_gtest_interop@@YAXPEBDH0@Z"
-            )]
-            #[cfg_attr(
-                not(windows),
-                link_name = "_ZN18rust_gtest_interop25rust_gtest_add_failure_atEPKciS1_"
-            )]
             fn rust_gtest_add_failure_at(
                 file: *const std::ffi::c_char,
                 line: i32,
@@ -183,14 +175,6 @@
     }
 
     extern "C" {
-        #[cfg_attr(
-            windows,
-            link_name = "?rust_gtest_default_factory@rust_gtest_interop@@YAPEAVTest@testing@@P6AXPEAV23@@Z@Z"
-        )]
-        #[cfg_attr(
-            not(windows),
-            link_name = "_ZN18rust_gtest_interop26rust_gtest_default_factoryEPFvPN7testing4TestEE"
-        )]
         /// extern for C++'s rust_gtest_default_factory().
         /// TODO(danakj): We do this by hand because cxx doesn't support passing
         /// raw function pointers: https://github.com/dtolnay/cxx/issues/1011.
@@ -200,14 +184,6 @@
     }
 
     extern "C" {
-        #[cfg_attr(
-            windows,
-            link_name = "?rust_gtest_add_test@rust_gtest_interop@@YAXP6APEAVTest@testing@@P6AXPEAV23@@Z@Z1PEBD33H@Z"
-        )]
-        #[cfg_attr(
-            not(windows),
-            link_name = "_ZN18rust_gtest_interop19rust_gtest_add_testEPFPN7testing4TestEPFvS2_EES4_PKcS8_S8_i"
-        )]
         /// extern for C++'s rust_gtest_add_test().
         ///
         /// Note that the `factory` parameter is actually a C++ function
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index f37afb27..01b0ce5 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -2324,6 +2324,21 @@
             ]
         }
     ],
+    "BackgroundThreadNormalMemoryPriorityWin": [
+        {
+            "platforms": [
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "BackgroundThreadNormalMemoryPriorityWin"
+                    ]
+                }
+            ]
+        }
+    ],
     "BeforeunloadEventCancelByPreventDefault": [
         {
             "platforms": [
@@ -3609,6 +3624,21 @@
             ]
         }
     ],
+    "ChromeOSScreenSaverDuration": [
+        {
+            "platforms": [
+                "chromeos"
+            ],
+            "experiments": [
+                {
+                    "name": "Dogfood_CANARY_DEV_50",
+                    "enable_features": [
+                        "ScreenSaverDuration"
+                    ]
+                }
+            ]
+        }
+    ],
     "ChromeOSWelcomeTour": [
         {
             "platforms": [
@@ -5003,6 +5033,32 @@
             ]
         }
     ],
+    "DefaultBrowserPromotionImprovementsPhase1": [
+        {
+            "platforms": [
+                "ios"
+            ],
+            "experiments": [
+                {
+                    "name": "Launch_Group_B",
+                    "params": {
+                        "cooldown-days": "14",
+                        "default_browser_video_promo_variant": "generic_conditions_halfscreen_promo",
+                        "impression-limit": "3"
+                    },
+                    "enable_features": [
+                        "DefaultBrowserVideoPromo",
+                        "NonModalDefaultBrowserPromoCooldownRefactor",
+                        "NonModalDefaultBrowserPromoImpressionLimit"
+                    ],
+                    "disable_features": [
+                        "DefaultBrowserGenericTailoredPromoTrain",
+                        "FullScreenPromoOnOmniboxCopyPaste"
+                    ]
+                }
+            ]
+        }
+    ],
     "DefaultGpuDiskCacheSize": [
         {
             "platforms": [
@@ -6689,6 +6745,28 @@
             ],
             "experiments": [
                 {
+                    "name": "Enabled_20231018_Dogfood",
+                    "params": {
+                        "pwa-companion-app-id": "ckdjfcfapbgminighllemapmpdlpihia",
+                        "pwa-companion-install-uri": "https://mypixelbuds.google.com/",
+                        "pwa-companion-play-store-uri": "https://play.google.com/store/apps/details?id=com.google.android.apps.wearables.maestro.companion"
+                    },
+                    "enable_features": [
+                        "FastPairPwaCompanion"
+                    ]
+                },
+                {
+                    "name": "Enabled_20231018",
+                    "params": {
+                        "pwa-companion-app-id": "ckdjfcfapbgminighllemapmpdlpihia",
+                        "pwa-companion-install-uri": "https://mypixelbuds.google.com/",
+                        "pwa-companion-play-store-uri": "https://play.google.com/store/apps/details?id=com.google.android.apps.wearables.maestro.companion"
+                    },
+                    "enable_features": [
+                        "FastPairPwaCompanion"
+                    ]
+                },
+                {
                     "name": "EnabledWithStagingLinks_Dogfood",
                     "params": {
                         "pwa-companion-app-id": "kncedjianpafagdchkiinagaaokkhpaa",
@@ -8165,24 +8243,6 @@
             ]
         }
     ],
-    "HoverCardImagePreviewSetting": [
-        {
-            "platforms": [
-                "chromeos",
-                "chromeos_lacros",
-                "linux",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "TabHoverCardImageSettings"
-                    ]
-                }
-            ]
-        }
-    ],
     "HttpsFirstModeV2ForTypicallySecureUsers": [
         {
             "platforms": [
@@ -13518,6 +13578,26 @@
             ]
         }
     ],
+    "ProtectedAudiencesClearOriginJoinedAdInterestGroups": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "chromeos_lacros",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "FledgeClearOriginJoinedAdInterestGroups"
+                    ]
+                }
+            ]
+        }
+    ],
     "ProtectedAudiencesHeaderDirectFromSellerSignalsStudy": [
         {
             "platforms": [
@@ -14703,6 +14783,440 @@
             ],
             "experiments": [
                 {
+                    "name": "CounterfactualControl_CANARY_DEV_20231017",
+                    "params": {
+                        "IPH_ScalableIphTimerBasedEight_availability": "any",
+                        "IPH_ScalableIphTimerBasedEight_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedEight_blocking": "none",
+                        "IPH_ScalableIphTimerBasedEight_event_1": "name:ScalableIphFiveMinTick;comparator:>=26;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedEight_event_trigger": "name:ScalableIphTimerBasedEightTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedEight_event_used": "name:ScalableIphTimerBasedEightEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedEight_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedEight_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedEight_tracking_only": "true",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomButtonActionType": "OpenPhoneHub",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomConditionPhoneHubOnboardingEligible": "True",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomNotificationBodyText": "You can quickly reply to messages from your Android phone, right from your Chromebook",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomNotificationButtonText": "Connect phone",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomNotificationId": "scalable_iph_timer_based_eight",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomNotificationSummaryText": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomNotificationTitle": "Connect your Android phone",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomUiType": "Notification",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedFive_availability": "any",
+                        "IPH_ScalableIphTimerBasedFive_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedFive_blocking": "none",
+                        "IPH_ScalableIphTimerBasedFive_event_1": "name:ScalableIphFiveMinTick;comparator:>=16;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedFive_event_trigger": "name:ScalableIphTimerBasedFiveTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedFive_event_used": "name:ScalableIphTimerBasedFiveEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedFive_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedFive_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedFive_tracking_only": "true",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomButtonActionType": "OpenSettingsPrinter",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomConditionHasSavedPrinter": "False",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomNotificationBodyText": "Easily add a printer to your Chromebook so it will be ready to go",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomNotificationButtonText": "Add printer",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomNotificationId": "scalable_iph_timer_based_five",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomNotificationSummaryText": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomNotificationTitle": "Connect a printer",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomUiType": "Notification",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedFour_availability": "any",
+                        "IPH_ScalableIphTimerBasedFour_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedFour_blocking": "none",
+                        "IPH_ScalableIphTimerBasedFour_event_1": "name:ScalableIphFiveMinTick;comparator:>=12;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedFour_event_precondition_personalization_app": "name:ScalableIphOpenPersonalizationApp;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedFour_event_trigger": "name:ScalableIphTimerBasedFourTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedFour_event_used": "name:ScalableIphTimerBasedFourEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedFour_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedFour_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedFour_tracking_only": "true",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomButtonActionType": "OpenPersonalizationApp",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomNotificationBodyText": "Make your Chromebook uniquely yours with a new wallpaper",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomNotificationButtonText": "Select wallpaper",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomNotificationId": "scalable_iph_timer_based_four",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomNotificationImageType": "Wallpaper",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomNotificationSummaryText": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomNotificationTitle": "Customize your wallpaper",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomUiType": "Notification",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedNine_availability": "any",
+                        "IPH_ScalableIphTimerBasedNine_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedNine_blocking": "none",
+                        "IPH_ScalableIphTimerBasedNine_event_1": "name:ScalableIphFiveMinTick;comparator:>=30;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedNine_event_precondition_youtube_app_list": "name:ScalableIphAppListItemActivationYouTube;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedNine_event_precondition_youtube_shelf": "name:ScalableIphShelfItemActivationYouTube;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedNine_event_trigger": "name:ScalableIphTimerBasedNineTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedNine_event_used": "name:ScalableIphTimerBasedNineEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedNine_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedNine_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedNine_tracking_only": "true",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomBubbleButtonText": "Open YouTube",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomBubbleIcon": "YouTubeIcon",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomBubbleId": "scalable_iph_timer_based_nine",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomBubbleText": "Watch your favorite content on YouTube",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomButtonActionType": "OpenYouTube",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedOne_availability": "any",
+                        "IPH_ScalableIphTimerBasedOne_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedOne_blocking": "none",
+                        "IPH_ScalableIphTimerBasedOne_event_1": "name:ScalableIphFiveMinTick;comparator:>=0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedOne_event_trigger": "name:ScalableIphTimerBasedOneTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedOne_event_used": "name:ScalableIphTimerBasedOneEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedOne_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedOne_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedOne_tracking_only": "true",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomBubbleButtonText": "Open Chrome",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomBubbleIcon": "ChromeIcon",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomBubbleId": "scalable_iph_timer_based_one",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomBubbleText": "Connect to the world on your Chromebook with Chrome browser",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomButtonActionType": "OpenChrome",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedSeven_availability": "any",
+                        "IPH_ScalableIphTimerBasedSeven_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedSeven_blocking": "none",
+                        "IPH_ScalableIphTimerBasedSeven_event_1": "name:ScalableIphFiveMinTick;comparator:>=24;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_android_app_list": "name:ScalableIphAppListItemActivationOpenGooglePhotosAndroid;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_android_shelf": "name:ScalableIphShelfItemActivationGooglePhotosAndroid;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_web_app_list": "name:ScalableIphAppListItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_web_shelf": "name:ScalableIphShelfItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSeven_event_trigger": "name:ScalableIphTimerBasedSevenTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSeven_event_used": "name:ScalableIphTimerBasedSevenEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSeven_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedSeven_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedSeven_tracking_only": "true",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleButtonText": "Open Photos",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleIcon": "GooglePhotosIcon",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleId": "scalable_iph_timer_based_seven",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleText": "Explore your favorite memories in Google Photos",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomButtonActionType": "OpenGooglePhotos",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedSix_availability": "any",
+                        "IPH_ScalableIphTimerBasedSix_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedSix_blocking": "none",
+                        "IPH_ScalableIphTimerBasedSix_event_1": "name:ScalableIphFiveMinTick;comparator:>=18;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSix_event_precondition_google_play_app_list": "name:ScalableIphAppListItemActivationOpenGooglePlayStore;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSix_event_precondition_google_play_shelf": "name:ScalableIphShelfItemActivationGooglePlay;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSix_event_trigger": "name:ScalableIphTimerBasedSixTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSix_event_used": "name:ScalableIphTimerBasedSixEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSix_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedSix_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedSix_tracking_only": "true",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomButtonActionType": "OpenPlayStore",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomNotificationBodyText": "Download your favorite Android apps from the Google Play Store and use them on your Chromebook",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomNotificationButtonText": "Open Play Store",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomNotificationId": "scalable_iph_timer_based_six",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomNotificationSummaryText": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomNotificationTitle": "Install apps from the Play Store",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomUiType": "Notification",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedTen_availability": "any",
+                        "IPH_ScalableIphTimerBasedTen_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedTen_blocking": "none",
+                        "IPH_ScalableIphTimerBasedTen_event_1": "name:ScalableIphFiveMinTick;comparator:>=48;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTen_event_precondition_print_job": "name:ScalableIphPrintJobCreated;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTen_event_trigger": "name:ScalableIphTimerBasedTenTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTen_event_used": "name:ScalableIphTimerBasedTenEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTen_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedTen_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedTen_tracking_only": "true",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomBubbleButtonText": "Select file",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomBubbleIcon": "PrintJobsIcon",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomBubbleId": "scalable_iph_timer_based_ten",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomBubbleText": "Printing is easy with your Chromebook",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomButtonActionType": "OpenFileManager",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedThree_availability": "any",
+                        "IPH_ScalableIphTimerBasedThree_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedThree_blocking": "none",
+                        "IPH_ScalableIphTimerBasedThree_event_1": "name:ScalableIphFiveMinTick;comparator:>=2;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedThree_event_precondition_google_docs_app_list": "name:ScalableIphAppListItemActivationGoogleDocs;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedThree_event_precondition_google_docs_shelf": "name:ScalableIphShelfItemActivationGoogleDocs;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedThree_event_trigger": "name:ScalableIphTimerBasedThreeTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedThree_event_used": "name:ScalableIphTimerBasedThreeEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedThree_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedThree_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedThree_tracking_only": "true",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomBubbleButtonText": "Open Docs",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomBubbleIcon": "GoogleDocsIcon",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomBubbleId": "scalable_iph_timer_based_three",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomBubbleText": "Create, edit, and collaborate with Google Docs",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomButtonActionType": "OpenGoogleDocs",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedTwo_availability": "any",
+                        "IPH_ScalableIphTimerBasedTwo_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedTwo_blocking": "none",
+                        "IPH_ScalableIphTimerBasedTwo_event_1": "name:ScalableIphFiveMinTick;comparator:>=1;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTwo_event_precondition_launcher": "name:ScalableIphAppListShown;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTwo_event_trigger": "name:ScalableIphTimerBasedTwoTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTwo_event_used": "name:ScalableIphAppListShown;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTwo_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedTwo_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedTwo_tracking_only": "true",
+                        "IPH_ScalableIphTimerBasedTwo_x_CustomBubbleId": "scalable_iph_timer_based_two",
+                        "IPH_ScalableIphTimerBasedTwo_x_CustomBubbleText": "Search and find your apps in the Launcher \u25c9",
+                        "IPH_ScalableIphTimerBasedTwo_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedTwo_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedTwo_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedTwo_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphTimerBasedTwo_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedEight_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedEight_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedEight_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedEight_event_1": "name:ScalableIphUnlocked;comparator:>=7;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedEight_event_trigger": "name:ScalableIphUnlockedBasedEightTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedEight_event_used": "name:ScalableIphUnlockedBasedEightEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedEight_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedEight_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedEight_tracking_only": "true",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomBubbleButtonText": "Connect phone",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomBubbleId": "scalable_iph_unlocked_based_eight",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomBubbleText": "Quickly reply to your messages from your Android phone",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomButtonActionType": "OpenPhoneHub",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomConditionPhoneHubOnboardingEligible": "True",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedFive_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedFive_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedFive_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedFive_event_1": "name:ScalableIphUnlocked;comparator:>=4;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFive_event_precondition_google_docs_app_list": "name:ScalableIphAppListItemActivationGoogleDocs;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFive_event_precondition_google_docs_shelf": "name:ScalableIphShelfItemActivationGoogleDocs;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFive_event_trigger": "name:ScalableIphUnlockedBasedFiveTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFive_event_used": "name:ScalableIphUnlockedBasedFiveEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFive_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedFive_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedFive_tracking_only": "true",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleButtonText": "Open Docs",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleIcon": "GoogleDocsIcon",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleId": "scalable_iph_unlocked_based_five",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleText": "Create, edit, and collaborate with Google Docs",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomButtonActionType": "OpenGoogleDocs",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedFour_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedFour_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedFour_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedFour_event_1": "name:ScalableIphUnlocked;comparator:>=3;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFour_event_precondition_google_play_app_list": "name:ScalableIphAppListItemActivationOpenGooglePlayStore;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFour_event_precondition_google_play_shelf": "name:ScalableIphShelfItemActivationGooglePlay;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFour_event_trigger": "name:ScalableIphUnlockedBasedFourTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFour_event_used": "name:ScalableIphUnlockedBasedFourEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFour_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedFour_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedFour_tracking_only": "true",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleButtonText": "Open Play Store",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleIcon": "PlayStoreIcon",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleId": "scalable_iph_unlocked_based_four",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleText": "Get your favorite apps from the Play Store",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomButtonActionType": "OpenPlayStore",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedNine_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedNine_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedNine_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedNine_event_1": "name:ScalableIphUnlocked;comparator:>=8;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedNine_event_precondition_youtube_app_list": "name:ScalableIphAppListItemActivationYouTube;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedNine_event_precondition_youtube_shelf": "name:ScalableIphShelfItemActivationYouTube;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedNine_event_trigger": "name:ScalableIphUnlockedBasedNineTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedNine_event_used": "name:ScalableIphUnlockedBasedNineEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedNine_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedNine_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedNine_tracking_only": "true",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleButtonText": "Open YouTube",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleIcon": "YouTubeIcon",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleId": "scalable_iph_unlocked_based_nine",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleText": "Watch your favorite content on YouTube",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomButtonActionType": "OpenYouTube",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedOne_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedOne_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedOne_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedOne_event_1": "name:ScalableIphUnlocked;comparator:>=0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedOne_event_trigger": "name:ScalableIphUnlockedBasedOneTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedOne_event_used": "name:ScalableIphUnlockedBasedOneEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedOne_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedOne_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedOne_tracking_only": "true",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleButtonText": "Open Chrome",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleIcon": "ChromeIcon",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleId": "scalable_iph_unlocked_based_one",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleText": "Connect to the world on your Chromebook with Chrome browser",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomButtonActionType": "OpenChrome",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedSeven_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedSeven_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedSeven_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedSeven_event_1": "name:ScalableIphUnlocked;comparator:>=6;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSeven_event_trigger": "name:ScalableIphUnlockedBasedSevenTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSeven_event_used": "name:ScalableIphUnlockedBasedSevenEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSeven_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedSeven_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedSeven_tracking_only": "true",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleButtonText": "Add printer",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleIcon": "PrintJobsIcon",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleId": "scalable_iph_unlocked_based_seven",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleText": "Easily add a printer to your Chromebook",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomButtonActionType": "OpenSettingsPrinter",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomConditionHasSavedPrinter": "False",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedSix_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedSix_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedSix_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedSix_event_1": "name:ScalableIphUnlocked;comparator:>=5;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_android_app_list": "name:ScalableIphAppListItemActivationOpenGooglePhotosAndroid;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_android_shelf": "name:ScalableIphShelfItemActivationGooglePhotosAndroid;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_web_app_list": "name:ScalableIphAppListItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_web_shelf": "name:ScalableIphShelfItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSix_event_trigger": "name:ScalableIphUnlockedBasedSixTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSix_event_used": "name:ScalableIphUnlockedBasedSixEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSix_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedSix_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedSix_tracking_only": "true",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleButtonText": "Open Photos",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleIcon": "GooglePhotosIcon",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleId": "scalable_iph_unlocked_based_six",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleText": "Explore your favorite memories in Google Photos",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomButtonActionType": "OpenGooglePhotos",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedTen_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedTen_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedTen_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedTen_event_1": "name:ScalableIphUnlocked;comparator:>=9;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTen_event_precondition_print_job": "name:ScalableIphPrintJobCreated;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTen_event_trigger": "name:ScalableIphUnlockedBasedTenTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTen_event_used": "name:ScalableIphUnlockedBasedTenEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTen_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedTen_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedTen_tracking_only": "true",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleButtonText": "Select file",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleIcon": "PrintJobsIcon",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleId": "scalable_iph_unlocked_based_ten",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleText": "Printing is easy with your Chromebook",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomButtonActionType": "OpenFileManager",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedThree_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedThree_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedThree_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedThree_event_1": "name:ScalableIphUnlocked;comparator:>=2;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedThree_event_precondition_personalization_app": "name:ScalableIphOpenPersonalizationApp;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedThree_event_trigger": "name:ScalableIphUnlockedBasedThreeTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedThree_event_used": "name:ScalableIphUnlockedBasedThreeEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedThree_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedThree_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedThree_tracking_only": "true",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomBubbleButtonText": "Select wallpaper",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomBubbleId": "scalable_iph_unlocked_based_three",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomBubbleText": "Make your Chromebook uniquely yours with a new wallpaper",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomButtonActionType": "OpenPersonalizationApp",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedTwo_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedTwo_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedTwo_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedTwo_event_1": "name:ScalableIphUnlocked;comparator:>=1;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTwo_event_precondition_launcher": "name:ScalableIphAppListShown;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTwo_event_trigger": "name:ScalableIphUnlockedBasedTwoTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTwo_event_used": "name:ScalableIphAppListShown;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTwo_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedTwo_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedTwo_tracking_only": "true",
+                        "IPH_ScalableIphUnlockedBasedTwo_x_CustomBubbleId": "scalable_iph_unlocked_based_two",
+                        "IPH_ScalableIphUnlockedBasedTwo_x_CustomBubbleText": "Search and find your apps in the Launcher \u25c9",
+                        "IPH_ScalableIphUnlockedBasedTwo_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedTwo_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedTwo_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedTwo_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedTwo_x_CustomVersionNumber": "1"
+                    },
+                    "enable_features": [
+                        "IPH_ScalableIphTimerBasedEight",
+                        "IPH_ScalableIphTimerBasedFive",
+                        "IPH_ScalableIphTimerBasedFour",
+                        "IPH_ScalableIphTimerBasedNine",
+                        "IPH_ScalableIphTimerBasedOne",
+                        "IPH_ScalableIphTimerBasedSeven",
+                        "IPH_ScalableIphTimerBasedSix",
+                        "IPH_ScalableIphTimerBasedTen",
+                        "IPH_ScalableIphTimerBasedThree",
+                        "IPH_ScalableIphTimerBasedTwo",
+                        "IPH_ScalableIphUnlockedBasedEight",
+                        "IPH_ScalableIphUnlockedBasedFive",
+                        "IPH_ScalableIphUnlockedBasedFour",
+                        "IPH_ScalableIphUnlockedBasedNine",
+                        "IPH_ScalableIphUnlockedBasedOne",
+                        "IPH_ScalableIphUnlockedBasedSeven",
+                        "IPH_ScalableIphUnlockedBasedSix",
+                        "IPH_ScalableIphUnlockedBasedTen",
+                        "IPH_ScalableIphUnlockedBasedThree",
+                        "IPH_ScalableIphUnlockedBasedTwo",
+                        "ScalableIph"
+                    ],
+                    "disable_features": [
+                        "ShelfLauncherNudge"
+                    ]
+                },
+                {
                     "name": "ScalableIph_Teamfood",
                     "params": {
                         "IPH_ScalableIphHelpAppBasedEight_availability": "any",
@@ -15251,6 +15765,431 @@
                     "disable_features": [
                         "ShelfLauncherNudge"
                     ]
+                },
+                {
+                    "name": "TimerBased_CANARY_DEV_20231017",
+                    "params": {
+                        "IPH_ScalableIphTimerBasedEight_availability": "any",
+                        "IPH_ScalableIphTimerBasedEight_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedEight_blocking": "none",
+                        "IPH_ScalableIphTimerBasedEight_event_1": "name:ScalableIphFiveMinTick;comparator:>=26;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedEight_event_trigger": "name:ScalableIphTimerBasedEightTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedEight_event_used": "name:ScalableIphTimerBasedEightEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedEight_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedEight_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomButtonActionType": "OpenPhoneHub",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomConditionPhoneHubOnboardingEligible": "True",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomNotificationBodyText": "You can quickly reply to messages from your Android phone, right from your Chromebook",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomNotificationButtonText": "Connect phone",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomNotificationId": "scalable_iph_timer_based_eight",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomNotificationSummaryText": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomNotificationTitle": "Connect your Android phone",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomUiType": "Notification",
+                        "IPH_ScalableIphTimerBasedEight_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedFive_availability": "any",
+                        "IPH_ScalableIphTimerBasedFive_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedFive_blocking": "none",
+                        "IPH_ScalableIphTimerBasedFive_event_1": "name:ScalableIphFiveMinTick;comparator:>=16;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedFive_event_trigger": "name:ScalableIphTimerBasedFiveTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedFive_event_used": "name:ScalableIphTimerBasedFiveEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedFive_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedFive_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomButtonActionType": "OpenSettingsPrinter",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomConditionHasSavedPrinter": "False",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomNotificationBodyText": "Easily add a printer to your Chromebook so it will be ready to go",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomNotificationButtonText": "Add printer",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomNotificationId": "scalable_iph_timer_based_five",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomNotificationSummaryText": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomNotificationTitle": "Connect a printer",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomUiType": "Notification",
+                        "IPH_ScalableIphTimerBasedFive_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedFour_availability": "any",
+                        "IPH_ScalableIphTimerBasedFour_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedFour_blocking": "none",
+                        "IPH_ScalableIphTimerBasedFour_event_1": "name:ScalableIphFiveMinTick;comparator:>=12;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedFour_event_precondition_personalization_app": "name:ScalableIphOpenPersonalizationApp;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedFour_event_trigger": "name:ScalableIphTimerBasedFourTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedFour_event_used": "name:ScalableIphTimerBasedFourEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedFour_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedFour_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomButtonActionType": "OpenPersonalizationApp",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomNotificationBodyText": "Make your Chromebook uniquely yours with a new wallpaper",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomNotificationButtonText": "Select wallpaper",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomNotificationId": "scalable_iph_timer_based_four",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomNotificationImageType": "Wallpaper",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomNotificationSummaryText": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomNotificationTitle": "Customize your wallpaper",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomUiType": "Notification",
+                        "IPH_ScalableIphTimerBasedFour_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedNine_availability": "any",
+                        "IPH_ScalableIphTimerBasedNine_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedNine_blocking": "none",
+                        "IPH_ScalableIphTimerBasedNine_event_1": "name:ScalableIphFiveMinTick;comparator:>=30;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedNine_event_precondition_youtube_app_list": "name:ScalableIphAppListItemActivationYouTube;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedNine_event_precondition_youtube_shelf": "name:ScalableIphShelfItemActivationYouTube;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedNine_event_trigger": "name:ScalableIphTimerBasedNineTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedNine_event_used": "name:ScalableIphTimerBasedNineEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedNine_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedNine_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomBubbleButtonText": "Open YouTube",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomBubbleIcon": "YouTubeIcon",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomBubbleId": "scalable_iph_timer_based_nine",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomBubbleText": "Watch your favorite content on YouTube",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomButtonActionType": "OpenYouTube",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphTimerBasedNine_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedOne_availability": "any",
+                        "IPH_ScalableIphTimerBasedOne_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedOne_blocking": "none",
+                        "IPH_ScalableIphTimerBasedOne_event_1": "name:ScalableIphFiveMinTick;comparator:>=0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedOne_event_trigger": "name:ScalableIphTimerBasedOneTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedOne_event_used": "name:ScalableIphTimerBasedOneEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedOne_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedOne_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomBubbleButtonText": "Open Chrome",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomBubbleIcon": "ChromeIcon",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomBubbleId": "scalable_iph_timer_based_one",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomBubbleText": "Connect to the world on your Chromebook with Chrome browser",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomButtonActionType": "OpenChrome",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphTimerBasedOne_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedSeven_availability": "any",
+                        "IPH_ScalableIphTimerBasedSeven_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedSeven_blocking": "none",
+                        "IPH_ScalableIphTimerBasedSeven_event_1": "name:ScalableIphFiveMinTick;comparator:>=24;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_android_app_list": "name:ScalableIphAppListItemActivationOpenGooglePhotosAndroid;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_android_shelf": "name:ScalableIphShelfItemActivationGooglePhotosAndroid;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_web_app_list": "name:ScalableIphAppListItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_web_shelf": "name:ScalableIphShelfItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSeven_event_trigger": "name:ScalableIphTimerBasedSevenTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSeven_event_used": "name:ScalableIphTimerBasedSevenEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSeven_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedSeven_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleButtonText": "Open Photos",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleIcon": "GooglePhotosIcon",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleId": "scalable_iph_timer_based_seven",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleText": "Explore your favorite memories in Google Photos",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomButtonActionType": "OpenGooglePhotos",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphTimerBasedSeven_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedSix_availability": "any",
+                        "IPH_ScalableIphTimerBasedSix_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedSix_blocking": "none",
+                        "IPH_ScalableIphTimerBasedSix_event_1": "name:ScalableIphFiveMinTick;comparator:>=18;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSix_event_precondition_google_play_app_list": "name:ScalableIphAppListItemActivationOpenGooglePlayStore;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSix_event_precondition_google_play_shelf": "name:ScalableIphShelfItemActivationGooglePlay;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSix_event_trigger": "name:ScalableIphTimerBasedSixTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSix_event_used": "name:ScalableIphTimerBasedSixEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedSix_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedSix_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomButtonActionType": "OpenPlayStore",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomNotificationBodyText": "Download your favorite Android apps from the Google Play Store and use them on your Chromebook",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomNotificationButtonText": "Open Play Store",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomNotificationId": "scalable_iph_timer_based_six",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomNotificationSummaryText": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomNotificationTitle": "Install apps from the Play Store",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomUiType": "Notification",
+                        "IPH_ScalableIphTimerBasedSix_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedTen_availability": "any",
+                        "IPH_ScalableIphTimerBasedTen_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedTen_blocking": "none",
+                        "IPH_ScalableIphTimerBasedTen_event_1": "name:ScalableIphFiveMinTick;comparator:>=48;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTen_event_precondition_print_job": "name:ScalableIphPrintJobCreated;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTen_event_trigger": "name:ScalableIphTimerBasedTenTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTen_event_used": "name:ScalableIphTimerBasedTenEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTen_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedTen_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomBubbleButtonText": "Select file",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomBubbleIcon": "PrintJobsIcon",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomBubbleId": "scalable_iph_timer_based_ten",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomBubbleText": "Printing is easy with your Chromebook",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomButtonActionType": "OpenFileManager",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphTimerBasedTen_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedThree_availability": "any",
+                        "IPH_ScalableIphTimerBasedThree_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedThree_blocking": "none",
+                        "IPH_ScalableIphTimerBasedThree_event_1": "name:ScalableIphFiveMinTick;comparator:>=2;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedThree_event_precondition_google_docs_app_list": "name:ScalableIphAppListItemActivationGoogleDocs;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedThree_event_precondition_google_docs_shelf": "name:ScalableIphShelfItemActivationGoogleDocs;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedThree_event_trigger": "name:ScalableIphTimerBasedThreeTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedThree_event_used": "name:ScalableIphTimerBasedThreeEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedThree_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedThree_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomBubbleButtonText": "Open Docs",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomBubbleIcon": "GoogleDocsIcon",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomBubbleId": "scalable_iph_timer_based_three",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomBubbleText": "Create, edit, and collaborate with Google Docs",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomButtonActionType": "OpenGoogleDocs",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphTimerBasedThree_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphTimerBasedTwo_availability": "any",
+                        "IPH_ScalableIphTimerBasedTwo_blocked_by": "none",
+                        "IPH_ScalableIphTimerBasedTwo_blocking": "none",
+                        "IPH_ScalableIphTimerBasedTwo_event_1": "name:ScalableIphFiveMinTick;comparator:>=1;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTwo_event_precondition_launcher": "name:ScalableIphAppListShown;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTwo_event_trigger": "name:ScalableIphTimerBasedTwoTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTwo_event_used": "name:ScalableIphAppListShown;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphTimerBasedTwo_session_rate": "any",
+                        "IPH_ScalableIphTimerBasedTwo_session_rate_impact": "none",
+                        "IPH_ScalableIphTimerBasedTwo_x_CustomBubbleId": "scalable_iph_timer_based_two",
+                        "IPH_ScalableIphTimerBasedTwo_x_CustomBubbleText": "Search and find your apps in the Launcher \u25c9",
+                        "IPH_ScalableIphTimerBasedTwo_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphTimerBasedTwo_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphTimerBasedTwo_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphTimerBasedTwo_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphTimerBasedTwo_x_CustomVersionNumber": "1"
+                    },
+                    "enable_features": [
+                        "IPH_ScalableIphTimerBasedEight",
+                        "IPH_ScalableIphTimerBasedFive",
+                        "IPH_ScalableIphTimerBasedFour",
+                        "IPH_ScalableIphTimerBasedNine",
+                        "IPH_ScalableIphTimerBasedOne",
+                        "IPH_ScalableIphTimerBasedSeven",
+                        "IPH_ScalableIphTimerBasedSix",
+                        "IPH_ScalableIphTimerBasedTen",
+                        "IPH_ScalableIphTimerBasedThree",
+                        "IPH_ScalableIphTimerBasedTwo",
+                        "ScalableIph"
+                    ],
+                    "disable_features": [
+                        "ShelfLauncherNudge"
+                    ]
+                },
+                {
+                    "name": "UnlockedBased_CANARY_DEV_20231017",
+                    "params": {
+                        "IPH_ScalableIphUnlockedBasedEight_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedEight_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedEight_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedEight_event_1": "name:ScalableIphUnlocked;comparator:>=7;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedEight_event_trigger": "name:ScalableIphUnlockedBasedEightTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedEight_event_used": "name:ScalableIphUnlockedBasedEightEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedEight_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedEight_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomBubbleButtonText": "Connect phone",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomBubbleId": "scalable_iph_unlocked_based_eight",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomBubbleText": "Quickly reply to your messages from your Android phone",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomButtonActionType": "OpenPhoneHub",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomConditionPhoneHubOnboardingEligible": "True",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedEight_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedFive_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedFive_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedFive_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedFive_event_1": "name:ScalableIphUnlocked;comparator:>=4;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFive_event_precondition_google_docs_app_list": "name:ScalableIphAppListItemActivationGoogleDocs;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFive_event_precondition_google_docs_shelf": "name:ScalableIphShelfItemActivationGoogleDocs;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFive_event_trigger": "name:ScalableIphUnlockedBasedFiveTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFive_event_used": "name:ScalableIphUnlockedBasedFiveEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFive_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedFive_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleButtonText": "Open Docs",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleIcon": "GoogleDocsIcon",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleId": "scalable_iph_unlocked_based_five",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleText": "Create, edit, and collaborate with Google Docs",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomButtonActionType": "OpenGoogleDocs",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedFive_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedFour_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedFour_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedFour_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedFour_event_1": "name:ScalableIphUnlocked;comparator:>=3;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFour_event_precondition_google_play_app_list": "name:ScalableIphAppListItemActivationOpenGooglePlayStore;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFour_event_precondition_google_play_shelf": "name:ScalableIphShelfItemActivationGooglePlay;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFour_event_trigger": "name:ScalableIphUnlockedBasedFourTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFour_event_used": "name:ScalableIphUnlockedBasedFourEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedFour_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedFour_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleButtonText": "Open Play Store",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleIcon": "PlayStoreIcon",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleId": "scalable_iph_unlocked_based_four",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleText": "Get your favorite apps from the Play Store",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomButtonActionType": "OpenPlayStore",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedFour_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedNine_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedNine_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedNine_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedNine_event_1": "name:ScalableIphUnlocked;comparator:>=8;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedNine_event_precondition_youtube_app_list": "name:ScalableIphAppListItemActivationYouTube;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedNine_event_precondition_youtube_shelf": "name:ScalableIphShelfItemActivationYouTube;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedNine_event_trigger": "name:ScalableIphUnlockedBasedNineTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedNine_event_used": "name:ScalableIphUnlockedBasedNineEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedNine_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedNine_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleButtonText": "Open YouTube",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleIcon": "YouTubeIcon",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleId": "scalable_iph_unlocked_based_nine",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleText": "Watch your favorite content on YouTube",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomButtonActionType": "OpenYouTube",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedNine_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedOne_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedOne_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedOne_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedOne_event_1": "name:ScalableIphUnlocked;comparator:>=0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedOne_event_trigger": "name:ScalableIphUnlockedBasedOneTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedOne_event_used": "name:ScalableIphUnlockedBasedOneEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedOne_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedOne_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleButtonText": "Open Chrome",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleIcon": "ChromeIcon",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleId": "scalable_iph_unlocked_based_one",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleText": "Connect to the world on your Chromebook with Chrome browser",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomButtonActionType": "OpenChrome",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedOne_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedSeven_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedSeven_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedSeven_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedSeven_event_1": "name:ScalableIphUnlocked;comparator:>=6;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSeven_event_trigger": "name:ScalableIphUnlockedBasedSevenTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSeven_event_used": "name:ScalableIphUnlockedBasedSevenEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSeven_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedSeven_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleButtonText": "Add printer",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleIcon": "PrintJobsIcon",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleId": "scalable_iph_unlocked_based_seven",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleText": "Easily add a printer to your Chromebook",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomButtonActionType": "OpenSettingsPrinter",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomConditionHasSavedPrinter": "False",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedSeven_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedSix_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedSix_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedSix_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedSix_event_1": "name:ScalableIphUnlocked;comparator:>=5;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_android_app_list": "name:ScalableIphAppListItemActivationOpenGooglePhotosAndroid;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_android_shelf": "name:ScalableIphShelfItemActivationGooglePhotosAndroid;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_web_app_list": "name:ScalableIphAppListItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_web_shelf": "name:ScalableIphShelfItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSix_event_trigger": "name:ScalableIphUnlockedBasedSixTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSix_event_used": "name:ScalableIphUnlockedBasedSixEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedSix_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedSix_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleButtonText": "Open Photos",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleIcon": "GooglePhotosIcon",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleId": "scalable_iph_unlocked_based_six",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleText": "Explore your favorite memories in Google Photos",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomButtonActionType": "OpenGooglePhotos",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedSix_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedTen_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedTen_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedTen_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedTen_event_1": "name:ScalableIphUnlocked;comparator:>=9;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTen_event_precondition_print_job": "name:ScalableIphPrintJobCreated;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTen_event_trigger": "name:ScalableIphUnlockedBasedTenTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTen_event_used": "name:ScalableIphUnlockedBasedTenEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTen_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedTen_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleButtonText": "Select file",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleIcon": "PrintJobsIcon",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleId": "scalable_iph_unlocked_based_ten",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleText": "Printing is easy with your Chromebook",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomButtonActionType": "OpenFileManager",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedTen_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedThree_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedThree_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedThree_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedThree_event_1": "name:ScalableIphUnlocked;comparator:>=2;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedThree_event_precondition_personalization_app": "name:ScalableIphOpenPersonalizationApp;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedThree_event_trigger": "name:ScalableIphUnlockedBasedThreeTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedThree_event_used": "name:ScalableIphUnlockedBasedThreeEventUsed;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedThree_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedThree_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomBubbleButtonText": "Select wallpaper",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomBubbleId": "scalable_iph_unlocked_based_three",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomBubbleText": "Make your Chromebook uniquely yours with a new wallpaper",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomButtonActionType": "OpenPersonalizationApp",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedThree_x_CustomVersionNumber": "1",
+                        "IPH_ScalableIphUnlockedBasedTwo_availability": "any",
+                        "IPH_ScalableIphUnlockedBasedTwo_blocked_by": "none",
+                        "IPH_ScalableIphUnlockedBasedTwo_blocking": "none",
+                        "IPH_ScalableIphUnlockedBasedTwo_event_1": "name:ScalableIphUnlocked;comparator:>=1;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTwo_event_precondition_launcher": "name:ScalableIphAppListShown;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTwo_event_trigger": "name:ScalableIphUnlockedBasedTwoTriggered;comparator:==0;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTwo_event_used": "name:ScalableIphAppListShown;comparator:any;window:7;storage:8",
+                        "IPH_ScalableIphUnlockedBasedTwo_session_rate": "any",
+                        "IPH_ScalableIphUnlockedBasedTwo_session_rate_impact": "none",
+                        "IPH_ScalableIphUnlockedBasedTwo_x_CustomBubbleId": "scalable_iph_unlocked_based_two",
+                        "IPH_ScalableIphUnlockedBasedTwo_x_CustomBubbleText": "Search and find your apps in the Launcher \u25c9",
+                        "IPH_ScalableIphUnlockedBasedTwo_x_CustomBubbleTitle": "Welcome Tips",
+                        "IPH_ScalableIphUnlockedBasedTwo_x_CustomConditionClientAgeInDays": "6",
+                        "IPH_ScalableIphUnlockedBasedTwo_x_CustomConditionNetworkConnection": "Online",
+                        "IPH_ScalableIphUnlockedBasedTwo_x_CustomUiType": "Bubble",
+                        "IPH_ScalableIphUnlockedBasedTwo_x_CustomVersionNumber": "1"
+                    },
+                    "enable_features": [
+                        "IPH_ScalableIphUnlockedBasedEight",
+                        "IPH_ScalableIphUnlockedBasedFive",
+                        "IPH_ScalableIphUnlockedBasedFour",
+                        "IPH_ScalableIphUnlockedBasedNine",
+                        "IPH_ScalableIphUnlockedBasedOne",
+                        "IPH_ScalableIphUnlockedBasedSeven",
+                        "IPH_ScalableIphUnlockedBasedSix",
+                        "IPH_ScalableIphUnlockedBasedTen",
+                        "IPH_ScalableIphUnlockedBasedThree",
+                        "IPH_ScalableIphUnlockedBasedTwo",
+                        "ScalableIph"
+                    ],
+                    "disable_features": [
+                        "ShelfLauncherNudge"
+                    ]
                 }
             ]
         }
diff --git a/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy b/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
index 72589c2..d86f9ecc 100644
--- a/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
+++ b/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
@@ -378,11 +378,11 @@
         Path fetchTemplatePath = Paths.get(sourceUri).resolveSibling('3ppFetch.template')
         Template fetchTemplate = new SimpleTemplateEngine().createTemplate(fetchTemplatePath.toFile())
 
-        Set<Project> subprojects = [] as Set
-        subprojects.add(project)
-        subprojects.addAll(project.subprojects)
+        Set<Project> allProjects = [] as Set
+        allProjects.add(project)
+        allProjects.addAll(project.subprojects)
         ChromiumDepGraph graph = new ChromiumDepGraph(
-                projects: subprojects, logger: project.logger, skipLicenses: skipLicenses)
+                projects: allProjects, logger: project.logger, skipLicenses: skipLicenses)
         String normalisedRepoPath = normalisePath(repositoryPath)
 
         // 1. Parse the dependency data
@@ -453,7 +453,10 @@
             mergeLicenses(dependency, normalisedRepoPath)
         }
 
-        validateDependencies(graph.dependencies.values())
+        // Skip when --no-subprojects is passed.
+        if (project.subprojects) {
+            validateAndroidX(graph.dependencies.values())
+        }
 
         // 3. Generate the root level build files
         updateBuildTargetDeclaration(graph, normalisedRepoPath)
@@ -890,7 +893,7 @@
         buildFile.write(matcher.replaceFirst(Matcher.quoteReplacement(out)))
     }
 
-    private void validateDependencies(
+    private void validateAndroidX(
             Collection<ChromiumDepGraph.DependencyDescription> dependencies) {
         dependencies.each { dependency ->
             if (dependency.id.contains('androidx') &&
@@ -899,7 +902,7 @@
                     allowedPrefix -> dependency.id.startsWith(allowedPrefix)
                 }
                 if (!hasAllowedDep) {
-                    String errorMsg = ("${dependency.fileName} uses non-SNAPSHOT version."
+                    String errorMsg = ("${dependency.fileName} uses non-SNAPSHOT version. "
                           + "If this is expected, add ${dependency.id} to "
                           + '|ALLOWED_ANDROIDX_NON_SNAPSHOT_DEPS_PREFIXES| list.')
                     throw new IllegalStateException(errorMsg)
diff --git a/third_party/android_deps/fetch_all.py b/third_party/android_deps/fetch_all.py
index 1846cb7..864f3bb 100755
--- a/third_party/android_deps/fetch_all.py
+++ b/third_party/android_deps/fetch_all.py
@@ -497,6 +497,9 @@
     parser.add_argument('--override-artifact',
                         action='append',
                         help='lib_subpath:url of .aar / .jar to override.')
+    parser.add_argument('--no-subprojects',
+                        action='store_true',
+                        help='Ignore subprojects.txt for faster runs.')
     parser.add_argument('-v',
                         '--verbose',
                         dest='verbose_count',
@@ -530,8 +533,11 @@
              _CUSTOM_ANDROID_DEPS_FILES,
              src_path_must_exist=is_primary_android_deps)
 
-        subprojects = _ParseSubprojects(
-            os.path.join(args.android_deps_dir, 'subprojects.txt'))
+        if args.no_subprojects:
+            subprojects = None
+        else:
+            subprojects = _ParseSubprojects(
+                os.path.join(args.android_deps_dir, 'subprojects.txt'))
         subproject_dirs = []
         if subprojects:
             for (index, subproject) in enumerate(subprojects):
diff --git a/third_party/android_provider/README.chromium b/third_party/android_provider/README.chromium
index 7357c46..e8d43ad 100644
--- a/third_party/android_provider/README.chromium
+++ b/third_party/android_provider/README.chromium
@@ -1,5 +1,5 @@
 Name: MediaStoreUtils Android sample.
-URL: https://android.googlesource.com/platform/cts/+/master/tests/tests/provider/src/android/provider/cts/MediaStoreUtils.java
+URL: https://android.googlesource.com/platform/cts/
 Version: 50f25a19f2a3de940d6ef7eac84b37d1c62f1b5f
 License: Apache 2.0
 License File: LICENSE
@@ -12,7 +12,7 @@
 MediaStoreUtils.java is based on a public Android sample that was
 available as part of the Android cts libraries. It is
 also available from:
-https://android.googlesource.com/platform/cts/+/master/tests/tests/provider/src/android/provider/cts/MediaStoreUtils.java
+https://android.googlesource.com/platform/cts/+/50f25a19f2a3de940d6ef7eac84b37d1c62f1b5f/tests/tests/provider/src/android/provider/cts/MediaStoreUtils.java
 
 Local Modifications:
 - Added logs
diff --git a/third_party/angle b/third_party/angle
index f56f970..889b01e 160000
--- a/third_party/angle
+++ b/third_party/angle
@@ -1 +1 @@
-Subproject commit f56f97009543b0a93aca86fd425400e649aaf51d
+Subproject commit 889b01efcbf6e993d29f937515ca7e9d5e73b990
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index c3813e2..e19e496 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -498,6 +498,7 @@
       WarnAttributeValueExceedsMaxSize
       WarnDomainNonASCII
       WarnThirdPartyPhaseout
+      WarnCrossSiteRedirectDowngradeChangesInclusion
 
   type CookieOperation extends string
     enum
@@ -770,6 +771,15 @@
     properties
       array of string trackingSites
 
+  # This issue warns about third-party sites that are accessing cookies on the
+  # current page, and have been permitted due to having a global metadata grant.
+  # Note that in this context 'site' means eTLD+1. For example, if the URL
+  # `https://example.test:80/web_page` was accessing cookies, the site reported
+  # would be `example.test`.
+  type CookieDeprecationMetadataIssueDetails extends object
+    properties
+      array of string allowedSites
+
   type ClientHintIssueReason extends string
     enum
       # Items in the accept-ch meta tag allow list must be valid origins.
@@ -915,6 +925,7 @@
       ClientHintIssue
       FederatedAuthRequestIssue
       BounceTrackingIssue
+      CookieDeprecationMetadataIssue
       StylesheetLoadingIssue
       FederatedAuthUserInfoRequestIssue
       PropertyRuleIssue
@@ -940,6 +951,7 @@
       optional ClientHintIssueDetails clientHintIssueDetails
       optional FederatedAuthRequestIssueDetails federatedAuthRequestIssueDetails
       optional BounceTrackingIssueDetails bounceTrackingIssueDetails
+      optional CookieDeprecationMetadataIssueDetails cookieDeprecationMetadataIssueDetails
       optional StylesheetLoadingIssueDetails stylesheetLoadingIssueDetails
       optional PropertyRuleIssueDetails propertyRuleIssueDetails
       optional FederatedAuthUserInfoRequestIssueDetails federatedAuthUserInfoRequestIssueDetails
diff --git a/third_party/blink/public/mojom/devtools/inspector_issue.mojom b/third_party/blink/public/mojom/devtools/inspector_issue.mojom
index ad6ea165..7a14219 100644
--- a/third_party/blink/public/mojom/devtools/inspector_issue.mojom
+++ b/third_party/blink/public/mojom/devtools/inspector_issue.mojom
@@ -23,6 +23,7 @@
   kLowTextContrastIssue,
   kFederatedAuthRequestIssue,
   kBounceTrackingIssue,
+  kCookieDeprecationMetadataIssue,
   kGenericIssue,
   kDeprecationIssue,
   kFederatedAuthUserInfoRequestIssue,
@@ -161,6 +162,7 @@
   kWarnAttributeValueExceedsMaxSize,
   kWarnDomainNonASCII,
   kWarnThirdPartyPhaseout,
+  kWarnCrossSiteRedirectDowngradeChangesInclusion,
 };
 
 // Specific information about |kCookieIssue| type issues.
@@ -268,6 +270,10 @@
   array<string> tracking_sites;
 };
 
+struct CookieDeprecationMetadataIssueDetails {
+  array<string> allowed_sites;
+};
+
 enum GenericIssueErrorType {
   kCrossOriginPortalPostMessageError,
   kFormLabelForNameError,
@@ -313,6 +319,7 @@
   LowTextContrastIssue? low_text_contrast_details;
   FederatedAuthRequestIssueDetails? federated_auth_request_details;
   BounceTrackingIssueDetails? bounce_tracking_issue_details;
+  CookieDeprecationMetadataIssueDetails? cookie_deprecation_metadata_issue_details;
   GenericIssueDetails? generic_issue_details;
   DeprecationIssueDetails? deprecation_issue_details;
   FederatedAuthUserInfoRequestIssueDetails? federated_auth_user_info_request_details;
diff --git a/third_party/blink/public/mojom/mediastream/media_devices.mojom b/third_party/blink/public/mojom/mediastream/media_devices.mojom
index b54641ba..d0ee27b 100644
--- a/third_party/blink/public/mojom/mediastream/media_devices.mojom
+++ b/third_party/blink/public/mojom/mediastream/media_devices.mojom
@@ -16,6 +16,11 @@
   kNumMediaDeviceTypes
 };
 
+enum SubCaptureTargetType {
+  kCropTarget,
+  kRestrictionTarget
+};
+
 // The values for this enum match the ones defined in
 // https://w3c.github.io/mediacapture-main/#def-constraint-facingMode
 // with the addition of kNone, which would map to the empty string in
@@ -130,11 +135,13 @@
   [EnableIfNot=is_android]
   CloseFocusWindowOfOpportunity(string label);
 
-  // Mints a new crop-ID, associates it with the browsing context in which
-  // it was produced, and returns it. This crop-ID can later be used as the
-  // input for BrowserCaptureMediaStreamTrack.cropTo().
+  // Mints a new ID backing a SubCaptureTarget.
+  // * CropTargetIds back a CropTarget, which is the input type
+  //   for BrowserCaptureMediaStreamTrack.cropTo().
+  // * RestrictionTargetIds back a RestrictionTarget, which is the input type
+  //   for BrowserCaptureMediaStreamTrack.restrictTo().
   [EnableIfNot=is_android]
-  ProduceCropId() => (string crop_id);
+  ProduceSubCaptureTargetId(SubCaptureTargetType type) => (string id);
 };
 
 // This object lives in the renderer process and is used by the browser process
diff --git a/third_party/blink/public/mojom/mediastream/media_stream.mojom b/third_party/blink/public/mojom/mediastream/media_stream.mojom
index fbd87c44..77cfc9e 100644
--- a/third_party/blink/public/mojom/mediastream/media_stream.mojom
+++ b/third_party/blink/public/mojom/mediastream/media_stream.mojom
@@ -263,7 +263,7 @@
   Crop(mojo_base.mojom.UnguessableToken device_id,
        mojo_base.mojom.Token crop_id,
        uint32 crop_version)
-    => (media.mojom.CropRequestResult crop_result);
+    => (media.mojom.ApplySubCaptureTargetResult result);
 
   // Get a MediaStreamDevice metadata object which refers to the same flow of
   // media backing an existing MediaStreamDevice.
diff --git a/third_party/blink/public/platform/web_theme_engine.h b/third_party/blink/public/platform/web_theme_engine.h
index 4a21764..93206f3 100644
--- a/third_party/blink/public/platform/web_theme_engine.h
+++ b/third_party/blink/public/platform/web_theme_engine.h
@@ -191,7 +191,10 @@
   };
 
   struct ScrollbarButtonExtraParams {
+    // TODO(crbug.com/1493088): We should probably pass the border-radius
+    // instead.
     float zoom = 0;
+    bool needs_rounded_corner = false;
     bool right_to_left = false;
     absl::optional<SkColor> thumb_color;
     absl::optional<SkColor> track_color;
diff --git a/third_party/blink/public/web/modules/mediastream/media_stream_video_source.h b/third_party/blink/public/web/modules/mediastream/media_stream_video_source.h
index 00adb32..e899436 100644
--- a/third_party/blink/public/web/modules/mediastream/media_stream_video_source.h
+++ b/third_party/blink/public/web/modules/mediastream/media_stream_video_source.h
@@ -182,7 +182,8 @@
   virtual void Crop(
       const base::Token& crop_id,
       uint32_t crop_version,
-      base::OnceCallback<void(media::mojom::CropRequestResult)> callback);
+      base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+          callback);
 
   // If a new |crop_version| can be assigned, returns it.
   // Otherwise, returns nullopt. (Can happen if the source does not support
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc
index b531fd8..4055936 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc
@@ -169,7 +169,7 @@
     return;
   }
 
-  ScriptState::Scope scope(script_state_);
+  ScriptState::Scope scope(script_state_.Get());
   ResolveOrRejectImmediately();
 }
 
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
index 59aafca..640b942 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h
@@ -172,7 +172,7 @@
     DCHECK(new_state == kResolving || new_state == kRejecting);
     state_ = new_state;
 
-    ScriptState::Scope scope(script_state_);
+    ScriptState::Scope scope(script_state_.Get());
 
     // Calling ToV8 in a ScriptForbiddenScope will trigger a CHECK and
     // cause a crash. ToV8 just invokes a constructor for wrapper creation,
@@ -184,7 +184,7 @@
       ScriptForbiddenScope::AllowUserAgentScript allow_script;
       v8::Isolate* isolate = script_state_->GetIsolate();
       v8::MicrotasksScope microtasks_scope(
-          isolate, ToMicrotaskQueue(script_state_),
+          isolate, ToMicrotaskQueue(script_state_.Get()),
           v8::MicrotasksScope::kDoNotRunMicrotasks);
       value_.Reset(isolate, ToV8(value, script_state_->GetContext()->Global(),
                                  script_state_->GetIsolate()));
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h b/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h
index a7380ad7..b874003 100644
--- a/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h
+++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h
@@ -116,7 +116,8 @@
   kEncodedAudioChunkTag = 'y',  // uint32_t -> transferred chunk
   kEncodedVideoChunkTag = 'z',  // uint32_t -> transferred chunk
 
-  kCropTargetTag = 'c',  // crop_id:WebCoreString
+  kCropTargetTag = 'c',         // crop_id:WebCoreString
+  kRestrictionTargetTag = 'D',  // restriction_id:WebCoreString
 
   kMediaSourceHandleTag = 'S',  // uint32_t -> transferred MediaSourceHandle
 
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
index cf8f9b69..6fc853d 100644
--- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
+++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
@@ -26,6 +26,7 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_file_system_file_handle.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_media_source_handle.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_restriction_target.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_certificate.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_audio_frame.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_video_frame.h"
@@ -41,6 +42,7 @@
 #include "third_party/blink/renderer/modules/mediasource/media_source_handle_impl.h"
 #include "third_party/blink/renderer/modules/mediastream/crop_target.h"
 #include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
+#include "third_party/blink/renderer/modules/mediastream/restriction_target.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h"
@@ -121,6 +123,8 @@
       return ReadMediaStreamTrack();
     case kCropTargetTag:
       return ReadCropTarget();
+    case kRestrictionTargetTag:
+      return ReadRestrictionTarget();
     case kMediaSourceHandleTag:
       return ReadMediaSourceHandle();
     default:
@@ -650,6 +654,21 @@
   return MakeGarbageCollected<CropTarget>(crop_id);
 }
 
+RestrictionTarget*
+V8ScriptValueDeserializerForModules::ReadRestrictionTarget() {
+  if (!RuntimeEnabledFeatures::ElementCaptureEnabled(
+          ExecutionContext::From(GetScriptState()))) {
+    return nullptr;
+  }
+
+  String restriction_id;
+  if (!ReadUTF8String(&restriction_id) || restriction_id.empty()) {
+    return nullptr;
+  }
+
+  return MakeGarbageCollected<RestrictionTarget>(restriction_id);
+}
+
 MediaSourceHandleImpl*
 V8ScriptValueDeserializerForModules::ReadMediaSourceHandle() {
   uint32_t index;
@@ -721,6 +740,8 @@
       return V8MediaStreamTrack::IsExposed(execution_context);
     case kCropTargetTag:
       return V8CropTarget::IsExposed(execution_context);
+    case kRestrictionTargetTag:
+      return V8RestrictionTarget::IsExposed(execution_context);
     case kMediaSourceHandleTag:
       return V8MediaSourceHandle::IsExposed(execution_context);
     default:
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h
index 1473fca..3203163b 100644
--- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h
+++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.h
@@ -17,6 +17,7 @@
 class EncodedVideoChunk;
 class FileSystemHandle;
 class MediaSourceHandleImpl;
+class RestrictionTarget;
 class RTCEncodedAudioFrame;
 class RTCEncodedVideoFrame;
 class VideoFrame;
@@ -63,6 +64,7 @@
   EncodedVideoChunk* ReadEncodedVideoChunk();
   MediaStreamTrack* ReadMediaStreamTrack();
   CropTarget* ReadCropTarget();
+  RestrictionTarget* ReadRestrictionTarget();
   MediaSourceHandleImpl* ReadMediaSourceHandle();
 };
 
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc
index 356a70f..1c00257 100644
--- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc
+++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc
@@ -26,6 +26,7 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_media_source_handle.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_point_2d.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_restriction_target.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_certificate.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_audio_frame.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoded_video_frame.h"
@@ -43,6 +44,7 @@
 #include "third_party/blink/renderer/modules/mediastream/crop_target.h"
 #include "third_party/blink/renderer/modules/mediastream/media_stream_track.h"
 #include "third_party/blink/renderer/modules/mediastream/media_stream_utils.h"
+#include "third_party/blink/renderer/modules/mediastream/restriction_target.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_delegate.h"
@@ -314,6 +316,20 @@
     }
     return WriteCropTarget(crop_target);
   }
+  if (auto* restriction_target =
+          dispatcher.ToMostDerived<RestrictionTarget>()) {
+    if (!RuntimeEnabledFeatures::ElementCaptureEnabled(
+            ExecutionContext::From(GetScriptState()))) {
+      return false;
+    }
+    if (IsForStorage()) {
+      exception_state.ThrowDOMException(
+          DOMExceptionCode::kDataCloneError,
+          "A RestrictionTarget cannot be serialized for storage.");
+      return false;
+    }
+    return WriteRestrictionTarget(restriction_target);
+  }
   if (auto* media_source_handle =
           dispatcher.ToMostDerived<MediaSourceHandleImpl>()) {
     if (IsForStorage()) {
@@ -687,6 +703,16 @@
   return true;
 }
 
+bool V8ScriptValueSerializerForModules::WriteRestrictionTarget(
+    RestrictionTarget* restriction_target) {
+  CHECK(restriction_target);
+  const String& id = restriction_target->GetId();
+  CHECK(!id.empty());
+  WriteAndRequireInterfaceTag(kRestrictionTargetTag);
+  WriteUTF8String(id);
+  return true;
+}
+
 bool V8ScriptValueSerializerForModules::WriteMediaSourceHandle(
     MediaSourceHandleImpl* handle,
     ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.h b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.h
index 5b86727..9386790 100644
--- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.h
+++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.h
@@ -20,6 +20,7 @@
 class CropTarget;
 class FileSystemHandle;
 class MediaSourceHandleImpl;
+class RestrictionTarget;
 class RTCEncodedAudioFrame;
 class RTCEncodedVideoFrame;
 class VideoFrameHandle;
@@ -59,6 +60,7 @@
                              ScriptWrappable::TypeDispatcher& dispatcher,
                              ExceptionState& exception_state);
   bool WriteCropTarget(CropTarget*);
+  bool WriteRestrictionTarget(RestrictionTarget*);
   bool WriteMediaSourceHandle(MediaSourceHandleImpl* handle,
                               ExceptionState& exception_state);
 };
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc
index 4197284..f9e0dad 100644
--- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc
+++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc
@@ -29,6 +29,7 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_crypto_key.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_dom_file_system.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_restriction_target.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_certificate.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -45,6 +46,7 @@
 #include "third_party/blink/renderer/modules/mediastream/media_stream_video_track.h"
 #include "third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h"
 #include "third_party/blink/renderer/modules/mediastream/mock_video_capturer_source.h"
+#include "third_party/blink/renderer/modules/mediastream/restriction_target.h"
 #include "third_party/blink/renderer/modules/mediastream/test/transfer_test_utils.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h"
@@ -1832,7 +1834,7 @@
   EXPECT_FALSE(blink_track->Ended());
 }
 
-#if !BUILDFLAG(IS_ANDROID)  // CropTarget is not exposed on Android.
+#if !BUILDFLAG(IS_ANDROID)  // SubCaptureTargets are not exposed on Android.
 TEST(V8ScriptValueSerializerForModulesTest, RoundTripCropTarget) {
   V8TestingScope scope;
 
@@ -1848,6 +1850,25 @@
   ASSERT_NE(new_crop_target, nullptr);
   EXPECT_EQ(new_crop_target->GetId(), crop_id);
 }
+
+TEST(V8ScriptValueSerializerForModulesTest, RoundTripRestrictionTarget) {
+  V8TestingScope scope;
+  ScopedElementCaptureForTest element_capture(true);
+
+  const String restriction_id("8e7e0c22-67a0-4c39-b4dc-a20433262f8e");
+
+  RestrictionTarget* const restriction_target =
+      MakeGarbageCollected<RestrictionTarget>(restriction_id);
+
+  v8::Local<v8::Value> wrapper =
+      ToV8(restriction_target, scope.GetScriptState());
+  v8::Local<v8::Value> result = RoundTripForModules(wrapper, scope);
+
+  RestrictionTarget* const new_restriction_target =
+      V8RestrictionTarget::ToWrappable(scope.GetIsolate(), result);
+  ASSERT_NE(new_restriction_target, nullptr);
+  EXPECT_EQ(new_restriction_target->GetId(), restriction_id);
+}
 #endif
 
 TEST(V8ScriptValueSerializerForModulesTest,
diff --git a/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc
index b2cc33bd..fc451e5 100644
--- a/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc
@@ -25,7 +25,7 @@
     case CSSPropertyID::kBorderImageSource:
       return style.BorderImageSource();
     case CSSPropertyID::kListStyleImage:
-      return style.ListStyleImage();
+      return style.ListStyleImage().Get();
     case CSSPropertyID::kWebkitMaskBoxImageSource:
       return style.MaskBoxImageSource();
     default:
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc b/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc
index 9060b83..18d4efd 100644
--- a/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc
+++ b/third_party/blink/renderer/core/animation/keyframe_effect_model_test.cc
@@ -191,7 +191,7 @@
         To<InvalidatableInterpolation>(value.Get())->GetProperty();
     if (property.IsCSSProperty() &&
         property.GetCSSProperty().PropertyID() == id)
-      return value;
+      return value.Get();
   }
   return nullptr;
 }
diff --git a/third_party/blink/renderer/core/animation/scroll_timeline.cc b/third_party/blink/renderer/core/animation/scroll_timeline.cc
index 927077a..5d892e8e 100644
--- a/third_party/blink/renderer/core/animation/scroll_timeline.cc
+++ b/third_party/blink/renderer/core/animation/scroll_timeline.cc
@@ -81,7 +81,7 @@
       axis_(axis) {}
 
 Element* ScrollTimeline::RetainingElement() const {
-  return reference_element_;
+  return reference_element_.Get();
 }
 
 // TODO(crbug.com/1060384): This section is missing from the spec rewrite.
diff --git a/third_party/blink/renderer/core/clipboard/data_transfer.cc b/third_party/blink/renderer/core/clipboard/data_transfer.cc
index b7dbc2a0..14f896f 100644
--- a/third_party/blink/renderer/core/clipboard/data_transfer.cc
+++ b/third_party/blink/renderer/core/clipboard/data_transfer.cc
@@ -331,7 +331,7 @@
 FileList* DataTransfer::files() const {
   if (!CanReadData()) {
     files_->clear();
-    return files_;
+    return files_.Get();
   }
 
   if (!files_->IsEmpty())
diff --git a/third_party/blink/renderer/core/css/counters_scope_tree.cc b/third_party/blink/renderer/core/css/counters_scope_tree.cc
index bbf7ca0..ccde9c1 100644
--- a/third_party/blink/renderer/core/css/counters_scope_tree.cc
+++ b/third_party/blink/renderer/core/css/counters_scope_tree.cc
@@ -338,7 +338,7 @@
     // If we found direct ancestor.
     if (IsAncestorOf((*rev_it)->RootElement(), element) ||
         &(*rev_it)->RootElement() == &element) {
-      return *rev_it;
+      return rev_it->Get();
     }
   }
   if (ancestor_sibling_scope) {
diff --git a/third_party/blink/renderer/core/css/css_font_face.h b/third_party/blink/renderer/core/css/css_font_face.h
index 6493a483..f8c7fe8 100644
--- a/third_party/blink/renderer/core/css/css_font_face.h
+++ b/third_party/blink/renderer/core/css/css_font_face.h
@@ -57,7 +57,7 @@
 
   // Front source is the first successfully loaded source.
   const CSSFontFaceSource* FrontSource() const {
-    return sources_.empty() ? nullptr : sources_.front();
+    return sources_.empty() ? nullptr : sources_.front().Get();
   }
   FontFace* GetFontFace() const { return font_face_.Get(); }
 
diff --git a/third_party/blink/renderer/core/css/css_math_expression_node.h b/third_party/blink/renderer/core/css/css_math_expression_node.h
index 0927d21..d816449 100644
--- a/third_party/blink/renderer/core/css/css_math_expression_node.h
+++ b/third_party/blink/renderer/core/css/css_math_expression_node.h
@@ -214,7 +214,7 @@
 
   explicit CSSMathExpressionNumericLiteral(const CSSNumericLiteralValue* value);
 
-  CSSMathExpressionNode* Copy() const final { return Create(value_); }
+  CSSMathExpressionNode* Copy() const final { return Create(value_.Get()); }
 
   const CSSNumericLiteralValue& GetValue() const { return *value_; }
 
diff --git a/third_party/blink/renderer/core/css/css_property_value.h b/third_party/blink/renderer/core/css/css_property_value.h
index 9623797..8bd3bc3a 100644
--- a/third_party/blink/renderer/core/css/css_property_value.h
+++ b/third_party/blink/renderer/core/css/css_property_value.h
@@ -78,7 +78,7 @@
 
   CSSPropertyValue(const CSSPropertyValue& other)
       : metadata_(other.metadata_),
-        value_(other.value_, decltype(value_)::AtomicInitializerTag{}) {}
+        value_(other.value_.Get(), decltype(value_)::AtomicInitializerTag{}) {}
   CSSPropertyValue& operator=(const CSSPropertyValue& other) = default;
 
   // FIXME: Remove this.
diff --git a/third_party/blink/renderer/core/css/css_segmented_font_face.cc b/third_party/blink/renderer/core/css/css_segmented_font_face.cc
index ec0bacaa..73c649b9 100644
--- a/third_party/blink/renderer/core/css/css_segmented_font_face.cc
+++ b/third_party/blink/renderer/core/css/css_segmented_font_face.cc
@@ -223,16 +223,16 @@
       font_description, range_set));
 }
 
-bool CSSSegmentedFontFace::CheckFont(const String& text) const {
+bool CSSSegmentedFontFace::CheckFont(UChar32 c) const {
   return font_faces_->ForEachUntilFalse(WTF::BindRepeating(
-      [](const String& text, Member<FontFace> font_face) -> bool {
+      [](UChar32 c, Member<FontFace> font_face) -> bool {
         if (font_face->LoadStatus() != FontFace::kLoaded &&
-            font_face->CssFontFace()->Ranges()->IntersectsWith(text)) {
+            font_face->CssFontFace()->Ranges()->Contains(c)) {
           return false;
         }
         return true;
       },
-      text));
+      c));
 }
 
 void CSSSegmentedFontFace::Match(const String& text,
diff --git a/third_party/blink/renderer/core/css/css_segmented_font_face.h b/third_party/blink/renderer/core/css/css_segmented_font_face.h
index ed5f769..bab6ab0b 100644
--- a/third_party/blink/renderer/core/css/css_segmented_font_face.h
+++ b/third_party/blink/renderer/core/css/css_segmented_font_face.h
@@ -108,7 +108,7 @@
 
   scoped_refptr<FontData> GetFontData(const FontDescription&);
 
-  bool CheckFont(const String&) const;
+  bool CheckFont(UChar32) const;
   void Match(const String&, HeapVector<Member<FontFace>>*) const;
   void WillUseFontData(const FontDescription&, const String& text);
   void WillUseRange(const FontDescription&, const blink::FontDataForRangeSet&);
diff --git a/third_party/blink/renderer/core/css/css_value_pool.h b/third_party/blink/renderer/core/css/css_value_pool.h
index bc29086..fb300ef8 100644
--- a/third_party/blink/renderer/core/css/css_value_pool.h
+++ b/third_party/blink/renderer/core/css/css_value_pool.h
@@ -157,8 +157,9 @@
     if (Member<CSSColor>* found = color_value_cache_.Find(color, hash); found) {
       return found->Get();
     }
-    return color_value_cache_.Insert(
-        color, MakeGarbageCollected<CSSColor>(color), hash);
+    return color_value_cache_
+        .Insert(color, MakeGarbageCollected<CSSColor>(color), hash)
+        .Get();
   }
   FontFamilyValueCache::AddResult GetFontFamilyCacheEntry(
       const String& family_name) {
diff --git a/third_party/blink/renderer/core/css/css_view_transitions_rule.cc b/third_party/blink/renderer/core/css/css_view_transitions_rule.cc
index 71676fae..c6a40f0 100644
--- a/third_party/blink/renderer/core/css/css_view_transitions_rule.cc
+++ b/third_party/blink/renderer/core/css/css_view_transitions_rule.cc
@@ -4,9 +4,17 @@
 
 #include "third_party/blink/renderer/core/css/css_view_transitions_rule.h"
 
+#include "third_party/blink/renderer/core/css/css_identifier_value.h"
 #include "third_party/blink/renderer/core/css/css_rule.h"
+#include "third_party/blink/renderer/core/css/css_style_sheet.h"
+#include "third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h"
+#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
+#include "third_party/blink/renderer/core/css/parser/css_tokenizer.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/css/style_rule_view_transitions.h"
+#include "third_party/blink/renderer/core/dom/document.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
 namespace blink {
@@ -41,9 +49,34 @@
   return String();
 }
 
-void CSSViewTransitionsRule::setNavigationTrigger(const ExecutionContext*,
-                                                  const String&) {
-  // TODO(crbug.com/1463966): Implement
+void CSSViewTransitionsRule::setNavigationTrigger(
+    const ExecutionContext* execution_context,
+    const String& text) {
+  CSSStyleSheet* style_sheet = parentStyleSheet();
+  auto& context = *MakeGarbageCollected<CSSParserContext>(
+      ParserContext(execution_context->GetSecureContextMode()), style_sheet);
+  CSSTokenizer tokenizer(text);
+  auto tokens = tokenizer.TokenizeToEOF();
+  CSSParserTokenRange token_range(tokens);
+  AtRuleDescriptorID descriptor_id = AtRuleDescriptorID::NavigationTrigger;
+  CSSValue* new_value =
+      AtRuleDescriptorParser::ParseAtViewTransitionsDescriptor(
+          descriptor_id, token_range, context);
+  if (!new_value) {
+    return;
+  }
+
+  const auto* id = DynamicTo<CSSIdentifierValue>(new_value);
+  if (!id || (id->GetValueID() != CSSValueID::kCrossDocumentSameOrigin &&
+              id->GetValueID() != CSSValueID::kNone)) {
+    return;
+  }
+
+  view_transitions_rule_->SetNavigationTrigger(new_value);
+
+  if (Document* document = style_sheet->OwnerDocument()) {
+    document->GetStyleEngine().UpdateViewTransitionsOptIn();
+  }
 }
 
 void CSSViewTransitionsRule::Reattach(StyleRuleBase* rule) {
diff --git a/third_party/blink/renderer/core/css/element_rule_collector.cc b/third_party/blink/renderer/core/css/element_rule_collector.cc
index 1e48e5c..11dd45a 100644
--- a/third_party/blink/renderer/core/css/element_rule_collector.cc
+++ b/third_party/blink/renderer/core/css/element_rule_collector.cc
@@ -101,7 +101,7 @@
   }
   for (const auto& [sheet, rule_set] : style_engine.ActiveUserStyleSheets()) {
     if (FindStyleRule(sheet.Get(), rule) != nullptr) {
-      return sheet;
+      return sheet.Get();
     }
   }
 
@@ -189,7 +189,7 @@
     if (iter_ == intervals_.begin()) {
       return nullptr;
     }
-    return std::prev(iter_)->value;
+    return std::prev(iter_)->value.Get();
   }
 
  private:
@@ -369,7 +369,7 @@
   if (!style_rule_list_) {
     style_rule_list_ = MakeGarbageCollected<StyleRuleList>();
   }
-  return style_rule_list_;
+  return style_rule_list_.Get();
 }
 
 inline RuleIndexList* ElementRuleCollector::EnsureRuleList() {
diff --git a/third_party/blink/renderer/core/css/font_face_set.cc b/third_party/blink/renderer/core/css/font_face_set.cc
index 4e7f5786..cabc3db 100644
--- a/third_party/blink/renderer/core/css/font_face_set.cc
+++ b/third_party/blink/renderer/core/css/font_face_set.cc
@@ -238,32 +238,26 @@
   FontSelector* font_selector = GetFontSelector();
   FontFaceCache* font_face_cache = font_selector->GetFontFaceCache();
 
-  bool has_loaded_faces = false;
-  for (const FontFamily* f = &font.GetFontDescription().Family(); f;
-       f = f->Next()) {
-    if (f->FamilyIsGeneric()) {
-      continue;
-    }
-    CSSSegmentedFontFace* face =
-        font_face_cache->Get(font.GetFontDescription(), f->FamilyName());
-    if (face) {
-      if (!face->CheckFont(text)) {
+  unsigned index = 0;
+  while (index < text.length()) {
+    UChar32 c = text.CharacterStartingAt(index);
+    index += U16_LENGTH(c);
+
+    for (const FontFamily* f = &font.GetFontDescription().Family(); f;
+         f = f->Next()) {
+      if (f->FamilyIsGeneric() || font_selector->IsPlatformFamilyMatchAvailable(
+                                      font.GetFontDescription(), *f)) {
+        continue;
+      }
+
+      CSSSegmentedFontFace* face =
+          font_face_cache->Get(font.GetFontDescription(), f->FamilyName());
+      if (face && !face->CheckFont(c)) {
         return false;
       }
-      has_loaded_faces = true;
     }
   }
-  if (has_loaded_faces) {
-    return true;
-  }
-  for (const FontFamily* f = &font.GetFontDescription().Family(); f;
-       f = f->Next()) {
-    if (font_selector->IsPlatformFamilyMatchAvailable(font.GetFontDescription(),
-                                                      *f)) {
-      return true;
-    }
-  }
-  return false;
+  return true;
 }
 
 void FontFaceSet::FireDoneEvent() {
diff --git a/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.cc b/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.cc
index c6f0358d..bbfaf613 100644
--- a/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/scoped_style_resolver.cc
@@ -356,7 +356,7 @@
   DCHECK(fallback_name);
   auto iter = position_fallback_rule_map_.find(fallback_name);
   if (iter != position_fallback_rule_map_.end()) {
-    return iter->value;
+    return iter->value.Get();
   }
   return nullptr;
 }
diff --git a/third_party/blink/renderer/core/css/rule_set_test.cc b/third_party/blink/renderer/core/css/rule_set_test.cc
index c02daa4..bbc0a27 100644
--- a/third_party/blink/renderer/core/css/rule_set_test.cc
+++ b/third_party/blink/renderer/core/css/rule_set_test.cc
@@ -684,7 +684,7 @@
   }
 
   const CascadeLayer* ImplicitOuterLayer() {
-    return GetRuleSet().implicit_outer_layer_;
+    return GetRuleSet().implicit_outer_layer_.Get();
   }
 
   const RuleData& GetIdRule(const char* key) {
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc
index d842647a..6d4392a2 100644
--- a/third_party/blink/renderer/core/css/style_engine.cc
+++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -2345,6 +2345,23 @@
       CSSDefaultStyleSheets::ScreenEval());
 }
 
+void StyleEngine::UpdateViewTransitionsOptIn() {
+  bool cross_document_enabled = false;
+
+  // TODO(https://crbug.com/1463966): This will likely need to change to a
+  // CSSValueList if we want to support multiple tokens as a trigger.
+  if (view_transitions_rule_) {
+    if (const CSSValue* value =
+            view_transitions_rule_->GetNavigationTrigger()) {
+      cross_document_enabled = To<CSSIdentifierValue>(value)->GetValueID() ==
+                               CSSValueID::kCrossDocumentSameOrigin;
+    }
+  }
+
+  ViewTransitionSupplement::From(GetDocument())
+      ->OnViewTransitionsStyleUpdated(cross_document_enabled);
+}
+
 bool StyleEngine::HasRulesForId(const AtomicString& id) const {
   DCHECK(global_rule_set_);
   return global_rule_set_->GetRuleFeatureSet().HasSelectorForId(id);
@@ -3019,20 +3036,7 @@
     }
   }
 
-  bool cross_document_enabled = false;
-
-  // TODO(https://crbug.com/1463966): This will likely need to change to a
-  // CSSValueList if we want to support multiple tokens as a trigger.
-  if (view_transitions_rule_) {
-    if (const CSSValue* value =
-            view_transitions_rule_->GetNavigationTrigger()) {
-      cross_document_enabled = To<CSSIdentifierValue>(value)->GetValueID() ==
-                               CSSValueID::kCrossDocumentSameOrigin;
-    }
-  }
-
-  ViewTransitionSupplement::From(GetDocument())
-      ->OnViewTransitionsStyleUpdated(cross_document_enabled);
+  UpdateViewTransitionsOptIn();
 }
 
 void StyleEngine::AddFontPaletteValuesRules(const RuleSet& rule_set) {
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h
index b4a9bb2..398c36e 100644
--- a/third_party/blink/renderer/core/css/style_engine.h
+++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -676,6 +676,7 @@
   const char* NameInHeapSnapshot() const override { return "StyleEngine"; }
 
   RuleSet* DefaultViewTransitionStyle() const;
+  void UpdateViewTransitionsOptIn();
 
   const ActiveStyleSheetVector& ActiveUserStyleSheets() const {
     return active_user_style_sheets_;
diff --git a/third_party/blink/renderer/core/css/style_rule.h b/third_party/blink/renderer/core/css/style_rule.h
index 9d7a349..19cee7b 100644
--- a/third_party/blink/renderer/core/css/style_rule.h
+++ b/third_party/blink/renderer/core/css/style_rule.h
@@ -220,7 +220,7 @@
   ~StyleRule();
 
   void SetProperties(CSSPropertyValueSet* properties) {
-    DCHECK_EQ(properties_, nullptr);
+    DCHECK_EQ(properties_.Get(), nullptr);
     properties_ = properties;
   }
 
diff --git a/third_party/blink/renderer/core/css/style_rule_view_transitions.cc b/third_party/blink/renderer/core/css/style_rule_view_transitions.cc
index 2013422..3b6ad1b6 100644
--- a/third_party/blink/renderer/core/css/style_rule_view_transitions.cc
+++ b/third_party/blink/renderer/core/css/style_rule_view_transitions.cc
@@ -7,6 +7,7 @@
 #include "base/auto_reset.h"
 #include "base/memory/values_equivalent.h"
 #include "third_party/blink/renderer/core/css/cascade_layer.h"
+#include "third_party/blink/renderer/core/css/css_identifier_value.h"
 #include "third_party/blink/renderer/core/css/css_value_list.h"
 
 namespace blink {
@@ -26,6 +27,10 @@
   return navigation_trigger_.Get();
 }
 
+void StyleRuleViewTransitions::SetNavigationTrigger(const CSSValue* new_value) {
+  navigation_trigger_ = new_value;
+}
+
 void StyleRuleViewTransitions::TraceAfterDispatch(
     blink::Visitor* visitor) const {
   visitor->Trace(layer_);
diff --git a/third_party/blink/renderer/core/css/style_rule_view_transitions.h b/third_party/blink/renderer/core/css/style_rule_view_transitions.h
index 7b892ca..77f1dd22 100644
--- a/third_party/blink/renderer/core/css/style_rule_view_transitions.h
+++ b/third_party/blink/renderer/core/css/style_rule_view_transitions.h
@@ -6,7 +6,6 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_RULE_VIEW_TRANSITIONS_H_
 
 #include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/css/parser/at_rule_descriptors.h"
 #include "third_party/blink/renderer/core/css/style_rule.h"
 
 namespace blink {
@@ -18,13 +17,14 @@
   ~StyleRuleViewTransitions();
 
   const CSSValue* GetNavigationTrigger() const;
+  void SetNavigationTrigger(const CSSValue* new_value);
 
   StyleRuleViewTransitions* Copy() const {
     return MakeGarbageCollected<StyleRuleViewTransitions>(*this);
   }
 
   void SetCascadeLayer(const CascadeLayer* layer) { layer_ = layer; }
-  const CascadeLayer* GetCascadeLayer() const { return layer_; }
+  const CascadeLayer* GetCascadeLayer() const { return layer_.Get(); }
 
   void TraceAfterDispatch(blink::Visitor*) const;
 
diff --git a/third_party/blink/renderer/core/css/style_traversal_root_test.cc b/third_party/blink/renderer/core/css/style_traversal_root_test.cc
index 623fc979..7a01532 100644
--- a/third_party/blink/renderer/core/css/style_traversal_root_test.cc
+++ b/third_party/blink/renderer/core/css/style_traversal_root_test.cc
@@ -89,7 +89,7 @@
     //     `-- div#g
   }
   Document& GetDocument() { return *document_; }
-  Element* DivElement(ElementIndex index) { return elements_->at(index); }
+  Element* DivElement(ElementIndex index) { return elements_->at(index).Get(); }
 
  private:
   ScopedNullExecutionContext execution_context_;
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 171cd3bb..27de52e1 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -2819,22 +2819,21 @@
   }
 
   if (!description->ignore_css_margins) {
-    // The percentage is calculated with respect to the width even for margin
-    // top and bottom.
-    // http://www.w3.org/TR/CSS2/box.html#margin-properties
-    float width = description->size.width();
     if (!style.MarginTop().IsAuto()) {
-      description->margin_top = IntValueForLength(style.MarginTop(), width);
+      description->margin_top =
+          IntValueForLength(style.MarginTop(), description->size.height());
     }
     if (!style.MarginRight().IsAuto()) {
-      description->margin_right = IntValueForLength(style.MarginRight(), width);
+      description->margin_right =
+          IntValueForLength(style.MarginRight(), description->size.width());
     }
     if (!style.MarginBottom().IsAuto()) {
       description->margin_bottom =
-          IntValueForLength(style.MarginBottom(), width);
+          IntValueForLength(style.MarginBottom(), description->size.height());
     }
     if (!style.MarginLeft().IsAuto()) {
-      description->margin_left = IntValueForLength(style.MarginLeft(), width);
+      description->margin_left =
+          IntValueForLength(style.MarginLeft(), description->size.width());
     }
   }
 
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index f51f2d4a..00549b9 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -608,7 +608,8 @@
   // following DCHECK can be removed.
   DCHECK(
       !GetDocument().IsActive() || GetDocument().InStyleRecalc() ||
-      !GetDocument().NeedsLayoutTreeUpdateForNodeIncludingDisplayLocked(*this));
+      !GetDocument().NeedsLayoutTreeUpdateForNodeIncludingDisplayLocked(*this))
+      << *this;
 
   if (LayoutObject* layout_object = GetLayoutObject()) {
     return layout_object->StyleRef().IsFocusable();
@@ -4316,13 +4317,6 @@
       }
     }
 
-    // TODO(https://crbug.com/576815): Once we have final spec text for
-    // https://github.com/whatwg/html/issues/3699 we should recheck the
-    // relative order of this check and the "Skip elements with valid
-    // dir attribute" check above, and add tests for the case that
-    // exercises both.  (Note that if the order is switched, this test
-    // needs to consider the dir attribute on the slot element rather
-    // than just jumping to its shadow host.)
     if (slot && RuntimeEnabledFeatures::CSSPseudoDirEnabled()) {
       ShadowRoot* root = slot->ContainingShadowRoot();
       return root->host().CachedDirectionality();
diff --git a/third_party/blink/renderer/core/editing/caret_display_item_client_test.cc b/third_party/blink/renderer/core/editing/caret_display_item_client_test.cc
index e16f6d8e..9f13b46b 100644
--- a/third_party/blink/renderer/core/editing/caret_display_item_client_test.cc
+++ b/third_party/blink/renderer/core/editing/caret_display_item_client_test.cc
@@ -67,11 +67,11 @@
   }
 
   const LayoutBlock* CaretLayoutBlock() {
-    return GetCaretDisplayItemClient().layout_block_;
+    return GetCaretDisplayItemClient().layout_block_.Get();
   }
 
   const LayoutBlock* PreviousCaretLayoutBlock() {
-    return GetCaretDisplayItemClient().previous_layout_block_;
+    return GetCaretDisplayItemClient().previous_layout_block_.Get();
   }
 
   bool ShouldPaintCursorCaret(const LayoutBlock& block) {
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
index a2f93121..40777759 100644
--- a/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
+++ b/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
@@ -41,7 +41,7 @@
   // TODO(editing-dev): We should use |CompositionEphemeralRange()| instead
   // of having |GetCompositionRange()| and marking |InputMethodControllerTest|
   // as friend class.
-  Range* GetCompositionRange() { return Controller().composition_range_; }
+  Range* GetCompositionRange() { return Controller().composition_range_.Get(); }
 
   Element* InsertHTMLElement(const char* element_code, const char* element_id);
   void CreateHTMLWithCompositionInputEventListeners();
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 4e0f7d06..ed24fcd 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -92,6 +92,7 @@
 #include "third_party/blink/renderer/core/editing/editor.h"
 #include "third_party/blink/renderer/core/editing/ephemeral_range.h"
 #include "third_party/blink/renderer/core/editing/frame_selection.h"
+#include "third_party/blink/renderer/core/editing/ime/edit_context.h"
 #include "third_party/blink/renderer/core/editing/ime/input_method_controller.h"
 #include "third_party/blink/renderer/core/editing/iterators/text_iterator.h"
 #include "third_party/blink/renderer/core/editing/selection_template.h"
@@ -1893,7 +1894,11 @@
     LocalFrame* focused_frame = page_->GetFocusController().FocusedFrame();
     if (focused_frame) {
       // Finish an ongoing composition to delete the composition node.
-      if (focused_frame->GetInputMethodController().HasComposition()) {
+      if (focused_frame->GetInputMethodController().GetActiveEditContext()) {
+        focused_frame->GetInputMethodController()
+            .GetActiveEditContext()
+            ->FinishComposingText(WebInputMethodController::kKeepSelection);
+      } else if (focused_frame->GetInputMethodController().HasComposition()) {
         // TODO(editing-dev): The use of
         // UpdateStyleAndLayout needs to be audited.
         // See http://crbug.com/590369 for more details.
diff --git a/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc b/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc
index 5985a16..a16f8bd 100644
--- a/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc
+++ b/third_party/blink/renderer/core/fetch/fetch_data_loader_test.cc
@@ -94,7 +94,7 @@
       completion_notifier_->SignalError(BytesConsumer::Error());
     }
 
-    BytesConsumer* GetDestination() { return destination_; }
+    BytesConsumer* GetDestination() { return destination_.Get(); }
 
     void Trace(Visitor* visitor) const override {
       visitor->Trace(destination_);
diff --git a/third_party/blink/renderer/core/frame/ad_tracker_test.cc b/third_party/blink/renderer/core/frame/ad_tracker_test.cc
index 3cd29c4..f665caa 100644
--- a/third_party/blink/renderer/core/frame/ad_tracker_test.cc
+++ b/third_party/blink/renderer/core/frame/ad_tracker_test.cc
@@ -137,7 +137,7 @@
     if (!execution_context_)
       return AdTracker::GetCurrentExecutionContext();
 
-    return execution_context_;
+    return execution_context_.Get();
   }
 
   bool CalculateIfAdSubresource(ExecutionContext* execution_context,
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 41f28165..7a19232 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -1634,7 +1634,7 @@
 }
 
 DOMVisualViewport* LocalDOMWindow::visualViewport() {
-  return visualViewport_;
+  return visualViewport_.Get();
 }
 
 const AtomicString& LocalDOMWindow::name() const {
@@ -1938,17 +1938,17 @@
     custom_elements_ = MakeGarbageCollected<CustomElementRegistry>(this);
     custom_elements_->AssociatedWith(*document_);
   }
-  return custom_elements_;
+  return custom_elements_.Get();
 }
 
 CustomElementRegistry* LocalDOMWindow::MaybeCustomElements() const {
-  return custom_elements_;
+  return custom_elements_.Get();
 }
 
 External* LocalDOMWindow::external() {
   if (!external_)
     external_ = MakeGarbageCollected<External>();
-  return external_;
+  return external_.Get();
 }
 
 bool LocalDOMWindow::isSecureContext() const {
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h b/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h
index 9f24a48..b4ccfa4 100644
--- a/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h
+++ b/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h
@@ -96,7 +96,7 @@
   ScriptValue GetConstructorForScript() override { return ScriptValue(); }
 
   V8CustomElementConstructor* GetV8CustomElementConstructor() override {
-    return constructor_;
+    return constructor_.Get();
   }
 
   bool RunConstructor(Element& element) override;
diff --git a/third_party/blink/renderer/core/html/forms/date_time_chooser.h b/third_party/blink/renderer/core/html/forms/date_time_chooser.h
index 5cb49a9..924a4b9 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_chooser.h
+++ b/third_party/blink/renderer/core/html/forms/date_time_chooser.h
@@ -33,6 +33,7 @@
 
 #include "third_party/blink/public/mojom/choosers/date_time_chooser.mojom-blink-forward.h"
 #include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/html/forms/input_type.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -51,7 +52,11 @@
       delete;
   CORE_EXPORT ~DateTimeChooserParameters();
 
-  AtomicString type;
+  // InputType::Type is a subset of FormControlType. InputType::Type is
+  // sufficient because DateTimeChooser only deals with HTMLInputElements. It's
+  // preferable over FormControlType because with InputType::TypeToString() a
+  // string conversion is already available.
+  InputType::Type type;
   gfx::Rect anchor_rect_in_screen;
   // Locale name for which the chooser should be localized. This
   // might be an invalid name because it comes from HTML lang
diff --git a/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc b/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc
index b548625..531958a7 100644
--- a/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc
+++ b/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc
@@ -85,20 +85,27 @@
   return popup_ ? popup_->RootAXObject() : nullptr;
 }
 
-static String ValueToDateTimeString(double value, AtomicString type) {
+static String ValueToDateTimeString(double value, InputType::Type type) {
   DateComponents components;
-  if (type == input_type_names::kDate)
-    components.SetMillisecondsSinceEpochForDate(value);
-  else if (type == input_type_names::kDatetimeLocal)
-    components.SetMillisecondsSinceEpochForDateTimeLocal(value);
-  else if (type == input_type_names::kMonth)
-    components.SetMonthsSinceEpoch(value);
-  else if (type == input_type_names::kTime)
-    components.SetMillisecondsSinceMidnight(value);
-  else if (type == input_type_names::kWeek)
-    components.SetMillisecondsSinceEpochForWeek(value);
-  else
-    NOTREACHED();
+  switch (type) {
+    case InputType::Type::kDate:
+      components.SetMillisecondsSinceEpochForDate(value);
+      break;
+    case InputType::Type::kDateTimeLocal:
+      components.SetMillisecondsSinceEpochForDateTimeLocal(value);
+      break;
+    case InputType::Type::kMonth:
+      components.SetMonthsSinceEpoch(value);
+      break;
+    case InputType::Type::kTime:
+      components.SetMillisecondsSinceMidnight(value);
+      break;
+    case InputType::Type::kWeek:
+      components.SetMillisecondsSinceEpochForWeek(value);
+      break;
+    default:
+      NOTREACHED();
+  }
   return components.GetType() == DateComponents::kInvalid
              ? String()
              : components.ToString();
@@ -109,18 +116,21 @@
   String step_base_string = String::Number(parameters_->step_base, 11);
   String today_label_string;
   String other_date_label_string;
-  if (parameters_->type == input_type_names::kMonth) {
-    today_label_string = GetLocale().QueryString(IDS_FORM_THIS_MONTH_LABEL);
-    other_date_label_string =
-        GetLocale().QueryString(IDS_FORM_OTHER_MONTH_LABEL);
-  } else if (parameters_->type == input_type_names::kWeek) {
-    today_label_string = GetLocale().QueryString(IDS_FORM_THIS_WEEK_LABEL);
-    other_date_label_string =
-        GetLocale().QueryString(IDS_FORM_OTHER_WEEK_LABEL);
-  } else {
-    today_label_string = GetLocale().QueryString(IDS_FORM_CALENDAR_TODAY);
-    other_date_label_string =
-        GetLocale().QueryString(IDS_FORM_OTHER_DATE_LABEL);
+  switch (parameters_->type) {
+    case InputType::Type::kMonth:
+      today_label_string = GetLocale().QueryString(IDS_FORM_THIS_MONTH_LABEL);
+      other_date_label_string =
+          GetLocale().QueryString(IDS_FORM_OTHER_MONTH_LABEL);
+      break;
+    case InputType::Type::kWeek:
+      today_label_string = GetLocale().QueryString(IDS_FORM_THIS_WEEK_LABEL);
+      other_date_label_string =
+          GetLocale().QueryString(IDS_FORM_OTHER_WEEK_LABEL);
+      break;
+    default:
+      today_label_string = GetLocale().QueryString(IDS_FORM_CALENDAR_TODAY);
+      other_date_label_string =
+          GetLocale().QueryString(IDS_FORM_OTHER_DATE_LABEL);
   }
 
   AddString(
@@ -135,8 +145,8 @@
         ChooserResourceLoader::GetSuggestionPickerDarkModeStyleSheet());
   }
   data->Append(ChooserResourceLoader::GetCalendarPickerStyleSheet());
-  if (parameters_->type == input_type_names::kTime ||
-      parameters_->type == input_type_names::kDatetimeLocal) {
+  if (parameters_->type == InputType::Type::kTime ||
+      parameters_->type == InputType::Type::kDateTimeLocal) {
     data->Append(ChooserResourceLoader::GetTimePickerStyleSheet());
   }
   AddString(
@@ -184,7 +194,8 @@
 #if BUILDFLAG(IS_MAC)
   AddProperty("isBorderTransparent", true, data);
 #endif
-  AddProperty("mode", parameters_->type.GetString(), data);
+  AddProperty("mode", InputType::TypeToString(parameters_->type).GetString(),
+              data);
   AddProperty("isAMPMFirst", parameters_->is_ampm_first, data);
   AddProperty("hasAMPM", parameters_->has_ampm, data);
   AddProperty("hasSecond", parameters_->has_second, data);
@@ -233,9 +244,9 @@
   data->Append(ChooserResourceLoader::GetPickerCommonJS());
   data->Append(ChooserResourceLoader::GetSuggestionPickerJS());
   data->Append(ChooserResourceLoader::GetMonthPickerJS());
-  if (parameters_->type == input_type_names::kTime) {
+  if (parameters_->type == InputType::Type::kTime) {
     data->Append(ChooserResourceLoader::GetTimePickerJS());
-  } else if (parameters_->type == input_type_names::kDatetimeLocal) {
+  } else if (parameters_->type == InputType::Type::kDateTimeLocal) {
     data->Append(ChooserResourceLoader::GetTimePickerJS());
     data->Append(ChooserResourceLoader::GetDateTimeLocalPickerJS());
   }
diff --git a/third_party/blink/renderer/core/html/forms/external_date_time_chooser.cc b/third_party/blink/renderer/core/html/forms/external_date_time_chooser.cc
index 2e7245e..104ca54 100644
--- a/third_party/blink/renderer/core/html/forms/external_date_time_chooser.cc
+++ b/third_party/blink/renderer/core/html/forms/external_date_time_chooser.cc
@@ -41,20 +41,21 @@
 
 namespace blink {
 
-static ui::TextInputType ToTextInputType(const AtomicString& source) {
-  if (source == input_type_names::kDate)
-    return ui::TextInputType::TEXT_INPUT_TYPE_DATE;
-  if (source == input_type_names::kDatetime)
-    return ui::TextInputType::TEXT_INPUT_TYPE_TIME;
-  if (source == input_type_names::kDatetimeLocal)
-    return ui::TextInputType::TEXT_INPUT_TYPE_DATE_TIME_LOCAL;
-  if (source == input_type_names::kMonth)
-    return ui::TextInputType::TEXT_INPUT_TYPE_MONTH;
-  if (source == input_type_names::kTime)
-    return ui::TextInputType::TEXT_INPUT_TYPE_TIME;
-  if (source == input_type_names::kWeek)
-    return ui::TextInputType::TEXT_INPUT_TYPE_WEEK;
-  return ui::TextInputType::TEXT_INPUT_TYPE_NONE;
+static ui::TextInputType ToTextInputType(InputType::Type source) {
+  switch (source) {
+    case InputType::Type::kDate:
+      return ui::TextInputType::TEXT_INPUT_TYPE_DATE;
+    case InputType::Type::kDateTimeLocal:
+      return ui::TextInputType::TEXT_INPUT_TYPE_DATE_TIME_LOCAL;
+    case InputType::Type::kMonth:
+      return ui::TextInputType::TEXT_INPUT_TYPE_MONTH;
+    case InputType::Type::kTime:
+      return ui::TextInputType::TEXT_INPUT_TYPE_TIME;
+    case InputType::Type::kWeek:
+      return ui::TextInputType::TEXT_INPUT_TYPE_WEEK;
+    default:
+      return ui::TextInputType::TEXT_INPUT_TYPE_NONE;
+  }
 }
 
 ExternalDateTimeChooser::~ExternalDateTimeChooser() = default;
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.cc b/third_party/blink/renderer/core/html/forms/html_input_element.cc
index 165e32a..9c1c4aec 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -2105,7 +2105,7 @@
   if (!GetDocument().View())
     return false;
 
-  parameters.type = type();
+  parameters.type = input_type_->type();
   parameters.minimum = Minimum();
   parameters.maximum = Maximum();
   parameters.required = IsRequired();
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element_test.cc b/third_party/blink/renderer/core/html/forms/html_input_element_test.cc
index dc040cb..ba93f845 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element_test.cc
+++ b/third_party/blink/renderer/core/html/forms/html_input_element_test.cc
@@ -243,7 +243,7 @@
   DateTimeChooserParameters params;
   bool success = input->SetupDateTimeChooserParameters(params);
   EXPECT_TRUE(success);
-  EXPECT_EQ("date", params.type);
+  EXPECT_EQ(InputType::Type::kDate, params.type);
   EXPECT_EQ(gfx::Rect(16, 16, 400, 100), params.anchor_rect_in_screen);
 }
 
diff --git a/third_party/blink/renderer/core/html/forms/input_type.cc b/third_party/blink/renderer/core/html/forms/input_type.cc
index 4e0ecc1..c3b0631 100644
--- a/third_party/blink/renderer/core/html/forms/input_type.cc
+++ b/third_party/blink/renderer/core/html/forms/input_type.cc
@@ -78,6 +78,56 @@
 
 namespace blink {
 
+const AtomicString& InputType::TypeToString(Type type) {
+  switch (type) {
+    case Type::kButton:
+      return input_type_names::kButton;
+    case Type::kCheckbox:
+      return input_type_names::kCheckbox;
+    case Type::kColor:
+      return input_type_names::kColor;
+    case Type::kDate:
+      return input_type_names::kDate;
+    case Type::kDateTimeLocal:
+      return input_type_names::kDatetimeLocal;
+    case Type::kEmail:
+      return input_type_names::kEmail;
+    case Type::kFile:
+      return input_type_names::kFile;
+    case Type::kHidden:
+      return input_type_names::kHidden;
+    case Type::kImage:
+      return input_type_names::kImage;
+    case Type::kMonth:
+      return input_type_names::kMonth;
+    case Type::kNumber:
+      return input_type_names::kNumber;
+    case Type::kPassword:
+      return input_type_names::kPassword;
+    case Type::kRadio:
+      return input_type_names::kRadio;
+    case Type::kRange:
+      return input_type_names::kRange;
+    case Type::kReset:
+      return input_type_names::kReset;
+    case Type::kSearch:
+      return input_type_names::kSearch;
+    case Type::kSubmit:
+      return input_type_names::kSubmit;
+    case Type::kTelephone:
+      return input_type_names::kTel;
+    case Type::kText:
+      return input_type_names::kText;
+    case Type::kTime:
+      return input_type_names::kTime;
+    case Type::kURL:
+      return input_type_names::kUrl;
+    case Type::kWeek:
+      return input_type_names::kWeek;
+  }
+  NOTREACHED_NORETURN();
+}
+
 // Listed once to avoid any discrepancy between InputType::Create and
 // InputType::NormalizeTypeName.
 //
@@ -142,52 +192,7 @@
 }
 
 const AtomicString& InputType::FormControlTypeAsString() const {
-  switch (type_) {
-    case Type::kButton:
-      return input_type_names::kButton;
-    case Type::kCheckbox:
-      return input_type_names::kCheckbox;
-    case Type::kColor:
-      return input_type_names::kColor;
-    case Type::kDate:
-      return input_type_names::kDate;
-    case Type::kDateTimeLocal:
-      return input_type_names::kDatetimeLocal;
-    case Type::kEmail:
-      return input_type_names::kEmail;
-    case Type::kFile:
-      return input_type_names::kFile;
-    case Type::kHidden:
-      return input_type_names::kHidden;
-    case Type::kImage:
-      return input_type_names::kImage;
-    case Type::kMonth:
-      return input_type_names::kMonth;
-    case Type::kNumber:
-      return input_type_names::kNumber;
-    case Type::kPassword:
-      return input_type_names::kPassword;
-    case Type::kRadio:
-      return input_type_names::kRadio;
-    case Type::kRange:
-      return input_type_names::kRange;
-    case Type::kReset:
-      return input_type_names::kReset;
-    case Type::kSearch:
-      return input_type_names::kSearch;
-    case Type::kSubmit:
-      return input_type_names::kSubmit;
-    case Type::kTelephone:
-      return input_type_names::kTel;
-    case Type::kText:
-      return input_type_names::kText;
-    case Type::kTime:
-      return input_type_names::kTime;
-    case Type::kURL:
-      return input_type_names::kUrl;
-    case Type::kWeek:
-      return input_type_names::kWeek;
-  }
+  return TypeToString(type_);
 }
 
 bool InputType::IsTextField() const {
diff --git a/third_party/blink/renderer/core/html/forms/input_type.h b/third_party/blink/renderer/core/html/forms/input_type.h
index 2189071..280bfc81 100644
--- a/third_party/blink/renderer/core/html/forms/input_type.h
+++ b/third_party/blink/renderer/core/html/forms/input_type.h
@@ -55,6 +55,47 @@
 // other than HTMLInputElement.
 class CORE_EXPORT InputType : public GarbageCollected<InputType> {
  public:
+  // The type attribute of HTMLInputElement is an enumerated attribute:
+  // https://html.spec.whatwg.org/multipage/input.html#attr-input-type
+  // These values are a subset of the `FormControlType` enum. They have the same
+  // binary representation so that FormControlType() reduces to a type cast.
+  enum class Type : std::underlying_type_t<mojom::blink::FormControlType> {
+    kButton = base::to_underlying(mojom::blink::FormControlType::kInputButton),
+    kColor = base::to_underlying(mojom::blink::FormControlType::kInputColor),
+    kFile = base::to_underlying(mojom::blink::FormControlType::kInputFile),
+    kHidden = base::to_underlying(mojom::blink::FormControlType::kInputHidden),
+    kImage = base::to_underlying(mojom::blink::FormControlType::kInputImage),
+    kNumber = base::to_underlying(mojom::blink::FormControlType::kInputNumber),
+    kRange = base::to_underlying(mojom::blink::FormControlType::kInputRange),
+    kReset = base::to_underlying(mojom::blink::FormControlType::kInputReset),
+    kSubmit = base::to_underlying(mojom::blink::FormControlType::kInputSubmit),
+
+    // BaseCheckable
+    kRadio = base::to_underlying(mojom::blink::FormControlType::kInputRadio),
+    kCheckbox =
+        base::to_underlying(mojom::blink::FormControlType::kInputCheckbox),
+
+    // BaseTemporal
+    kDate = base::to_underlying(mojom::blink::FormControlType::kInputDate),
+    kDateTimeLocal =
+        base::to_underlying(mojom::blink::FormControlType::kInputDatetimeLocal),
+    kMonth = base::to_underlying(mojom::blink::FormControlType::kInputMonth),
+    kTime = base::to_underlying(mojom::blink::FormControlType::kInputTime),
+    kWeek = base::to_underlying(mojom::blink::FormControlType::kInputWeek),
+
+    // BaseText
+    kEmail = base::to_underlying(mojom::blink::FormControlType::kInputEmail),
+    kPassword =
+        base::to_underlying(mojom::blink::FormControlType::kInputPassword),
+    kSearch = base::to_underlying(mojom::blink::FormControlType::kInputSearch),
+    kTelephone =
+        base::to_underlying(mojom::blink::FormControlType::kInputTelephone),
+    kURL = base::to_underlying(mojom::blink::FormControlType::kInputUrl),
+    kText = base::to_underlying(mojom::blink::FormControlType::kInputText),
+  };
+
+  static const AtomicString& TypeToString(Type);
+
   static InputType* Create(HTMLInputElement&, const AtomicString&);
   static const AtomicString& NormalizeTypeName(const AtomicString&);
   InputType(const InputType&) = delete;
@@ -64,6 +105,8 @@
 
   virtual InputTypeView* CreateView() = 0;
 
+  Type type() const { return type_; }
+
   const AtomicString& FormControlTypeAsString() const;
   mojom::blink::FormControlType FormControlType() const {
     return static_cast<mojom::blink::FormControlType>(
@@ -288,45 +331,6 @@
   virtual ColorChooserClient* GetColorChooserClient();
 
  protected:
-  // The type attribute of HTMLInputElement is an enumerated attribute:
-  // https://html.spec.whatwg.org/multipage/input.html#attr-input-type
-  // These values are a subset of the `FormControlType` enum. They have the same
-  // binary representation so that FormControlType() reduces to a type cast.
-  enum class Type : std::underlying_type_t<mojom::blink::FormControlType> {
-    kButton = base::to_underlying(mojom::blink::FormControlType::kInputButton),
-    kColor = base::to_underlying(mojom::blink::FormControlType::kInputColor),
-    kFile = base::to_underlying(mojom::blink::FormControlType::kInputFile),
-    kHidden = base::to_underlying(mojom::blink::FormControlType::kInputHidden),
-    kImage = base::to_underlying(mojom::blink::FormControlType::kInputImage),
-    kNumber = base::to_underlying(mojom::blink::FormControlType::kInputNumber),
-    kRange = base::to_underlying(mojom::blink::FormControlType::kInputRange),
-    kReset = base::to_underlying(mojom::blink::FormControlType::kInputReset),
-    kSubmit = base::to_underlying(mojom::blink::FormControlType::kInputSubmit),
-
-    // BaseCheckable
-    kRadio = base::to_underlying(mojom::blink::FormControlType::kInputRadio),
-    kCheckbox =
-        base::to_underlying(mojom::blink::FormControlType::kInputCheckbox),
-
-    // BaseTemporal
-    kDate = base::to_underlying(mojom::blink::FormControlType::kInputDate),
-    kDateTimeLocal =
-        base::to_underlying(mojom::blink::FormControlType::kInputDatetimeLocal),
-    kMonth = base::to_underlying(mojom::blink::FormControlType::kInputMonth),
-    kTime = base::to_underlying(mojom::blink::FormControlType::kInputTime),
-    kWeek = base::to_underlying(mojom::blink::FormControlType::kInputWeek),
-
-    // BaseText
-    kEmail = base::to_underlying(mojom::blink::FormControlType::kInputEmail),
-    kPassword =
-        base::to_underlying(mojom::blink::FormControlType::kInputPassword),
-    kSearch = base::to_underlying(mojom::blink::FormControlType::kInputSearch),
-    kTelephone =
-        base::to_underlying(mojom::blink::FormControlType::kInputTelephone),
-    kURL = base::to_underlying(mojom::blink::FormControlType::kInputUrl),
-    kText = base::to_underlying(mojom::blink::FormControlType::kInputText),
-  };
-
   InputType(Type type, HTMLInputElement& element)
       : type_(type), element_(element) {}
   HTMLInputElement& GetElement() const { return *element_; }
diff --git a/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc b/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
index 6566eeb8..866dd67 100644
--- a/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
+++ b/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
@@ -415,8 +415,7 @@
       MakeGarbageCollected<DateTimeEditElement, Document&,
                            DateTimeEditElement::EditControlOwner&>(document,
                                                                    *this));
-  if (LayoutTheme::GetTheme().SupportsCalendarPicker(
-          input_type_->FormControlTypeAsString())) {
+  if (LayoutTheme::GetTheme().SupportsCalendarPicker(input_type_->type())) {
     picker_indicator_is_always_visible_ = true;
   }
   container->AppendChild(
diff --git a/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc b/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc
index a5076ac..b2e6d48 100644
--- a/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc
+++ b/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc
@@ -277,7 +277,7 @@
   if (!name_to_group_map_)
     return nullptr;
   auto it = name_to_group_map_->find(name);
-  return it != name_to_group_map_->end() ? it->value : nullptr;
+  return it != name_to_group_map_->end() ? it->value.Get() : nullptr;
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/forms/select_type.cc b/third_party/blink/renderer/core/html/forms/select_type.cc
index 5ecd2c65..4d84b0a 100644
--- a/third_party/blink/renderer/core/html/forms/select_type.cc
+++ b/third_party/blink/renderer/core/html/forms/select_type.cc
@@ -1070,7 +1070,7 @@
 
 HTMLOptionElement* ListBoxSelectType::ActiveSelectionEnd() const {
   if (active_selection_end_)
-    return active_selection_end_;
+    return active_selection_end_.Get();
   return select_->LastSelectedOption();
 }
 
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.cc b/third_party/blink/renderer/core/html/forms/text_control_element.cc
index 8af0ae29..5deeba8b 100644
--- a/third_party/blink/renderer/core/html/forms/text_control_element.cc
+++ b/third_party/blink/renderer/core/html/forms/text_control_element.cc
@@ -1059,7 +1059,7 @@
   DCHECK(!inner_editor_);
   inner_editor_ =
       MakeGarbageCollected<TextControlInnerEditorElement>(GetDocument());
-  return inner_editor_;
+  return inner_editor_.Get();
 }
 
 const String& TextControlElement::SuggestedValue() const {
diff --git a/third_party/blink/renderer/core/html/html_collection.cc b/third_party/blink/renderer/core/html/html_collection.cc
index 56729215..6ad86c0 100644
--- a/third_party/blink/renderer/core/html/html_collection.cc
+++ b/third_party/blink/renderer/core/html/html_collection.cc
@@ -264,7 +264,7 @@
     case kPopoverInvokers:
       if (auto* invoker = DynamicTo<HTMLFormControlElement>(
               const_cast<HTMLElement&>(element))) {
-        return invoker->popoverTargetElement().popover;
+        return invoker->popoverTargetElement().popover != nullptr;
       }
       return false;
     case kClassCollectionType:
@@ -457,11 +457,11 @@
   const NamedItemCache& cache = GetNamedItemCache();
   const auto* id_results = cache.GetElementsById(name);
   if (id_results && !id_results->empty())
-    return id_results->front();
+    return id_results->front().Get();
 
   const auto* name_results = cache.GetElementsByName(name);
   if (name_results && !name_results->empty())
-    return name_results->front();
+    return name_results->front().Get();
 
   return nullptr;
 }
diff --git a/third_party/blink/renderer/core/html/html_collection.h b/third_party/blink/renderer/core/html/html_collection.h
index 7022aa8..ba4a0151 100644
--- a/third_party/blink/renderer/core/html/html_collection.h
+++ b/third_party/blink/renderer/core/html/html_collection.h
@@ -155,7 +155,7 @@
                                 Element* element) {
       HeapVector<Member<Element>>* vector =
           map.insert(key, MakeGarbageCollected<HeapVector<Member<Element>>>())
-              .stored_value->value;
+              .stored_value->value.Get();
       vector->push_back(element);
     }
 
diff --git a/third_party/blink/renderer/core/html/html_slot_element.cc b/third_party/blink/renderer/core/html/html_slot_element.cc
index d9e8977..8cb9d02 100644
--- a/third_party/blink/renderer/core/html/html_slot_element.cc
+++ b/third_party/blink/renderer/core/html/html_slot_element.cc
@@ -378,9 +378,19 @@
   HTMLElement::AttributeChanged(params);
 }
 
+// When the result of `SupportsAssignment()` changes, the behavior of a
+// <slot> element for ancestors with dir=auto changes.
+void HTMLSlotElement::UpdateDirAutoAncestorsForSupportsAssignmentChange() {
+  if (RuntimeEnabledFeatures::CSSPseudoDirEnabled() &&
+      SelfOrAncestorHasDirAutoAttribute()) {
+    UpdateAncestorWithDirAuto(UpdateAncestorTraversal::ExcludeSelf);
+  }
+}
+
 Node::InsertionNotificationRequest HTMLSlotElement::InsertedInto(
     ContainerNode& insertion_point) {
   HTMLElement::InsertedInto(insertion_point);
+  UpdateDirAutoAncestorsForSupportsAssignmentChange();
   if (SupportsAssignment()) {
     ShadowRoot* root = ContainingShadowRoot();
     DCHECK(root);
@@ -453,6 +463,7 @@
     DCHECK(assigned_nodes_.empty());
   }
 
+  UpdateDirAutoAncestorsForSupportsAssignmentChange();
   HTMLElement::RemovedFrom(insertion_point);
 }
 
diff --git a/third_party/blink/renderer/core/html/html_slot_element.h b/third_party/blink/renderer/core/html/html_slot_element.h
index 06290838..4f95529 100644
--- a/third_party/blink/renderer/core/html/html_slot_element.h
+++ b/third_party/blink/renderer/core/html/html_slot_element.h
@@ -159,6 +159,8 @@
   void ClearAssignedNodesAndFlatTreeChildren();
   void DetachDisplayLockedAssignedNodesLayoutTreeIfNeeded();
 
+  void UpdateDirAutoAncestorsForSupportsAssignmentChange();
+
   HeapVector<Member<Node>> assigned_nodes_;
   HeapVector<Member<Node>> flat_tree_children_;
 
diff --git a/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc b/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc
index 40c22ad..a022e0b 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc
+++ b/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc
@@ -200,7 +200,7 @@
   }
 
   MediaCustomControlsFullscreenDetector* FullscreenDetector() {
-    return Video()->custom_controls_fullscreen_detector_;
+    return Video()->custom_controls_fullscreen_detector_.Get();
   }
 };
 
diff --git a/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector_test.cc b/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector_test.cc
index 6a02184d..2ca6ccb 100644
--- a/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector_test.cc
+++ b/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector_test.cc
@@ -27,7 +27,7 @@
 
   static MediaCustomControlsFullscreenDetector* FullscreenDetectorFor(
       HTMLVideoElement* video_element) {
-    return video_element->custom_controls_fullscreen_detector_;
+    return video_element->custom_controls_fullscreen_detector_.Get();
   }
 
   MediaCustomControlsFullscreenDetector* FullscreenDetector() const {
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
index dc4c888..03e1d47 100644
--- a/third_party/blink/renderer/core/html/parser/html_document_parser.cc
+++ b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
@@ -773,17 +773,13 @@
   if (is_stopped_or_parsing_fragment)
     return false;
 
-  if (IsPaused()) {
-    DCHECK_EQ(tokenizer_.GetState(), HTMLTokenizer::kDataState);
-
-    if (preloader_ && !background_scanner_) {
-      if (!preload_scanner_) {
-        preload_scanner_ = CreatePreloadScanner(
-            TokenPreloadScanner::ScannerType::kMainDocument);
-        preload_scanner_->AppendToEnd(input_.Current());
-      }
-      ScanAndPreload(preload_scanner_.get());
+  if (IsPaused() && preloader_ && !background_scanner_) {
+    if (!preload_scanner_) {
+      preload_scanner_ =
+          CreatePreloadScanner(TokenPreloadScanner::ScannerType::kMainDocument);
+      preload_scanner_->AppendToEnd(input_.Current());
     }
+    ScanAndPreload(preload_scanner_.get());
   }
 
   // should_run_until_completion implies that we should not yield
diff --git a/third_party/blink/renderer/core/html/parser/html_element_stack.cc b/third_party/blink/renderer/core/html/parser/html_element_stack.cc
index 970b388..3fd5a1a 100644
--- a/third_party/blink/renderer/core/html/parser/html_element_stack.cc
+++ b/third_party/blink/renderer/core/html/parser/html_element_stack.cc
@@ -507,17 +507,17 @@
 
 Element* HTMLElementStack::HeadElement() const {
   DCHECK(head_element_);
-  return head_element_;
+  return head_element_.Get();
 }
 
 Element* HTMLElementStack::BodyElement() const {
   DCHECK(body_element_);
-  return body_element_;
+  return body_element_.Get();
 }
 
 ContainerNode* HTMLElementStack::RootNode() const {
   DCHECK(root_node_);
-  return root_node_;
+  return root_node_.Get();
 }
 
 void HTMLElementStack::PushCommon(HTMLStackItem* item) {
diff --git a/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc b/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc
index dabfe26..90633be 100644
--- a/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_issue_conversion.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/inspector/inspector_issue_conversion.h"
 
+#include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-blink-forward.h"
 #include "third_party/blink/renderer/core/inspector/inspector_issue.h"
 #include "third_party/blink/renderer/core/inspector/protocol/audits.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
@@ -59,6 +60,7 @@
     case mojom::blink::InspectorIssueCode::kFederatedAuthRequestIssue:
     case mojom::blink::InspectorIssueCode::kFederatedAuthUserInfoRequestIssue:
     case mojom::blink::InspectorIssueCode::kBounceTrackingIssue:
+    case mojom::blink::InspectorIssueCode::kCookieDeprecationMetadataIssue:
     case mojom::blink::InspectorIssueCode::kGenericIssue:
     case mojom::blink::InspectorIssueCode::kDeprecationIssue:
     case mojom::blink::InspectorIssueCode::kAttributionReportingIssue:
@@ -142,6 +144,10 @@
       return protocol::Audits::CookieWarningReasonEnum::WarnDomainNonASCII;
     case blink::mojom::blink::CookieWarningReason::kWarnThirdPartyPhaseout:
       return protocol::Audits::CookieWarningReasonEnum::WarnThirdPartyPhaseout;
+    case blink::mojom::blink::CookieWarningReason::
+        kWarnCrossSiteRedirectDowngradeChangesInclusion:
+      return protocol::Audits::CookieWarningReasonEnum::
+          WarnCrossSiteRedirectDowngradeChangesInclusion;
   }
 }
 
diff --git a/third_party/blink/renderer/core/inspector/network_resources_data.cc b/third_party/blink/renderer/core/inspector/network_resources_data.cc
index 6601721..0dddaa7 100644
--- a/third_party/blink/renderer/core/inspector/network_resources_data.cc
+++ b/third_party/blink/renderer/core/inspector/network_resources_data.cc
@@ -439,7 +439,8 @@
   if (request_id.IsNull())
     return nullptr;
   auto it = request_id_to_resource_data_map_.find(request_id);
-  return it != request_id_to_resource_data_map_.end() ? it->value : nullptr;
+  return it != request_id_to_resource_data_map_.end() ? it->value.Get()
+                                                      : nullptr;
 }
 
 void NetworkResourcesData::EnsureNoDataForRequestId(const String& request_id) {
diff --git a/third_party/blink/renderer/core/layout/custom_scrollbar.h b/third_party/blink/renderer/core/layout/custom_scrollbar.h
index 83f1cdf6..aa5aa58 100644
--- a/third_party/blink/renderer/core/layout/custom_scrollbar.h
+++ b/third_party/blink/renderer/core/layout/custom_scrollbar.h
@@ -70,11 +70,11 @@
 
   LayoutCustomScrollbarPart* GetPart(ScrollbarPart part_type) {
     auto it = parts_.find(part_type);
-    return it != parts_.end() ? it->value : nullptr;
+    return it != parts_.end() ? it->value.Get() : nullptr;
   }
   const LayoutCustomScrollbarPart* GetPart(ScrollbarPart part_type) const {
     auto it = parts_.find(part_type);
-    return it != parts_.end() ? it->value : nullptr;
+    return it != parts_.end() ? it->value.Get() : nullptr;
   }
 
   void InvalidateDisplayItemClientsOfScrollbarParts();
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h
index 15bb4a2..409e9e5 100644
--- a/third_party/blink/renderer/core/layout/layout_box.h
+++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -867,7 +867,7 @@
   void ClearSpannerPlaceholder();
   LayoutMultiColumnSpannerPlaceholder* SpannerPlaceholder() const final {
     NOT_DESTROYED();
-    return rare_data_ ? rare_data_->spanner_placeholder_ : nullptr;
+    return rare_data_ ? rare_data_->spanner_placeholder_.Get() : nullptr;
   }
 
   bool MapToVisualRectInAncestorSpaceInternal(
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index 165bee8ce..be862724 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -1768,7 +1768,7 @@
 
   Node* GetNode() const {
     NOT_DESTROYED();
-    return IsAnonymous() ? nullptr : node_;
+    return IsAnonymous() ? nullptr : node_.Get();
   }
 
   Node* NonPseudoNode() const {
diff --git a/third_party/blink/renderer/core/layout/layout_theme.cc b/third_party/blink/renderer/core/layout/layout_theme.cc
index 712b374..91b997d 100644
--- a/third_party/blink/renderer/core/layout/layout_theme.cc
+++ b/third_party/blink/renderer/core/layout/layout_theme.cc
@@ -820,15 +820,11 @@
   return file.name();
 }
 
-bool LayoutTheme::SupportsCalendarPicker(const AtomicString& type) const {
+bool LayoutTheme::SupportsCalendarPicker(InputType::Type type) const {
   DCHECK(RuntimeEnabledFeatures::InputMultipleFieldsUIEnabled());
-  if (type == input_type_names::kTime)
-    return true;
-
-  return type == input_type_names::kDate ||
-         type == input_type_names::kDatetime ||
-         type == input_type_names::kDatetimeLocal ||
-         type == input_type_names::kMonth || type == input_type_names::kWeek;
+  return type == InputType::Type::kTime || type == InputType::Type::kDate ||
+         type == InputType::Type::kDateTimeLocal ||
+         type == InputType::Type::kMonth || type == InputType::Type::kWeek;
 }
 
 void LayoutTheme::AdjustControlPartStyle(ComputedStyleBuilder& builder) {
diff --git a/third_party/blink/renderer/core/layout/layout_theme.h b/third_party/blink/renderer/core/layout/layout_theme.h
index bb78a8fa..8af3d5f8 100644
--- a/third_party/blink/renderer/core/layout/layout_theme.h
+++ b/third_party/blink/renderer/core/layout/layout_theme.h
@@ -27,6 +27,7 @@
 #include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink-forward.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/css_value_keywords.h"
+#include "third_party/blink/renderer/core/html/forms/input_type.h"
 #include "third_party/blink/renderer/platform/graphics/color.h"
 #include "third_party/blink/renderer/platform/theme_types.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -85,7 +86,7 @@
 
   // A method asking if the platform is able to show a calendar picker for a
   // given input type.
-  virtual bool SupportsCalendarPicker(const AtomicString&) const;
+  virtual bool SupportsCalendarPicker(InputType::Type) const;
 
   // Text selection colors.
   Color ActiveSelectionBackgroundColor(
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc
index 4269716e..9c73eeffc4 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_abstract_inline_text_box.cc
@@ -49,7 +49,7 @@
         To<LayoutText>(cursor.CurrentMutableLayoutObject());
     if (it != map_->end()) {
       CHECK(layout_text->HasAbstractInlineTextBox());
-      return it->value;
+      return it->value.Get();
     }
     auto* obj = MakeGarbageCollected<NGAbstractInlineTextBox>(cursor);
     map_->Set(key, obj);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
index d8536a7..cecb267 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
@@ -180,7 +180,7 @@
   const ComputedStyle& Style() const {
     return layout_object_->EffectiveStyle(StyleVariant());
   }
-  const LayoutObject* GetLayoutObject() const { return layout_object_; }
+  const LayoutObject* GetLayoutObject() const { return layout_object_.Get(); }
   LayoutObject* GetMutableLayoutObject() const {
     return const_cast<LayoutObject*>(layout_object_.Get());
   }
@@ -262,7 +262,7 @@
   // Returns |NGPhysicalBoxFragment| if one is associated with this item.
   const NGPhysicalBoxFragment* BoxFragment() const {
     if (Type() == kBox)
-      return box_.box_fragment;
+      return box_.box_fragment.Get();
     return nullptr;
   }
   const NGPhysicalBoxFragment* PostLayoutBoxFragment() const {
@@ -285,7 +285,7 @@
   // this function. See |InlineBreakToken()| for example.
   const NGPhysicalLineBoxFragment* LineBoxFragment() const {
     if (Type() == kLine)
-      return line_.line_box_fragment;
+      return line_.line_box_fragment.Get();
     return nullptr;
   }
 
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
index e2e9149..c05403a5 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
@@ -958,7 +958,7 @@
     DCHECK(data->offset_mapping);
   }
 
-  return data->offset_mapping;
+  return data->offset_mapping.Get();
 }
 
 void NGInlineNode::ComputeOffsetMapping(LayoutBlockFlow* layout_block_flow,
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
index 358d3d5..07a3b1fa 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping_test.cc
@@ -189,7 +189,7 @@
   }
 
   bool IsOffsetMappingStored() const {
-    return layout_block_flow_->GetNGInlineNodeData()->offset_mapping;
+    return layout_block_flow_->GetNGInlineNodeData()->offset_mapping != nullptr;
   }
 
   const LayoutText* GetLayoutTextUnder(const char* parent_id) {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment_test.cc
index 5c77008..2453b68 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment_test.cc
@@ -28,7 +28,7 @@
   const NGPhysicalLineBoxFragment* GetLineBox() const {
     HeapVector<Member<const NGPhysicalLineBoxFragment>> lines = GetLineBoxes();
     if (!lines.empty())
-      return lines.front();
+      return lines.front().Get();
     return nullptr;
   }
 };
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc
index e66059e..f5936d1 100644
--- a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc
+++ b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc
@@ -44,7 +44,7 @@
 
 NGInlineNodeData* LayoutNGBlockFlow::GetNGInlineNodeData() const {
   NOT_DESTROYED();
-  return ng_inline_node_data_;
+  return ng_inline_node_data_.Get();
 }
 
 void LayoutNGBlockFlow::ResetNGInlineNodeData() {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
index eebf8ed5..183d5cc 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
@@ -19,132 +19,140 @@
 
 namespace {
 
-enum AxisEdge { kStart, kCenter, kEnd };
-
-inline AxisEdge GetStaticPositionEdge(
+inline InsetModifiedContainingBlock::InsetBias GetStaticPositionInsetBias(
     LogicalStaticPosition::InlineEdge inline_edge) {
+  using InsetBias = InsetModifiedContainingBlock::InsetBias;
   switch (inline_edge) {
     case LogicalStaticPosition::InlineEdge::kInlineStart:
-      return kStart;
+      return InsetBias::kStart;
     case LogicalStaticPosition::InlineEdge::kInlineCenter:
-      return kCenter;
+      return InsetBias::kEqual;
     case LogicalStaticPosition::InlineEdge::kInlineEnd:
-      return kEnd;
+      return InsetBias::kEnd;
   }
 }
 
-inline AxisEdge GetStaticPositionEdge(
+inline InsetModifiedContainingBlock::InsetBias GetStaticPositionInsetBias(
     LogicalStaticPosition::BlockEdge block_edge) {
+  using InsetBias = InsetModifiedContainingBlock::InsetBias;
   switch (block_edge) {
     case LogicalStaticPosition::BlockEdge::kBlockStart:
-      return kStart;
+      return InsetBias::kStart;
     case LogicalStaticPosition::BlockEdge::kBlockCenter:
-      return kCenter;
+      return InsetBias::kEqual;
     case LogicalStaticPosition::BlockEdge::kBlockEnd:
-      return kEnd;
+      return InsetBias::kEnd;
   }
 }
 
-inline LayoutUnit StaticPositionStartInset(AxisEdge edge,
-                                           LayoutUnit static_position_offset,
-                                           LayoutUnit size) {
-  switch (edge) {
-    case kStart:
-      return static_position_offset;
-    case kCenter:
-      return static_position_offset - (size / 2);
-    case kEnd:
-      return static_position_offset - size;
-  }
-}
-
-inline LayoutUnit StaticPositionEndInset(AxisEdge edge,
-                                         LayoutUnit static_position_offset,
-                                         LayoutUnit available_size,
-                                         LayoutUnit size) {
-  switch (edge) {
-    case kStart:
-      return available_size - static_position_offset - size;
-    case kCenter:
-      return available_size - static_position_offset - (size / 2);
-    case kEnd:
-      return available_size - static_position_offset;
-  }
-}
-
-// Computes the available-space as an (offset, size) pair, accounting for insets
-// and the static-position.
-std::pair<LayoutUnit, LayoutUnit> ComputeAvailableSpaceInOneAxis(
+// Computes the inset modified containing block in one axis, accounting for
+// insets and the static-position.
+void ComputeUnclampedIMCBInOneAxis(
     const LayoutUnit available_size,
     const absl::optional<LayoutUnit>& inset_start,
     const absl::optional<LayoutUnit>& inset_end,
     const LayoutUnit static_position_offset,
-    AxisEdge static_position_edge) {
+    InsetModifiedContainingBlock::InsetBias static_position_inset_bias,
+    bool start_side_matches_containing_block,
+    LayoutUnit* imcb_start_out,
+    LayoutUnit* imcb_end_out,
+    InsetModifiedContainingBlock::InsetBias* imcb_inset_bias_out) {
   DCHECK_NE(available_size, kIndefiniteSize);
-  LayoutUnit computed_offset;
-  LayoutUnit computed_available_size;
-
   if (!inset_start && !inset_end) {
     // If both our insets are auto, the available-space is defined by the
     // static-position.
-    switch (static_position_edge) {
-      case kStart:
+    switch (static_position_inset_bias) {
+      case InsetModifiedContainingBlock::InsetBias::kStart:
         // The available-space for the start static-position "grows" towards the
         // end edge.
         // |      *----------->|
-        computed_offset = static_position_offset;
-        computed_available_size = available_size - static_position_offset;
+        *imcb_start_out = static_position_offset;
+        *imcb_end_out = LayoutUnit();
         break;
-      case kCenter: {
+      case InsetModifiedContainingBlock::InsetBias::kEqual: {
         // The available-space for the center static-position "grows" towards
         // both edges (equally), and stops when it hits the first one.
         // |<-----*----->      |
-        LayoutUnit half_computed_available_size = std::min(
+        LayoutUnit half_imcb_size = std::min(
             static_position_offset, available_size - static_position_offset);
-        computed_offset = static_position_offset - half_computed_available_size;
-        computed_available_size = 2 * half_computed_available_size;
+        *imcb_start_out = static_position_offset - half_imcb_size;
+        *imcb_end_out =
+            available_size - static_position_offset - half_imcb_size;
         break;
       }
-      case kEnd:
+      case InsetModifiedContainingBlock::InsetBias::kEnd:
         // The available-space for the end static-position "grows" towards the
         // start edge.
         // |<-----*            |
-        computed_offset = LayoutUnit();
-        computed_available_size = static_position_offset;
+        *imcb_end_out = available_size - static_position_offset;
+        *imcb_start_out = LayoutUnit();
         break;
     }
+    *imcb_inset_bias_out = static_position_inset_bias;
   } else {
-    // Otherwise we just subtract the insets.
-    computed_available_size = available_size -
-                              inset_start.value_or(LayoutUnit()) -
-                              inset_end.value_or(LayoutUnit());
-    computed_offset = inset_start.value_or(LayoutUnit());
-  }
+    // Otherwise we just resolve auto to 0.
+    *imcb_start_out = inset_start.value_or(LayoutUnit());
+    *imcb_end_out = inset_end.value_or(LayoutUnit());
 
-  return std::make_pair(computed_offset, computed_available_size);
+    if (!inset_start.has_value() || !inset_end.has_value()) {
+      // In the case that only one inset is auto, that is the weaker inset;
+      *imcb_inset_bias_out =
+          inset_start.has_value()
+              ? InsetModifiedContainingBlock::InsetBias::kStart
+              : InsetModifiedContainingBlock::InsetBias::kEnd;
+    } else {
+      // Otherwise the weaker inset is the inset of the end edge (where end is
+      // interpreted relative to the writing mode of the containing block).
+      *imcb_inset_bias_out =
+          start_side_matches_containing_block
+              ? InsetModifiedContainingBlock::InsetBias::kStart
+              : InsetModifiedContainingBlock::InsetBias::kEnd;
+    }
+  }
 }
 
-// Computes the insets, and margins if necessary.
-// https://www.w3.org/TR/css-position-3/#abs-non-replaced-width
-// https://www.w3.org/TR/css-position-3/#abs-non-replaced-height
-void ComputeInsets(const LayoutUnit margin_percentage_resolution_size,
-                   const LayoutUnit available_size,
-                   const LayoutUnit computed_available_size,
-                   const Length& margin_start_length,
-                   const Length& margin_end_length,
-                   absl::optional<LayoutUnit> inset_start,
-                   absl::optional<LayoutUnit> inset_end,
-                   const LayoutUnit static_position_offset,
-                   AxisEdge static_position_edge,
-                   bool is_start_dominant,
-                   bool is_block_direction,
-                   LayoutUnit size,
-                   LayoutUnit* inset_start_out,
-                   LayoutUnit* inset_end_out,
-                   LayoutUnit* margin_start_out,
-                   LayoutUnit* margin_end_out) {
-  DCHECK_NE(available_size, kIndefiniteSize);
+InsetModifiedContainingBlock ComputeUnclampedIMCB(
+    const LogicalSize& available_size,
+    const NGLogicalOutOfFlowInsets& insets,
+    const LogicalStaticPosition& static_position,
+    const WritingDirectionMode& container_writing_direction,
+    const WritingDirectionMode& self_writing_direction) {
+  InsetModifiedContainingBlock imcb;
+  imcb.available_size = available_size;
 
+  // Determines if the "start" sides of margins match.
+  const LogicalToLogical start_sides_match(
+      container_writing_direction, self_writing_direction,
+      /* inline_start */ true, /* inline_end */ false,
+      /* block_start */ true, /* block_end */ false);
+
+  ComputeUnclampedIMCBInOneAxis(
+      available_size.inline_size, insets.inline_start, insets.inline_end,
+      static_position.offset.inline_offset,
+      GetStaticPositionInsetBias(static_position.inline_edge),
+      start_sides_match.InlineStart(), &imcb.inline_start, &imcb.inline_end,
+      &imcb.inline_inset_bias);
+  ComputeUnclampedIMCBInOneAxis(
+      available_size.block_size, insets.block_start, insets.block_end,
+      static_position.offset.block_offset,
+      GetStaticPositionInsetBias(static_position.block_edge),
+      start_sides_match.BlockStart(), &imcb.block_start, &imcb.block_end,
+      &imcb.block_inset_bias);
+  return imcb;
+}
+
+// Absolutize margin values to pixels and resolve any auto margins.
+// https://drafts.csswg.org/css-position-3/#abspos-margins
+void ComputeMargins(const LayoutUnit margin_percentage_resolution_size,
+                    const LayoutUnit imcb_size,
+                    const Length& margin_start_length,
+                    const Length& margin_end_length,
+                    const LayoutUnit size,
+                    bool has_auto_inset,
+                    bool is_start_dominant,
+                    bool is_block_direction,
+                    LayoutUnit* margin_start_out,
+                    LayoutUnit* margin_end_out) {
   absl::optional<LayoutUnit> margin_start;
   if (!margin_start_length.IsAuto()) {
     margin_start = MinimumValueForLength(margin_start_length,
@@ -157,14 +165,13 @@
   }
 
   // Solving the equation:
-  // |inset_start| + |margin_start| + |size| + |margin_end| + |inset_end| =
-  // |available_size|
-  if (inset_start && inset_end) {
+  // |margin_start| + |size| + |margin_end| = |imcb_size|
+  if (!has_auto_inset) {
     // "If left, right, and width are not auto:"
     // Compute margins.
-    LayoutUnit free_space = computed_available_size - size -
-                            margin_start.value_or(LayoutUnit()) -
-                            margin_end.value_or(LayoutUnit());
+    const LayoutUnit free_space = imcb_size - size -
+                                  margin_start.value_or(LayoutUnit()) -
+                                  margin_end.value_or(LayoutUnit());
 
     if (!margin_start && !margin_end) {
       // When both margins are auto.
@@ -185,46 +192,59 @@
       margin_start = free_space;
     } else if (!margin_end) {
       margin_end = free_space;
-    } else {
-      // Are the values over-constrained? Relax the end.
-      if (is_start_dominant) {
-        inset_end = *inset_end + free_space;
-      } else {
-        inset_start = *inset_start + free_space;
-      }
     }
   }
 
   // Set any unknown margins.
-  if (!margin_start)
-    margin_start = LayoutUnit();
-  if (!margin_end)
-    margin_end = LayoutUnit();
+  *margin_start_out = margin_start.value_or(LayoutUnit());
+  *margin_end_out = margin_end.value_or(LayoutUnit());
+}
 
-  if (!inset_start && !inset_end) {
-    LayoutUnit margin_size = size + *margin_start + *margin_end;
-    if (is_start_dominant) {
-      inset_start = StaticPositionStartInset(
-          static_position_edge, static_position_offset, margin_size);
-    } else {
-      inset_end =
-          StaticPositionEndInset(static_position_edge, static_position_offset,
-                                 available_size, margin_size);
-    }
+void ResizeIMCBInOneAxis(
+    LayoutUnit& inset_start,
+    LayoutUnit& inset_end,
+    const InsetModifiedContainingBlock::InsetBias& inset_bias,
+    const LayoutUnit& amount) {
+  switch (inset_bias) {
+    case InsetModifiedContainingBlock::InsetBias::kStart:
+      inset_end += amount;
+      break;
+    case InsetModifiedContainingBlock::InsetBias::kEnd:
+      inset_start += amount;
+      break;
+    case InsetModifiedContainingBlock::InsetBias::kEqual:
+      inset_start += amount / 2;
+      inset_end += amount / 2;
+      break;
   }
+}
 
-  if (!inset_start) {
-    inset_start =
-        available_size - size - *inset_end - *margin_start - *margin_end;
-  } else if (!inset_end) {
-    inset_end =
-        available_size - size - *inset_start - *margin_start - *margin_end;
-  }
+// Align the margin box within the inset-modified containing block as defined by
+// its self-alignment properties.
+// https://drafts.csswg.org/css-position-3/#abspos-layout
+void ComputeInsets(
+    const LayoutUnit available_size,
+    const LayoutUnit passed_imcb_start,
+    const LayoutUnit passed_imcb_end,
+    const InsetModifiedContainingBlock::InsetBias& imcb_inset_bias,
+    const LayoutUnit margin_start,
+    const LayoutUnit margin_end,
+    const LayoutUnit size,
+    LayoutUnit* inset_start_out,
+    LayoutUnit* inset_end_out) {
+  DCHECK_NE(available_size, kIndefiniteSize);
+  LayoutUnit imcb_start = passed_imcb_start;
+  LayoutUnit imcb_end = passed_imcb_end;
+  const LayoutUnit free_space =
+      available_size - imcb_start - imcb_end - margin_start - margin_end - size;
 
-  *inset_start_out = *inset_start + *margin_start;
-  *inset_end_out = *inset_end + *margin_end;
-  *margin_start_out = *margin_start;
-  *margin_end_out = *margin_end;
+  // Move the weaker inset edge to consume all the free space, so that:
+  // `imcb_start` + `margin_start` + `size` + `margin_end` + `imcb_end` =
+  // `available_size`
+  ResizeIMCBInOneAxis(imcb_start, imcb_end, imcb_inset_bias, free_space);
+
+  *inset_start_out = imcb_start + margin_start;
+  *inset_end_out = imcb_end + margin_end;
 }
 
 bool CanComputeBlockSizeWithoutLayout(const NGBlockNode& node) {
@@ -304,58 +324,69 @@
           insets.BlockEnd()};
 }
 
-LogicalRect ComputeOutOfFlowAvailableRect(
-    const NGBlockNode& node,
-    const NGConstraintSpace& space,
-    const NGLogicalOutOfFlowInsets& insets,
-    const LogicalStaticPosition& static_position) {
-  return ComputeOutOfFlowAvailableRect(node, space.AvailableSize(), insets,
-                                       static_position);
-}
-
-LogicalRect ComputeOutOfFlowAvailableRect(
+InsetModifiedContainingBlock ComputeInsetModifiedContainingBlock(
     const NGBlockNode& node,
     const LogicalSize& available_size,
     const NGLogicalOutOfFlowInsets& insets,
-    const LogicalStaticPosition& static_position) {
-  LayoutUnit inline_offset, inline_size;
-  std::tie(inline_offset, inline_size) = ComputeAvailableSpaceInOneAxis(
-      available_size.inline_size, insets.inline_start, insets.inline_end,
-      static_position.offset.inline_offset,
-      GetStaticPositionEdge(static_position.inline_edge));
-  LayoutUnit block_offset, block_size;
-  std::tie(block_offset, block_size) = ComputeAvailableSpaceInOneAxis(
-      available_size.block_size, insets.block_start, insets.block_end,
-      static_position.offset.block_offset,
-      GetStaticPositionEdge(static_position.block_edge));
-  return LogicalRect(inline_offset, block_offset, inline_size, block_size);
+    const LogicalStaticPosition& static_position,
+    const WritingDirectionMode& container_writing_direction,
+    const WritingDirectionMode& self_writing_direction) {
+  InsetModifiedContainingBlock imcb =
+      ComputeUnclampedIMCB(available_size, insets, static_position,
+                           container_writing_direction, self_writing_direction);
+  // Clamp any negative size to 0.
+  if (imcb.InlineSize() < LayoutUnit()) {
+    ResizeIMCBInOneAxis(imcb.inline_start, imcb.inline_end,
+                        imcb.inline_inset_bias, imcb.InlineSize());
+  }
+  if (imcb.BlockSize() < LayoutUnit()) {
+    ResizeIMCBInOneAxis(imcb.block_start, imcb.block_end, imcb.block_inset_bias,
+                        imcb.BlockSize());
+  }
+  if (node.IsTable()) {
+    // Tables should not be larger than the container.
+    if (imcb.InlineSize() > available_size.inline_size) {
+      ResizeIMCBInOneAxis(imcb.inline_start, imcb.inline_end,
+                          imcb.inline_inset_bias,
+                          imcb.InlineSize() - available_size.inline_size);
+    }
+    if (imcb.BlockSize() > available_size.block_size) {
+      ResizeIMCBInOneAxis(imcb.block_start, imcb.block_end,
+                          imcb.block_inset_bias,
+                          imcb.BlockSize() - available_size.block_size);
+    }
+  }
+  return imcb;
+}
+
+InsetModifiedContainingBlock ComputeIMCBForPositionFallback(
+    const LogicalSize& available_size,
+    const NGLogicalOutOfFlowInsets& insets,
+    const LogicalStaticPosition& static_position,
+    const WritingDirectionMode& container_writing_direction,
+    const WritingDirectionMode& self_writing_direction) {
+  return ComputeUnclampedIMCB(available_size, insets, static_position,
+                              container_writing_direction,
+                              self_writing_direction);
 }
 
 bool ComputeOutOfFlowInlineDimensions(
     const NGBlockNode& node,
     const ComputedStyle& style,
     const NGConstraintSpace& space,
-    const NGLogicalOutOfFlowInsets& insets,
+    const InsetModifiedContainingBlock& imcb,
     const BoxStrut& border_padding,
-    const LogicalStaticPosition& static_position,
-    LogicalSize computed_available_size,
     const absl::optional<LogicalSize>& replaced_size,
     const WritingDirectionMode container_writing_direction,
     const Length::AnchorEvaluator* anchor_evaluator,
     NGLogicalOutOfFlowDimensions* dimensions) {
   DCHECK(dimensions);
-  bool depends_on_min_max_sizes = false;
+  DCHECK_GE(imcb.InlineSize(), LayoutUnit());
 
-  const bool is_table = node.IsTable();
+  bool depends_on_min_max_sizes = false;
   const bool can_compute_block_size_without_layout =
       CanComputeBlockSizeWithoutLayout(node);
 
-  if (is_table) {
-    computed_available_size.inline_size = std::min(
-        computed_available_size.inline_size, space.AvailableSize().inline_size);
-    DCHECK_GE(computed_available_size.inline_size, LayoutUnit());
-  }
-
   auto MinMaxSizesFunc = [&](MinMaxSizesType type) -> MinMaxSizesResult {
     DCHECK(!node.IsReplaced());
 
@@ -369,11 +400,10 @@
 
     // Compute our block-size if we haven't already.
     if (dimensions->size.block_size == kIndefiniteSize) {
-      ComputeOutOfFlowBlockDimensions(
-          node, style, space, insets, border_padding, static_position,
-          computed_available_size,
-          /* replaced_size */ absl::nullopt, container_writing_direction,
-          anchor_evaluator, dimensions);
+      ComputeOutOfFlowBlockDimensions(node, style, space, imcb, border_padding,
+                                      /* replaced_size */ absl::nullopt,
+                                      container_writing_direction,
+                                      anchor_evaluator, dimensions);
     }
 
     // Create a new space, setting the fixed block-size.
@@ -388,6 +418,9 @@
                                    builder.ToConstraintSpace());
   };
 
+  const bool has_auto_inline_inset =
+      style.LogicalInlineStart().IsAuto() || style.LogicalInlineEnd().IsAuto();
+
   LayoutUnit inline_size;
   if (replaced_size) {
     DCHECK(node.IsReplaced());
@@ -396,12 +429,11 @@
     Length main_inline_length = style.LogicalWidth();
     Length min_inline_length = style.LogicalMinWidth();
 
-    const bool stretch_inline_size = !style.LogicalInlineStart().IsAuto() &&
-                                     !style.LogicalInlineEnd().IsAuto();
+    const bool stretch_inline_size = !has_auto_inline_inset;
 
     // Determine how "auto" should resolve.
     if (main_inline_length.IsAuto()) {
-      if (is_table) {
+      if (node.IsTable()) {
         // Tables always shrink-to-fit.
         main_inline_length = Length::FitContent();
       } else if (!style.AspectRatio().IsAuto() &&
@@ -427,32 +459,38 @@
 
     LayoutUnit main_inline_size = ResolveMainInlineLength(
         space, style, border_padding, MinMaxSizesFunc, main_inline_length,
-        computed_available_size.inline_size, anchor_evaluator);
+        imcb.InlineSize(), anchor_evaluator);
     MinMaxSizes min_max_inline_sizes = ComputeMinMaxInlineSizes(
         space, node, border_padding, MinMaxSizesFunc, &min_inline_length,
-        computed_available_size.inline_size, anchor_evaluator);
+        imcb.InlineSize(), anchor_evaluator);
 
     inline_size = min_max_inline_sizes.ClampSizeToMinAndMax(main_inline_size);
   }
 
   dimensions->size.inline_size = inline_size;
 
-  // Determines if the "start" sides match.
-  const bool is_start_dominant =
+  // Determines if the "start" sides of margins match.
+  const bool is_margin_start_dominant =
       LogicalToLogical(container_writing_direction, style.GetWritingDirection(),
                        /* inline_start */ true, /* inline_end */ false,
                        /* block_start */ true, /* block_end */ false)
           .InlineStart();
 
-  ComputeInsets(
-      space.PercentageResolutionInlineSizeForParentWritingMode(),
-      space.AvailableSize().inline_size, computed_available_size.inline_size,
-      style.MarginStart(), style.MarginEnd(), insets.inline_start,
-      insets.inline_end, static_position.offset.inline_offset,
-      GetStaticPositionEdge(static_position.inline_edge), is_start_dominant,
-      false /* is_block_direction */, inline_size,
-      &dimensions->inset.inline_start, &dimensions->inset.inline_end,
-      &dimensions->margins.inline_start, &dimensions->margins.inline_end);
+  // Determines if this is the block axis in the containing block.
+  const bool is_block_direction = !IsParallelWritingMode(
+      container_writing_direction.GetWritingMode(), style.GetWritingMode());
+
+  ComputeMargins(space.PercentageResolutionInlineSizeForParentWritingMode(),
+                 imcb.InlineSize(), style.MarginStart(), style.MarginEnd(),
+                 inline_size, has_auto_inline_inset, is_margin_start_dominant,
+                 is_block_direction, &dimensions->margins.inline_start,
+                 &dimensions->margins.inline_end);
+
+  ComputeInsets(space.AvailableSize().inline_size, imcb.inline_start,
+                imcb.inline_end, imcb.inline_inset_bias,
+                dimensions->margins.inline_start,
+                dimensions->margins.inline_end, inline_size,
+                &dimensions->inset.inline_start, &dimensions->inset.inline_end);
 
   return depends_on_min_max_sizes;
 }
@@ -461,28 +499,21 @@
     const NGBlockNode& node,
     const ComputedStyle& style,
     const NGConstraintSpace& space,
-    const NGLogicalOutOfFlowInsets& insets,
+    const InsetModifiedContainingBlock& imcb,
     const BoxStrut& border_padding,
-    const LogicalStaticPosition& static_position,
-    LogicalSize computed_available_size,
     const absl::optional<LogicalSize>& replaced_size,
     const WritingDirectionMode container_writing_direction,
     const Length::AnchorEvaluator* anchor_evaluator,
     NGLogicalOutOfFlowDimensions* dimensions) {
   DCHECK(dimensions);
+  DCHECK_GE(imcb.BlockSize(), LayoutUnit());
+
+  const bool is_table = node.IsTable();
 
   const NGLayoutResult* result = nullptr;
 
-  const bool is_table = node.IsTable();
-  if (is_table) {
-    computed_available_size.block_size = std::min(
-        computed_available_size.block_size, space.AvailableSize().block_size);
-    DCHECK_GE(computed_available_size.block_size, LayoutUnit());
-  }
-
   MinMaxSizes min_max_block_sizes = ComputeMinMaxBlockSizes(
-      space, style, border_padding, computed_available_size.block_size,
-      anchor_evaluator);
+      space, style, border_padding, imcb.Size().block_size, anchor_evaluator);
 
   auto IntrinsicBlockSizeFunc = [&]() -> LayoutUnit {
     DCHECK(!node.IsReplaced());
@@ -516,6 +547,9 @@
         .BlockSize();
   };
 
+  const bool has_auto_block_inset =
+      style.LogicalTop().IsAuto() || style.LogicalBottom().IsAuto();
+
   LayoutUnit block_size;
   if (replaced_size) {
     DCHECK(node.IsReplaced());
@@ -523,8 +557,7 @@
   } else {
     Length main_block_length = style.LogicalHeight();
 
-    const bool stretch_block_size =
-        !style.LogicalTop().IsAuto() && !style.LogicalBottom().IsAuto();
+    const bool stretch_block_size = !has_auto_block_inset;
 
     // Determine how "auto" should resolve.
     if (main_block_length.IsAuto()) {
@@ -542,7 +575,7 @@
 
     LayoutUnit main_block_size = ResolveMainBlockLength(
         space, style, border_padding, main_block_length, IntrinsicBlockSizeFunc,
-        computed_available_size.block_size, anchor_evaluator);
+        imcb.BlockSize(), anchor_evaluator);
 
     // Manually resolve any intrinsic/content min/max block-sizes.
     // TODO(crbug.com/1135207): |ComputeMinMaxBlockSizes()| should handle this.
@@ -562,22 +595,28 @@
 
   dimensions->size.block_size = block_size;
 
-  // Determines if the "start" sides match.
-  const bool is_start_dominant =
+  // Determines if the "start" sides of margins match.
+  const bool is_margin_start_dominant =
       LogicalToLogical(container_writing_direction, style.GetWritingDirection(),
                        /* inline_start */ true, /* inline_end */ false,
                        /* block_start */ true, /* block_end */ false)
           .BlockStart();
 
-  ComputeInsets(
-      space.PercentageResolutionInlineSizeForParentWritingMode(),
-      space.AvailableSize().block_size, computed_available_size.block_size,
-      style.MarginBefore(), style.MarginAfter(), insets.block_start,
-      insets.block_end, static_position.offset.block_offset,
-      GetStaticPositionEdge(static_position.block_edge), is_start_dominant,
-      true /* is_block_direction */, block_size, &dimensions->inset.block_start,
-      &dimensions->inset.block_end, &dimensions->margins.block_start,
-      &dimensions->margins.block_end);
+  // Determines if this is the block axis in the containing block.
+  const bool is_block_direction = IsParallelWritingMode(
+      container_writing_direction.GetWritingMode(), style.GetWritingMode());
+
+  ComputeMargins(space.PercentageResolutionInlineSizeForParentWritingMode(),
+                 imcb.BlockSize(), style.MarginBefore(), style.MarginAfter(),
+                 block_size, has_auto_block_inset, is_margin_start_dominant,
+                 is_block_direction, &dimensions->margins.block_start,
+                 &dimensions->margins.block_end);
+
+  ComputeInsets(space.AvailableSize().block_size, imcb.block_start,
+                imcb.block_end, imcb.block_inset_bias,
+                dimensions->margins.block_start, dimensions->margins.block_end,
+                block_size, &dimensions->inset.block_start,
+                &dimensions->inset.block_end);
 
   return result;
 }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h
index e68ab8bb..2ca1fb3 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.h
@@ -52,19 +52,60 @@
                        const LogicalSize& available_size,
                        NGAnchorEvaluatorImpl* anchor_evaluator);
 
-// Computes the inset-modified containing block without the final step of
-// clamping negative sizes to zero.
+struct CORE_EXPORT InsetModifiedContainingBlock {
+  // The original containing block size that the insets refer to.
+  LogicalSize available_size;
+
+  // Resolved insets of the IMCB.
+  LayoutUnit inline_start;
+  LayoutUnit inline_end;
+  LayoutUnit block_start;
+  LayoutUnit block_end;
+
+  // Indicates how the insets were calculated. Besides, when we need to clamp
+  // the IMCB size, the stronger inset (i.e., the inset we are biased towards)
+  // stays at the same place, and the weaker inset is moved; If both insets are
+  // equally strong, both are moved by the same amount.
+  enum class InsetBias { kStart, kEnd, kEqual };
+  InsetBias inline_inset_bias = InsetBias::kStart;
+  InsetBias block_inset_bias = InsetBias::kStart;
+
+  LayoutUnit InlineEndOffset() const {
+    return available_size.inline_size - inline_end;
+  }
+  LayoutUnit BlockEndOffset() const {
+    return available_size.block_size - block_end;
+  }
+  LayoutUnit InlineSize() const {
+    return available_size.inline_size - inline_start - inline_end;
+  }
+  LayoutUnit BlockSize() const {
+    return available_size.block_size - block_start - block_end;
+  }
+  LogicalSize Size() const { return LogicalSize(InlineSize(), BlockSize()); }
+};
+
+// Computes the inset-modified containing block for resolving size, margins and
+// final position of the out-of-flow node.
 // https://www.w3.org/TR/css-position-3/#inset-modified-containing-block
-CORE_EXPORT LogicalRect
-ComputeOutOfFlowAvailableRect(const NGBlockNode&,
-                              const NGConstraintSpace&,
-                              const NGLogicalOutOfFlowInsets&,
-                              const LogicalStaticPosition&);
-CORE_EXPORT LogicalRect
-ComputeOutOfFlowAvailableRect(const NGBlockNode&,
-                              const LogicalSize& available_size,
-                              const NGLogicalOutOfFlowInsets&,
-                              const LogicalStaticPosition&);
+CORE_EXPORT InsetModifiedContainingBlock ComputeInsetModifiedContainingBlock(
+    const NGBlockNode& node,
+    const LogicalSize& available_size,
+    const NGLogicalOutOfFlowInsets&,
+    const LogicalStaticPosition&,
+    const WritingDirectionMode& container_writing_direction,
+    const WritingDirectionMode& self_writing_direction);
+
+// Similar to `ComputeInsetModifiedContainingBlock`, but returns the
+// scroll-adjusted IMCB at the initial scroll position, which is for the
+// position fallback algorithm only.
+// https://www.w3.org/TR/css-anchor-position-1/#fallback-apply
+CORE_EXPORT InsetModifiedContainingBlock ComputeIMCBForPositionFallback(
+    const LogicalSize& available_size,
+    const NGLogicalOutOfFlowInsets&,
+    const LogicalStaticPosition&,
+    const WritingDirectionMode& container_writing_direction,
+    const WritingDirectionMode& self_writing_direction);
 
 // The following routines implement the absolute size resolution algorithm.
 // https://www.w3.org/TR/css-position-3/#abs-non-replaced-width
@@ -84,10 +125,8 @@
     const NGBlockNode&,
     const ComputedStyle& style,
     const NGConstraintSpace&,
-    const NGLogicalOutOfFlowInsets&,
+    const InsetModifiedContainingBlock&,
     const BoxStrut& border_padding,
-    const LogicalStaticPosition&,
-    LogicalSize computed_available_size,
     const absl::optional<LogicalSize>& replaced_size,
     const WritingDirectionMode container_writing_direction,
     const Length::AnchorEvaluator* anchor_evaluator,
@@ -99,10 +138,8 @@
     const NGBlockNode&,
     const ComputedStyle& style,
     const NGConstraintSpace&,
-    const NGLogicalOutOfFlowInsets&,
+    const InsetModifiedContainingBlock&,
     const BoxStrut& border_padding,
-    const LogicalStaticPosition&,
-    LogicalSize computed_available_size,
     const absl::optional<LogicalSize>& replaced_size,
     const WritingDirectionMode container_writing_direction,
     const Length::AnchorEvaluator* anchor_evaluator,
diff --git a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils_test.cc b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils_test.cc
index 3aabb7f5..63db380 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils_test.cc
@@ -117,12 +117,13 @@
         PhysicalOffset());
     const NGLogicalOutOfFlowInsets insets = ComputeOutOfFlowInsets(
         node.Style(), space.AvailableSize(), &anchor_evaluator);
-    LogicalSize computed_available_size =
-        ComputeOutOfFlowAvailableRect(node, space, insets, static_position)
-            .size;
+    const InsetModifiedContainingBlock imcb =
+        ComputeInsetModifiedContainingBlock(
+            node, space.AvailableSize(), insets, static_position,
+            container_writing_direction, node.Style().GetWritingDirection());
     blink::ComputeOutOfFlowInlineDimensions(
-        node, node.Style(), space, insets, border_padding, static_position,
-        computed_available_size, absl::nullopt, container_writing_direction,
+        node, node.Style(), space, imcb, border_padding, absl::nullopt,
+        container_writing_direction,
         /* anchor_evaluator */ nullptr, dimensions);
     GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kAfterPerformLayout);
     GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kLayoutClean);
@@ -153,12 +154,13 @@
         PhysicalOffset());
     const NGLogicalOutOfFlowInsets insets = ComputeOutOfFlowInsets(
         node.Style(), space.AvailableSize(), &anchor_evaluator);
-    LogicalSize computed_available_size =
-        ComputeOutOfFlowAvailableRect(node, space, insets, static_position)
-            .size;
+    const InsetModifiedContainingBlock imcb =
+        ComputeInsetModifiedContainingBlock(
+            node, space.AvailableSize(), insets, static_position,
+            container_writing_direction, node.Style().GetWritingDirection());
     blink::ComputeOutOfFlowBlockDimensions(
-        node, node.Style(), space, insets, border_padding, static_position,
-        computed_available_size, absl::nullopt, container_writing_direction,
+        node, node.Style(), space, imcb, border_padding, absl::nullopt,
+        container_writing_direction,
         /* anchor_evaluator */ nullptr, dimensions);
     GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kAfterPerformLayout);
     GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kLayoutClean);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_anchor_query.cc b/third_party/blink/renderer/core/layout/ng/ng_anchor_query.cc
index 25412bec..5d8c224d 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_anchor_query.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_anchor_query.cc
@@ -129,7 +129,7 @@
     const NGAnchorKey& key) const {
   if (const NGPhysicalAnchorReference* reference =
           AnchorReference(query_object, key)) {
-    return reference->layout_object;
+    return reference->layout_object.Get();
   }
   return nullptr;
 }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
index c412e06..0f6e1c1 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -1149,8 +1149,7 @@
 
   // At this point, perform any final table-cell adjustments needed.
   if (ConstraintSpace().IsTableCell()) {
-    NGTableAlgorithmUtils::FinalizeTableCellLayout(intrinsic_block_size_,
-                                                   &container_builder_);
+    FinalizeTableCellLayout(intrinsic_block_size_, &container_builder_);
   }
 
   if (Style().AlignContentBlockCenter() &&
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
index a08995c..87f42c8 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
@@ -334,8 +334,7 @@
   }
 
   if (ConstraintSpace().IsTableCell()) {
-    NGTableAlgorithmUtils::FinalizeTableCellLayout(intrinsic_block_size_,
-                                                   &container_builder_);
+    FinalizeTableCellLayout(intrinsic_block_size_, &container_builder_);
   }
 
   NGOutOfFlowLayoutPart(Node(), ConstraintSpace(), &container_builder_).Run();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_spanner_path.h b/third_party/blink/renderer/core/layout/ng/ng_column_spanner_path.h
index 72ae00b0..5d7128fa 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_column_spanner_path.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_column_spanner_path.h
@@ -22,7 +22,7 @@
       : box_(block.GetLayoutBox()), child_(child) {}
 
   NGBlockNode BlockNode() const { return NGBlockNode(box_); }
-  const NGColumnSpannerPath* Child() const { return child_; }
+  const NGColumnSpannerPath* Child() const { return child_.Get(); }
 
   void Trace(Visitor* visitor) const {
     visitor->Trace(box_);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc
index a0fc4c0..5bc2474 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc
@@ -298,7 +298,7 @@
   if (!rare_data_) {
     rare_data_ = MakeGarbageCollected<RareData>();
   }
-  return rare_data_;
+  return rare_data_.Get();
 }
 
 void NGLayoutResult::CopyMutableOutOfFlowData(
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
index 7ae9f0e..a30117db 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -1854,12 +1854,10 @@
     }
   }
 
-  const LogicalRect unclamped_available_rect =
-      ComputeOutOfFlowAvailableRect(node_info.node, node_info.constraint_space,
-                                    insets, node_info.static_position);
-
-  const LogicalSize computed_available_size =
-      unclamped_available_rect.size.ClampNegativeToZero();
+  const InsetModifiedContainingBlock imcb = ComputeInsetModifiedContainingBlock(
+      node_info.node, node_info.constraint_space.AvailableSize(), insets,
+      node_info.static_position, container_writing_direction,
+      candidate_writing_direction);
 
   const BoxStrut border_padding =
       ComputeBorders(node_info.constraint_space, node_info.node) +
@@ -1868,18 +1866,17 @@
   absl::optional<LogicalSize> replaced_size;
   if (node_info.node.IsReplaced()) {
     replaced_size = ComputeReplacedSize(
-        node_info.node, node_info.constraint_space, border_padding,
-        computed_available_size, ReplacedSizeMode::kNormal, anchor_evaluator);
+        node_info.node, node_info.constraint_space, border_padding, imcb.Size(),
+        ReplacedSizeMode::kNormal, anchor_evaluator);
   }
 
   OffsetInfo offset_info;
   NGLogicalOutOfFlowDimensions& node_dimensions = offset_info.node_dimensions;
   offset_info.inline_size_depends_on_min_max_sizes =
       ComputeOutOfFlowInlineDimensions(
-          node_info.node, candidate_style, node_info.constraint_space, insets,
-          border_padding, node_info.static_position, computed_available_size,
-          replaced_size, container_writing_direction, anchor_evaluator,
-          &node_dimensions);
+          node_info.node, candidate_style, node_info.constraint_space, imcb,
+          border_padding, replaced_size, container_writing_direction,
+          anchor_evaluator, &node_dimensions);
 
   const absl::optional<LogicalRect> additional_fallback_bounds =
       try_fit_available_space
@@ -1887,15 +1884,20 @@
           : absl::nullopt;
 
   // Calculate the inline scroll offset range where the inline dimension fits.
+  absl::optional<InsetModifiedContainingBlock> imcb_for_position_fallback;
   absl::optional<LayoutUnit> inline_scroll_min;
   absl::optional<LayoutUnit> inline_scroll_max;
   absl::optional<LayoutUnit> additional_inline_scroll_min;
   absl::optional<LayoutUnit> additional_inline_scroll_max;
   if (try_fit_available_space) {
+    imcb_for_position_fallback = ComputeIMCBForPositionFallback(
+        node_info.constraint_space.AvailableSize(), insets,
+        node_info.static_position, container_writing_direction,
+        candidate_writing_direction);
     if (!CalculateNonOverflowingRangeInOneAxis(
             insets.inline_start, insets.inline_end,
-            unclamped_available_rect.offset.inline_offset,
-            unclamped_available_rect.InlineEndOffset(),
+            imcb_for_position_fallback->inline_start,
+            imcb_for_position_fallback->InlineEndOffset(),
             node_dimensions.MarginBoxInlineStart(),
             node_dimensions.MarginBoxInlineEnd(),
             additional_fallback_bounds.has_value()
@@ -1916,10 +1918,9 @@
   // our min/max sizes, only run if needed.
   if (node_dimensions.size.block_size == kIndefiniteSize) {
     offset_info.initial_layout_result = ComputeOutOfFlowBlockDimensions(
-        node_info.node, candidate_style, node_info.constraint_space, insets,
-        border_padding, node_info.static_position, computed_available_size,
-        replaced_size, container_writing_direction, anchor_evaluator,
-        &node_dimensions);
+        node_info.node, candidate_style, node_info.constraint_space, imcb,
+        border_padding, replaced_size, container_writing_direction,
+        anchor_evaluator, &node_dimensions);
   }
 
   // Calculate the block scroll offset range where the block dimension fits.
@@ -1930,8 +1931,8 @@
   if (try_fit_available_space) {
     if (!CalculateNonOverflowingRangeInOneAxis(
             insets.block_start, insets.block_end,
-            unclamped_available_rect.offset.block_offset,
-            unclamped_available_rect.BlockEndOffset(),
+            imcb_for_position_fallback->block_start,
+            imcb_for_position_fallback->BlockEndOffset(),
             node_dimensions.MarginBoxBlockStart(),
             node_dimensions.MarginBoxBlockEnd(),
             additional_fallback_bounds.has_value()
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
index ba88386..8bebcfb 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h
@@ -166,7 +166,7 @@
   }
 
   const NGTableFragmentData::ColumnGeometries* TableColumnGeometries() const {
-    return rare_data_->table_column_geometries_;
+    return rare_data_->table_column_geometries_.Get();
   }
 
   const NGTableBorders* TableCollapsedBorders() const {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
index e8e2b62..0d79a6d 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h
@@ -452,12 +452,12 @@
   // returns |nullptr| for the historical reasons. TODO(kojii): We may change
   // this in future. Use |IsLineBox()| instead of testing this is |nullptr|.
   const LayoutObject* GetLayoutObject() const {
-    return IsCSSBox() ? layout_object_ : nullptr;
+    return IsCSSBox() ? layout_object_.Get() : nullptr;
   }
   // TODO(kojii): We should not have mutable version at all, the use of this
   // function should be eliminiated over time.
   LayoutObject* GetMutableLayoutObject() const {
-    return IsCSSBox() ? layout_object_ : nullptr;
+    return IsCSSBox() ? layout_object_.Get() : nullptr;
   }
   // Similar to |GetLayoutObject|, but returns the |LayoutObject| of its
   // container for |!IsCSSBox()| fragments instead of |nullptr|.
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc
index 3a0a1bb..6e3d1b9 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc
@@ -128,9 +128,8 @@
       table.Style().GetWritingDirection();
 
   wtf_size_t box_order = 0;
-  wtf_size_t table_column_count =
-      NGTableAlgorithmUtils::ComputeMaximumNonMergeableColumnCount(
-          grouped_children.columns, table.Style().IsFixedTableLayout());
+  wtf_size_t table_column_count = ComputeMaximumNonMergeableColumnCount(
+      grouped_children.columns, table.Style().IsFixedTableLayout());
   wtf_size_t table_row_index = 0;
   // Mark cell borders.
   bool found_multispan_cells = false;
@@ -149,10 +148,10 @@
         // Rowspan has to be limited by section size. Since we do not know
         // section size, we have to rerun cell distribution with limited
         // rowspans.
-        table_column_count = std::max(
-            table_column_count, NGTableAlgorithmHelpers::ComputeMaxColumn(
-                                    tabulator.CurrentColumn(), cell_colspan,
-                                    table.Style().IsFixedTableLayout()));
+        table_column_count =
+            std::max(table_column_count,
+                     ComputeMaxColumn(tabulator.CurrentColumn(), cell_colspan,
+                                      table.Style().IsFixedTableLayout()));
         if (!found_multispan_cells) {
           table_borders->MergeBorders(
               table_row_index, tabulator.CurrentColumn(),
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
index 505468d..b4acd50 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm.cc
@@ -233,10 +233,9 @@
         .ClampNegativeToZero();
   }
 
-  const MinMaxSizes grid_min_max =
-      NGTableAlgorithmHelpers::ComputeGridInlineMinMax(
-          table, column_constraints, undistributable_space, is_fixed_layout,
-          /* is_layout_pass */ true);
+  const MinMaxSizes grid_min_max = ComputeGridInlineMinMax(
+      table, column_constraints, undistributable_space, is_fixed_layout,
+      /* is_layout_pass */ true);
 
   // Standard: "used width of the table".
   LayoutUnit used_table_inline_size = ComputeUsedInlineSizeForTableFragment(
@@ -338,9 +337,8 @@
            cell_index < row.start_cell_index + row.cell_count; ++cell_index) {
         const auto& cell_block_constraint = cell_block_constraints[cell_index];
         const auto [cell_block_size, is_initial_block_size_indefinite] =
-            NGTableAlgorithmUtils::ComputeCellBlockSize(
-                cell_block_constraint, rows, row_index, border_spacing,
-                is_table_block_size_specified);
+            ComputeCellBlockSize(cell_block_constraint, rows, row_index,
+                                 border_spacing, is_table_block_size_specified);
 
         LayoutUnit rowspan_block_size =
             cell_block_constraint.effective_rowspan > 1 ? cell_block_size
@@ -553,7 +551,7 @@
   }
 
   const Vector<LayoutUnit> column_sizes =
-      NGTableAlgorithmHelpers::SynchronizeAssignableTableInlineSizeAndColumns(
+      SynchronizeAssignableTableInlineSizeAndColumns(
           assignable_table_inline_size, is_fixed_layout, *column_constraints);
 
   // Final inline size must depend on column locations, because columns can be
@@ -607,7 +605,7 @@
 
   // Distribute assignable table width.
   const Vector<LayoutUnit> column_sizes =
-      NGTableAlgorithmHelpers::SynchronizeAssignableTableInlineSizeAndColumns(
+      SynchronizeAssignableTableInlineSizeAndColumns(
           assignable_table_inline_size, is_fixed_layout, *column_constraints);
 
   Vector<NGTableColumnLocation> column_locations;
@@ -721,10 +719,9 @@
       *column_constraints, border_padding.InlineSum(),
       border_spacing.inline_size);
 
-  const MinMaxSizes grid_min_max =
-      NGTableAlgorithmHelpers::ComputeGridInlineMinMax(
-          Node(), *column_constraints, undistributable_space, is_fixed_layout,
-          /* is_layout_pass */ false);
+  const MinMaxSizes grid_min_max = ComputeGridInlineMinMax(
+      Node(), *column_constraints, undistributable_space, is_fixed_layout,
+      /* is_layout_pass */ false);
 
   MinMaxSizes min_max{
       std::max(grid_min_max.min_size, caption_constraint.min_size),
@@ -788,7 +785,7 @@
     wtf_size_t section_index = 0;
     for (auto it = grouped_children.begin(); it != grouped_children.end();
          ++it) {
-      NGTableAlgorithmUtils::ComputeSectionMinimumRowBlockSizes(
+      ComputeSectionMinimumRowBlockSizes(
           *it, table_grid_inline_size, is_table_block_size_specified,
           column_locations, table_borders, border_spacing.block_size,
           section_index++, it.TreatAsTBody(), sections, rows,
@@ -834,7 +831,7 @@
     LayoutUnit distributable_block_size = std::max(
         LayoutUnit(), css_table_block_size - table_border_padding.BlockSum());
     if (distributable_block_size > total_table_min_block_size_) {
-      NGTableAlgorithmHelpers::DistributeTableBlockSizeToSections(
+      DistributeTableBlockSizeToSections(
           border_spacing.block_size, distributable_block_size, sections, rows);
     }
   }
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc
index da06ae8..b397fef 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.cc
@@ -877,7 +877,7 @@
 
 }  // namespace
 
-MinMaxSizes NGTableAlgorithmHelpers::ComputeGridInlineMinMax(
+MinMaxSizes ComputeGridInlineMinMax(
     const NGTableNode& node,
     const NGTableTypes::Columns& column_constraints,
     LayoutUnit undistributable_space,
@@ -958,7 +958,7 @@
   return min_max;
 }
 
-void NGTableAlgorithmHelpers::DistributeColspanCellsToColumns(
+void DistributeColspanCellsToColumns(
     const NGTableTypes::ColspanCells& colspan_cells,
     LayoutUnit inline_border_spacing,
     bool is_fixed_layout,
@@ -981,8 +981,7 @@
 // Standard: https://www.w3.org/TR/css-tables-3/#width-distribution-algorithm
 // After synchroniziation, assignable table inline size and sum of column
 // final inline sizes will be equal.
-Vector<LayoutUnit>
-NGTableAlgorithmHelpers::SynchronizeAssignableTableInlineSizeAndColumns(
+Vector<LayoutUnit> SynchronizeAssignableTableInlineSizeAndColumns(
     LayoutUnit assignable_table_inline_size,
     bool is_fixed_layout,
     const NGTableTypes::Columns& column_constraints) {
@@ -1001,10 +1000,9 @@
   }
 }
 
-void NGTableAlgorithmHelpers::DistributeRowspanCellToRows(
-    const NGTableTypes::RowspanCell& rowspan_cell,
-    LayoutUnit border_block_spacing,
-    NGTableTypes::Rows* rows) {
+void DistributeRowspanCellToRows(const NGTableTypes::RowspanCell& rowspan_cell,
+                                 LayoutUnit border_block_spacing,
+                                 NGTableTypes::Rows* rows) {
   DCHECK_GT(rowspan_cell.effective_rowspan, 1u);
   DistributeExcessBlockSizeToRows(rowspan_cell.start_row,
                                   rowspan_cell.effective_rowspan,
@@ -1014,7 +1012,7 @@
 }
 
 // Legacy code ignores section block size.
-void NGTableAlgorithmHelpers::DistributeSectionFixedBlockSizeToRows(
+void DistributeSectionFixedBlockSizeToRows(
     const wtf_size_t start_row,
     const wtf_size_t rowspan,
     LayoutUnit section_fixed_block_size,
@@ -1027,11 +1025,10 @@
                                   percentage_resolution_block_size, rows);
 }
 
-void NGTableAlgorithmHelpers::DistributeTableBlockSizeToSections(
-    LayoutUnit border_block_spacing,
-    LayoutUnit table_block_size,
-    NGTableTypes::Sections* sections,
-    NGTableTypes::Rows* rows) {
+void DistributeTableBlockSizeToSections(LayoutUnit border_block_spacing,
+                                        LayoutUnit table_block_size,
+                                        NGTableTypes::Sections* sections,
+                                        NGTableTypes::Rows* rows) {
   if (sections->empty())
     return;
 
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h
index 791c20f..b60f2be 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h
@@ -14,58 +14,57 @@
 class NGTableNode;
 
 // Table size distribution algorithms.
-class CORE_EXPORT NGTableAlgorithmHelpers {
- public:
-  // Compute maximum number of table columns that can deduced from single cell
-  // and its colspan.
-  static wtf_size_t ComputeMaxColumn(wtf_size_t current_column,
-                                     wtf_size_t colspan,
-                                     bool is_fixed_table_layout) {
-    // In fixed mode, every column is preserved.
-    if (is_fixed_table_layout)
-      return current_column + colspan;
-    return current_column + 1;
+
+// Compute maximum number of table columns that can deduced from single cell
+// and its colspan.
+constexpr wtf_size_t ComputeMaxColumn(wtf_size_t current_column,
+                                      wtf_size_t colspan,
+                                      bool is_fixed_table_layout) {
+  // In fixed mode, every column is preserved.
+  if (is_fixed_table_layout) {
+    return current_column + colspan;
   }
+  return current_column + 1;
+}
 
-  // |undistributable_space| is size of space not occupied by cells
-  // (borders, border spacing).
-  static MinMaxSizes ComputeGridInlineMinMax(
-      const NGTableNode& node,
-      const NGTableTypes::Columns& column_constraints,
-      LayoutUnit undistributable_space,
-      bool is_fixed_layout,
-      bool is_layout_pass);
+// |undistributable_space| is size of space not occupied by cells
+// (borders, border spacing).
+CORE_EXPORT MinMaxSizes
+ComputeGridInlineMinMax(const NGTableNode& node,
+                        const NGTableTypes::Columns& column_constraints,
+                        LayoutUnit undistributable_space,
+                        bool is_fixed_layout,
+                        bool is_layout_pass);
 
-  static void DistributeColspanCellsToColumns(
-      const NGTableTypes::ColspanCells& colspan_cells,
-      LayoutUnit inline_border_spacing,
-      bool is_fixed_layout,
-      NGTableTypes::Columns* column_constraints);
+CORE_EXPORT void DistributeColspanCellsToColumns(
+    const NGTableTypes::ColspanCells& colspan_cells,
+    LayoutUnit inline_border_spacing,
+    bool is_fixed_layout,
+    NGTableTypes::Columns* column_constraints);
 
-  static Vector<LayoutUnit> SynchronizeAssignableTableInlineSizeAndColumns(
-      LayoutUnit assignable_table_inline_size,
-      bool is_fixed_layout,
-      const NGTableTypes::Columns& column_constraints);
+CORE_EXPORT Vector<LayoutUnit> SynchronizeAssignableTableInlineSizeAndColumns(
+    LayoutUnit assignable_table_inline_size,
+    bool is_fixed_layout,
+    const NGTableTypes::Columns& column_constraints);
 
-  static void DistributeRowspanCellToRows(
-      const NGTableTypes::RowspanCell& rowspan_cell,
-      LayoutUnit border_block_spacing,
-      NGTableTypes::Rows* rows);
+CORE_EXPORT void DistributeRowspanCellToRows(
+    const NGTableTypes::RowspanCell& rowspan_cell,
+    LayoutUnit border_block_spacing,
+    NGTableTypes::Rows* rows);
 
-  static void DistributeSectionFixedBlockSizeToRows(
-      const wtf_size_t start_row,
-      const wtf_size_t end_row,
-      LayoutUnit section_fixed_block_size,
-      LayoutUnit border_block_spacing,
-      LayoutUnit percentage_resolution_block_size,
-      NGTableTypes::Rows* rows);
+CORE_EXPORT void DistributeSectionFixedBlockSizeToRows(
+    const wtf_size_t start_row,
+    const wtf_size_t end_row,
+    LayoutUnit section_fixed_block_size,
+    LayoutUnit border_block_spacing,
+    LayoutUnit percentage_resolution_block_size,
+    NGTableTypes::Rows* rows);
 
-  static void DistributeTableBlockSizeToSections(
-      LayoutUnit border_block_spacing,
-      LayoutUnit table_block_size,
-      NGTableTypes::Sections* sections,
-      NGTableTypes::Rows* rows);
-};
+CORE_EXPORT void DistributeTableBlockSizeToSections(
+    LayoutUnit border_block_spacing,
+    LayoutUnit table_block_size,
+    NGTableTypes::Sections* sections,
+    NGTableTypes::Rows* rows);
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers_test.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers_test.cc
index b85ada2..4b1072c 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers_test.cc
@@ -71,8 +71,8 @@
   column_constraints->data.push_back(MakeColumn(0, 10));
   column_constraints->data.push_back(MakeColumn(0, 20));
   column_constraints->data.push_back(MakeColumn(0, 10, 30));
-  NGTableAlgorithmHelpers::DistributeColspanCellsToColumns(
-      colspan_cells, LayoutUnit(), false, column_constraints.get());
+  DistributeColspanCellsToColumns(colspan_cells, LayoutUnit(), false,
+                                  column_constraints.get());
   EXPECT_EQ(column_constraints->data[0].percent, 10);
   EXPECT_EQ(column_constraints->data[1].percent, 20);
 
@@ -83,8 +83,8 @@
   column_constraints->data.push_back(MakeColumn(0, 0));
   column_constraints->data.push_back(MakeColumn(0, 0));
   column_constraints->data.push_back(MakeColumn(0, 10, 10));
-  NGTableAlgorithmHelpers::DistributeColspanCellsToColumns(
-      colspan_cells, LayoutUnit(), false, column_constraints.get());
+  DistributeColspanCellsToColumns(colspan_cells, LayoutUnit(), false,
+                                  column_constraints.get());
   EXPECT_EQ(column_constraints->data[0].percent, 25);
   EXPECT_EQ(column_constraints->data[1].percent, 25);
 }
@@ -110,8 +110,8 @@
   column_constraints->data.push_back(MakeColumn(0, 10));
   column_constraints->data.push_back(MakeColumn(0, 10));
   column_constraints->data.push_back(MakeColumn(0, 20));
-  NGTableAlgorithmHelpers::DistributeColspanCellsToColumns(
-      colspan_cells, LayoutUnit(), false, column_constraints.get());
+  DistributeColspanCellsToColumns(colspan_cells, LayoutUnit(), false,
+                                  column_constraints.get());
   EXPECT_EQ(column_constraints->data[0].min_inline_size, 25);
   EXPECT_EQ(column_constraints->data[1].min_inline_size, 25);
   EXPECT_EQ(column_constraints->data[2].min_inline_size, 50);
@@ -138,8 +138,8 @@
   column_constraints->data.push_back(MakeColumn(0, 10, absl::nullopt, true));
   column_constraints->data.push_back(MakeColumn(10, 10, absl::nullopt, true));
   column_constraints->data.push_back(MakeColumn(0, 20, absl::nullopt, true));
-  NGTableAlgorithmHelpers::DistributeColspanCellsToColumns(
-      colspan_cells, LayoutUnit(), false, column_constraints.get());
+  DistributeColspanCellsToColumns(colspan_cells, LayoutUnit(), false,
+                                  column_constraints.get());
   EXPECT_EQ(column_constraints->data[0].min_inline_size, 25);
   EXPECT_EQ(column_constraints->data[1].min_inline_size, 25);
   EXPECT_EQ(column_constraints->data[2].min_inline_size, 50);
@@ -171,7 +171,7 @@
   LayoutUnit assignable_table_inline_size =
       column_widths[0] + column_widths[1] + column_widths[2] + column_widths[3];
   Vector<LayoutUnit> column_sizes =
-      NGTableAlgorithmHelpers::SynchronizeAssignableTableInlineSizeAndColumns(
+      SynchronizeAssignableTableInlineSizeAndColumns(
           assignable_table_inline_size, false, *column_constraints);
   EXPECT_EQ(column_sizes[0], column_widths[0]);
   EXPECT_EQ(column_sizes[1], column_widths[1]);
@@ -199,9 +199,9 @@
   column_constraints->data.push_back(MakeColumn(20, 200));
   column_constraints->data.push_back(MakeColumn(30, 300));
 
-  MinMaxSizes minmax = NGTableAlgorithmHelpers::ComputeGridInlineMinMax(
-      node, *column_constraints, undistributable_space, is_fixed_layout,
-      is_layout_pass);
+  MinMaxSizes minmax =
+      ComputeGridInlineMinMax(node, *column_constraints, undistributable_space,
+                              is_fixed_layout, is_layout_pass);
   EXPECT_EQ(minmax.min_size, LayoutUnit(60));
   EXPECT_EQ(minmax.max_size, LayoutUnit(600));
 
@@ -211,16 +211,16 @@
   column_constraints->data.push_back(MakeColumn(10, 99, 10));
   column_constraints->data.push_back(MakeColumn(10, 10));
   column_constraints->data.push_back(MakeColumn(10, 10));
-  minmax = NGTableAlgorithmHelpers::ComputeGridInlineMinMax(
-      node, *column_constraints, undistributable_space, is_fixed_layout,
-      is_layout_pass);
+  minmax =
+      ComputeGridInlineMinMax(node, *column_constraints, undistributable_space,
+                              is_fixed_layout, is_layout_pass);
   EXPECT_EQ(minmax.min_size, LayoutUnit(30));
   EXPECT_EQ(minmax.max_size, LayoutUnit(990));
 
   is_layout_pass = false;
-  minmax = NGTableAlgorithmHelpers::ComputeGridInlineMinMax(
-      node, *column_constraints, undistributable_space, is_fixed_layout,
-      is_layout_pass);
+  minmax =
+      ComputeGridInlineMinMax(node, *column_constraints, undistributable_space,
+                              is_fixed_layout, is_layout_pass);
   EXPECT_EQ(minmax.min_size, LayoutUnit(30));
   EXPECT_EQ(minmax.max_size, LayoutUnit(119));
 
@@ -231,9 +231,9 @@
   column_constraints->data.push_back(MakeColumn(10, 100, 10));
   column_constraints->data.push_back(MakeColumn(10, 10, 10));
   column_constraints->data.push_back(MakeColumn(10, 800));
-  minmax = NGTableAlgorithmHelpers::ComputeGridInlineMinMax(
-      node, *column_constraints, undistributable_space, is_fixed_layout,
-      is_layout_pass);
+  minmax =
+      ComputeGridInlineMinMax(node, *column_constraints, undistributable_space,
+                              is_fixed_layout, is_layout_pass);
   EXPECT_EQ(minmax.min_size, LayoutUnit(30));
   EXPECT_EQ(minmax.max_size, LayoutUnit(1000));
 }
@@ -246,8 +246,7 @@
   rows.push_back(MakeRow(10));
   rows.push_back(MakeRow(20));
   rows.push_back(MakeRow(30));
-  NGTableAlgorithmHelpers::DistributeRowspanCellToRows(rowspan_cell,
-                                                       LayoutUnit(), &rows);
+  DistributeRowspanCellToRows(rowspan_cell, LayoutUnit(), &rows);
   EXPECT_EQ(rows[0].block_size, LayoutUnit(50));
   EXPECT_EQ(rows[1].block_size, LayoutUnit(100));
   EXPECT_EQ(rows[2].block_size, LayoutUnit(150));
@@ -257,8 +256,7 @@
   rows.push_back(MakeRow(0));
   rows.push_back(MakeRow(10));
   rows.push_back(MakeRow(0));
-  NGTableAlgorithmHelpers::DistributeRowspanCellToRows(rowspan_cell,
-                                                       LayoutUnit(), &rows);
+  DistributeRowspanCellToRows(rowspan_cell, LayoutUnit(), &rows);
   EXPECT_EQ(rows[0].block_size, LayoutUnit(0));
   EXPECT_EQ(rows[1].block_size, LayoutUnit(300));
   EXPECT_EQ(rows[2].block_size, LayoutUnit(0));
@@ -268,8 +266,7 @@
   rows.push_back(MakeRow(0));
   rows.push_back(MakeRow(0));
   rows.push_back(MakeRow(0));
-  NGTableAlgorithmHelpers::DistributeRowspanCellToRows(rowspan_cell,
-                                                       LayoutUnit(), &rows);
+  DistributeRowspanCellToRows(rowspan_cell, LayoutUnit(), &rows);
   EXPECT_EQ(rows[0].block_size, LayoutUnit(0));
   EXPECT_EQ(rows[1].block_size, LayoutUnit(0));
   EXPECT_EQ(rows[2].block_size, LayoutUnit(300));
@@ -282,8 +279,8 @@
   rows.push_back(MakeRow(100));
   rows.push_back(MakeRow(100, true, false, 50));
   rows.push_back(MakeRow(100));
-  NGTableAlgorithmHelpers::DistributeSectionFixedBlockSizeToRows(
-      0, 3, LayoutUnit(1000), LayoutUnit(), LayoutUnit(1000), &rows);
+  DistributeSectionFixedBlockSizeToRows(0, 3, LayoutUnit(1000), LayoutUnit(),
+                                        LayoutUnit(1000), &rows);
   EXPECT_EQ(rows[0].block_size, LayoutUnit(250));
   EXPECT_EQ(rows[1].block_size, LayoutUnit(500));
   EXPECT_EQ(rows[2].block_size, LayoutUnit(250));
@@ -296,8 +293,8 @@
   // Empty sections only grow if there are no other growable sections.
   sections.push_back(MakeSection(&rows, 0));
   sections.push_back(MakeSection(&rows, 100));
-  NGTableAlgorithmHelpers::DistributeTableBlockSizeToSections(
-      LayoutUnit(), LayoutUnit(500), &sections, &rows);
+  DistributeTableBlockSizeToSections(LayoutUnit(), LayoutUnit(500), &sections,
+                                     &rows);
   EXPECT_EQ(sections[0].block_size, LayoutUnit(400));
 
   // Sections with % block size grow to percentage.
@@ -305,8 +302,8 @@
   rows.Shrink(0);
   sections.push_back(MakeSection(&rows, 100, 1, 90));
   sections.push_back(MakeSection(&rows, 100));
-  NGTableAlgorithmHelpers::DistributeTableBlockSizeToSections(
-      LayoutUnit(), LayoutUnit(1000), &sections, &rows);
+  DistributeTableBlockSizeToSections(LayoutUnit(), LayoutUnit(1000), &sections,
+                                     &rows);
   EXPECT_EQ(sections[0].block_size, LayoutUnit(900));
   EXPECT_EQ(sections[1].block_size, LayoutUnit(100));
 
@@ -320,8 +317,8 @@
   // 30% section grows to 300px.
   // Extra 600 px is distributed between 300 and 100 px proportionally.
   // TODO(atotic) Is this what we want? FF/Edge/Legacy all disagree.
-  NGTableAlgorithmHelpers::DistributeTableBlockSizeToSections(
-      LayoutUnit(), LayoutUnit(1000), &sections, &rows);
+  DistributeTableBlockSizeToSections(LayoutUnit(), LayoutUnit(1000), &sections,
+                                     &rows);
   EXPECT_EQ(sections[0].block_size, LayoutUnit(300));
   EXPECT_EQ(sections[1].block_size, LayoutUnit(700));
 
@@ -333,8 +330,8 @@
   section.is_constrained = false;
   sections.push_back(section);
   sections.push_back(MakeSection(&rows, 100));
-  NGTableAlgorithmHelpers::DistributeTableBlockSizeToSections(
-      LayoutUnit(), LayoutUnit(1000), &sections, &rows);
+  DistributeTableBlockSizeToSections(LayoutUnit(), LayoutUnit(1000), &sections,
+                                     &rows);
   EXPECT_EQ(sections[0].block_size, LayoutUnit(900));
   EXPECT_EQ(sections[1].block_size, LayoutUnit(100));
 }
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.cc
index 636a9e45..757fc5e2 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.cc
@@ -138,9 +138,9 @@
   std::stable_sort(colspan_cell_constraints->begin(),
                    colspan_cell_constraints->end(), colspan_cell_less_than);
 
-  NGTableAlgorithmHelpers::DistributeColspanCellsToColumns(
-      *colspan_cell_constraints, inline_border_spacing, is_fixed_layout,
-      column_constraints);
+  DistributeColspanCellsToColumns(*colspan_cell_constraints,
+                                  inline_border_spacing, is_fixed_layout,
+                                  column_constraints);
 
   // Column total percentage inline-size is clamped to 100%.
   // Auto tables: max(0, 100% minus the sum of percentages of all
@@ -221,7 +221,7 @@
         /* is_new_fc */ true);
 
     // We want these values to match the "layout" pass as close as possible.
-    NGTableAlgorithmUtils::SetupTableCellConstraintSpaceBuilder(
+    SetupTableCellConstraintSpaceBuilder(
         table_writing_direction, cell, cell_borders, column_locations,
         /* cell_block_size */ kIndefiniteSize, cell_percentage_inline_size,
         /* alignment_baseline */ absl::nullopt,
@@ -258,8 +258,7 @@
     is_constrained |=
         cell_block_constraint.is_constrained && !has_effective_rowspan;
     row_baseline_tabulator.ProcessCell(
-        fragment, NGTableAlgorithmUtils::IsBaseline(cell_style.VerticalAlign()),
-        has_effective_rowspan,
+        fragment, cell_style.VerticalAlign(), has_effective_rowspan,
         has_descendant_that_depends_on_percentage_block_size);
 
     // Compute cell's css block size.
@@ -422,7 +421,7 @@
       bool ignore_because_of_fixed_layout =
           is_fixed_layout && (!is_first_section || !is_first_row);
 
-      wtf_size_t max_column = NGTableAlgorithmHelpers::ComputeMaxColumn(
+      wtf_size_t max_column = ComputeMaxColumn(
           colspan_cell_tabulator.CurrentColumn(), colspan, is_fixed_layout);
       if (max_column >= cell_inline_constraints->size())
         cell_inline_constraints->Grow(max_column);
@@ -459,11 +458,18 @@
   }
 }
 
+bool IsBaseline(EVerticalAlign align) {
+  return align == EVerticalAlign::kBaseline ||
+         align == EVerticalAlign::kBaselineMiddle ||
+         align == EVerticalAlign::kSub || align == EVerticalAlign::kSuper ||
+         align == EVerticalAlign::kTextTop ||
+         align == EVerticalAlign::kTextBottom ||
+         align == EVerticalAlign::kLength;
+}
+
 }  // namespace
 
-// static
-NGTableAlgorithmUtils::CellBlockSizeData
-NGTableAlgorithmUtils::ComputeCellBlockSize(
+CellBlockSizeData ComputeCellBlockSize(
     const NGTableTypes::CellBlockConstraint& cell_block_constraint,
     const NGTableTypes::Rows& rows,
     wtf_size_t row_index,
@@ -493,8 +499,7 @@
   return {cell_block_size, !is_initial_block_size_definite};
 }
 
-// static
-void NGTableAlgorithmUtils::SetupTableCellConstraintSpaceBuilder(
+void SetupTableCellConstraintSpaceBuilder(
     const WritingDirectionMode table_writing_direction,
     const NGBlockNode cell,
     const BoxStrut& cell_borders,
@@ -559,7 +564,7 @@
 }
 
 // Computes maximum possible number of non-mergeable columns.
-wtf_size_t NGTableAlgorithmUtils::ComputeMaximumNonMergeableColumnCount(
+wtf_size_t ComputeMaximumNonMergeableColumnCount(
     const HeapVector<NGBlockNode>& columns,
     bool is_fixed_layout) {
   // Build column constraints.
@@ -581,8 +586,7 @@
   return column_index + 1;
 }
 
-scoped_refptr<NGTableTypes::Columns>
-NGTableAlgorithmUtils::ComputeColumnConstraints(
+scoped_refptr<NGTableTypes::Columns> ComputeColumnConstraints(
     const NGBlockNode& table,
     const NGTableGroupedChildren& grouped_children,
     const NGTableBorders& table_borders,
@@ -619,7 +623,7 @@
   return column_constraints;
 }
 
-void NGTableAlgorithmUtils::ComputeSectionMinimumRowBlockSizes(
+void ComputeSectionMinimumRowBlockSizes(
     const NGBlockNode& section,
     const LayoutUnit cell_percentage_inline_size,
     const bool is_table_block_size_specified,
@@ -679,8 +683,7 @@
   // Redistribute rowspanned cell block sizes.
   std::stable_sort(rowspan_cells.begin(), rowspan_cells.end());
   for (const auto& rowspan_cell : rowspan_cells) {
-    NGTableAlgorithmHelpers::DistributeRowspanCellToRows(
-        rowspan_cell, block_border_spacing, rows);
+    DistributeRowspanCellToRows(rowspan_cell, block_border_spacing, rows);
   }
 
   const wtf_size_t block_spacing_count =
@@ -697,7 +700,7 @@
     LayoutUnit section_fixed_block_size =
         LayoutUnit(section_specified_block_length.Value());
     if (section_fixed_block_size > section_block_size) {
-      NGTableAlgorithmHelpers::DistributeSectionFixedBlockSizeToRows(
+      DistributeSectionFixedBlockSizeToRows(
           start_row, current_row - start_row, section_fixed_block_size,
           block_border_spacing, section_fixed_block_size, rows);
       section_block_size = section_fixed_block_size;
@@ -708,9 +711,8 @@
                                   section_block_size, treat_section_as_tbody));
 }
 
-void NGTableAlgorithmUtils::FinalizeTableCellLayout(
-    LayoutUnit unconstrained_intrinsic_block_size,
-    NGBoxFragmentBuilder* builder) {
+void FinalizeTableCellLayout(LayoutUnit unconstrained_intrinsic_block_size,
+                             NGBoxFragmentBuilder* builder) {
   const NGBlockNode& node = builder->Node();
   const NGConstraintSpace& space = builder->ConstraintSpace();
   const bool has_inflow_children = !builder->Children().empty();
@@ -812,10 +814,10 @@
 
 void NGRowBaselineTabulator::ProcessCell(
     const NGBoxFragment& fragment,
-    const bool is_baseline_aligned,
+    EVerticalAlign align,
     const bool is_rowspanned,
     const bool descendant_depends_on_percentage_block_size) {
-  if (is_baseline_aligned && fragment.HasDescendantsForTablePart() &&
+  if (IsBaseline(align) && fragment.HasDescendantsForTablePart() &&
       fragment.FirstBaseline()) {
     max_cell_baseline_depends_on_percentage_block_descendant_ |=
         descendant_depends_on_percentage_block_size;
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.h
index d03a02c..d4a2103 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.h
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.h
@@ -20,77 +20,65 @@
 struct NGTableColumnLocation;
 
 // Table size distribution algorithms.
-class NGTableAlgorithmUtils {
- public:
-  static bool IsBaseline(EVerticalAlign align) {
-    return align == EVerticalAlign::kBaseline ||
-           align == EVerticalAlign::kBaselineMiddle ||
-           align == EVerticalAlign::kSub || align == EVerticalAlign::kSuper ||
-           align == EVerticalAlign::kTextTop ||
-           align == EVerticalAlign::kTextBottom ||
-           align == EVerticalAlign::kLength;
-  }
 
-  // Computes a cell's block-size, and if its initial block-size should be
-  // considered indefinite.
-  struct CellBlockSizeData {
-    LayoutUnit block_size;
-    bool is_initial_block_size_indefinite;
-  };
-  static CellBlockSizeData ComputeCellBlockSize(
-      const NGTableTypes::CellBlockConstraint& cell_block_constraint,
-      const NGTableTypes::Rows& rows,
-      wtf_size_t row_index,
-      const LogicalSize& border_spacing,
-      bool is_table_block_size_specified);
-
-  // Sets up a constraint space builder for a table-cell.
-  //
-  // In order to make the cache as effective as possible, we try and keep
-  // creating the constraint-space for table-cells as consistent as possible.
-  static void SetupTableCellConstraintSpaceBuilder(
-      const WritingDirectionMode table_writing_direction,
-      const NGBlockNode cell,
-      const BoxStrut& cell_borders,
-      const Vector<NGTableColumnLocation>& column_locations,
-      LayoutUnit cell_block_size,
-      LayoutUnit percentage_inline_size,
-      absl::optional<LayoutUnit> alignment_baseline,
-      wtf_size_t start_column,
-      bool is_initial_block_size_indefinite,
-      bool is_restricted_block_size_table,
-      bool has_collapsed_borders,
-      NGCacheSlot,
-      NGConstraintSpaceBuilder*);
-
-  static wtf_size_t ComputeMaximumNonMergeableColumnCount(
-      const HeapVector<NGBlockNode>& columns,
-      bool is_fixed_layout);
-
-  static scoped_refptr<NGTableTypes::Columns> ComputeColumnConstraints(
-      const NGBlockNode& table,
-      const NGTableGroupedChildren&,
-      const NGTableBorders& table_borders,
-      const BoxStrut& border_padding);
-
-  static void ComputeSectionMinimumRowBlockSizes(
-      const NGBlockNode& section,
-      const LayoutUnit cell_percentage_resolution_inline_size,
-      const bool is_table_block_size_specified,
-      const Vector<NGTableColumnLocation>& column_locations,
-      const NGTableBorders& table_borders,
-      const LayoutUnit block_border_spacing,
-      wtf_size_t section_index,
-      bool treat_section_as_tbody,
-      NGTableTypes::Sections* sections,
-      NGTableTypes::Rows* rows,
-      NGTableTypes::CellBlockConstraints* cell_block_constraints);
-
-  // Performs any final adjustments for table-cells at the end of layout.
-  static void FinalizeTableCellLayout(
-      LayoutUnit unconstrained_intrinsic_block_size,
-      NGBoxFragmentBuilder*);
+// Computes a cell's block-size, and if its initial block-size should be
+// considered indefinite.
+struct CellBlockSizeData {
+  LayoutUnit block_size;
+  bool is_initial_block_size_indefinite;
 };
+CellBlockSizeData ComputeCellBlockSize(
+    const NGTableTypes::CellBlockConstraint& cell_block_constraint,
+    const NGTableTypes::Rows& rows,
+    wtf_size_t row_index,
+    const LogicalSize& border_spacing,
+    bool is_table_block_size_specified);
+
+// Sets up a constraint space builder for a table-cell.
+//
+// In order to make the cache as effective as possible, we try and keep
+// creating the constraint-space for table-cells as consistent as possible.
+void SetupTableCellConstraintSpaceBuilder(
+    const WritingDirectionMode table_writing_direction,
+    const NGBlockNode cell,
+    const BoxStrut& cell_borders,
+    const Vector<NGTableColumnLocation>& column_locations,
+    LayoutUnit cell_block_size,
+    LayoutUnit percentage_inline_size,
+    absl::optional<LayoutUnit> alignment_baseline,
+    wtf_size_t start_column,
+    bool is_initial_block_size_indefinite,
+    bool is_restricted_block_size_table,
+    bool has_collapsed_borders,
+    NGCacheSlot,
+    NGConstraintSpaceBuilder*);
+
+wtf_size_t ComputeMaximumNonMergeableColumnCount(
+    const HeapVector<NGBlockNode>& columns,
+    bool is_fixed_layout);
+
+scoped_refptr<NGTableTypes::Columns> ComputeColumnConstraints(
+    const NGBlockNode& table,
+    const NGTableGroupedChildren&,
+    const NGTableBorders& table_borders,
+    const BoxStrut& border_padding);
+
+void ComputeSectionMinimumRowBlockSizes(
+    const NGBlockNode& section,
+    const LayoutUnit cell_percentage_resolution_inline_size,
+    const bool is_table_block_size_specified,
+    const Vector<NGTableColumnLocation>& column_locations,
+    const NGTableBorders& table_borders,
+    const LayoutUnit block_border_spacing,
+    wtf_size_t section_index,
+    bool treat_section_as_tbody,
+    NGTableTypes::Sections* sections,
+    NGTableTypes::Rows* rows,
+    NGTableTypes::CellBlockConstraints* cell_block_constraints);
+
+// Performs any final adjustments for table-cells at the end of layout.
+void FinalizeTableCellLayout(LayoutUnit unconstrained_intrinsic_block_size,
+                             NGBoxFragmentBuilder*);
 
 // NGColspanCellTabulator keeps track of columns occupied by colspanned cells
 // when traversing rows in a section. It is used to compute cell's actual
@@ -136,7 +124,7 @@
 class NGRowBaselineTabulator {
  public:
   void ProcessCell(const NGBoxFragment& fragment,
-                   bool is_baseline_aligned,
+                   EVerticalAlign align,
                    bool is_rowspanned,
                    bool descendant_depends_on_percentage_block_size);
 
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc
index c30fe57..1c54746 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_node.cc
@@ -37,7 +37,7 @@
   scoped_refptr<const NGTableTypes::Columns> column_constraints =
       layout_table->GetCachedTableColumnConstraints();
   if (!column_constraints) {
-    column_constraints = NGTableAlgorithmUtils::ComputeColumnConstraints(
+    column_constraints = ComputeColumnConstraints(
         *this, grouped_children, *GetTableBorders(), border_padding);
     layout_table->SetCachedTableColumnConstraints(column_constraints.get());
   }
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_row_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_row_layout_algorithm.cc
index 579d788..92934c1 100644
--- a/third_party/blink/renderer/core/layout/ng/table/ng_table_row_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_row_layout_algorithm.cc
@@ -66,7 +66,7 @@
                                          cell.Style().GetWritingDirection(),
                                          /* is_new_fc */ true);
 
-        NGTableAlgorithmUtils::SetupTableCellConstraintSpaceBuilder(
+        SetupTableCellConstraintSpaceBuilder(
             table_data.table_writing_direction, cell, cell_data.borders,
             table_data.column_locations, cell_block_size,
             container_builder_.InlineSize(), row_baseline,
@@ -183,9 +183,7 @@
       const NGBoxFragment fragment(table_data.table_writing_direction,
                                    physical_fragment);
       row_baseline_tabulator.ProcessCell(
-          fragment,
-          NGTableAlgorithmUtils::IsBaseline(cell_style.VerticalAlign()),
-          has_rowspan,
+          fragment, cell_style.VerticalAlign(), has_rowspan,
           cell_data.has_descendant_that_depends_on_percentage_block_size);
       if (min_block_size_should_encompass_intrinsic_size) {
         max_cell_block_size =
diff --git a/third_party/blink/renderer/core/layout/svg/svg_resources.cc b/third_party/blink/renderer/core/layout/svg/svg_resources.cc
index 67be773..e260dad 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_resources.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_resources.cc
@@ -215,7 +215,7 @@
   FilterData(FilterEffect* last_effect, SVGFilterGraphNodeMap* node_map)
       : last_effect_(last_effect), node_map_(node_map) {}
 
-  bool HasEffects() const { return last_effect_; }
+  bool HasEffects() const { return last_effect_ != nullptr; }
   sk_sp<PaintFilter> BuildPaintFilter() {
     return paint_filter_builder::Build(last_effect_, kInterpolationSpaceSRGB);
   }
diff --git a/third_party/blink/renderer/core/layout/text_autosizer.cc b/third_party/blink/renderer/core/layout/text_autosizer.cc
index 33218f7..b3fe529 100644
--- a/third_party/blink/renderer/core/layout/text_autosizer.cc
+++ b/third_party/blink/renderer/core/layout/text_autosizer.cc
@@ -916,7 +916,7 @@
       superclusters_.insert(fingerprint, nullptr);
   is_new_entry = add_result.is_new_entry;
   if (!add_result.is_new_entry)
-    return add_result.stored_value->value;
+    return add_result.stored_value->value.Get();
 
   Supercluster* supercluster = MakeGarbageCollected<Supercluster>(roots);
   add_result.stored_value->value = supercluster;
@@ -1082,7 +1082,7 @@
     cluster->deepest_block_containing_all_text_ =
         DeepestBlockContainingAllText(cluster->root_);
 
-  return cluster->deepest_block_containing_all_text_;
+  return cluster->deepest_block_containing_all_text_.Get();
 }
 
 // FIXME: Refactor this to look more like TextAutosizer::deepestCommonAncestor.
@@ -1290,7 +1290,7 @@
 
 TextAutosizer::Cluster* TextAutosizer::CurrentCluster() const {
   SECURITY_DCHECK(!cluster_stack_.empty());
-  return cluster_stack_.back();
+  return cluster_stack_.back().Get();
 }
 
 TextAutosizer::Cluster::Cluster(const LayoutBlock* root,
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context_test.cc b/third_party/blink/renderer/core/loader/base_fetch_context_test.cc
index 099d7ea..e4f7a43 100644
--- a/third_party/blink/renderer/core/loader/base_fetch_context_test.cc
+++ b/third_party/blink/renderer/core/loader/base_fetch_context_test.cc
@@ -115,7 +115,7 @@
   }
 
   ExecutionContext* GetExecutionContext() const override {
-    return execution_context_;
+    return execution_context_.Get();
   }
 
  private:
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc b/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc
index 343cf981..b7267b3 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc
@@ -65,7 +65,7 @@
   }
 
   bool WasNotifyFinished() const { return was_notify_finished_; }
-  ModuleScript* GetModuleScript() { return module_script_; }
+  ModuleScript* GetModuleScript() { return module_script_.Get(); }
 
  private:
   bool was_notify_finished_ = false;
@@ -85,7 +85,7 @@
     return KURL(base_url, module_request);
   }
 
-  ScriptState* GetScriptState() override { return script_state_; }
+  ScriptState* GetScriptState() override { return script_state_.Get(); }
 
   ModuleScriptFetcher* CreateModuleScriptFetcher(
       ModuleScriptCustomFetchType custom_fetch_type,
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc
index 10ce9c1b..7c75115 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc
@@ -50,7 +50,7 @@
   }
 
   bool WasNotifyFinished() const { return was_notify_finished_; }
-  ModuleScript* GetModuleScript() { return module_script_; }
+  ModuleScript* GetModuleScript() { return module_script_.Get(); }
 
  private:
   bool was_notify_finished_ = false;
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl_test.cc b/third_party/blink/renderer/core/page/chrome_client_impl_test.cc
index 6cf00905..488a05a 100644
--- a/third_party/blink/renderer/core/page/chrome_client_impl_test.cc
+++ b/third_party/blink/renderer/core/page/chrome_client_impl_test.cc
@@ -270,7 +270,7 @@
     LocalFrame* frame = main_frame_->GetFrame();
     DateTimeChooserParameters params;
     params.locale = DefaultLanguage();
-    params.type = input_type_names::kTime;
+    params.type = InputType::Type::kTime;
     DateTimeChooser* chooser = chrome_client_impl_->OpenDateTimeChooser(
         frame, date_time_chooser_client_, params);
     if (chooser)
@@ -324,7 +324,7 @@
   void FilesChosen(FileChooserFileInfoList, const base::FilePath&) override {}
   void WillOpenPopup() override {}
 
-  LocalFrame* FrameOrNull() const override { return frame_; }
+  LocalFrame* FrameOrNull() const override { return frame_.Get(); }
 
   Member<LocalFrame> frame_;
 };
diff --git a/third_party/blink/renderer/core/page/touch_adjustment.cc b/third_party/blink/renderer/core/page/touch_adjustment.cc
index 548624a..be9467f 100644
--- a/third_party/blink/renderer/core/page/touch_adjustment.cc
+++ b/third_party/blink/renderer/core/page/touch_adjustment.cc
@@ -65,7 +65,7 @@
       : node_(node), quad_(quad) {}
   void Trace(Visitor* visitor) const { visitor->Trace(node_); }
 
-  Node* GetNode() const { return node_; }
+  Node* GetNode() const { return node_.Get(); }
   gfx::QuadF Quad() const { return quad_; }
   gfx::Rect BoundingBox() const {
     return gfx::ToEnclosingRect(quad_.BoundingBox());
diff --git a/third_party/blink/renderer/core/paint/background_image_geometry.cc b/third_party/blink/renderer/core/paint/background_image_geometry.cc
index 3298cfe..98ef56e 100644
--- a/third_party/blink/renderer/core/paint/background_image_geometry.cc
+++ b/third_party/blink/renderer/core/paint/background_image_geometry.cc
@@ -530,11 +530,9 @@
     PhysicalBoxStrut& snapped_box_outset) const {
   switch (fill_layer.Origin()) {
     case EFillBox::kFillBox:
-    case EFillBox::kStrokeBox:
-    case EFillBox::kViewBox:
-      // TODO(pdr): These are not yet implemented for origin.
-      NOTREACHED();
-      break;
+    // Spec: For elements with associated CSS layout box, the used values for
+    // fill-box compute to content-box.
+    // https://drafts.fxtf.org/css-masking/#the-mask-clip
     case EFillBox::kContent:
       // If the PaddingOutsets are zero then this is equivalent to
       // kPadding and we should apply the snapping logic.
@@ -572,6 +570,11 @@
                                     LayoutUnit(inner_border_rect.bottom());
       }
       return;
+    case EFillBox::kStrokeBox:
+    case EFillBox::kViewBox:
+    // Spec: For elements with associated CSS layout box, ... stroke-box and
+    // view-box compute to border-box.
+    // https://drafts.fxtf.org/css-masking/#the-mask-clip
     case EFillBox::kBorder:
       // All adjustments remain 0.
       snapped_box_outset = unsnapped_box_outset = PhysicalBoxStrut();
diff --git a/third_party/blink/renderer/core/paint/fragment_data.h b/third_party/blink/renderer/core/paint/fragment_data.h
index e7d2c6e5..0b2802b 100644
--- a/third_party/blink/renderer/core/paint/fragment_data.h
+++ b/third_party/blink/renderer/core/paint/fragment_data.h
@@ -26,7 +26,7 @@
 class CORE_EXPORT FragmentData final : public GarbageCollected<FragmentData> {
  public:
   FragmentData* NextFragment() const {
-    return rare_data_ ? rare_data_->next_fragment_ : nullptr;
+    return rare_data_ ? rare_data_->next_fragment_.Get() : nullptr;
   }
   FragmentData& EnsureNextFragment();
 
@@ -57,13 +57,13 @@
   // depending on the return value of LayoutBoxModelObject::LayerTypeRequired().
   PaintLayer* Layer() const {
     AssertIsFirst();
-    return rare_data_ ? rare_data_->layer : nullptr;
+    return rare_data_ ? rare_data_->layer.Get() : nullptr;
   }
   void SetLayer(PaintLayer*);
 
   StickyPositionScrollingConstraints* StickyConstraints() const {
     AssertIsFirst();
-    return rare_data_ ? rare_data_->sticky_constraints : nullptr;
+    return rare_data_ ? rare_data_->sticky_constraints.Get() : nullptr;
   }
   void SetStickyConstraints(StickyPositionScrollingConstraints* constraints) {
     AssertIsFirst();
diff --git a/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.cc b/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.cc
index a413c46..c4ef84ac 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_paint_order_iterator.cc
@@ -40,7 +40,7 @@
     if (root_->StackingNode()) {
       const auto& neg_z_order_list = root_->StackingNode()->NegZOrderList();
       if (index_ < neg_z_order_list.size())
-        return neg_z_order_list[index_++];
+        return neg_z_order_list[index_++].Get();
     }
 
     index_ = 0;
@@ -68,7 +68,7 @@
     if (root_->StackingNode()) {
       const auto& pos_z_order_list = root_->StackingNode()->PosZOrderList();
       if (index_ < pos_z_order_list.size())
-        return pos_z_order_list[index_++];
+        return pos_z_order_list[index_++].Get();
     }
 
     index_ = 0;
@@ -83,7 +83,7 @@
     if (root_->StackingNode()) {
       const auto& neg_z_order_list = root_->StackingNode()->NegZOrderList();
       if (index_ >= 0)
-        return neg_z_order_list[index_--];
+        return neg_z_order_list[index_--].Get();
     }
 
     remaining_children_ &= ~kNegativeZOrderChildren;
@@ -111,7 +111,7 @@
     if (root_->StackingNode()) {
       const auto& pos_z_order_list = root_->StackingNode()->PosZOrderList();
       if (index_ >= 0)
-        return pos_z_order_list[index_--];
+        return pos_z_order_list[index_--].Get();
     }
 
     remaining_children_ &= ~kPositiveZOrderChildren;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_stacking_node.h b/third_party/blink/renderer/core/paint/paint_layer_stacking_node.h
index b2d72b0..b03bbcb 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_stacking_node.h
+++ b/third_party/blink/renderer/core/paint/paint_layer_stacking_node.h
@@ -119,7 +119,7 @@
     auto it = layer_to_overlay_overflow_controls_painting_after_.find(layer);
     return it == layer_to_overlay_overflow_controls_painting_after_.end()
                ? nullptr
-               : it->value;
+               : it->value.Get();
   }
 
   void ClearNeedsReorderOverlayOverflowControls();
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index e382205..b16cc69 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -1226,6 +1226,24 @@
         if (object_.HasHiddenBackface()) {
           state.backface_visibility =
               TransformPaintPropertyNode::BackfaceVisibility::kHidden;
+        } else if (RuntimeEnabledFeatures::
+                       BackfaceVisibilityNewInheritanceEnabled()) {
+          if (!context_.can_inherit_backface_visibility ||
+              style.Has3DTransformOperation()) {
+            // We want to set backface-visibility back to visible, if the
+            // parent doesn't allow this element to inherit backface visibility
+            // (e.g. if the parent preserves 3d), or this element has a
+            // syntactically-3D transform in *any* of the transform properties
+            // (not just 'transform'). This means that backface-visibility on
+            // an ancestor element no longer affects this element.
+            state.backface_visibility =
+                TransformPaintPropertyNode::BackfaceVisibility::kVisible;
+          } else {
+            // Otherwise we want to inherit backface-visibility.
+            DCHECK_EQ(
+                state.backface_visibility,
+                TransformPaintPropertyNode::BackfaceVisibility::kInherited);
+          }
         } else if (state.direct_compositing_reasons !=
                    CompositingReason::kNone) {
           // The above condition fixes a CompositeAfterPaint regression
@@ -2663,7 +2681,12 @@
       // scrolling contents.
       if (object_.HasTransform() && object_.StyleRef().BackfaceVisibility() ==
                                         EBackfaceVisibility::kHidden) {
-        state.flags.delegates_to_parent_for_backface = true;
+        if (RuntimeEnabledFeatures::BackfaceVisibilityNewInheritanceEnabled()) {
+          CHECK_EQ(state.backface_visibility,
+                   TransformPaintPropertyNode::BackfaceVisibility::kInherited);
+        } else {
+          state.flags.delegates_to_parent_for_backface = true;
+        }
       }
 
       auto effective_change_type = properties_->UpdateScrollTranslation(
@@ -3109,6 +3132,12 @@
   }
 #endif
 
+  // Child transform nodes should not inherit backface visibility if the parent
+  // transform node preserves 3d. This is before UpdatePerspective() because
+  // perspective itself doesn't affect backface visibility inheritance.
+  context_.can_inherit_backface_visibility =
+      context_.should_flatten_inherited_transform;
+
   if (properties_) {
     UpdateInnerBorderRadiusClip();
     UpdateOverflowClip();
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.h b/third_party/blink/renderer/core/paint/paint_property_tree_builder.h
index 3481d97..6855951 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.h
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.h
@@ -146,6 +146,12 @@
   // be updated whenever |transform| is; flattening only needs to happen
   // to immediate children.
   bool should_flatten_inherited_transform = false;
+
+  // Whether newly created child Transform nodes can inherit
+  // backface-visibility from the parent. Some situations (e.g. having 3d
+  // transform operations) of the child can override this flag.
+  bool can_inherit_backface_visibility = false;
+
   // Rendering context for 3D sorting. See
   // TransformPaintPropertyNode::renderingContextId.
   unsigned rendering_context_id = 0;
diff --git a/third_party/blink/renderer/core/paint/timing/paint_timing_detector.cc b/third_party/blink/renderer/core/paint/timing/paint_timing_detector.cc
index 4e7e099..8b0d0f6 100644
--- a/third_party/blink/renderer/core/paint/timing/paint_timing_detector.cc
+++ b/third_party/blink/renderer/core/paint/timing/paint_timing_detector.cc
@@ -389,7 +389,7 @@
 LargestContentfulPaintCalculator*
 PaintTimingDetector::GetLargestContentfulPaintCalculator() {
   if (largest_contentful_paint_calculator_) {
-    return largest_contentful_paint_calculator_;
+    return largest_contentful_paint_calculator_.Get();
   }
 
   auto* dom_window = frame_view_->GetFrame().DomWindow();
@@ -400,7 +400,7 @@
   largest_contentful_paint_calculator_ =
       MakeGarbageCollected<LargestContentfulPaintCalculator>(
           DOMWindowPerformance::performance(*dom_window));
-  return largest_contentful_paint_calculator_;
+  return largest_contentful_paint_calculator_.Get();
 }
 
 bool PaintTimingDetector::NotifyMetricsIfLargestImagePaintChanged(
diff --git a/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector.cc
index a931ef5..cee69fe 100644
--- a/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector.cc
+++ b/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector.cc
@@ -79,7 +79,7 @@
     DCHECK(!time.is_null());
     ReportCandidateToTrace(*largest_text_);
   }
-  return largest_text_;
+  return largest_text_.Get();
 }
 
 void TextPaintTimingDetector::OnPaintFinished() {
diff --git a/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector.h b/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector.h
index e0d9dfa..fcf52f7 100644
--- a/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector.h
+++ b/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector.h
@@ -62,7 +62,7 @@
 
   inline TextRecord* LargestText() {
     DCHECK(!largest_text_ || !largest_text_->paint_time.is_null());
-    return largest_text_;
+    return largest_text_.Get();
   }
   void MaybeUpdateLargestText(TextRecord* record);
   void MaybeUpdateLargestIgnoredText(const LayoutObject&,
diff --git a/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector_test.cc b/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector_test.cc
index 31b1d2a0..ec8f201 100644
--- a/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector_test.cc
+++ b/third_party/blink/renderer/core/paint/timing/text_paint_timing_detector_test.cc
@@ -76,7 +76,7 @@
   }
 
   LargestTextPaintManager* GetLargestTextPaintManager() {
-    return GetTextPaintTimingDetector()->ltp_manager_;
+    return GetTextPaintTimingDetector()->ltp_manager_.Get();
   }
 
   wtf_size_t CountRecordedSize() {
diff --git a/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5 b/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5
index d85afb9..574df40 100644
--- a/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5
+++ b/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5
@@ -405,7 +405,6 @@
       name: "Unload",
       permissions_policy_name: "unload",
       feature_default: "EnableForAll",
-      depends_on: ["PermissionsPolicyUnload"],
     },
     {
       name: "VerticalScroll",
diff --git a/third_party/blink/renderer/core/permissions_policy/permissions_policy_parser.cc b/third_party/blink/renderer/core/permissions_policy/permissions_policy_parser.cc
index 70058b4..077b289 100644
--- a/third_party/blink/renderer/core/permissions_policy/permissions_policy_parser.cc
+++ b/third_party/blink/renderer/core/permissions_policy/permissions_policy_parser.cc
@@ -212,17 +212,8 @@
   mojom::blink::PermissionsPolicyFeature feature =
       feature_names_.at(effective_feature_name);
 
-  // TODO(https://crbug.com/1324111): Remove this after OT.
   if (feature == mojom::blink::PermissionsPolicyFeature::kUnload) {
-    if (!execution_context_ ||
-        !RuntimeEnabledFeatures::PermissionsPolicyUnloadEnabled(
-            execution_context_)) {
-      // kUnload should not be recognised unless the OT is enabled.
-      feature = mojom::blink::PermissionsPolicyFeature::kNotFound;
-    } else if (execution_context_->IsWindow()) {
-      // Counter is required for Origin Trial.
-      execution_context_->CountUse(WebFeature::kPermissionsPolicyUnload);
-    }
+    UseCounter::Count(execution_context_, WebFeature::kPermissionsPolicyUnload);
   }
   return feature;
 }
diff --git a/third_party/blink/renderer/core/script/classic_pending_script.cc b/third_party/blink/renderer/core/script/classic_pending_script.cc
index c11a3d3..1b1cade 100644
--- a/third_party/blink/renderer/core/script/classic_pending_script.cc
+++ b/third_party/blink/renderer/core/script/classic_pending_script.cc
@@ -501,7 +501,7 @@
                          TRACE_EVENT_FLAG_FLOW_IN, "not_streamed_reason",
                          classic_script_->NotStreamingReason());
 
-  return classic_script_;
+  return classic_script_.Get();
 }
 
 // static
diff --git a/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc b/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
index ecab366..a33fd4e 100644
--- a/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
+++ b/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
@@ -68,7 +68,7 @@
 
  private:
   // Implements Modulator:
-  ScriptState* GetScriptState() final { return script_state_; }
+  ScriptState* GetScriptState() final { return script_state_.Get(); }
 
   ModuleScript* GetFetchedModuleScript(const KURL& url,
                                        ModuleType module_type) final {
diff --git a/third_party/blink/renderer/core/script/html_parser_script_runner.cc b/third_party/blink/renderer/core/script/html_parser_script_runner.cc
index ad72846..8abbbc9 100644
--- a/third_party/blink/renderer/core/script/html_parser_script_runner.cc
+++ b/third_party/blink/renderer/core/script/html_parser_script_runner.cc
@@ -425,7 +425,7 @@
     }
     return nullptr;
   }
-  return waiting_scripts->TakeFirst();
+  return waiting_scripts->TakeFirst().Get();
 }
 
 // <specdef href="https://html.spec.whatwg.org/C/#stop-parsing">
diff --git a/third_party/blink/renderer/core/script/module_map_test.cc b/third_party/blink/renderer/core/script/module_map_test.cc
index afd03dcb..f94a54f 100644
--- a/third_party/blink/renderer/core/script/module_map_test.cc
+++ b/third_party/blink/renderer/core/script/module_map_test.cc
@@ -47,7 +47,7 @@
   }
 
   bool WasNotifyFinished() const { return was_notify_finished_; }
-  ModuleScript* GetModuleScript() { return module_script_; }
+  ModuleScript* GetModuleScript() { return module_script_.Get(); }
 
  private:
   bool was_notify_finished_ = false;
@@ -106,7 +106,7 @@
   ModuleRecordResolver* GetModuleRecordResolver() override {
     return resolver_.Get();
   }
-  ScriptState* GetScriptState() override { return script_state_; }
+  ScriptState* GetScriptState() override { return script_state_.Get(); }
 
   class TestModuleScriptFetcher final
       : public GarbageCollected<TestModuleScriptFetcher>,
diff --git a/third_party/blink/renderer/core/script/module_script_test.cc b/third_party/blink/renderer/core/script/module_script_test.cc
index f22a580..212b715 100644
--- a/third_party/blink/renderer/core/script/module_script_test.cc
+++ b/third_party/blink/renderer/core/script/module_script_test.cc
@@ -43,7 +43,7 @@
   }
 
  private:
-  ScriptState* GetScriptState() override { return script_state_; }
+  ScriptState* GetScriptState() override { return script_state_.Get(); }
 
   Member<ScriptState> script_state_;
 };
diff --git a/third_party/blink/renderer/core/scroll/scrollbar.cc b/third_party/blink/renderer/core/scroll/scrollbar.cc
index 92b1d44b..2a94387 100644
--- a/third_party/blink/renderer/core/scroll/scrollbar.cc
+++ b/third_party/blink/renderer/core/scroll/scrollbar.cc
@@ -889,6 +889,16 @@
   return false;
 }
 
+bool Scrollbar::ContainerIsFormControl() const {
+  if (!style_source_) {
+    return false;
+  }
+  if (const auto* element = DynamicTo<Element>(style_source_->GetNode())) {
+    return element->IsFormControlElement();
+  }
+  return false;
+}
+
 EScrollbarWidth Scrollbar::CSSScrollbarWidth() const {
   if (style_source_) {
     return style_source_->StyleRef().ScrollbarWidth();
diff --git a/third_party/blink/renderer/core/scroll/scrollbar.h b/third_party/blink/renderer/core/scroll/scrollbar.h
index cdefbc6..82037f3 100644
--- a/third_party/blink/renderer/core/scroll/scrollbar.h
+++ b/third_party/blink/renderer/core/scroll/scrollbar.h
@@ -206,6 +206,7 @@
 
   float EffectiveZoom() const;
   bool ContainerIsRightToLeft() const;
+  bool ContainerIsFormControl() const;
 
   // scrollbar-width CSS property
   EScrollbarWidth CSSScrollbarWidth() const;
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme.cc b/third_party/blink/renderer/core/scroll/scrollbar_theme.cc
index 0899878..16b0b87 100644
--- a/third_party/blink/renderer/core/scroll/scrollbar_theme.cc
+++ b/third_party/blink/renderer/core/scroll/scrollbar_theme.cc
@@ -128,6 +128,7 @@
                                       .toSkColor4f()
                                       .toSkColor();
   }
+  // TODO(crbug.com/1493088): Rounded corner of scroll corner for form controls.
   WebThemeEngine::ExtraParams extra_params(scrollbar_track);
   WebThemeEngineHelper::GetNativeThemeEngine()->Paint(
       context.Canvas(), WebThemeEngine::kPartScrollbarCorner,
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc b/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc
index 46128e9..96b292d 100644
--- a/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc
+++ b/third_party/blink/renderer/core/scroll/scrollbar_theme_aura.cc
@@ -283,6 +283,9 @@
 
   WebThemeEngine::ScrollbarButtonExtraParams scrollbar_button;
   scrollbar_button.zoom = scrollbar.EffectiveZoom();
+  // TODO(crbug.com/1493088): Should not draw rounded corner for a button
+  // adjacent to the scroll corner.
+  scrollbar_button.needs_rounded_corner = scrollbar.ContainerIsFormControl();
   scrollbar_button.right_to_left = scrollbar.ContainerIsRightToLeft();
   if (scrollbar.ScrollbarThumbColor().has_value()) {
     scrollbar_button.thumb_color =
diff --git a/third_party/blink/renderer/core/streams/readable_stream_test.cc b/third_party/blink/renderer/core/streams/readable_stream_test.cc
index 06969cc..ef6e7b5 100644
--- a/third_party/blink/renderer/core/streams/readable_stream_test.cc
+++ b/third_party/blink/renderer/core/streams/readable_stream_test.cc
@@ -637,7 +637,7 @@
     return ScriptPromise::CastUndefined(script_state_);
   }
 
-  ScriptState* GetScriptState() override { return script_state_; }
+  ScriptState* GetScriptState() override { return script_state_.Get(); }
 
   void Trace(Visitor* visitor) const override {
     visitor->Trace(script_state_);
@@ -659,7 +659,7 @@
   MOCK_METHOD2(Cancel,
                ScriptPromise(v8::Local<v8::Value> reason, ExceptionState&));
 
-  ScriptState* GetScriptState() override { return script_state_; }
+  ScriptState* GetScriptState() override { return script_state_.Get(); }
 
   void Trace(Visitor* visitor) const override {
     visitor->Trace(script_state_);
diff --git a/third_party/blink/renderer/core/streams/transferable_streams.cc b/third_party/blink/renderer/core/streams/transferable_streams.cc
index 48441a9..f0c6b52c8 100644
--- a/third_party/blink/renderer/core/streams/transferable_streams.cc
+++ b/third_party/blink/renderer/core/streams/transferable_streams.cc
@@ -346,8 +346,8 @@
 
   WritableStream* CreateWritableStream(ExceptionState&);
 
-  ScriptState* GetScriptState() const override { return script_state_; }
-  MessagePort* GetMessagePort() const override { return message_port_; }
+  ScriptState* GetScriptState() const override { return script_state_.Get(); }
+  MessagePort* GetMessagePort() const override { return message_port_.Get(); }
   void HandleMessage(MessageType type, v8::Local<v8::Value> value) override;
   void HandleError(v8::Local<v8::Value> error) override;
 
@@ -667,8 +667,8 @@
 
   ReadableStream* CreateReadableStream(ExceptionState&);
 
-  ScriptState* GetScriptState() const override { return script_state_; }
-  MessagePort* GetMessagePort() const override { return message_port_; }
+  ScriptState* GetScriptState() const override { return script_state_.Get(); }
+  MessagePort* GetMessagePort() const override { return message_port_.Get(); }
   void HandleMessage(MessageType type, v8::Local<v8::Value> value) override;
   void HandleError(v8::Local<v8::Value> error) override;
 
diff --git a/third_party/blink/renderer/core/streams/transform_stream_test.cc b/third_party/blink/renderer/core/streams/transform_stream_test.cc
index e4428a6..1127492 100644
--- a/third_party/blink/renderer/core/streams/transform_stream_test.cc
+++ b/third_party/blink/renderer/core/streams/transform_stream_test.cc
@@ -102,7 +102,7 @@
     return ScriptPromise::CastUndefined(script_state_);
   }
 
-  ScriptState* GetScriptState() override { return script_state_; }
+  ScriptState* GetScriptState() override { return script_state_.Get(); }
 
   void Trace(Visitor* visitor) const override {
     visitor->Trace(script_state_);
@@ -140,7 +140,7 @@
                ScriptPromise(TransformStreamDefaultController*,
                              ExceptionState&));
 
-  ScriptState* GetScriptState() override { return script_state_; }
+  ScriptState* GetScriptState() override { return script_state_.Get(); }
 
   void Trace(Visitor* visitor) const override {
     visitor->Trace(script_state_);
diff --git a/third_party/blink/renderer/core/streams/writable_stream.cc b/third_party/blink/renderer/core/streams/writable_stream.cc
index 1cc4e1b..7099123 100644
--- a/third_party/blink/renderer/core/streams/writable_stream.cc
+++ b/third_party/blink/renderer/core/streams/writable_stream.cc
@@ -50,7 +50,7 @@
   PendingAbortRequest(const PendingAbortRequest&) = delete;
   PendingAbortRequest& operator=(const PendingAbortRequest&) = delete;
 
-  StreamPromiseResolver* GetPromise() { return promise_; }
+  StreamPromiseResolver* GetPromise() { return promise_.Get(); }
   v8::Local<v8::Value> Reason(v8::Isolate* isolate) {
     return reason_.Get(isolate);
   }
diff --git a/third_party/blink/renderer/core/style/style_crossfade_image.cc b/third_party/blink/renderer/core/style/style_crossfade_image.cc
index 8da3842..1bfbbbec 100644
--- a/third_party/blink/renderer/core/style/style_crossfade_image.cc
+++ b/third_party/blink/renderer/core/style/style_crossfade_image.cc
@@ -27,7 +27,7 @@
 }
 
 CSSValue* StyleCrossfadeImage::CssValue() const {
-  return original_value_;
+  return original_value_.Get();
 }
 
 CSSValue* StyleCrossfadeImage::ComputedCSSValue(
diff --git a/third_party/blink/renderer/core/style/style_generated_image.cc b/third_party/blink/renderer/core/style/style_generated_image.cc
index 182569be..43f58b79 100644
--- a/third_party/blink/renderer/core/style/style_generated_image.cc
+++ b/third_party/blink/renderer/core/style/style_generated_image.cc
@@ -65,7 +65,7 @@
     return image_gradient_value->ComputedCSSValue(style, allow_visited_style);
   }
   DCHECK(IsA<CSSPaintValue>(image_generator_value_.Get()));
-  return image_generator_value_;
+  return image_generator_value_.Get();
 }
 
 IntrinsicSizingInfo StyleGeneratedImage::GetNaturalSizingInfo(
diff --git a/third_party/blink/renderer/core/style/style_image_set.cc b/third_party/blink/renderer/core/style/style_image_set.cc
index 2a705c7..7f1e243 100644
--- a/third_party/blink/renderer/core/style/style_image_set.cc
+++ b/third_party/blink/renderer/core/style/style_image_set.cc
@@ -57,7 +57,7 @@
 }
 
 CSSValue* StyleImageSet::CssValue() const {
-  return image_set_value_;
+  return image_set_value_.Get();
 }
 
 CSSValue* StyleImageSet::ComputedCSSValue(const ComputedStyle& style,
diff --git a/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc b/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc
index edae42ae..64f35d5 100644
--- a/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc
+++ b/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc
@@ -213,11 +213,11 @@
   if (!id.empty()) {
     auto builtin_it = builtin_effects_.find(id);
     if (builtin_it != builtin_effects_.end())
-      return builtin_it->value;
+      return builtin_it->value.Get();
 
     auto named_it = named_effects_.find(id);
     if (named_it != named_effects_.end())
-      return named_it->value;
+      return named_it->value.Get();
   }
 
   if (last_effect_)
diff --git a/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h b/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h
index d7ff07d..c000540 100644
--- a/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h
+++ b/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h
@@ -59,7 +59,7 @@
   FilterEffect* EffectForElement(
       SVGFilterPrimitiveStandardAttributes& primitive) {
     auto it = effect_element_.find(&primitive);
-    return it != effect_element_.end() ? it->value : nullptr;
+    return it != effect_element_.end() ? it->value.Get() : nullptr;
   }
 
   void InvalidateDependentEffects(FilterEffect*);
diff --git a/third_party/blink/renderer/core/svg/svg_element.h b/third_party/blink/renderer/core/svg/svg_element.h
index 3586fc4..04c7ba5 100644
--- a/third_party/blink/renderer/core/svg/svg_element.h
+++ b/third_party/blink/renderer/core/svg/svg_element.h
@@ -327,7 +327,8 @@
   // adjustments on changes, so we need to break possible cycles here.
   SVGElementSet& invalidating_dependencies = GetDependencyTraversalVisitedSet();
 
-  for (SVGElement* element : *dependencies) {
+  for (auto& member : *dependencies) {
+    auto* element = member.Get();
     if (!element->GetLayoutObject())
       continue;
     if (UNLIKELY(!invalidating_dependencies.insert(element).is_new_entry)) {
diff --git a/third_party/blink/renderer/core/svg/svg_element_rare_data.h b/third_party/blink/renderer/core/svg/svg_element_rare_data.h
index ae3838b..5926e70 100644
--- a/third_party/blink/renderer/core/svg/svg_element_rare_data.h
+++ b/third_party/blink/renderer/core/svg/svg_element_rare_data.h
@@ -81,7 +81,7 @@
     return web_animated_attributes_;
   }
 
-  ElementSMILAnimations* GetSMILAnimations() { return smil_animations_; }
+  ElementSMILAnimations* GetSMILAnimations() { return smil_animations_.Get(); }
   ElementSMILAnimations& EnsureSMILAnimations();
 
   MutableCSSPropertyValueSet* AnimatedSMILStyleProperties() const {
@@ -96,7 +96,9 @@
     needs_override_computed_style_update_ = true;
   }
 
-  SVGElementResourceClient* GetSVGResourceClient() { return resource_client_; }
+  SVGElementResourceClient* GetSVGResourceClient() {
+    return resource_client_.Get();
+  }
   SVGElementResourceClient& EnsureSVGResourceClient(SVGElement*);
 
   AffineTransform* AnimateMotionTransform();
diff --git a/third_party/blink/renderer/core/svg/svg_resource_document_content.cc b/third_party/blink/renderer/core/svg/svg_resource_document_content.cc
index 7889578..83c307d3 100644
--- a/third_party/blink/renderer/core/svg/svg_resource_document_content.cc
+++ b/third_party/blink/renderer/core/svg/svg_resource_document_content.cc
@@ -77,7 +77,7 @@
     entry = MakeGarbageCollected<SVGResourceDocumentContent>(
         resource, GetSupplementable()->GetExecutionContext());
   }
-  return entry;
+  return entry.Get();
 }
 
 void SVGExternalDocumentCache::Trace(Visitor* visitor) const {
@@ -121,7 +121,7 @@
     if (!document_ && resource_->HasData())
       document_ = CreateDocument(resource_, context_);
   }
-  return document_;
+  return document_.Get();
 }
 
 const KURL& SVGResourceDocumentContent::Url() const {
diff --git a/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc b/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc
index bd40304..7602577 100644
--- a/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc
+++ b/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc
@@ -20,7 +20,7 @@
   auto& entry = resources_.insert(id, nullptr).stored_value->value;
   if (!entry)
     entry = MakeGarbageCollected<LocalSVGResource>(*tree_scope_, id);
-  return entry;
+  return entry.Get();
 }
 
 LocalSVGResource* SVGTreeScopeResources::ExistingResourceForId(
@@ -30,7 +30,7 @@
   auto it = resources_.find(id);
   if (it == resources_.end())
     return nullptr;
-  return it->value;
+  return it->value.Get();
 }
 
 void SVGTreeScopeResources::ProcessCustomWeakness(const LivenessBroker& info) {
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index d199053..2942781 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -1428,7 +1428,7 @@
       text->GetDocument().Markers().MarkersFor(*text, marker_types.value());
   if (markers.size() <= index)
     return nullptr;
-  return markers[index];
+  return markers[index].Get();
 }
 
 Range* Internals::markerRangeForNode(Text* text,
diff --git a/third_party/blink/renderer/core/testing/intersection_observer_test_helper.h b/third_party/blink/renderer/core/testing/intersection_observer_test_helper.h
index 40aeff09..fd1cb88 100644
--- a/third_party/blink/renderer/core/testing/intersection_observer_test_helper.h
+++ b/third_party/blink/renderer/core/testing/intersection_observer_test_helper.h
@@ -41,7 +41,9 @@
   }
   int CallCount() const { return call_count_; }
   int EntryCount() const { return entries_.size(); }
-  const IntersectionObserverEntry* LastEntry() const { return entries_.back(); }
+  const IntersectionObserverEntry* LastEntry() const {
+    return entries_.back().Get();
+  }
   void Clear() {
     entries_.clear();
     call_count_ = 0;
diff --git a/third_party/blink/renderer/core/timing/largest_contentful_paint.cc b/third_party/blink/renderer/core/timing/largest_contentful_paint.cc
index 4752328..32b9239 100644
--- a/third_party/blink/renderer/core/timing/largest_contentful_paint.cc
+++ b/third_party/blink/renderer/core/timing/largest_contentful_paint.cc
@@ -54,7 +54,7 @@
   if (!document.IsActive() || !document.GetFrame())
     return nullptr;
 
-  return element_;
+  return element_.Get();
 }
 
 void LargestContentfulPaint::BuildJSONValue(V8ObjectBuilder& builder) const {
diff --git a/third_party/blink/renderer/core/timing/layout_shift_attribution.cc b/third_party/blink/renderer/core/timing/layout_shift_attribution.cc
index 3f46162..3e5cfde2 100644
--- a/third_party/blink/renderer/core/timing/layout_shift_attribution.cc
+++ b/third_party/blink/renderer/core/timing/layout_shift_attribution.cc
@@ -32,15 +32,15 @@
 }
 
 Node* LayoutShiftAttribution::rawNodeForInspector() const {
-  return node_;
+  return node_.Get();
 }
 
 DOMRectReadOnly* LayoutShiftAttribution::previousRect() const {
-  return previous_rect_;
+  return previous_rect_.Get();
 }
 
 DOMRectReadOnly* LayoutShiftAttribution::currentRect() const {
-  return current_rect_;
+  return current_rect_.Get();
 }
 
 ScriptValue LayoutShiftAttribution::toJSONForBinding(
diff --git a/third_party/blink/renderer/core/timing/performance_entry.cc b/third_party/blink/renderer/core/timing/performance_entry.cc
index 34a653f..7da334d 100644
--- a/third_party/blink/renderer/core/timing/performance_entry.cc
+++ b/third_party/blink/renderer/core/timing/performance_entry.cc
@@ -93,7 +93,7 @@
 }
 
 DOMWindow* PerformanceEntry::source() const {
-  return source_;
+  return source_.Get();
 }
 
 mojom::blink::PerformanceMarkOrMeasurePtr
diff --git a/third_party/blink/renderer/core/timing/window_performance.cc b/third_party/blink/renderer/core/timing/window_performance.cc
index 2c626c25..e0f681c 100644
--- a/third_party/blink/renderer/core/timing/window_performance.cc
+++ b/third_party/blink/renderer/core/timing/window_performance.cc
@@ -888,7 +888,7 @@
 EventCounts* WindowPerformance::eventCounts() {
   if (!event_counts_)
     event_counts_ = MakeGarbageCollected<EventCounts>();
-  return event_counts_;
+  return event_counts_.Get();
 }
 
 uint64_t WindowPerformance::interactionCount() const {
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc b/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc
index 7fa095e..f630263 100644
--- a/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc
+++ b/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc
@@ -101,6 +101,13 @@
   return supplement->StartTransition(document, callback, exception_state);
 }
 
+DOMViewTransition* ViewTransitionSupplement::startViewTransition(
+    ScriptState* script_state,
+    Document& document,
+    ExceptionState& exception_state) {
+  return startViewTransition(script_state, document, nullptr, exception_state);
+}
+
 DOMViewTransition* ViewTransitionSupplement::StartTransition(
     Document& document,
     V8ViewTransitionCallback* callback,
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_supplement.h b/third_party/blink/renderer/core/view_transition/view_transition_supplement.h
index 8c2e7299..759a53d 100644
--- a/third_party/blink/renderer/core/view_transition/view_transition_supplement.h
+++ b/third_party/blink/renderer/core/view_transition/view_transition_supplement.h
@@ -30,11 +30,16 @@
 
   // Creates and starts a same-document ViewTransition initiated using the
   // script API.
+  // With callback:
   static DOMViewTransition* startViewTransition(
       ScriptState*,
       Document&,
       V8ViewTransitionCallback* callback,
       ExceptionState&);
+  // Without callback:
+  static DOMViewTransition* startViewTransition(ScriptState*,
+                                                Document&,
+                                                ExceptionState&);
 
   // Creates a ViewTransition to cache the state of a Document before a
   // navigation. The cached state is provided to the caller using the
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_supplement.idl b/third_party/blink/renderer/core/view_transition/view_transition_supplement.idl
index b947efa..4c9fc0d 100644
--- a/third_party/blink/renderer/core/view_transition/view_transition_supplement.idl
+++ b/third_party/blink/renderer/core/view_transition/view_transition_supplement.idl
@@ -5,5 +5,5 @@
 [
     ImplementedAs=ViewTransitionSupplement
 ] partial interface Document {
-    [MeasureAs=ViewTransition, CallWith=ScriptState, RaisesException] ViewTransition startViewTransition(optional ViewTransitionCallback? callback = null);
+    [MeasureAs=ViewTransition, CallWith=ScriptState, RaisesException] ViewTransition startViewTransition(optional ViewTransitionCallback callback);
 };
diff --git a/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc b/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc
index 6d4df91..667cd7d 100644
--- a/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc
+++ b/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc
@@ -182,7 +182,7 @@
 
 ExecutionContext* ThreadedMessagingProxyBase::GetExecutionContext() const {
   DCHECK(IsParentContextThread());
-  return execution_context_;
+  return execution_context_.Get();
 }
 
 ParentExecutionContextTaskRunners*
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
index fe89e69..5b6a11c9 100644
--- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
@@ -315,7 +315,7 @@
 
   // Check if the fetcher has already been initialized, otherwise initialize it.
   if (inside_settings_resource_fetcher_)
-    return inside_settings_resource_fetcher_;
+    return inside_settings_resource_fetcher_.Get();
 
   // Because CSP is initialized inside the WorkerGlobalScope or
   // WorkletGlobalScope constructor, GetContentSecurityPolicy() should be
@@ -327,7 +327,7 @@
   inside_settings_resource_fetcher_ = CreateFetcherInternal(
       *MakeGarbageCollected<FetchClientSettingsObjectImpl>(*this),
       *GetContentSecurityPolicy(), *resource_timing_notifier);
-  return inside_settings_resource_fetcher_;
+  return inside_settings_resource_fetcher_.Get();
 }
 
 ResourceFetcher* WorkerOrWorkletGlobalScope::CreateFetcherInternal(
diff --git a/third_party/blink/renderer/core/workers/worklet.cc b/third_party/blink/renderer/core/workers/worklet.cc
index 541082f..3a4455a2 100644
--- a/third_party/blink/renderer/core/workers/worklet.cc
+++ b/third_party/blink/renderer/core/workers/worklet.cc
@@ -115,7 +115,7 @@
 
 WorkletGlobalScopeProxy* Worklet::FindAvailableGlobalScope() {
   DCHECK(IsMainThread());
-  return proxies_.at(SelectGlobalScope());
+  return proxies_.at(SelectGlobalScope()).Get();
 }
 
 // Implementation of the second half of the "addModule(moduleURL, options)"
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worklet_global_scope.cc
index ee97e3d1..63ef787e7 100644
--- a/third_party/blink/renderer/core/workers/worklet_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worklet_global_scope.cc
@@ -267,7 +267,7 @@
 
 LocalFrame* WorkletGlobalScope::GetFrame() const {
   DCHECK(IsMainThreadWorkletGlobalScope());
-  return frame_;
+  return frame_.Get();
 }
 
 // Implementation of the first half of the "fetch and invoke a worklet script"
diff --git a/third_party/blink/renderer/core/xml/xpath_node_set.cc b/third_party/blink/renderer/core/xml/xpath_node_set.cc
index 723a3ef..778576d 100644
--- a/third_party/blink/renderer/core/xml/xpath_node_set.cc
+++ b/third_party/blink/renderer/core/xml/xpath_node_set.cc
@@ -51,7 +51,7 @@
 static inline Node* ParentWithDepth(unsigned depth,
                                     const NodeSetVector& parents) {
   DCHECK_GE(parents.size(), depth + 1);
-  return parents[parents.size() - 1 - depth];
+  return parents[parents.size() - 1 - depth].Get();
 }
 
 static void SortBlock(unsigned from,
diff --git a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
index 94ac8c5..1d83323 100644
--- a/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
+++ b/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.cc
@@ -364,7 +364,7 @@
     parsed_response_ = true;
   }
 
-  return response_document_;
+  return response_document_.Get();
 }
 
 v8::Local<v8::Value> XMLHttpRequest::ResponseJSON(
@@ -405,7 +405,7 @@
         BlobDataHandle::Create(std::move(blob_data), size));
   }
 
-  return response_blob_;
+  return response_blob_.Get();
 }
 
 DOMArrayBuffer* XMLHttpRequest::ResponseArrayBuffer() {
@@ -437,7 +437,7 @@
     }
   }
 
-  return response_array_buffer_;
+  return response_array_buffer_.Get();
 }
 
 // https://xhr.spec.whatwg.org/#dom-xmlhttprequest-response
@@ -575,7 +575,7 @@
 XMLHttpRequestUpload* XMLHttpRequest::upload() {
   if (!upload_)
     upload_ = MakeGarbageCollected<XMLHttpRequestUpload>(this);
-  return upload_;
+  return upload_.Get();
 }
 
 void XMLHttpRequest::TrackProgress(uint64_t length) {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc b/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc
index bbc5c57..624c047 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_inline_text_box.cc
@@ -210,7 +210,7 @@
 }
 
 NGAbstractInlineTextBox* AXInlineTextBox::GetInlineTextBox() const {
-  return inline_text_box_;
+  return inline_text_box_.Get();
 }
 
 AXObject* AXInlineTextBox::NextOnLine() const {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc b/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
index 5f012f0b..222ac07 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc
@@ -161,7 +161,7 @@
     children_.push_back(popup);
   }
   DCHECK_EQ(children_.size(), 1U);
-  return children_[0];
+  return children_[0].Get();
 }
 
 bool AXMenuList::IsCollapsed() const {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index 2976804..8f4c2fb 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -4205,12 +4205,33 @@
     return false;
   }
 
+  // We should not need layout/style updates at this point.
+  CHECK(!elem->NeedsStyleRecalc())
+      << "\n* Element: " << elem << "\n* Object: " << ToString(true, true)
+      << "\n* LayoutObject: " << GetLayoutObject();
+  CHECK(
+      !GetDocument()->NeedsLayoutTreeUpdateForNodeIncludingDisplayLocked(*elem))
+      << "\n* Element: " << elem << "\n* Object: " << ToString(true, true)
+      << "\n* LayoutObject: " << GetLayoutObject();
+
   // Focusable: element supports focus.
   return elem->SupportsFocus();
 }
 
 bool AXObject::IsKeyboardFocusable() const {
-  return CanSetFocusAttribute() && GetElement()->IsKeyboardFocusable();
+  if (!CanSetFocusAttribute()) {
+    return false;
+  }
+
+  Element& element = *GetElement();
+  Document& document = *GetDocument();
+  CHECK(!element.NeedsStyleRecalc())
+      << "\n* Element: " << element << "\n* Object: " << ToString(true, true)
+      << "\n* LayoutObject: " << GetLayoutObject();
+  CHECK(!document.NeedsLayoutTreeUpdateForNodeIncludingDisplayLocked(element))
+      << "\n* Element: " << element << "\n* Object: " << ToString(true, true)
+      << "\n* LayoutObject: " << GetLayoutObject();
+  return element.IsKeyboardFocusable();
 }
 
 bool AXObject::CanSetSelectedAttribute() const {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h
index 94c1d2ba..3dc621b 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -1100,7 +1100,7 @@
   // Get the parent of this object if it has already been created.
   // Works for all nodes, and may return nodes that are accessibility ignored,
   // including nodes that might not be in the tree.
-  AXObject* CachedParentObject() const { return parent_; }
+  AXObject* CachedParentObject() const { return parent_.Get(); }
 
   // Get the current unignored children without refreshing them, even if
   // children_dirty_ aka NeedsToUpdateChildren() is true.
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index dbcfd84..c95de79 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -3237,14 +3237,15 @@
 }
 
 bool AXObjectCacheImpl::IsAriaOwned(const AXObject* object) const {
-  return relation_cache_ ? relation_cache_->IsAriaOwned(object) : false;
+  CHECK(relation_cache_);
+  return relation_cache_->IsAriaOwned(object);
 }
 
 AXObject* AXObjectCacheImpl::ValidatedAriaOwner(const AXObject* object) const {
   DCHECK(GetDocument().Lifecycle().GetState() >=
          DocumentLifecycle::kLayoutClean);
-  return relation_cache_ ? relation_cache_->ValidatedAriaOwner(object)
-                         : nullptr;
+  CHECK(relation_cache_);
+  return relation_cache_->ValidatedAriaOwner(object);
 }
 
 void AXObjectCacheImpl::ValidatedAriaOwnedChildren(
@@ -3252,18 +3253,15 @@
     HeapVector<Member<AXObject>>& owned_children) {
   DCHECK(GetDocument().Lifecycle().GetState() >=
          DocumentLifecycle::kLayoutClean);
-  if (relation_cache_) {
-    relation_cache_->ValidatedAriaOwnedChildren(owner, owned_children);
-  }
+  CHECK(relation_cache_);
+  relation_cache_->ValidatedAriaOwnedChildren(owner, owned_children);
 }
 
 bool AXObjectCacheImpl::MayHaveHTMLLabel(const HTMLElement& elem) {
   CHECK(elem.GetDocument().Lifecycle().GetState() >=
         DocumentLifecycle::kLayoutClean)
       << "Unclean document at lifecycle " << elem.GetDocument().ToString();
-  if (!relation_cache_) {
-    return false;
-  }
+  CHECK(relation_cache_);
 
   // Return false if this type of element will not accept a <label for> label.
   if (!elem.IsLabelable())
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
index 25e6c657..785e4b3 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -125,7 +125,7 @@
   // The main document.
   Document& GetDocument() const { return *document_; }
   // The popup document, if showing, otherwise null.
-  Document* GetPopupDocumentIfShowing() const { return popup_document_; }
+  Document* GetPopupDocumentIfShowing() const { return popup_document_.Get(); }
 
   AXObject* FocusedObject();
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc b/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc
index 9898dac8..1b4d3ed2 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc
@@ -81,7 +81,7 @@
 }
 
 AccessibleNode* AXVirtualObject::GetAccessibleNode() const {
-  return accessible_node_;
+  return accessible_node_.Get();
 }
 
 String AXVirtualObject::TextAlternative(
diff --git a/third_party/blink/renderer/modules/accessibility/blink_ax_tree_source.cc b/third_party/blink/renderer/modules/accessibility/blink_ax_tree_source.cc
index 5acf9da..85b0c96 100644
--- a/third_party/blink/renderer/modules/accessibility/blink_ax_tree_source.cc
+++ b/third_party/blink/renderer/modules/accessibility/blink_ax_tree_source.cc
@@ -229,13 +229,13 @@
 AXObject* BlinkAXTreeSource::GetRoot() const {
   CHECK(frozen_);
   CHECK(root_);
-  return root_;
+  return root_.Get();
 }
 
 AXObject* BlinkAXTreeSource::GetFocusedObject() const {
   CHECK(frozen_);
   CHECK(focus_);
-  return focus_;
+  return focus_.Get();
 }
 
 AXObject* BlinkAXTreeSource::GetFromId(int32_t id) const {
diff --git a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc
index d74d4d0..aa0ad9c 100644
--- a/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc
+++ b/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc
@@ -342,7 +342,7 @@
     const String& name) {
   auto it = animator_definitions_.find(name);
   if (it != animator_definitions_.end())
-    return it->value;
+    return it->value.Get();
   return nullptr;
 }
 
diff --git a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
index 3f1fcb6d..4eeb0c1 100644
--- a/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
+++ b/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc
@@ -724,7 +724,7 @@
 
 KeyframeEffect* WorkletAnimation::GetEffect() const {
   DCHECK(effects_.at(0));
-  return effects_.at(0);
+  return effects_.at(0).Get();
 }
 
 bool WorkletAnimation::IsActiveAnimation() const {
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc
index c86656a8..f6df6b5 100644
--- a/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc
+++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc
@@ -61,7 +61,7 @@
 }
 
 Request* BackgroundFetchRecord::request() const {
-  return request_;
+  return request_.Get();
 }
 
 void BackgroundFetchRecord::UpdateState(
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
index 0c4b8cd..0f3296b 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
@@ -656,7 +656,7 @@
   auto it =
       device_instance_map_.find(device_ptr->id.DeviceIdInBase64().c_str());
   if (it != device_instance_map_.end()) {
-    return it->value;
+    return it->value.Get();
   }
 
   BluetoothDevice* device = MakeGarbageCollected<BluetoothDevice>(
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc
index 874c1f2..a4c2434c 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc
@@ -61,7 +61,7 @@
 }
 
 BluetoothServiceDataMap* BluetoothAdvertisingEvent::serviceData() const {
-  return service_data_map_;
+  return service_data_map_.Get();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc
index 935f0ca..8ffab0fd 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc
@@ -28,7 +28,7 @@
         std::move(remote_gatt_service), is_primary, device_instance_id,
         device_);
   }
-  return service;
+  return service.Get();
 }
 
 bool BluetoothAttributeInstanceMap::ContainsService(
@@ -50,7 +50,7 @@
     characteristic = MakeGarbageCollected<BluetoothRemoteGATTCharacteristic>(
         context, std::move(remote_gatt_characteristic), service, device_);
   }
-  return characteristic;
+  return characteristic.Get();
 }
 
 bool BluetoothAttributeInstanceMap::ContainsCharacteristic(
@@ -69,7 +69,7 @@
     descriptor = MakeGarbageCollected<BluetoothRemoteGATTDescriptor>(
         std::move(remote_gatt_descriptor), characteristic);
   }
-  return descriptor;
+  return descriptor.Get();
 }
 
 bool BluetoothAttributeInstanceMap::ContainsDescriptor(
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_track_generator.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_track_generator.cc
index dab87903..cf3fa86 100644
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_track_generator.cc
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_track_generator.cc
@@ -136,14 +136,14 @@
 
 WritableStream* MediaStreamTrackGenerator::writable(ScriptState* script_state) {
   if (writable_)
-    return writable_;
+    return writable_.Get();
 
   if (kind() == "video")
     CreateVideoStream(script_state);
   else if (kind() == "audio")
     CreateAudioStream(script_state);
 
-  return writable_;
+  return writable_.Get();
 }
 
 PushableMediaStreamVideoSource* MediaStreamTrackGenerator::PushableVideoSource()
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_track_processor.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_track_processor.cc
index a8ac63b..5c0fc8fd 100644
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_track_processor.cc
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_track_processor.cc
@@ -58,7 +58,7 @@
 
 ReadableStream* MediaStreamTrackProcessor::readable(ScriptState* script_state) {
   if (source_stream_)
-    return source_stream_;
+    return source_stream_.Get();
 
   if (input_track_->Component()->GetSourceType() ==
       MediaStreamSource::kTypeVideo) {
@@ -71,7 +71,7 @@
       MakeGarbageCollected<UnderlyingSourceCloser>(input_track_, this);
   input_track_->AddObserver(source_closer_);
 
-  return source_stream_;
+  return source_stream_.Get();
 }
 
 void MediaStreamTrackProcessor::CreateVideoSourceStream(
diff --git a/third_party/blink/renderer/modules/breakout_box/video_track_generator.cc b/third_party/blink/renderer/modules/breakout_box/video_track_generator.cc
index 41b82b7..c74cf4f 100644
--- a/third_party/blink/renderer/modules/breakout_box/video_track_generator.cc
+++ b/third_party/blink/renderer/modules/breakout_box/video_track_generator.cc
@@ -58,7 +58,7 @@
 }
 
 MediaStreamTrack* VideoTrackGenerator::track() {
-  return wrapped_generator_;
+  return wrapped_generator_.Get();
 }
 
 void VideoTrackGenerator::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel_unittest.cc b/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel_unittest.cc
index 4eba811..5fac859 100644
--- a/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel_unittest.cc
+++ b/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel_unittest.cc
@@ -57,7 +57,7 @@
     channel_->addEventListener(event_type_names::kMessageerror, listener);
   }
 
-  BroadcastChannel* channel() const { return channel_; }
+  BroadcastChannel* channel() const { return channel_.Get(); }
   const HeapVector<Member<MessageEvent>>& received_events() const {
     return received_events_;
   }
diff --git a/third_party/blink/renderer/modules/buckets/storage_bucket.cc b/third_party/blink/renderer/modules/buckets/storage_bucket.cc
index ae33d21f..bc9afda 100644
--- a/third_party/blink/renderer/modules/buckets/storage_bucket.cc
+++ b/third_party/blink/renderer/modules/buckets/storage_bucket.cc
@@ -156,7 +156,7 @@
     remote_->GetIdbFactory(remote_factory.InitWithNewPipeAndPassReceiver());
     idb_factory_->SetRemote(std::move(remote_factory));
   }
-  return idb_factory_;
+  return idb_factory_.Get();
 }
 
 LockManager* StorageBucket::locks() {
@@ -166,7 +166,7 @@
     lock_manager_ = MakeGarbageCollected<LockManager>(*navigator_base_);
     lock_manager_->SetManager(std::move(lock_manager), GetExecutionContext());
   }
-  return lock_manager_;
+  return lock_manager_.Get();
 }
 
 CacheStorage* StorageBucket::caches(ExceptionState& exception_state) {
@@ -180,7 +180,7 @@
         std::move(cache_storage));
   }
 
-  return caches_;
+  return caches_.Get();
 }
 
 ScriptPromise StorageBucket::getDirectory(ScriptState* script_state,
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_test.cc b/third_party/blink/renderer/modules/cache_storage/cache_test.cc
index 48111a43..cbac531c 100644
--- a/third_party/blink/renderer/modules/cache_storage/cache_test.cc
+++ b/third_party/blink/renderer/modules/cache_storage/cache_test.cc
@@ -299,7 +299,7 @@
   AbortController* CreateAbortController(ScriptState* script_state) override {
     if (!abort_controller_)
       abort_controller_ = AbortController::Create(script_state);
-    return abort_controller_;
+    return abort_controller_.Get();
   }
 
  private:
diff --git a/third_party/blink/renderer/modules/cache_storage/global_cache_storage.cc b/third_party/blink/renderer/modules/cache_storage/global_cache_storage.cc
index 9e9ca71..b8296cb 100644
--- a/third_party/blink/renderer/modules/cache_storage/global_cache_storage.cc
+++ b/third_party/blink/renderer/modules/cache_storage/global_cache_storage.cc
@@ -58,7 +58,7 @@
       caches_ = MakeGarbageCollected<CacheStorage>(
           context, GlobalFetch::ScopedFetcher::From(fetching_scope));
     }
-    return caches_;
+    return caches_.Get();
   }
 
   void Trace(Visitor* visitor) const override {
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path_test.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path_test.cc
index 416175e..a3ecf446 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path_test.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path_test.cc
@@ -26,7 +26,7 @@
       : execution_context_(context) {}
 
   ExecutionContext* GetTopExecutionContext() const override {
-    return execution_context_;
+    return execution_context_.Get();
   }
 
   void Trace(Visitor* v) const override {
diff --git a/third_party/blink/renderer/modules/cookie_store/global_cookie_store.cc b/third_party/blink/renderer/modules/cookie_store/global_cookie_store.cc
index 630190a6..fca9d3d 100644
--- a/third_party/blink/renderer/modules/cookie_store/global_cookie_store.cc
+++ b/third_party/blink/renderer/modules/cookie_store/global_cookie_store.cc
@@ -58,7 +58,7 @@
       cookie_store_ = MakeGarbageCollected<CookieStore>(execution_context,
                                                         std::move(backend));
     }
-    return cookie_store_;
+    return cookie_store_.Get();
   }
 
   void Trace(Visitor* visitor) const override {
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc b/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc
index e05041c..aaa01b98 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc
+++ b/third_party/blink/renderer/modules/credentialmanagement/credential_manager_type_converters.cc
@@ -864,8 +864,8 @@
 TypeConverter<IdentityProviderPtr, blink::IdentityProviderConfig>::Convert(
     const blink::IdentityProviderConfig& provider) {
   if (provider.hasHolder() &&
-      blink::RuntimeEnabledFeatures::WebIdentityMDocsEnabled() &&
-      // TODO(https://crbug.com/1416939): make sure the MDocs API
+      blink::RuntimeEnabledFeatures::WebIdentityDigitalCredentialsEnabled() &&
+      // TODO(https://crbug.com/1416939): make sure the Digital Credentials API
       // works well with the Multiple IdP API.
       !blink::RuntimeEnabledFeatures::FedCmMultipleIdentityProvidersEnabled()) {
     auto mojo_provider = WalletProvider::New();
diff --git a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc
index d17e8a9..dae4a562 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc
+++ b/third_party/blink/renderer/modules/credentialmanagement/credentials_container.cc
@@ -1460,10 +1460,10 @@
         UseCounter::Count(resolver->GetExecutionContext(),
                           WebFeature::kFedCmLoginHint);
       }
-      if (RuntimeEnabledFeatures::WebIdentityMDocsEnabled() &&
+      if (RuntimeEnabledFeatures::WebIdentityDigitalCredentialsEnabled() &&
           !RuntimeEnabledFeatures::FedCmMultipleIdentityProvidersEnabled()) {
-        // TODO(https://crbug.com/1416939): make sure the MDocs API
-        // works well with the Multiple IdP API.
+        // TODO(https://crbug.com/1416939): make sure the Digital Credentials
+        //  API works well with the Multiple IdP API.
         if (provider->hasHolder()) {
           auto identity_provider =
               blink::mojom::blink::IdentityProvider::From(*provider);
diff --git a/third_party/blink/renderer/modules/credentialmanagement/identity_provider_config.idl b/third_party/blink/renderer/modules/credentialmanagement/identity_provider_config.idl
index 0e4c405..238bbd117 100644
--- a/third_party/blink/renderer/modules/credentialmanagement/identity_provider_config.idl
+++ b/third_party/blink/renderer/modules/credentialmanagement/identity_provider_config.idl
@@ -18,7 +18,7 @@
 
 // extends the IdentityProviderConfig with Wallet-specific attributes
 partial dictionary IdentityProviderConfig  {
-  [RuntimeEnabled=WebIdentityMDocs] WalletProvider holder;
+  [RuntimeEnabled=WebIdentityDigitalCredentials] WalletProvider holder;
 };
 
 dictionary WalletProvider  {
diff --git a/third_party/blink/renderer/modules/csspaint/css_paint_definition.h b/third_party/blink/renderer/modules/csspaint/css_paint_definition.h
index 6388607d..c27c330 100644
--- a/third_party/blink/renderer/modules/csspaint/css_paint_definition.h
+++ b/third_party/blink/renderer/modules/csspaint/css_paint_definition.h
@@ -76,10 +76,10 @@
   }
   const PaintRenderingContext2DSettings* GetPaintRenderingContext2DSettings()
       const {
-    return context_settings_;
+    return context_settings_.Get();
   }
 
-  ScriptState* GetScriptState() const { return script_state_; }
+  ScriptState* GetScriptState() const { return script_state_.Get(); }
 
   void Trace(Visitor* visitor) const override;
   const char* NameInHeapSnapshot() const override {
diff --git a/third_party/blink/renderer/modules/device_posture/navigator_device_posture.cc b/third_party/blink/renderer/modules/device_posture/navigator_device_posture.cc
index 2373395..9709db8 100644
--- a/third_party/blink/renderer/modules/device_posture/navigator_device_posture.cc
+++ b/third_party/blink/renderer/modules/device_posture/navigator_device_posture.cc
@@ -24,7 +24,7 @@
     supplement = MakeGarbageCollected<NavigatorDevicePosture>(navigator);
     ProvideTo(navigator, supplement);
   }
-  return supplement->posture_;
+  return supplement->posture_.Get();
 }
 
 NavigatorDevicePosture::NavigatorDevicePosture(Navigator& navigator)
diff --git a/third_party/blink/renderer/modules/direct_sockets/tcp_readable_stream_wrapper_unittest.cc b/third_party/blink/renderer/modules/direct_sockets/tcp_readable_stream_wrapper_unittest.cc
index 6c9da349..b7017fd 100644
--- a/third_party/blink/renderer/modules/direct_sockets/tcp_readable_stream_wrapper_unittest.cc
+++ b/third_party/blink/renderer/modules/direct_sockets/tcp_readable_stream_wrapper_unittest.cc
@@ -52,7 +52,7 @@
         script_state,
         WTF::BindOnce(&StreamCreator::Close, WrapWeakPersistent(this)),
         std::move(data_pipe_consumer));
-    return stream_wrapper_;
+    return stream_wrapper_.Get();
   }
 
   void ResetPipe() { data_pipe_producer_.reset(); }
diff --git a/third_party/blink/renderer/modules/direct_sockets/tcp_writable_stream_wrapper_unittest.cc b/third_party/blink/renderer/modules/direct_sockets/tcp_writable_stream_wrapper_unittest.cc
index 96d5494..dccc524 100644
--- a/third_party/blink/renderer/modules/direct_sockets/tcp_writable_stream_wrapper_unittest.cc
+++ b/third_party/blink/renderer/modules/direct_sockets/tcp_writable_stream_wrapper_unittest.cc
@@ -52,7 +52,7 @@
     auto* script_state = scope.GetScriptState();
     stream_wrapper_ = MakeGarbageCollected<TCPWritableStreamWrapper>(
         script_state, base::DoNothing(), std::move(data_pipe_producer));
-    return stream_wrapper_;
+    return stream_wrapper_.Get();
   }
 
   void ResetPipe() { data_pipe_consumer_.reset(); }
diff --git a/third_party/blink/renderer/modules/direct_sockets/udp_readable_stream_wrapper_unittest.cc b/third_party/blink/renderer/modules/direct_sockets/udp_readable_stream_wrapper_unittest.cc
index 2062900..b9bb3d1a 100644
--- a/third_party/blink/renderer/modules/direct_sockets/udp_readable_stream_wrapper_unittest.cc
+++ b/third_party/blink/renderer/modules/direct_sockets/udp_readable_stream_wrapper_unittest.cc
@@ -107,7 +107,7 @@
     auto* script_state = scope.GetScriptState();
     stream_wrapper_ = MakeGarbageCollected<UDPReadableStreamWrapper>(
         script_state, base::DoNothing(), udp_socket, std::move(receiver));
-    return stream_wrapper_;
+    return stream_wrapper_.Get();
   }
 
   void Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/direct_sockets/udp_writable_stream_wrapper_unittest.cc b/third_party/blink/renderer/modules/direct_sockets/udp_writable_stream_wrapper_unittest.cc
index 872a3f5f..ad0d0ce 100644
--- a/third_party/blink/renderer/modules/direct_sockets/udp_writable_stream_wrapper_unittest.cc
+++ b/third_party/blink/renderer/modules/direct_sockets/udp_writable_stream_wrapper_unittest.cc
@@ -85,7 +85,7 @@
         script_state,
         WTF::BindOnce(&StreamCreator::Close, WrapWeakPersistent(this)),
         udp_socket, network::mojom::RestrictedUDPSocketMode::CONNECTED);
-    return stream_wrapper_;
+    return stream_wrapper_.Get();
   }
 
   void Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/document_picture_in_picture/picture_in_picture_controller_impl.cc b/third_party/blink/renderer/modules/document_picture_in_picture/picture_in_picture_controller_impl.cc
index fff688c3..2dd15e36 100644
--- a/third_party/blink/renderer/modules/document_picture_in_picture/picture_in_picture_controller_impl.cc
+++ b/third_party/blink/renderer/modules/document_picture_in_picture/picture_in_picture_controller_impl.cc
@@ -321,11 +321,11 @@
 
 PictureInPictureWindow* PictureInPictureControllerImpl::pictureInPictureWindow()
     const {
-  return picture_in_picture_window_;
+  return picture_in_picture_window_.Get();
 }
 
 Element* PictureInPictureControllerImpl::PictureInPictureElement() const {
-  return picture_in_picture_element_;
+  return picture_in_picture_element_.Get();
 }
 
 Element* PictureInPictureControllerImpl::PictureInPictureElement(
@@ -345,7 +345,7 @@
 #if !BUILDFLAG(IS_ANDROID)
 LocalDOMWindow* PictureInPictureControllerImpl::documentPictureInPictureWindow()
     const {
-  return document_picture_in_picture_window_;
+  return document_picture_in_picture_window_.Get();
 }
 
 void PictureInPictureControllerImpl::CreateDocumentPictureInPictureWindow(
diff --git a/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc b/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc
index d3870ffe..bfbb583a 100644
--- a/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc
+++ b/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc
@@ -95,7 +95,7 @@
     return ScriptPromise::CastUndefined(script_state_);
   }
 
-  ScriptState* GetScriptState() override { return script_state_; }
+  ScriptState* GetScriptState() override { return script_state_.Get(); }
 
   void Trace(Visitor* visitor) const override {
     visitor->Trace(script_state_);
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc b/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc
index cfb4a50..443d9c8 100644
--- a/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc
+++ b/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc
@@ -110,7 +110,7 @@
 
   DOMArrayBuffer* Data() const {
     DCHECK_EQ(Type::kSetServerCertificate, type_);
-    return data_;
+    return data_.Get();
   }
 
   const String& StringData() const {
diff --git a/third_party/blink/renderer/modules/formatted_text/formatted_text_style.cc b/third_party/blink/renderer/modules/formatted_text/formatted_text_style.cc
index 96658f19..104db78 100644
--- a/third_party/blink/renderer/modules/formatted_text/formatted_text_style.cc
+++ b/third_party/blink/renderer/modules/formatted_text/formatted_text_style.cc
@@ -22,7 +22,7 @@
 }
 
 const CSSPropertyValueSet* FormattedTextStyle::GetCssPropertySet() const {
-  return css_property_value_set_;
+  return css_property_value_set_.Get();
 }
 
 void FormattedTextStyle::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/hid/hid.cc b/third_party/blink/renderer/modules/hid/hid.cc
index b84b1fc..72c9653 100644
--- a/third_party/blink/renderer/modules/hid/hid.cc
+++ b/third_party/blink/renderer/modules/hid/hid.cc
@@ -286,7 +286,7 @@
 HIDDevice* HID::GetOrCreateDevice(device::mojom::blink::HidDeviceInfoPtr info) {
   auto it = device_cache_.find(info->guid);
   if (it != device_cache_.end()) {
-    return it->value;
+    return it->value.Get();
   }
 
   const String guid = info->guid;
diff --git a/third_party/blink/renderer/modules/imagecapture/image_capture.cc b/third_party/blink/renderer/modules/imagecapture/image_capture.cc
index 773070c..0109100 100644
--- a/third_party/blink/renderer/modules/imagecapture/image_capture.cc
+++ b/third_party/blink/renderer/modules/imagecapture/image_capture.cc
@@ -93,7 +93,7 @@
       }
       // The advanced constraint sets.
       wtf_size_t advanced_index = index_ - 1u;
-      return constraints_->advanced()[advanced_index];
+      return constraints_->advanced()[advanced_index].Get();
     }
     ForwardIterator& operator++() {
       ++index_;
@@ -1859,7 +1859,7 @@
 }
 
 MediaTrackConstraints* ImageCapture::GetMediaTrackConstraints() const {
-  return current_constraints_;
+  return current_constraints_.Get();
 }
 
 void ImageCapture::ClearMediaTrackConstraints() {
diff --git a/third_party/blink/renderer/modules/indexeddb/global_indexed_db.cc b/third_party/blink/renderer/modules/indexeddb/global_indexed_db.cc
index a4f5d09..dd2e4ca 100644
--- a/third_party/blink/renderer/modules/indexeddb/global_indexed_db.cc
+++ b/third_party/blink/renderer/modules/indexeddb/global_indexed_db.cc
@@ -37,7 +37,7 @@
   IDBFactory* IdbFactory(ExecutionContext* context) {
     if (!idb_factory_)
       idb_factory_ = MakeGarbageCollected<IDBFactory>(context);
-    return idb_factory_;
+    return idb_factory_.Get();
   }
 
   void Trace(Visitor* visitor) const override {
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc b/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
index 15bad617..a4a6df0 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
@@ -910,7 +910,7 @@
 
   IDBIndexMap::iterator it = index_map_.find(name);
   if (it != index_map_.end())
-    return it->value;
+    return it->value.Get();
 
   int64_t index_id = FindIndexId(name);
   if (index_id == IDBIndexMetadata::kInvalidId) {
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request.cc b/third_party/blink/renderer/modules/indexeddb/idb_request.cc
index e60dcb53..3bb3cec 100644
--- a/third_party/blink/renderer/modules/indexeddb/idb_request.cc
+++ b/third_party/blink/renderer/modules/indexeddb/idb_request.cc
@@ -287,13 +287,13 @@
         IDBDatabase::kRequestNotFinishedErrorMessage);
     return nullptr;
   }
-  return error_;
+  return error_.Get();
 }
 
 const IDBRequest::Source* IDBRequest::source(ScriptState* script_state) const {
   if (!GetExecutionContext())
     return nullptr;
-  return source_;
+  return source_.Get();
 }
 
 const String& IDBRequest::readyState() const {
diff --git a/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc b/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc
index 7ededb4..f7be4ee 100644
--- a/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc
+++ b/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc
@@ -27,7 +27,7 @@
     supplement = MakeGarbageCollected<NavigatorKeyboard>(navigator);
     ProvideTo(navigator, supplement);
   }
-  return supplement->keyboard_;
+  return supplement->keyboard_.Get();
 }
 
 void NavigatorKeyboard::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc
index 6a9bc5b..70b9891 100644
--- a/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc
+++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc
@@ -111,7 +111,7 @@
                                                   CSSValueID::kNone);
   SetOverflowElementIsWanted(false);
 
-  return overflow_label_element_;
+  return overflow_label_element_.Get();
 }
 
 void MediaControlInputElement::UpdateOverflowSubtitleElement(String text) {
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h b/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h
index 1b754a0..dc7058f2 100644
--- a/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h
+++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h
@@ -32,7 +32,7 @@
   void Trace(Visitor*) const override;
 
   MediaControlInputElement* OverflowElementForTests() const {
-    return overflow_element_;
+    return overflow_element_.Get();
   }
 
   // Get the size of the element in pixels or the default if we cannot get the
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
index c1b0479..89e1186 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
@@ -228,10 +228,10 @@
 
   MediaControlsImpl& MediaControls() { return *media_controls_; }
   MediaControlVolumeSliderElement* VolumeSliderElement() const {
-    return media_controls_->volume_slider_;
+    return media_controls_->volume_slider_.Get();
   }
   MediaControlTimelineElement* TimelineElement() const {
-    return media_controls_->timeline_;
+    return media_controls_->timeline_.Get();
   }
   Element* TimelineTrackElement() const {
     if (!TimelineElement())
@@ -239,35 +239,35 @@
     return &TimelineElement()->GetTrackElement();
   }
   MediaControlCurrentTimeDisplayElement* GetCurrentTimeDisplayElement() const {
-    return media_controls_->current_time_display_;
+    return media_controls_->current_time_display_.Get();
   }
   MediaControlRemainingTimeDisplayElement* GetRemainingTimeDisplayElement()
       const {
-    return media_controls_->duration_display_;
+    return media_controls_->duration_display_.Get();
   }
   MediaControlMuteButtonElement* MuteButtonElement() const {
-    return media_controls_->mute_button_;
+    return media_controls_->mute_button_.Get();
   }
   MediaControlCastButtonElement* CastButtonElement() const {
-    return media_controls_->cast_button_;
+    return media_controls_->cast_button_.Get();
   }
   MediaControlDownloadButtonElement* DownloadButtonElement() const {
-    return media_controls_->download_button_;
+    return media_controls_->download_button_.Get();
   }
   MediaControlFullscreenButtonElement* FullscreenButtonElement() const {
-    return media_controls_->fullscreen_button_;
+    return media_controls_->fullscreen_button_.Get();
   }
   MediaControlPlaybackSpeedButtonElement* PlaybackSpeedButtonElement() const {
-    return media_controls_->playback_speed_button_;
+    return media_controls_->playback_speed_button_.Get();
   }
   MediaControlPlayButtonElement* PlayButtonElement() const {
-    return media_controls_->play_button_;
+    return media_controls_->play_button_.Get();
   }
   MediaControlOverflowMenuButtonElement* OverflowMenuButtonElement() const {
-    return media_controls_->overflow_menu_;
+    return media_controls_->overflow_menu_.Get();
   }
   MediaControlOverflowMenuListElement* OverflowMenuListElement() const {
-    return media_controls_->overflow_list_;
+    return media_controls_->overflow_list_.Get();
   }
 
   MockWebMediaPlayerForImpl* WebMediaPlayer() {
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc
index e827741f..538c8783 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc
@@ -140,7 +140,8 @@
 
   bool IsObservingVisibility() const {
     return GetMediaControls()
-        .rotate_to_fullscreen_delegate_->intersection_observer_;
+               .rotate_to_fullscreen_delegate_->intersection_observer_ !=
+           nullptr;
   }
 
   bool ObservedVisibility() const {
diff --git a/third_party/blink/renderer/modules/mediasession/media_session.cc b/third_party/blink/renderer/modules/mediasession/media_session.cc
index 889def45..ae6a167 100644
--- a/third_party/blink/renderer/modules/mediasession/media_session.cc
+++ b/third_party/blink/renderer/modules/mediasession/media_session.cc
@@ -208,7 +208,7 @@
 }
 
 MediaMetadata* MediaSession::metadata() const {
-  return metadata_;
+  return metadata_.Get();
 }
 
 void MediaSession::OnMetadataChanged() {
diff --git a/third_party/blink/renderer/modules/mediasource/media_source.cc b/third_party/blink/renderer/modules/mediasource/media_source.cc
index c41bc5ec..7128e04e 100644
--- a/third_party/blink/renderer/modules/mediasource/media_source.cc
+++ b/third_party/blink/renderer/modules/mediasource/media_source.cc
@@ -1346,7 +1346,7 @@
 std::pair<scoped_refptr<MediaSourceAttachmentSupplement>, MediaSourceTracer*>
 MediaSource::AttachmentAndTracer() const {
   base::AutoLock lock(attachment_link_lock_);
-  return std::make_pair(media_source_attachment_, attachment_tracer_);
+  return std::make_pair(media_source_attachment_, attachment_tracer_.Get());
 }
 
 void MediaSource::EndOfStreamAlgorithm(
@@ -1421,7 +1421,7 @@
   media_source_attachment_ = attachment;
   attachment_tracer_ =
       MakeGarbageCollected<SameThreadMediaSourceTracer>(element, this);
-  return attachment_tracer_;
+  return attachment_tracer_.Get();
 }
 
 bool MediaSource::StartWorkerAttachingToMainThreadMediaElement(
diff --git a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc
index 1b6bac5..81e6d29 100644
--- a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc
+++ b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc
@@ -52,7 +52,7 @@
 void ResolveCropPromiseHelper(
     ScriptPromiseResolverWithTracker<
         BrowserCaptureMediaStreamTrack::CropToResult>* resolver,
-    media::mojom::CropRequestResult result) {
+    media::mojom::ApplySubCaptureTargetResult result) {
   DCHECK(IsMainThread());
 
   if (!resolver) {
@@ -60,18 +60,18 @@
   }
 
   switch (result) {
-    case media::mojom::CropRequestResult::kSuccess:
+    case media::mojom::ApplySubCaptureTargetResult::kSuccess:
       // TODO(crbug.com/1264849): Delay reporting success to the Web-application
       // until "seeing" the last frame cropped to the previous crop-target.
       resolver->Resolve();
       return;
-    case media::mojom::CropRequestResult::kErrorGeneric:
+    case media::mojom::ApplySubCaptureTargetResult::kErrorGeneric:
       RaiseCropException(resolver, DOMExceptionCode::kAbortError,
                          "Unknown error.",
                          BrowserCaptureMediaStreamTrack::CropToResult::
                              kRejectedWithErrorGeneric);
       return;
-    case media::mojom::CropRequestResult::kUnsupportedCaptureDevice:
+    case media::mojom::ApplySubCaptureTargetResult::kUnsupportedCaptureDevice:
       // Note that this is an unsupported device; not an unsupported Element.
       // This should essentially not happen. If it happens, it indicates
       // something in the capture pipeline has been changed.
@@ -80,7 +80,7 @@
                          BrowserCaptureMediaStreamTrack::CropToResult::
                              kRejectedWithUnsupportedCaptureDevice);
       return;
-    case media::mojom::CropRequestResult::kNotImplemented:
+    case media::mojom::ApplySubCaptureTargetResult::kNotImplemented:
       // Unimplemented codepath reached, OTHER than lacking support for
       // a specific Element subtype.
       RaiseCropException(resolver, DOMExceptionCode::kOperationError,
@@ -88,7 +88,7 @@
                          BrowserCaptureMediaStreamTrack::CropToResult::
                              kRejectedWithNotImplemented);
       return;
-    case media::mojom::CropRequestResult::kNonIncreasingCropVersion:
+    case media::mojom::ApplySubCaptureTargetResult::kNonIncreasingVersion:
       // This should rarely happen, as the browser process would issue
       // a BadMessage in this case. But if that message has to hop from
       // the IO thread to the UI thread, it could theoretically happen
@@ -99,7 +99,7 @@
                          BrowserCaptureMediaStreamTrack::CropToResult::
                              kNonIncreasingCropVersion);
       return;
-    case media::mojom::CropRequestResult::kInvalidCropTarget:
+    case media::mojom::ApplySubCaptureTargetResult::kInvalidTarget:
       RaiseCropException(
           resolver, DOMExceptionCode::kNotAllowedError, "Invalid CropTarget.",
           BrowserCaptureMediaStreamTrack::CropToResult::kInvalidCropTarget);
@@ -242,7 +242,7 @@
 #if !BUILDFLAG(IS_ANDROID)
 void BrowserCaptureMediaStreamTrack::OnResultFromBrowserProcess(
     uint32_t crop_version,
-    media::mojom::CropRequestResult result) {
+    media::mojom::ApplySubCaptureTargetResult result) {
   DCHECK(IsMainThread());
   DCHECK_GT(crop_version, 0u);
 
@@ -252,8 +252,8 @@
   }
   CropPromiseInfo* const info = iter->value;
 
-  DCHECK(!info->crop_result.has_value()) << "Invoked twice.";
-  info->crop_result = result;
+  DCHECK(!info->result.has_value()) << "Invoked twice.";
+  info->result = result;
 
   MaybeFinalizeCropPromise(iter);
 }
@@ -282,15 +282,15 @@
 
   CropPromiseInfo* const info = iter->value;
 
-  if (!info->crop_result.has_value()) {
+  if (!info->result.has_value()) {
     return;
   }
 
-  const media::mojom::CropRequestResult result = info->crop_result.value();
+  const media::mojom::ApplySubCaptureTargetResult result = info->result.value();
 
   // Failure can be reported immediately, but success is only reported once
   // the new crop-version is observed.
-  if (result == media::mojom::CropRequestResult::kSuccess &&
+  if (result == media::mojom::ApplySubCaptureTargetResult::kSuccess &&
       !info->crop_version_observed) {
     return;
   }
@@ -298,7 +298,7 @@
   // When `result == kSuccess`, the callback will be removed by the track
   // itself as it invokes it. For failure, we remove the callback immediately,
   // since there's no need to wait.
-  if (result != media::mojom::CropRequestResult::kSuccess) {
+  if (result != media::mojom::ApplySubCaptureTargetResult::kSuccess) {
     MediaStreamTrackPlatform* const native_track =
         MediaStreamTrackPlatform::GetTrack(WebMediaStreamTrack(Component()));
     if (native_track) {
diff --git a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.h b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.h
index 21e404e..2b9c028 100644
--- a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.h
+++ b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.h
@@ -71,7 +71,7 @@
 
     const Member<ScriptPromiseResolverWithTracker<CropToResult>>
         promise_resolver;
-    absl::optional<media::mojom::CropRequestResult> crop_result;
+    absl::optional<media::mojom::ApplySubCaptureTargetResult> result;
     bool crop_version_observed = false;
   };
 
@@ -84,8 +84,9 @@
   // identifies this specific cropTo() invocation. When the browser process
   // responds with the result of the cropTo() invocation, it triggers
   // a call to OnResultFromBrowserProcess() with that |crop_version|.
-  void OnResultFromBrowserProcess(uint32_t crop_version,
-                                  media::mojom::CropRequestResult result);
+  void OnResultFromBrowserProcess(
+      uint32_t crop_version,
+      media::mojom::ApplySubCaptureTargetResult result);
 
   // OnCropVersionObserved() is posted as a callback, bound to a unique
   // |crop_version|. This callback be invoked when the first frame is observed
diff --git a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track_test.cc b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track_test.cc
index 8e202ed..9facebaa 100644
--- a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track_test.cc
@@ -99,8 +99,10 @@
   EXPECT_CALL(*media_stream_video_source, Crop(GUIDToToken(valid_id), _, _))
       .Times(1)
       .WillOnce(::testing::WithArg<2>(::testing::Invoke(
-          [](base::OnceCallback<void(media::mojom::CropRequestResult)> cb) {
-            std::move(cb).Run(media::mojom::CropRequestResult::kSuccess);
+          [](base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+                 cb) {
+            std::move(cb).Run(
+                media::mojom::ApplySubCaptureTargetResult::kSuccess);
           })));
 
   BrowserCaptureMediaStreamTrack* const track =
@@ -137,8 +139,10 @@
   EXPECT_CALL(*media_stream_video_source, Crop(GUIDToToken(valid_id), _, _))
       .Times(1)
       .WillOnce(::testing::WithArg<2>(::testing::Invoke(
-          [](base::OnceCallback<void(media::mojom::CropRequestResult)> cb) {
-            std::move(cb).Run(media::mojom::CropRequestResult::kErrorGeneric);
+          [](base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+                 cb) {
+            std::move(cb).Run(
+                media::mojom::ApplySubCaptureTargetResult::kErrorGeneric);
           })));
 
   BrowserCaptureMediaStreamTrack* const track =
diff --git a/third_party/blink/renderer/modules/mediastream/crop_target.cc b/third_party/blink/renderer/modules/mediastream/crop_target.cc
index 9e79be8..d218f9f 100644
--- a/third_party/blink/renderer/modules/mediastream/crop_target.cc
+++ b/third_party/blink/renderer/modules/mediastream/crop_target.cc
@@ -4,8 +4,10 @@
 
 #include "third_party/blink/renderer/modules/mediastream/crop_target.h"
 
+#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/modules/mediastream/media_devices.h"
+#include "third_party/blink/renderer/modules/mediastream/sub_capture_target.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 
 namespace blink {
@@ -14,10 +16,10 @@
                                       Element* element,
                                       ExceptionState& exception_state) {
   return SubCaptureTarget::fromElement(script_state, element, exception_state,
-                                       SubCaptureTargetType::kCropTarget);
+                                       SubCaptureTarget::Type::kCropTarget);
 }
 
 CropTarget::CropTarget(String id)
-    : SubCaptureTarget(SubCaptureTargetType::kCropTarget, std::move(id)) {}
+    : SubCaptureTarget(SubCaptureTarget::Type::kCropTarget, std::move(id)) {}
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.cc b/third_party/blink/renderer/modules/mediastream/media_devices.cc
index 21d6ade..ffbe9983 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_devices.cc
@@ -16,6 +16,7 @@
 #include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
 #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
 #include "third_party/blink/public/mojom/media/capture_handle_config.mojom-blink.h"
+#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h"
 #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-blink.h"
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
@@ -46,6 +47,7 @@
 #include "third_party/blink/renderer/modules/mediastream/media_stream.h"
 #include "third_party/blink/renderer/modules/mediastream/navigator_media_stream.h"
 #include "third_party/blink/renderer/modules/mediastream/restriction_target.h"
+#include "third_party/blink/renderer/modules/mediastream/sub_capture_target.h"
 #include "third_party/blink/renderer/modules/mediastream/user_media_client.h"
 #include "third_party/blink/renderer/platform/bindings/exception_messages.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -162,11 +164,12 @@
   kMaxValue = kElementAndMediaDevicesNotInSameExecutionContext
 };
 
-void RecordUma(SubCaptureTargetType type, ProduceTargetFunctionResult result) {
-  if (type == SubCaptureTargetType::kCropTarget) {
+void RecordUma(SubCaptureTarget::Type type,
+               ProduceTargetFunctionResult result) {
+  if (type == SubCaptureTarget::Type::kCropTarget) {
     base::UmaHistogramEnumeration(
         "Media.RegionCapture.ProduceCropTarget.Function.Result", result);
-  } else if (type == SubCaptureTargetType::kRestrictionTarget) {
+  } else if (type == SubCaptureTarget::Type::kRestrictionTarget) {
     base::UmaHistogramEnumeration(
         "Media.ElementCapture.ProduceTarget.Function.Result", result);
   } else {
@@ -182,11 +185,11 @@
   kMaxValue = kPromiseRejected
 };
 
-void RecordUma(SubCaptureTargetType type, ProduceTargetPromiseResult result) {
-  if (type == SubCaptureTargetType::kCropTarget) {
+void RecordUma(SubCaptureTarget::Type type, ProduceTargetPromiseResult result) {
+  if (type == SubCaptureTarget::Type::kCropTarget) {
     base::UmaHistogramEnumeration(
         "Media.RegionCapture.ProduceCropTarget.Promise.Result", result);
-  } else if (type == SubCaptureTargetType::kRestrictionTarget) {
+  } else if (type == SubCaptureTarget::Type::kRestrictionTarget) {
     base::UmaHistogramEnumeration(
         "Media.ElementCapture.ProduceTarget.Promise.Result", result);
   } else {
@@ -699,10 +702,10 @@
     ScriptState* script_state,
     Element* element,
     ExceptionState& exception_state,
-    SubCaptureTargetType type) {
+    SubCaptureTarget::Type type) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  CHECK(type == SubCaptureTargetType::kCropTarget ||
-        type == SubCaptureTargetType::kRestrictionTarget);
+  CHECK(type == SubCaptureTarget::Type::kCropTarget ||
+        type == SubCaptureTarget::Type::kRestrictionTarget);
 
 #if BUILDFLAG(IS_ANDROID)
   exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
@@ -739,12 +742,12 @@
     return ScriptPromise();
   }
 
-  if ((type == SubCaptureTargetType::kCropTarget &&
+  if ((type == SubCaptureTarget::Type::kCropTarget &&
        element->GetRegionCaptureCropId()) ||
-      (type == SubCaptureTargetType::kRestrictionTarget &&
+      (type == SubCaptureTarget::Type::kRestrictionTarget &&
        element->GetRestrictionTargetId())) {
     // A token was produced earlier and associated with the Element.
-    const base::Token token = (type == SubCaptureTargetType::kCropTarget)
+    const base::Token token = (type == SubCaptureTarget::Type::kCropTarget)
                                   ? element->GetRegionCaptureCropId()->value()
                                   : element->GetRestrictionTargetId()->value();
     DCHECK(!token.is_zero());
@@ -752,7 +755,7 @@
         script_state, exception_state.GetContext());
     const ScriptPromise promise = resolver->Promise();
     const WTF::String token_str(blink::TokenToGUID(token).AsLowercaseString());
-    if (type == SubCaptureTargetType::kCropTarget) {
+    if (type == SubCaptureTarget::Type::kCropTarget) {
       resolver->Resolve(MakeGarbageCollected<CropTarget>(token_str));
     } else {  // kRestrictionTarget
       resolver->Resolve(MakeGarbageCollected<RestrictionTarget>(token_str));
@@ -776,8 +779,8 @@
     return it->value->Promise();
   }
 
-  // Mints a new crop-ID on the browser process. Resolve when it's produced
-  // and ready to be used.
+  // Mints a new ID on the browser process.
+  // Resolves after it has been produced and is ready to be used.
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(
       script_state, exception_state.GetContext());
   map.insert(element, resolver);
@@ -786,19 +789,8 @@
   base::OnceCallback callback =
       WTF::BindOnce(&MediaDevices::ResolveSubCaptureTargetPromise,
                     WrapPersistent(this), WrapPersistent(element), type);
-
-  switch (type) {
-    case SubCaptureTargetType::kCropTarget:
-      GetDispatcherHost(window->GetFrame()).ProduceCropId(std::move(callback));
-      break;
-    case SubCaptureTargetType::kRestrictionTarget:
-      // TODO(crbug.com/1418194): Define  ProduceRestrictionTargetId, so as to
-      // complete this block as:
-      // GetDispatcherHost(
-      //   window->GetFrame()).ProduceRestrictionTargetId(std::move(callback));
-      NOTIMPLEMENTED();
-      break;
-  }
+  GetDispatcherHost(window->GetFrame())
+      .ProduceSubCaptureTargetId(type, std::move(callback));
 
   RecordUma(type, ProduceTargetFunctionResult::kPromiseProduced);
   return promise;
@@ -1119,11 +1111,11 @@
 
 #if !BUILDFLAG(IS_ANDROID)
 MediaDevices::ElementToResolverMap& MediaDevices::GetResolverMap(
-    SubCaptureTargetType type) {
+    SubCaptureTarget::Type type) {
   switch (type) {
-    case SubCaptureTargetType::kCropTarget:
+    case SubCaptureTarget::Type::kCropTarget:
       return crop_target_resolvers_;
-    case SubCaptureTargetType::kRestrictionTarget:
+    case SubCaptureTarget::Type::kRestrictionTarget:
       return restriction_target_resolvers_;
   }
   NOTREACHED_NORETURN();
@@ -1167,11 +1159,11 @@
 // An empty |id| signals failure; anything else has to be a valid GUID
 // and signals success.
 void MediaDevices::ResolveSubCaptureTargetPromise(Element* element,
-                                                  SubCaptureTargetType type,
+                                                  SubCaptureTarget::Type type,
                                                   const WTF::String& id) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  CHECK(type == SubCaptureTargetType::kCropTarget ||
-        type == SubCaptureTargetType::kRestrictionTarget);
+  CHECK(type == SubCaptureTarget::Type::kCropTarget ||
+        type == SubCaptureTarget::Type::kRestrictionTarget);
   CHECK(element);  // Persistent.
 
   ElementToResolverMap& map = GetResolverMap(type);
@@ -1183,14 +1175,21 @@
   if (id.empty()) {
     resolver->Reject();
     RecordUma(type, ProduceTargetPromiseResult::kPromiseRejected);
-  } else {
-    const base::Uuid guid = base::Uuid::ParseLowercase(id.Ascii());
-    DCHECK(guid.is_valid());
+    return;
+  }
+
+  const base::Uuid guid = base::Uuid::ParseLowercase(id.Ascii());
+  DCHECK(guid.is_valid());
+  if (type == SubCaptureTarget::Type::kCropTarget) {
     element->SetRegionCaptureCropId(
         std::make_unique<RegionCaptureCropId>(blink::GUIDToToken(guid)));
     resolver->Resolve(MakeGarbageCollected<CropTarget>(id));
-    RecordUma(type, ProduceTargetPromiseResult::kPromiseResolved);
+  } else {  // kRestrictionTarget as per earlier CHECK.
+    element->SetRestrictionTargetId(
+        std::make_unique<RestrictionTargetId>(blink::GUIDToToken(guid)));
+    resolver->Resolve(MakeGarbageCollected<RestrictionTarget>(id));
   }
+  RecordUma(type, ProduceTargetPromiseResult::kPromiseResolved);
 }
 #endif
 
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.h b/third_party/blink/renderer/modules/mediastream/media_devices.h
index 5a59758..0814787 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices.h
+++ b/third_party/blink/renderer/modules/mediastream/media_devices.h
@@ -53,11 +53,6 @@
   kMaxValue = kTimedOut
 };
 
-enum class SubCaptureTargetType {
-  kCropTarget,
-  kRestrictionTarget,
-};
-
 class MODULES_EXPORT MediaDevices final
     : public EventTarget,
       public ActiveScriptWrappable<MediaDevices>,
@@ -67,6 +62,8 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+  using SubCaptureTargetType = mojom::blink::SubCaptureTargetType;
+
   static const char kSupplementName[];
   static MediaDevices* mediaDevices(Navigator&);
   explicit MediaDevices(Navigator&);
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices_test.cc b/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
index e7483248..749c33d 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
@@ -26,6 +26,7 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_capture_handle_config.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_crop_target.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_media_device_info.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_restriction_target.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_user_media_stream_constraints.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/core/dom/events/event_listener.h"
@@ -36,6 +37,7 @@
 #include "third_party/blink/renderer/core/testing/page_test_base.h"
 #include "third_party/blink/renderer/modules/mediastream/crop_target.h"
 #include "third_party/blink/renderer/modules/mediastream/media_device_info.h"
+#include "third_party/blink/renderer/modules/mediastream/restriction_target.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support.h"
 #include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -206,14 +208,23 @@
 #if !BUILDFLAG(IS_ANDROID)
   void CloseFocusWindowOfOpportunity(const String& label) override {}
 
-  void ProduceCropId(ProduceCropIdCallback callback) override {
-    String next_crop_id = "";  // Empty, not null.
-    std::swap(next_crop_id_, next_crop_id);
-    std::move(callback).Run(std::move(next_crop_id));
+  void ProduceSubCaptureTargetId(
+      SubCaptureTarget::Type type,
+      ProduceSubCaptureTargetIdCallback callback) override {
+    auto it = next_ids_.find(type);
+    if (it == next_ids_.end()) {
+      GTEST_FAIL();
+    }
+    std::vector<String>& queue = it->second;
+    CHECK(!queue.empty());
+    String next_id = queue.front();
+    queue.erase(queue.begin());
+    std::move(callback).Run(std::move(next_id));
   }
 
-  void SetNextCropId(String next_crop_id) {
-    next_crop_id_ = std::move(next_crop_id);
+  void SetNextId(SubCaptureTarget::Type type, String next_id) {
+    std::vector<String>& queue = next_ids_[type];
+    queue.push_back(std::move(next_id));
   }
 #endif
 
@@ -274,9 +285,7 @@
   mojo::Remote<mojom::blink::MediaDevicesListener> listener_;
   mojo::Receiver<mojom::blink::MediaDevicesDispatcherHost> receiver_{this};
   mojom::blink::CaptureHandleConfigPtr expected_capture_handle_config_;
-#if !BUILDFLAG(IS_ANDROID)
-  String next_crop_id_ = "";  // Empty, not null.
-#endif
+  std::map<SubCaptureTarget::Type, std::vector<String>> next_ids_;
 
   Vector<Vector<WebMediaDeviceInfo>> enumeration_{static_cast<size_t>(
       blink::mojom::blink::MediaDeviceType::kNumMediaDeviceTypes)};
@@ -313,6 +322,22 @@
   EXPECT_EQ(device->kind(), ToString(type));
 }
 
+#if !BUILDFLAG(IS_ANDROID)
+SubCaptureTarget* ToSubCaptureTarget(const blink::ScriptValue& value) {
+  if (CropTarget* crop_target =
+          V8CropTarget::ToWrappable(value.GetIsolate(), value.V8Value())) {
+    return crop_target;
+  }
+
+  if (RestrictionTarget* restriction_target = V8RestrictionTarget::ToWrappable(
+          value.GetIsolate(), value.V8Value())) {
+    return restriction_target;
+  }
+
+  NOTREACHED_NORETURN();
+}
+#endif  // !BUILDFLAG(IS_ANDROID)
+
 }  // namespace
 
 class MediaDevicesTest : public PageTestBase {
@@ -729,13 +754,96 @@
             ToExceptionCode(DOMExceptionCode::kNotSupportedError));
 }
 
+#if !BUILDFLAG(IS_ANDROID)
+// This test logically belongs to the ProduceSubCaptureTargetTest suite,
+// but does not require parameterization.
+TEST_F(MediaDevicesTest, DistinctIdsForDistinctTypes) {
+  ScopedElementCaptureForTest scoped_element_capture(true);
+  V8TestingScope scope;
+  MediaDevices* const media_devices =
+      GetMediaDevices(*GetDocument().domWindow());
+  ASSERT_TRUE(media_devices);
+
+  dispatcher_host().SetNextId(SubCaptureTarget::Type::kCropTarget,
+                              String("983bf2ff-7410-416c-808a-78421cbd8fdc"));
+  dispatcher_host().SetNextId(SubCaptureTarget::Type::kRestrictionTarget,
+                              String("70db842e-5326-42c1-86b2-e3b2f74e97d2"));
+
+  SetBodyContent(R"HTML(
+    <div id='test-div'></div>
+  )HTML");
+
+  Document& document = GetDocument();
+  Element* const div = document.getElementById(AtomicString("test-div"));
+  const ScriptPromise first_promise = media_devices->ProduceSubCaptureTarget(
+      scope.GetScriptState(), div, scope.GetExceptionState(),
+      SubCaptureTarget::Type::kCropTarget);
+  ScriptPromiseTester first_tester(scope.GetScriptState(), first_promise);
+  first_tester.WaitUntilSettled();
+  EXPECT_TRUE(first_tester.IsFulfilled());
+  EXPECT_FALSE(scope.GetExceptionState().HadException());
+
+  // The second call to |produceSubCaptureTargetId|, given the different type,
+  // should return a different ID.
+  const ScriptPromise second_promise = media_devices->ProduceSubCaptureTarget(
+      scope.GetScriptState(), div, scope.GetExceptionState(),
+      SubCaptureTarget::Type::kRestrictionTarget);
+  ScriptPromiseTester second_tester(scope.GetScriptState(), second_promise);
+  second_tester.WaitUntilSettled();
+  EXPECT_TRUE(second_tester.IsFulfilled());
+  EXPECT_FALSE(scope.GetExceptionState().HadException());
+
+  const WTF::String first_result =
+      ToSubCaptureTarget(first_tester.Value())->GetId();
+  ASSERT_FALSE(first_result.empty());
+
+  const WTF::String second_result =
+      ToSubCaptureTarget(second_tester.Value())->GetId();
+  ASSERT_FALSE(second_result.empty());
+
+  EXPECT_NE(first_result, second_result);
+}
+#endif  // !BUILDFLAG(IS_ANDROID)
+
+class ProduceSubCaptureTargetTest
+    : public MediaDevicesTest,
+      public testing::WithParamInterface<
+          std::pair<SubCaptureTarget::Type, bool>> {
+ public:
+  ProduceSubCaptureTargetTest()
+      : type_(std::get<0>(GetParam())),
+        scoped_element_capture_(std::get<1>(GetParam())) {}
+  ~ProduceSubCaptureTargetTest() override = default;
+
+  const SubCaptureTarget::Type type_;
+  ScopedElementCaptureForTest scoped_element_capture_;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    _,
+    ProduceSubCaptureTargetTest,
+    ::testing::Values(std::make_pair(SubCaptureTarget::Type::kCropTarget,
+                                     /* Element Capture enabled: */ false),
+                      std::make_pair(SubCaptureTarget::Type::kCropTarget,
+                                     /* Element Capture enabled: */ true),
+                      std::make_pair(SubCaptureTarget::Type::kRestrictionTarget,
+                                     /* Element Capture enabled: */ true)));
+
 // Note: This test runs on non-Android too in order to prove that the test
 // itself is sane. (Rather than, for example, an exception always being thrown.)
-TEST_F(MediaDevicesTest, ProduceCropIdUnsupportedOnAndroid) {
+TEST_P(ProduceSubCaptureTargetTest, IdUnsupportedOnAndroid) {
   V8TestingScope scope;
   auto* media_devices = GetMediaDevices(*GetDocument().domWindow());
   ASSERT_TRUE(media_devices);
 
+#if !BUILDFLAG(IS_ANDROID)
+  // Note that the test will NOT produce false-positive on failure to call this.
+  // Rather, GTEST_FAIL would be called by ProduceSubCaptureTarget if it
+  // ends up being called.
+  dispatcher_host().SetNextId(
+      type_, String(base::Uuid::GenerateRandomV4().AsLowercaseString()));
+#endif
+
   SetBodyContent(R"HTML(
     <div id='test-div'></div>
     <iframe id='test-iframe' src="about:blank" />
@@ -744,8 +852,7 @@
   Document& document = GetDocument();
   Element* const div = document.getElementById(AtomicString("test-div"));
   const ScriptPromise div_promise = media_devices->ProduceSubCaptureTarget(
-      scope.GetScriptState(), div, scope.GetExceptionState(),
-      SubCaptureTargetType::kCropTarget);
+      scope.GetScriptState(), div, scope.GetExceptionState(), type_);
   platform()->RunUntilIdle();
 #if BUILDFLAG(IS_ANDROID)
   EXPECT_TRUE(scope.GetExceptionState().HadException());
@@ -756,7 +863,7 @@
 }
 
 #if !BUILDFLAG(IS_ANDROID)
-TEST_F(MediaDevicesTest, ProduceCropIdWithValidElement) {
+TEST_P(ProduceSubCaptureTargetTest, IdWithValidElement) {
   V8TestingScope scope;
   auto* media_devices = GetMediaDevices(*GetDocument().domWindow());
   ASSERT_TRUE(media_devices);
@@ -787,11 +894,10 @@
 
   for (const char* id : kElementIds) {
     Element* const element = document.getElementById(AtomicString(id));
-    dispatcher_host().SetNextCropId(
-        String(base::Uuid::GenerateRandomV4().AsLowercaseString()));
+    dispatcher_host().SetNextId(
+        type_, String(base::Uuid::GenerateRandomV4().AsLowercaseString()));
     const ScriptPromise promise = media_devices->ProduceSubCaptureTarget(
-        scope.GetScriptState(), element, scope.GetExceptionState(),
-        SubCaptureTargetType::kCropTarget);
+        scope.GetScriptState(), element, scope.GetExceptionState(), type_);
 
     ScriptPromiseTester script_promise_tester(scope.GetScriptState(), promise);
     script_promise_tester.WaitUntilSettled();
@@ -801,7 +907,7 @@
   }
 }
 
-TEST_F(MediaDevicesTest, ProduceCropIdRejectedIfDifferentWindow) {
+TEST_P(ProduceSubCaptureTargetTest, IdRejectedIfDifferentWindow) {
   V8TestingScope scope;
   // Intentionally sets up a MediaDevices object in a different window.
   auto* media_devices = GetMediaDevices(scope.GetWindow());
@@ -815,8 +921,7 @@
   Document& document = GetDocument();
   Element* const div = document.getElementById(AtomicString("test-div"));
   const ScriptPromise element_promise = media_devices->ProduceSubCaptureTarget(
-      scope.GetScriptState(), div, scope.GetExceptionState(),
-      SubCaptureTargetType::kCropTarget);
+      scope.GetScriptState(), div, scope.GetExceptionState(), type_);
   platform()->RunUntilIdle();
   EXPECT_TRUE(element_promise.IsEmpty());
   EXPECT_TRUE(scope.GetExceptionState().HadException());
@@ -827,12 +932,18 @@
       String("The Element and the MediaDevices object must be same-window."));
 }
 
-TEST_F(MediaDevicesTest, ProduceCropIdDuplicate) {
+TEST_P(ProduceSubCaptureTargetTest, DuplicateId) {
   V8TestingScope scope;
   auto* media_devices = GetMediaDevices(*GetDocument().domWindow());
   ASSERT_TRUE(media_devices);
-  dispatcher_host().SetNextCropId(
-      String(base::Uuid::GenerateRandomV4().AsLowercaseString()));
+
+  // This ID should be used for the single ID produced.
+  dispatcher_host().SetNextId(type_,
+                              String("983bf2ff-7410-416c-808a-78421cbd8fdc"));
+
+  // This ID should never be encountered.
+  dispatcher_host().SetNextId(type_,
+                              String("70db842e-5326-42c1-86b2-e3b2f74e97d2"));
 
   SetBodyContent(R"HTML(
     <div id='test-div'></div>
@@ -841,29 +952,32 @@
   Document& document = GetDocument();
   Element* const div = document.getElementById(AtomicString("test-div"));
   const ScriptPromise first_promise = media_devices->ProduceSubCaptureTarget(
-      scope.GetScriptState(), div, scope.GetExceptionState(),
-      SubCaptureTargetType::kCropTarget);
+      scope.GetScriptState(), div, scope.GetExceptionState(), type_);
   ScriptPromiseTester first_tester(scope.GetScriptState(), first_promise);
   first_tester.WaitUntilSettled();
   EXPECT_TRUE(first_tester.IsFulfilled());
   EXPECT_FALSE(scope.GetExceptionState().HadException());
 
-  // The second call to |produceCropId| should return the same ID.
+  // The second call to |produceSubCaptureTargetId| should return the same ID.
   const ScriptPromise second_promise = media_devices->ProduceSubCaptureTarget(
-      scope.GetScriptState(), div, scope.GetExceptionState(),
-      SubCaptureTargetType::kCropTarget);
+      scope.GetScriptState(), div, scope.GetExceptionState(), type_);
   ScriptPromiseTester second_tester(scope.GetScriptState(), second_promise);
   second_tester.WaitUntilSettled();
   EXPECT_TRUE(second_tester.IsFulfilled());
   EXPECT_FALSE(scope.GetExceptionState().HadException());
 
-  WTF::String first_result, second_result;
-  first_tester.Value().ToString(first_result);
-  second_tester.Value().ToString(second_result);
+  const WTF::String first_result =
+      ToSubCaptureTarget(first_tester.Value())->GetId();
+  ASSERT_FALSE(first_result.empty());
+
+  const WTF::String second_result =
+      ToSubCaptureTarget(second_tester.Value())->GetId();
+  ASSERT_FALSE(second_result.empty());
+
   EXPECT_EQ(first_result, second_result);
 }
 
-TEST_F(MediaDevicesTest, ProduceCropIdStringFormat) {
+TEST_P(ProduceSubCaptureTargetTest, CorrectTokenClassInstantiated) {
   V8TestingScope scope;
   auto* media_devices = GetMediaDevices(*GetDocument().domWindow());
   ASSERT_TRUE(media_devices);
@@ -874,21 +988,50 @@
 
   Document& document = GetDocument();
   Element* const div = document.getElementById(AtomicString("test-div"));
-  dispatcher_host().SetNextCropId(
-      String(base::Uuid::GenerateRandomV4().AsLowercaseString()));
+  dispatcher_host().SetNextId(
+      type_, String(base::Uuid::GenerateRandomV4().AsLowercaseString()));
+
   const ScriptPromise promise = media_devices->ProduceSubCaptureTarget(
-      scope.GetScriptState(), div, scope.GetExceptionState(),
-      SubCaptureTargetType::kCropTarget);
+      scope.GetScriptState(), div, scope.GetExceptionState(), type_);
+
+  ScriptPromiseTester tester(scope.GetScriptState(), promise);
+  tester.WaitUntilSettled();
+  ASSERT_TRUE(tester.IsFulfilled());
+  ASSERT_FALSE(scope.GetExceptionState().HadException());
+
+  // Type instantiated if and only if it's the expected type.
+  const blink::ScriptValue value = tester.Value();
+  EXPECT_EQ(!!V8CropTarget::ToWrappable(value.GetIsolate(), value.V8Value()),
+            type_ == SubCaptureTarget::Type::kCropTarget);
+  EXPECT_EQ(
+      !!V8RestrictionTarget::ToWrappable(value.GetIsolate(), value.V8Value()),
+      type_ == SubCaptureTarget::Type::kRestrictionTarget);
+}
+
+TEST_P(ProduceSubCaptureTargetTest, IdStringFormat) {
+  V8TestingScope scope;
+  auto* media_devices = GetMediaDevices(*GetDocument().domWindow());
+  ASSERT_TRUE(media_devices);
+
+  SetBodyContent(R"HTML(
+    <div id='test-div'></div>
+  )HTML");
+
+  Document& document = GetDocument();
+  Element* const div = document.getElementById(AtomicString("test-div"));
+  dispatcher_host().SetNextId(
+      type_, String(base::Uuid::GenerateRandomV4().AsLowercaseString()));
+  const ScriptPromise promise = media_devices->ProduceSubCaptureTarget(
+      scope.GetScriptState(), div, scope.GetExceptionState(), type_);
   ScriptPromiseTester tester(scope.GetScriptState(), promise);
   tester.WaitUntilSettled();
   EXPECT_TRUE(tester.IsFulfilled());
   EXPECT_FALSE(scope.GetExceptionState().HadException());
 
-  const CropTarget* const crop_target =
-      V8CropTarget::ToWrappable(scope.GetIsolate(), tester.Value().V8Value());
-  const WTF::String& crop_id = crop_target->GetId();
-  EXPECT_TRUE(crop_id.ContainsOnlyASCIIOrEmpty());
-  EXPECT_TRUE(base::Uuid::ParseLowercase(crop_id.Ascii()).is_valid());
+  const SubCaptureTarget* const target = ToSubCaptureTarget(tester.Value());
+  const WTF::String& id = target->GetId();
+  EXPECT_TRUE(id.ContainsOnlyASCIIOrEmpty());
+  EXPECT_TRUE(base::Uuid::ParseLowercase(id.Ascii()).is_valid());
 }
 #endif
 
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_track_impl.cc b/third_party/blink/renderer/modules/mediastream/media_stream_track_impl.cc
index 19a951e2..5e57d00 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_track_impl.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_track_impl.cc
@@ -699,7 +699,7 @@
       if (!video_stats_) {
         video_stats_ = MakeGarbageCollected<MediaStreamTrackVideoStats>(this);
       }
-      return video_stats_;
+      return video_stats_.Get();
     }
   }
 }
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc
index 878d899..3df5ea6b 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc
@@ -199,12 +199,14 @@
 void MediaStreamVideoCapturerSource::Crop(
     const base::Token& crop_id,
     uint32_t crop_version,
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
+    base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+        callback) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   const absl::optional<base::UnguessableToken>& session_id =
       device().serializable_session_id();
   if (!session_id.has_value()) {
-    std::move(callback).Run(media::mojom::CropRequestResult::kErrorGeneric);
+    std::move(callback).Run(
+        media::mojom::ApplySubCaptureTargetResult::kErrorGeneric);
     return;
   }
   GetMediaStreamDispatcherHost()->Crop(session_id.value(), crop_id,
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h b/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h
index 2361e02..6c5d284b 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h
@@ -95,8 +95,8 @@
 #if !BUILDFLAG(IS_ANDROID)
   void Crop(const base::Token& crop_id,
             uint32_t crop_version,
-            base::OnceCallback<void(media::mojom::CropRequestResult)> callback)
-      override;
+            base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+                callback) override;
   absl::optional<uint32_t> GetNextCropVersion() override;
 #endif
   uint32_t GetCropVersion() const override;
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc
index b65f6779..53534de 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc
@@ -568,8 +568,10 @@
 void MediaStreamVideoSource::Crop(
     const base::Token& crop_id,
     uint32_t crop_version,
-    base::OnceCallback<void(media::mojom::CropRequestResult)> callback) {
-  std::move(callback).Run(media::mojom::CropRequestResult::kErrorGeneric);
+    base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>
+        callback) {
+  std::move(callback).Run(
+      media::mojom::ApplySubCaptureTargetResult::kErrorGeneric);
 }
 
 absl::optional<uint32_t> MediaStreamVideoSource::GetNextCropVersion() {
diff --git a/third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h b/third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h
index 8fcbdbe..b449905 100644
--- a/third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h
+++ b/third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h
@@ -32,10 +32,12 @@
   MOCK_METHOD1(OnCapturingLinkSecured, void(bool));
   MOCK_METHOD1(OnSourceCanDiscardAlpha, void(bool can_discard_alpha));
   MOCK_CONST_METHOD0(SupportsEncodedOutput, bool());
-  MOCK_METHOD3(Crop,
-               void(const base::Token&,
-                    uint32_t,
-                    base::OnceCallback<void(media::mojom::CropRequestResult)>));
+  MOCK_METHOD3(
+      Crop,
+      void(
+          const base::Token&,
+          uint32_t,
+          base::OnceCallback<void(media::mojom::ApplySubCaptureTargetResult)>));
   MOCK_METHOD0(GetNextCropVersion, absl::optional<uint32_t>());
   MOCK_METHOD(uint32_t, GetCropVersion, (), (const, override));
 
diff --git a/third_party/blink/renderer/modules/mediastream/restriction_target.cc b/third_party/blink/renderer/modules/mediastream/restriction_target.cc
index a7625c6..24bae45 100644
--- a/third_party/blink/renderer/modules/mediastream/restriction_target.cc
+++ b/third_party/blink/renderer/modules/mediastream/restriction_target.cc
@@ -4,8 +4,10 @@
 
 #include "third_party/blink/renderer/modules/mediastream/restriction_target.h"
 
+#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/modules/mediastream/media_devices.h"
+#include "third_party/blink/renderer/modules/mediastream/sub_capture_target.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 
 namespace blink {
@@ -15,11 +17,11 @@
                                              ExceptionState& exception_state) {
   return SubCaptureTarget::fromElement(
       script_state, element, exception_state,
-      SubCaptureTargetType::kRestrictionTarget);
+      SubCaptureTarget::Type::kRestrictionTarget);
 }
 
 RestrictionTarget::RestrictionTarget(String id)
-    : SubCaptureTarget(SubCaptureTargetType::kRestrictionTarget,
+    : SubCaptureTarget(SubCaptureTarget::Type::kRestrictionTarget,
                        std::move(id)) {}
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/restriction_target.idl b/third_party/blink/renderer/modules/mediastream/restriction_target.idl
index 1220654..eb910b2 100644
--- a/third_party/blink/renderer/modules/mediastream/restriction_target.idl
+++ b/third_party/blink/renderer/modules/mediastream/restriction_target.idl
@@ -4,8 +4,7 @@
 
 // https://screen-share.github.io/element-capture/#dom-restrictiontarget
 
-// TODO(1418194): Make RestrictionTarget tokens Serializable.
-[Exposed=(Window,Worker), RuntimeEnabled = ElementCapture]
+[Exposed=(Window,Worker), Serializable, RuntimeEnabled = ElementCapture]
 interface RestrictionTarget {
   [
     Exposed=Window,
diff --git a/third_party/blink/renderer/modules/mediastream/screen_capture_media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/screen_capture_media_stream_track.cc
index 3db6fb0..3c5af77 100644
--- a/third_party/blink/renderer/modules/mediastream/screen_capture_media_stream_track.cc
+++ b/third_party/blink/renderer/modules/mediastream/screen_capture_media_stream_track.cc
@@ -45,7 +45,7 @@
         DOMExceptionCode::kInvalidStateError,
         "The ScreenDetailed object could not be created.");
   }
-  return screen_detailed_;
+  return screen_detailed_.Get();
 }
 
 void ScreenCaptureMediaStreamTrack::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/mediastream/sub_capture_target.cc b/third_party/blink/renderer/modules/mediastream/sub_capture_target.cc
index afdcdf2..867e4bc 100644
--- a/third_party/blink/renderer/modules/mediastream/sub_capture_target.cc
+++ b/third_party/blink/renderer/modules/mediastream/sub_capture_target.cc
@@ -12,7 +12,7 @@
 
 namespace blink {
 
-SubCaptureTarget::SubCaptureTarget(SubCaptureTargetType type, String id)
+SubCaptureTarget::SubCaptureTarget(Type type, String id)
     : type_(type), id_(std::move(id)) {
   CHECK(!id_.empty());
 }
@@ -20,7 +20,7 @@
 ScriptPromise SubCaptureTarget::fromElement(ScriptState* script_state,
                                             Element* element,
                                             ExceptionState& exception_state,
-                                            SubCaptureTargetType type) {
+                                            Type type) {
   DCHECK(IsMainThread());
 
 #if BUILDFLAG(IS_ANDROID)
diff --git a/third_party/blink/renderer/modules/mediastream/sub_capture_target.h b/third_party/blink/renderer/modules/mediastream/sub_capture_target.h
index 86c53b9c..609dbe1dc 100644
--- a/third_party/blink/renderer/modules/mediastream/sub_capture_target.h
+++ b/third_party/blink/renderer/modules/mediastream/sub_capture_target.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_SUB_CAPTURE_TARGET_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_SUB_CAPTURE_TARGET_H_
 
+#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
@@ -13,13 +14,14 @@
 namespace blink {
 
 class ScriptState;
-enum class SubCaptureTargetType;
 
 // Mutual non-Web-exposed parent class for various Web-exposed tokens
 // which use the same minting logic under the hood.
 class MODULES_EXPORT SubCaptureTarget : public ScriptWrappable {
  public:
-  SubCaptureTargetType GetType() const { return type_; }
+  using Type = mojom::blink::SubCaptureTargetType;
+
+  Type GetType() const { return type_; }
 
   // The ID is a UUID. SubCaptureTarget wraps it and abstracts it away for JS,
   // but internally, the implementation is based on this implementation detail.
@@ -29,12 +31,12 @@
   static ScriptPromise fromElement(ScriptState* script_state,
                                    Element* element,
                                    ExceptionState& exception_state,
-                                   SubCaptureTargetType type);
+                                   Type type);
 
-  SubCaptureTarget(SubCaptureTargetType type, String id);
+  SubCaptureTarget(Type type, String id);
 
  private:
-  const SubCaptureTargetType type_;
+  const Type type_;
 
   // TODO(crbug.com/1332628): Wrap the base::Token instead of wrapping its
   // string representation.
diff --git a/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.cc
index a3a2a04d..21e2059 100644
--- a/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.cc
+++ b/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.cc
@@ -288,7 +288,7 @@
   if (track_) {
     return track_->Component();
   }
-  return transferred_component_;
+  return transferred_component_.Get();
 }
 
 bool TransferredMediaStreamTrack::Ended() const {
@@ -321,7 +321,7 @@
 }
 
 ExecutionContext* TransferredMediaStreamTrack::GetExecutionContext() const {
-  return execution_context_;
+  return execution_context_.Get();
 }
 
 void TransferredMediaStreamTrack::AddedEventListener(
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_client.cc b/third_party/blink/renderer/modules/mediastream/user_media_client.cc
index 384a460..84d959b 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_client.cc
+++ b/third_party/blink/renderer/modules/mediastream/user_media_client.cc
@@ -270,7 +270,7 @@
 UserMediaRequest* UserMediaClient::Request::MoveUserMediaRequest() {
   auto user_media_request = user_media_request_;
   user_media_request_ = nullptr;
-  return user_media_request;
+  return user_media_request.Get();
 }
 
 UserMediaClient::UserMediaClient(
@@ -516,9 +516,9 @@
       (IsScreenCaptureMediaType(media_stream_type) ||
        media_stream_type ==
            mojom::blink::MediaStreamType::DISPLAY_AUDIO_CAPTURE)) {
-    return pending_display_requests_;
+    return pending_display_requests_.Get();
   } else {
-    return pending_requests_;
+    return pending_requests_.Get();
   }
 }
 
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_client.h b/third_party/blink/renderer/modules/mediastream/user_media_client.h
index 058a6e5b..97101a6 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_client.h
+++ b/third_party/blink/renderer/modules/mediastream/user_media_client.h
@@ -107,9 +107,9 @@
       return user_media_request_.Get();
     }
     blink::ApplyConstraintsRequest* apply_constraints_request() const {
-      return apply_constraints_request_;
+      return apply_constraints_request_.Get();
     }
-    MediaStreamComponent* track_to_stop() const { return track_to_stop_; }
+    MediaStreamComponent* track_to_stop() const { return track_to_stop_.Get(); }
 
     bool IsUserMedia() const { return !!user_media_request_; }
     bool IsApplyConstraints() const { return !!apply_constraints_request_; }
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc b/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc
index a11670f..d523bb2 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc
@@ -55,8 +55,9 @@
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #include "ui/display/screen_info.h"
 
-using testing::_;
-using testing::Mock;
+using blink::mojom::SubCaptureTargetType;
+using ::testing::_;
+using ::testing::Mock;
 
 namespace blink {
 
@@ -221,7 +222,11 @@
     NOTREACHED();
   }
 
-  void ProduceCropId(ProduceCropIdCallback callback) override { NOTREACHED(); }
+  void ProduceSubCaptureTargetId(
+      SubCaptureTargetType type,
+      ProduceSubCaptureTargetIdCallback callback) override {
+    NOTREACHED();
+  }
 #endif
 
   void GetAllVideoInputDeviceFormats(
@@ -336,7 +341,9 @@
     NOTREACHED();
   }
 
-  void ProduceCropId(ProduceCropIdCallback callback) override {
+  void ProduceSubCaptureTargetId(
+      SubCaptureTargetType type,
+      ProduceSubCaptureTargetIdCallback callback) override {
     std::move(callback).Run("");
   }
 #endif
@@ -430,7 +437,7 @@
   }
 
   MediaStreamDescriptor* last_generated_descriptor() {
-    return last_generated_descriptor_;
+    return last_generated_descriptor_.Get();
   }
   void ClearLastGeneratedStream() { last_generated_descriptor_ = nullptr; }
 
@@ -699,7 +706,7 @@
     EXPECT_EQ(audio_components.size(), 1u);
     EXPECT_TRUE(video_components.empty());
 
-    return audio_components[0];
+    return audio_components[0].Get();
   }
 
   void StartMockedVideoSource(
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
index 47ed1a47..a4759de 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
+++ b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
@@ -322,7 +322,7 @@
                             MediaStreamRequestResult result,
                             const String& result_name);
 
-  UserMediaRequest* request() { return request_; }
+  UserMediaRequest* request() { return request_.Get(); }
   int32_t request_id() const { return request_->request_id(); }
 
   State state() const { return state_; }
@@ -397,7 +397,7 @@
 
   MediaStreamDescriptorVector* descriptors() {
     DCHECK(descriptors_);
-    return descriptors_;
+    return descriptors_.Get();
   }
 
   const mojom::blink::StreamDevicesSet& devices_set() const {
@@ -1683,7 +1683,7 @@
   // set. Thus, all audio processing properties are known and can be surfaced
   // to |source|.
   SurfaceAudioProcessingSettings(source);
-  return component;
+  return component.Get();
 }
 
 void UserMediaProcessor::OnCreateNativeTracksCompleted(
@@ -1822,7 +1822,7 @@
         local_source->GetPlatformSource();
     const MediaStreamDevice& active_device = source->device();
     if (IsSameDevice(active_device, device)) {
-      return local_source;
+      return local_source.Get();
     }
   }
   return nullptr;
diff --git a/third_party/blink/renderer/modules/ml/BUILD.gn b/third_party/blink/renderer/modules/ml/BUILD.gn
index 871c3d8..495ebe2 100644
--- a/third_party/blink/renderer/modules/ml/BUILD.gn
+++ b/third_party/blink/renderer/modules/ml/BUILD.gn
@@ -71,10 +71,14 @@
 
   if (!is_chromeos) {
     sources += [
-      # MLGraphMojo is platform independent which packages the model information
-      # into a neutral struct type, it will be built and executed with hardware
+      # Platform independent sources which packages the model information
+      # into a neutral struct types, it will be built and executed with hardware
       # accelerated OS machine learning API in WebNN Service which run out of
       # renderer process.
+      "webnn/ml_context_mojo.cc",
+      "webnn/ml_context_mojo.h",
+      "webnn/ml_error_mojo.cc",
+      "webnn/ml_error_mojo.h",
       "webnn/ml_graph_mojo.cc",
       "webnn/ml_graph_mojo.h",
       "webnn/ml_graph_type_converter.cc",
diff --git a/third_party/blink/renderer/modules/ml/ml.cc b/third_party/blink/renderer/modules/ml/ml.cc
index 8dce516..97c4c143 100644
--- a/third_party/blink/renderer/modules/ml/ml.cc
+++ b/third_party/blink/renderer/modules/ml/ml.cc
@@ -5,11 +5,18 @@
 #include "third_party/blink/renderer/modules/ml/ml.h"
 
 #include "components/ml/mojom/web_platform_model.mojom-blink.h"
+#include "components/ml/webnn/features.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_context_options.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/modules/ml/buildflags.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 
+#if !BUILDFLAG(IS_CHROMEOS)
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.h"
+#endif
+
 namespace blink {
 
 namespace {
@@ -66,6 +73,26 @@
 
   auto promise = resolver->Promise();
 
+// TODO(crbug.com/1273291): Support async context creation for all contexts.
+#if BUILDFLAG(BUILD_WEBNN_WITH_XNNPACK) || BUILDFLAG(BUILD_WEBNN_ON_CROS)
+  if (option->devicePreference() == V8MLDevicePreference::Enum::kAuto ||
+      option->devicePreference() == V8MLDevicePreference::Enum::kCpu) {
+    auto* ml_context = MakeGarbageCollected<MLContext>(
+        option->devicePreference(), option->powerPreference(),
+        option->modelFormat(), option->numThreads(), this);
+    resolver->Resolve(ml_context);
+    return promise;
+  }
+#endif
+
+#if !BUILDFLAG(IS_CHROMEOS)
+  if (base::FeatureList::IsEnabled(
+          webnn::features::kEnableMachineLearningNeuralNetworkService)) {
+    MLContextMojo::ValidateAndCreateAsync(resolver, option, this);
+    return promise;
+  }
+#endif
+
   // Notice that currently, we just create the context in the renderer. In the
   // future we may add backend query ability to check whether a context is
   // supportable or not. At that time, this function will be truly asynced.
@@ -86,11 +113,28 @@
     return nullptr;
   }
 
-  // TODO(crbug/1405354): Query browser about whether the given context is
-  // supported.
-  return MakeGarbageCollected<MLContext>(
-      options->devicePreference(), options->powerPreference(),
-      options->modelFormat(), options->numThreads(), this);
+// TODO(crbug.com/1273291): support sync context creation for all contexts.
+#if BUILDFLAG(BUILD_WEBNN_WITH_XNNPACK) || BUILDFLAG(BUILD_WEBNN_ON_CROS)
+  if (options->devicePreference() == V8MLDevicePreference::Enum::kAuto ||
+      options->devicePreference() == V8MLDevicePreference::Enum::kCpu) {
+    return MLContext::ValidateAndCreateSync(options, this);
+  }
+#endif
+
+#if !BUILDFLAG(IS_CHROMEOS)
+  // The runtime enable feature is used to disable the cross process hardware
+  // acceleration by default.
+  if (base::FeatureList::IsEnabled(
+          webnn::features::kEnableMachineLearningNeuralNetworkService) &&
+      (options->devicePreference() == V8MLDevicePreference::Enum::kAuto ||
+       options->devicePreference() == V8MLDevicePreference::Enum::kGpu)) {
+    return MLContextMojo::ValidateAndCreateSync(exception_state, options, this);
+  }
+#endif
+
+  // TODO(crbug.com/1273291): throw exception once tests support all context
+  // types.
+  return MLContext::ValidateAndCreateSync(options, this);
 }
 
 void ML::EnsureModelLoaderServiceConnection(ScriptState* script_state) {
diff --git a/third_party/blink/renderer/modules/ml/ml_context.cc b/third_party/blink/renderer/modules/ml/ml_context.cc
index 2dc7b1f..26d541c 100644
--- a/third_party/blink/renderer/modules/ml/ml_context.cc
+++ b/third_party/blink/renderer/modules/ml/ml_context.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/modules/ml/ml_context.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ml_context_options.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/modules/ml/ml.h"
 #include "third_party/blink/renderer/modules/ml/ml_model_loader.h"
@@ -12,20 +13,13 @@
 
 namespace blink {
 
-namespace {
-
-namespace blink_mojom = webnn::mojom::blink;
-
-template <typename MojoResultType>
-mojo::StructPtr<MojoResultType> ToError(
-    const blink_mojom::Error::Code& error_code,
-    const WTF::String& error_message) {
-  return MojoResultType::NewError(
-      blink_mojom::Error::New(error_code, error_message));
+// static
+MLContext* MLContext::ValidateAndCreateSync(MLContextOptions* options, ML* ml) {
+  return MakeGarbageCollected<MLContext>(
+      options->devicePreference(), options->powerPreference(),
+      options->modelFormat(), options->numThreads(), ml);
 }
 
-}  // namespace
-
 MLContext::MLContext(const V8MLDevicePreference device_preference,
                      const V8MLPowerPreference power_preference,
                      const V8MLModelFormat model_format,
@@ -35,8 +29,7 @@
       power_preference_(power_preference),
       model_format_(model_format),
       num_threads_(num_threads),
-      ml_(ml),
-      webnn_context_(ml->GetExecutionContext()) {}
+      ml_(ml) {}
 
 MLContext::~MLContext() = default;
 
@@ -76,13 +69,12 @@
     ml_model_loader_ =
         MakeGarbageCollected<MLModelLoader>(execution_context, this);
   }
-  return ml_model_loader_;
+  return ml_model_loader_.Get();
 }
 
 void MLContext::Trace(Visitor* visitor) const {
   visitor->Trace(ml_);
   visitor->Trace(ml_model_loader_);
-  visitor->Trace(webnn_context_);
 
   ScriptWrappable::Trace(visitor);
 }
@@ -126,50 +118,29 @@
   graph->ComputeSync(inputs, outputs, exception_state);
 }
 
-void MLContext::CreateWebNNGraph(
-    ScriptState* script_state,
-    blink_mojom::GraphInfoPtr graph_info,
-    blink_mojom::WebNNContext::CreateGraphCallback callback) {
-  if (!webnn_context_.is_bound()) {
-    // Needs to create `WebNNContext` interface first.
-    auto options = blink_mojom::CreateContextOptions::New();
-    // TODO(crbug.com/1273291): Set power preference in the context option.
-    ml_->CreateWebNNContext(
-        std::move(options),
-        WTF::BindOnce(&MLContext::OnCreateWebNNContext, WrapPersistent(this),
-                      WrapPersistent(script_state), std::move(graph_info),
-                      std::move(callback)));
-  } else {
-    // Directly use `WebNNContext` to create `WebNNGraph` message pipe.
-    webnn_context_->CreateGraph(std::move(graph_info),
-                                WTF::BindOnce(std::move(callback)));
-  }
+void MLContext::CreateAsync(ScriptPromiseResolver* resolver,
+                            MLContextOptions* options) {
+  CreateAsyncImpl(resolver, options);
 }
 
-void MLContext::OnCreateWebNNContext(
-    ScriptState* script_state,
-    blink_mojom::GraphInfoPtr graph_info,
-    blink_mojom::WebNNContext::CreateGraphCallback callback,
-    blink_mojom::CreateContextResultPtr result) {
-  if (!script_state->ContextIsValid()) {
-    std::move(callback).Run(ToError<blink_mojom::CreateGraphResult>(
-        blink_mojom::Error::Code::kUnknownError, "Invalid script state."));
-    return;
-  }
+MLContext* MLContext::CreateSync(MLContextOptions* options,
+                                 ExceptionState& exception_state) {
+  return CreateSyncImpl(options, exception_state);
+}
 
-  if (result->is_error()) {
-    std::move(callback).Run(blink_mojom::CreateGraphResult::NewError(
-        std::move(result->get_error())));
-    return;
-  }
+void MLContext::CreateAsyncImpl(ScriptPromiseResolver* resolver,
+                                MLContextOptions* options) {
+  // TODO(crbug.com/1273291): Remove when async creation gets implemented for
+  // all context types.
+  NOTIMPLEMENTED();
+}
 
-  auto* execution_context = ExecutionContext::From(script_state);
-  webnn_context_.Bind(
-      std::move(result->get_context_remote()),
-      execution_context->GetTaskRunner(TaskType::kInternalDefault));
-
-  webnn_context_->CreateGraph(std::move(graph_info),
-                              WTF::BindOnce(std::move(callback)));
+MLContext* MLContext::CreateSyncImpl(MLContextOptions* options,
+                                     ExceptionState& exception_state) {
+  // TODO(crbug.com/1273291): Remove when sync creation gets implemented for
+  // all context types.
+  NOTIMPLEMENTED();
+  return nullptr;
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/ml/ml_context.h b/third_party/blink/renderer/modules/ml/ml_context.h
index f150b99b0..bdd3658 100644
--- a/third_party/blink/renderer/modules/ml/ml_context.h
+++ b/third_party/blink/renderer/modules/ml/ml_context.h
@@ -16,17 +16,21 @@
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/member.h"
 #include "third_party/blink/renderer/platform/heap/visitor.h"
-#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
 
 namespace blink {
 
 class ML;
+class MLContextOptions;
 class MLModelLoader;
 
-class MODULES_EXPORT MLContext final : public ScriptWrappable {
+class MODULES_EXPORT MLContext : public ScriptWrappable {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+  static MLContext* ValidateAndCreateSync(MLContextOptions* options, ML* ml);
+
+  // The constructor shouldn't be called directly. The callers should use
+  // CreateAsync() or CreateSync() method instead.
   MLContext(const V8MLDevicePreference device_preference,
             const V8MLPowerPreference power_preference,
             const V8MLModelFormat model_format,
@@ -63,10 +67,29 @@
                    const MLNamedArrayBufferViews& outputs,
                    ExceptionState& exception_state);
 
-  void CreateWebNNGraph(
-      ScriptState* script_state,
-      webnn::mojom::blink::GraphInfoPtr graph_info,
-      webnn::mojom::blink::WebNNContext::CreateGraphCallback callback);
+ protected:
+  // Create and initialize a MLContext object. Resolve the promise with
+  // this concrete object if the underlying context gets created
+  // successfully.
+  void CreateAsync(ScriptPromiseResolver* resolver, MLContextOptions* options);
+
+  // An MLContext backend should implement this method to create and initialize
+  // a platform specific context asynchronously.
+  virtual void CreateAsyncImpl(ScriptPromiseResolver* resolver,
+                               MLContextOptions* options);
+
+  // CreateSync() has the similar function as CreateAsync(). The difference is
+  // if there are no validation error, it calls CreateSyncImpl() implemented
+  // by a MLContext backend that initializes the context synchronously in the
+  // caller's thread. This method is called by ML to implement
+  // MLContext.createContextSync() method.
+  MLContext* CreateSync(MLContextOptions* options,
+                        ExceptionState& exception_state);
+
+  // An MLContext backend should implement this method to initialize the
+  // platform context synchronously in the caller's thread.
+  virtual MLContext* CreateSyncImpl(MLContextOptions* options,
+                                    ExceptionState& exception_state);
 
  private:
   V8MLDevicePreference device_preference_;
@@ -77,17 +100,6 @@
   Member<ML> ml_;
   // WebNN uses this MLModelLoader to build a computational graph.
   Member<MLModelLoader> ml_model_loader_;
-
-  // The callback of creating context called from WebNN server side.
-  void OnCreateWebNNContext(
-      ScriptState* script_state,
-      webnn::mojom::blink::GraphInfoPtr graph_info,
-      webnn::mojom::blink::WebNNContext::CreateGraphCallback callback,
-      webnn::mojom::blink::CreateContextResultPtr result);
-  // WebNN support multiple types of neural network inference hardware
-  // acceleration, the context of WebNN in server side is used to map different
-  // device and represent a state of graph execution processes.
-  HeapMojoRemote<webnn::mojom::blink::WebNNContext> webnn_context_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/ml/ml_model_loader_test.cc b/third_party/blink/renderer/modules/ml/ml_model_loader_test.cc
index 6158da1..fde597934 100644
--- a/third_party/blink/renderer/modules/ml/ml_model_loader_test.cc
+++ b/third_party/blink/renderer/modules/ml/ml_model_loader_test.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ml_context_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_data_type.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_model.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_power_preference.h"
@@ -158,10 +159,14 @@
 
   MLModelLoader* CreateTestLoader(V8TestingScope& scope) {
     ML* ml = MakeGarbageCollected<ML>(scope.GetExecutionContext());
-    MLContext* ml_context = MakeGarbageCollected<MLContext>(
-        V8MLDevicePreference(V8MLDevicePreference::Enum::kCpu),
-        V8MLPowerPreference(V8MLPowerPreference::Enum::kAuto),
-        V8MLModelFormat(V8MLModelFormat::Enum::kTflite), 1, ml);
+
+    MLContextOptions* options = MLContextOptions::Create();
+    options->setDevicePreference(V8MLDevicePreference::Enum::kCpu);
+    options->setPowerPreference(V8MLPowerPreference::Enum::kAuto);
+    options->setModelFormat(V8MLModelFormat::Enum::kTflite);
+
+    MLContext* ml_context = ml->createContextSync(
+        scope.GetScriptState(), options, scope.GetExceptionState());
     return MLModelLoader::Create(scope.GetScriptState(), ml_context,
                                  scope.GetExceptionState());
   }
diff --git a/third_party/blink/renderer/modules/ml/navigator_ml.cc b/third_party/blink/renderer/modules/ml/navigator_ml.cc
index bc0a885..c7ff70169 100644
--- a/third_party/blink/renderer/modules/ml/navigator_ml.cc
+++ b/third_party/blink/renderer/modules/ml/navigator_ml.cc
@@ -19,7 +19,7 @@
     supplement = MakeGarbageCollected<NavigatorML>(navigator);
     ProvideTo(navigator, supplement);
   }
-  return supplement->ml_;
+  return supplement->ml_.Get();
 }
 
 void NavigatorML::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/ml/webnn/fuzzer/conv2d_fuzzer.cc b/third_party/blink/renderer/modules/ml/webnn/fuzzer/conv2d_fuzzer.cc
index 4471d1a..a6e17b85 100644
--- a/third_party/blink/renderer/modules/ml/webnn/fuzzer/conv2d_fuzzer.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/fuzzer/conv2d_fuzzer.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "testing/libfuzzer/proto/lpm_interface.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
 #include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
@@ -70,10 +71,15 @@
     return page_holder.release();
   }();
 
-  auto* builder = CreateMLGraphBuilder(
-      page_holder->GetFrame().DomWindow()->GetExecutionContext());
+  ScriptState* script_state =
+      ToScriptStateForMainWorld(&page_holder->GetFrame());
 
   DummyExceptionStateForTesting exception_state;
+  auto* builder = CreateMLGraphBuilder(
+      page_holder->GetFrame().DomWindow()->GetExecutionContext(), script_state,
+      exception_state);
+  CHECK(builder);
+
   auto* input =
       BuildInput(builder, "input", Vector<uint32_t>(conv2d.input_dimensions()),
                  ToV8MLOperandType(conv2d.input_type()), exception_state);
diff --git a/third_party/blink/renderer/modules/ml/webnn/fuzzer/pool2d_fuzzer.cc b/third_party/blink/renderer/modules/ml/webnn/fuzzer/pool2d_fuzzer.cc
index 22fa2fb..0dd3936 100644
--- a/third_party/blink/renderer/modules/ml/webnn/fuzzer/pool2d_fuzzer.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/fuzzer/pool2d_fuzzer.cc
@@ -70,10 +70,15 @@
     return page_holder.release();
   }();
 
-  auto* builder = CreateMLGraphBuilder(
-      page_holder->GetFrame().DomWindow()->GetExecutionContext());
+  ScriptState* script_state =
+      ToScriptStateForMainWorld(&page_holder->GetFrame());
 
   DummyExceptionStateForTesting exception_state;
+  auto* builder = CreateMLGraphBuilder(
+      page_holder->GetFrame().DomWindow()->GetExecutionContext(), script_state,
+      exception_state);
+  CHECK(builder);
+
   auto* input =
       BuildInput(builder, "input", Vector<uint32_t>(pool2d.input_dimensions()),
                  ToV8MLOperandType(pool2d.input_type()), exception_state);
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.cc b/third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.cc
new file mode 100644
index 0000000..56bdc67
--- /dev/null
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.cc
@@ -0,0 +1,125 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ml_context_options.h"
+#include "third_party/blink/renderer/modules/ml/ml.h"
+#include "third_party/blink/renderer/modules/ml/webnn/ml_error_mojo.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+
+namespace blink {
+
+namespace {
+
+using webnn::mojom::blink::PowerPreference;
+
+PowerPreference ConvertBlinkPowerPreferenceToMojo(
+    const V8MLPowerPreference& power_preference_blink) {
+  switch (power_preference_blink.AsEnum()) {
+    case V8MLPowerPreference::Enum::kAuto:
+      return PowerPreference::kDefault;
+    case V8MLPowerPreference::Enum::kLowPower:
+      return PowerPreference::kLowPower;
+    case V8MLPowerPreference::Enum::kHighPerformance:
+      return PowerPreference::kHighPerformance;
+  }
+}
+
+}  // namespace
+
+// static
+void MLContextMojo::ValidateAndCreateAsync(ScriptPromiseResolver* resolver,
+                                           MLContextOptions* options,
+                                           ML* ml) {
+  // TODO(crbug.com/1273291): Remove unsupported options (ex. model_format)
+  // once the context gets implemented for non-mojo too.
+  auto* context = MakeGarbageCollected<MLContextMojo>(
+      options->devicePreference(), options->powerPreference(),
+      options->modelFormat(), options->numThreads(), ml);
+  context->CreateAsync(resolver, options);
+}
+
+// static
+MLContext* MLContextMojo::ValidateAndCreateSync(ExceptionState& exception_state,
+                                                MLContextOptions* options,
+                                                ML* ml) {
+  auto* context = MakeGarbageCollected<MLContextMojo>(
+      options->devicePreference(), options->powerPreference(),
+      options->modelFormat(), options->numThreads(), ml);
+  return context->CreateSync(options, exception_state);
+}
+
+void MLContextMojo::CreateAsyncImpl(ScriptPromiseResolver* resolver,
+                                    MLContextOptions* options) {
+  auto options_mojo = webnn::mojom::blink::CreateContextOptions::New();
+  options_mojo->power_preference =
+      ConvertBlinkPowerPreferenceToMojo(options->powerPreference());
+  GetML()->CreateWebNNContext(
+      std::move(options_mojo),
+      WTF::BindOnce(&MLContextMojo::OnCreateWebNNContext, WrapPersistent(this),
+                    WrapPersistent(resolver)));
+}
+
+MLContext* MLContextMojo::CreateSyncImpl(MLContextOptions* options,
+                                         ExceptionState& exception_state) {
+  // TODO(crbug.com/1273291): Support sync create that is only exposed to
+  // dedicated worker.
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+MLContextMojo::MLContextMojo(const V8MLDevicePreference device_preference,
+                             const V8MLPowerPreference power_preference,
+                             const V8MLModelFormat model_format,
+                             const unsigned int num_threads,
+                             ML* ml)
+    : MLContext(device_preference,
+                power_preference,
+                model_format,
+                num_threads,
+                ml),
+      remote_context_(ml->GetExecutionContext()) {}
+
+MLContextMojo::~MLContextMojo() = default;
+
+void MLContextMojo::Trace(Visitor* visitor) const {
+  visitor->Trace(remote_context_);
+  MLContext::Trace(visitor);
+}
+
+void MLContextMojo::CreateWebNNGraph(
+    webnn::mojom::blink::GraphInfoPtr graph_info,
+    webnn::mojom::blink::WebNNContext::CreateGraphCallback callback) {
+  CHECK(remote_context_.is_bound());
+
+  // Use `WebNNContext` to create `WebNNGraph` message pipe.
+  remote_context_->CreateGraph(std::move(graph_info),
+                               WTF::BindOnce(std::move(callback)));
+}
+
+void MLContextMojo::OnCreateWebNNContext(
+    ScriptPromiseResolver* resolver,
+    blink_mojom::CreateContextResultPtr result) {
+  if (result->is_error()) {
+    const auto& create_context_error = result->get_error();
+    resolver->Reject(MakeGarbageCollected<DOMException>(
+        ConvertWebNNErrorCodeToDOMExceptionCode(
+            create_context_error->error_code),
+        create_context_error->error_message));
+    return;
+  }
+
+  auto* script_state = resolver->GetScriptState();
+  auto* execution_context = ExecutionContext::From(script_state);
+  // Bind the end point of `WebNNContext` mojo interface in the blink side.
+  remote_context_.Bind(
+      std::move(result->get_context_remote()),
+      execution_context->GetTaskRunner(TaskType::kInternalDefault));
+
+  resolver->Resolve(this);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.h b/third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.h
new file mode 100644
index 0000000..ca745f4d
--- /dev/null
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.h
@@ -0,0 +1,76 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_CONTEXT_MOJO_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_CONTEXT_MOJO_H_
+
+#include "services/webnn/public/mojom/webnn_context_provider.mojom-blink.h"
+#include "services/webnn/public/mojom/webnn_graph.mojom-blink.h"
+#include "third_party/blink/renderer/modules/ml/ml_context.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
+
+namespace blink {
+
+class ML;
+class MLContextOptions;
+class ScriptPromiseResolver;
+
+// The `Mojo` in the class name means this context is backed by a service
+// running outside of Blink.
+class MODULES_EXPORT MLContextMojo : public MLContext {
+ public:
+  // Create and build a MLContextMojo object. Resolve the promise with
+  // this concrete object if the context is created successfully out of renderer
+  // process. Launch WebNN service and bind `WebNNContext` mojo interface
+  // to create `WebNNContext` message pipe if needed.
+  static void ValidateAndCreateAsync(ScriptPromiseResolver* resolver,
+                                     MLContextOptions* options,
+                                     ML* ml);
+
+  static MLContext* ValidateAndCreateSync(ExceptionState& exception_state,
+                                          MLContextOptions* options,
+                                          ML* ml);
+
+  MLContextMojo(const V8MLDevicePreference device_preference,
+                const V8MLPowerPreference power_preference,
+                const V8MLModelFormat model_format,
+                const unsigned int num_threads,
+                ML* ml);
+
+  ~MLContextMojo() override;
+
+  void Trace(Visitor* visitor) const override;
+
+  // Creates platform specific graph synchronously in the caller's thread. Once
+  // the platform graph is compiled, it should return a concrete MLGraph object.
+  // Otherwise, it should return a nullptr and throw a DOMException accordingly.
+  void CreateWebNNGraph(
+      webnn::mojom::blink::GraphInfoPtr graph_info,
+      webnn::mojom::blink::WebNNContext::CreateGraphCallback callback);
+
+ protected:
+  // Create `WebNNContext` message pipe with `ML` mojo interface, then
+  // create the context with the hardware accelerated OS machine
+  // learning API in the WebNN Service.
+  void CreateAsyncImpl(ScriptPromiseResolver* resolver,
+                       MLContextOptions* options) override;
+
+  MLContext* CreateSyncImpl(MLContextOptions* options,
+                            ExceptionState& exception_state) override;
+
+ private:
+  // The callback of creating `WebNNContext` mojo interface from WebNN Service.
+  // Return `CreateContextResult::kNotSupported` on non-supported input
+  // configuration.
+  void OnCreateWebNNContext(ScriptPromiseResolver* resolver,
+                            webnn::mojom::blink::CreateContextResultPtr result);
+
+  // The `WebNNContext` is a initialized context that can be used by the
+  // hardware accelerated OS machine learning API.
+  HeapMojoRemote<webnn::mojom::blink::WebNNContext> remote_context_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_CONTEXT_MOJO_H_
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_error_mojo.cc b/third_party/blink/renderer/modules/ml/webnn/ml_error_mojo.cc
new file mode 100644
index 0000000..3151ab2
--- /dev/null
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_error_mojo.cc
@@ -0,0 +1,22 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/ml/webnn/ml_error_mojo.h"
+
+namespace blink {
+
+#define DEFINE_WEBNN_ERROR_CODE_MAPPING(error_code) \
+  case blink_mojom::Error::Code::error_code: {      \
+    return DOMExceptionCode::error_code;            \
+  }
+
+DOMExceptionCode ConvertWebNNErrorCodeToDOMExceptionCode(
+    blink_mojom::Error::Code error_code) {
+  switch (error_code) {
+    DEFINE_WEBNN_ERROR_CODE_MAPPING(kUnknownError)
+    DEFINE_WEBNN_ERROR_CODE_MAPPING(kNotSupportedError)
+  }
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_error_mojo.h b/third_party/blink/renderer/modules/ml/webnn/ml_error_mojo.h
new file mode 100644
index 0000000..9b1506df
--- /dev/null
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_error_mojo.h
@@ -0,0 +1,28 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_ERROR_MOJO_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_ERROR_MOJO_H_
+
+#include "services/webnn/public/mojom/webnn_context_provider.mojom-blink.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
+
+namespace blink {
+
+namespace blink_mojom = webnn::mojom::blink;
+
+DOMExceptionCode ConvertWebNNErrorCodeToDOMExceptionCode(
+    blink_mojom::Error::Code error_code);
+
+template <typename MojoResultType>
+mojo::StructPtr<MojoResultType> ToError(
+    const blink_mojom::Error::Code& error_code,
+    const WTF::String& error_message) {
+  return MojoResultType::NewError(
+      blink_mojom::Error::New(error_code, error_message));
+}
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_ERROR_MOJO_H_
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc
index 4c87e5f3..2f083834 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc
@@ -481,7 +481,7 @@
 }
 
 MLContext* MLGraphBuilder::GetContext() const {
-  return ml_context_;
+  return ml_context_.Get();
 }
 
 // static
@@ -1763,7 +1763,10 @@
     // Reject unsupported error on unimplemented platform when getting
     // `WebNNContext` mojo interface with BrowserInterfaceBroker's
     // GetInterface() method before creating `WebNNGraph` message pipe.
-    MLGraphMojo::ValidateAndBuildAsync(ml_context_, named_outputs, resolver);
+    MLContextMojo* ml_context_mojo =
+        static_cast<MLContextMojo*>(ml_context_.Get());
+    MLGraphMojo::ValidateAndBuildAsync(ml_context_mojo, named_outputs,
+                                       resolver);
     return promise;
   }
 #endif
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc
index dcd94cf4..7f4a68f 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc
@@ -35,7 +35,9 @@
 
 TEST_F(MLGraphBuilderTest, InputTest) {
   V8TestingScope scope;
-  MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  MLGraphBuilder* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building a 2-D input without errors.
     auto* input =
@@ -110,7 +112,9 @@
 
 TEST_F(MLGraphBuilderTest, ConstantTest) {
   V8TestingScope scope;
-  MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  MLGraphBuilder* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building a 2-D constant without errors.
     auto* constant =
@@ -197,7 +201,9 @@
 
 TEST_F(MLGraphBuilderTest, ConcatTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building Concat with one input.
     Vector<uint32_t> input_a_shape({4, 4, 3});
@@ -405,7 +411,9 @@
 
 TEST_F(MLGraphBuilderTest, Conv2dTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test conv2d with default options.
     auto* input =
@@ -1109,7 +1117,9 @@
 
 TEST_F(MLGraphBuilderTest, ConvTranspose2dTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test convTranspose2d with default options.
     auto* input =
@@ -1910,7 +1920,9 @@
 
 TEST_F(MLGraphBuilderTest, Pool2dTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   const auto Pool2dKinds = {Pool2dKind::kAverage, Pool2dKind::kMax};
   for (const auto pool2d_kind : Pool2dKinds) {
     {
@@ -2332,7 +2344,9 @@
 
 TEST_F(MLGraphBuilderTest, PReluTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building prelu when slope_shape is the same as the input_shape.
     Vector<uint32_t> input_shape({3, 2, 5});
@@ -2460,7 +2474,9 @@
 
 TEST_F(MLGraphBuilderTest, ReluTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building relu with float32 input.
     Vector<uint32_t> input_shape({3, 4, 5});
@@ -2508,7 +2524,9 @@
 
 TEST_F(MLGraphBuilderTest, HardSwishTest) {
   V8TestingScope scope;
-  MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  MLGraphBuilder* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   ASSERT_NE(nullptr, builder);
   {
     // Test building hard-swish with float32 input.
@@ -2569,7 +2587,9 @@
 
 TEST_F(MLGraphBuilderTest, GemmTest) {
   V8TestingScope scope;
-  MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  MLGraphBuilder* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   ASSERT_NE(nullptr, builder);
   {
     // Test building gemm with default option.
@@ -2863,7 +2883,9 @@
 
 TEST_F(MLGraphBuilderTest, ElementWiseBinaryTest) {
   V8TestingScope scope;
-  MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  MLGraphBuilder* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Testing building add with two input dimensions - {8, 1, 6, 1} and {7, 1,
     // 5}. Both the a and b dimensions have axes with length one that are
@@ -2968,7 +2990,9 @@
 
 TEST_F(MLGraphBuilderTest, ElementWiseUnaryTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building element-wise abs.
     const Vector<uint32_t> input_shape({1});
@@ -3070,7 +3094,9 @@
 
 TEST_F(MLGraphBuilderTest, ReduceTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   const auto ReduceKinds = {ReduceKind::kMean, ReduceKind::kSum};
   for (const auto reduce_kind : ReduceKinds) {
     {
@@ -3143,7 +3169,9 @@
 
 TEST_F(MLGraphBuilderTest, ReshapeTest) {
   V8TestingScope scope;
-  MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  MLGraphBuilder* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building reshape with new shape = {3, null}.
     auto* input =
@@ -3270,7 +3298,9 @@
 
 TEST_F(MLGraphBuilderTest, Resample2dTest) {
   V8TestingScope scope;
-  MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  MLGraphBuilder* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building resample2d with default options.
     auto* input =
@@ -3509,7 +3539,9 @@
 
 TEST_F(MLGraphBuilderTest, TransposeTest) {
   V8TestingScope scope;
-  MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  MLGraphBuilder* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building transpose with default options.
     auto* input =
@@ -3597,7 +3629,9 @@
 
 TEST_F(MLGraphBuilderTest, ClampTest) {
   V8TestingScope scope;
-  MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  MLGraphBuilder* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building clamp with default options.
     auto* input =
@@ -3667,7 +3701,9 @@
 
 TEST_F(MLGraphBuilderTest, EluTest) {
   V8TestingScope scope;
-  MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  MLGraphBuilder* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building elu with float32 input and default options.
     auto* input =
@@ -3757,7 +3793,9 @@
 
 TEST_F(MLGraphBuilderTest, LeakyReluTest) {
   V8TestingScope scope;
-  MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  MLGraphBuilder* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building leaky_relu with float32 input.
     auto* input =
@@ -3810,7 +3848,9 @@
 
 TEST_F(MLGraphBuilderTest, PadTest) {
   V8TestingScope scope;
-  MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  MLGraphBuilder* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building pad with default options, beginningPadding = {1, 2} and
     // endingPadding = {1, 2}.
@@ -3878,7 +3918,9 @@
 
 TEST_F(MLGraphBuilderTest, Softmax) {
   V8TestingScope scope;
-  MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  MLGraphBuilder* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building softmax with float32 input.
     auto* input =
@@ -3923,7 +3965,9 @@
 
 TEST_F(MLGraphBuilderTest, SigmoidTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building sigmoid with float32 input.
     Vector<uint32_t> input_shape({3, 4, 5});
@@ -3967,7 +4011,9 @@
 
 TEST_F(MLGraphBuilderTest, SliceTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building slice with starts = {0, 1, 2} and sizes = {1, 2, 3}.
     Vector<uint32_t> input_shape({3, 4, 5});
@@ -4080,7 +4126,9 @@
 
 TEST_F(MLGraphBuilderTest, Split) {
   V8TestingScope scope;
-  MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  MLGraphBuilder* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building split with default option.
     auto* input =
@@ -4222,7 +4270,9 @@
 
 TEST_F(MLGraphBuilderTest, TanhTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test building tanh with float32 input.
     Vector<uint32_t> input_shape({3, 4});
@@ -4366,7 +4416,9 @@
 
 TEST_P(FakeMLGraphTest, BuildTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test throwing exception if the named outputs is empty.
     MLNamedOperands named_outputs;
@@ -4580,7 +4632,9 @@
 
 TEST_P(FakeMLGraphTest, ComputeTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   // Build a fake graph represents computation 'c = a * b';
   auto* a = BuildInput(builder, "a", {3, 4}, V8MLOperandType::Enum::kFloat32,
                        scope.GetExceptionState());
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_utils.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_utils.cc
index 2d2dc586..27e55dd 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_utils.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_utils.cc
@@ -6,6 +6,7 @@
 
 #include <numeric>
 
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_operand_descriptor.h"
 #include "third_party/blink/renderer/modules/ml/ml.h"
 #include "third_party/blink/renderer/modules/ml/ml_context.h"
@@ -13,12 +14,16 @@
 namespace blink {
 
 MLGraphBuilder* CreateMLGraphBuilder(ExecutionContext* execution_context,
+                                     ScriptState* script_state,
+                                     ExceptionState& exception_state,
                                      MLContextOptions* options) {
   auto* ml = MakeGarbageCollected<ML>(execution_context);
-  auto* context = MakeGarbageCollected<MLContext>(
-      options->devicePreference(), options->powerPreference(),
-      options->modelFormat(), options->numThreads(), ml);
-  return MLGraphBuilder::Create(context);
+  MLContext* ml_context =
+      ml->createContextSync(script_state, options, exception_state);
+  // createContextSync fails to create due to validation or invalid script
+  // state.
+  CHECK(ml_context);
+  return MLGraphBuilder::Create(ml_context);
 }
 
 MLOperand* BuildInput(MLGraphBuilder* builder,
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_utils.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_utils.h
index 172e3cc..3872874b 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_utils.h
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_utils.h
@@ -17,6 +17,8 @@
 
 MLGraphBuilder* CreateMLGraphBuilder(
     ExecutionContext* execution_context,
+    ScriptState* script_state,
+    ExceptionState& exception_state,
     MLContextOptions* options = MLContextOptions::Create());
 
 MLOperand* BuildInput(MLGraphBuilder* builder,
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.cc
index 35922e2..0d797d4 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.cc
@@ -8,9 +8,9 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_compute_result.h"
-#include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/modules/ml/ml.h"
+#include "third_party/blink/renderer/modules/ml/webnn/ml_error_mojo.h"
 #include "third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.h"
 #include "third_party/blink/renderer/modules/ml/webnn/ml_graph_utils.h"
 #include "third_party/blink/renderer/modules/ml/webnn/ml_operand.h"
@@ -116,23 +116,10 @@
   return graph_info;
 }
 
-#define DEFINE_WEBNN_ERROR_CODE_MAPPING(error_code) \
-  case blink_mojom::Error::Code::error_code: {      \
-    return DOMExceptionCode::error_code;            \
-  }
-
-DOMExceptionCode ConvertWebNNErrorCodeToDOMExceptionCode(
-    blink_mojom::Error::Code error_code) {
-  switch (error_code) {
-    DEFINE_WEBNN_ERROR_CODE_MAPPING(kUnknownError)
-    DEFINE_WEBNN_ERROR_CODE_MAPPING(kNotSupportedError)
-  }
-}
-
 }  // namespace
 
 // static
-void MLGraphMojo::ValidateAndBuildAsync(MLContext* context,
+void MLGraphMojo::ValidateAndBuildAsync(MLContextMojo* context,
                                         const MLNamedOperands& named_outputs,
                                         ScriptPromiseResolver* resolver) {
   auto* graph =
@@ -140,13 +127,16 @@
   graph->BuildAsync(named_outputs, resolver);
 }
 
-MLGraphMojo::MLGraphMojo(ScriptState* script_state, MLContext* context)
-    : MLGraph(context), remote_graph_(ExecutionContext::From(script_state)) {}
+MLGraphMojo::MLGraphMojo(ScriptState* script_state, MLContextMojo* context)
+    : MLGraph(context),
+      ml_context_mojo_(context),
+      remote_graph_(ExecutionContext::From(script_state)) {}
 
 MLGraphMojo::~MLGraphMojo() = default;
 
 void MLGraphMojo::Trace(Visitor* visitor) const {
   visitor->Trace(remote_graph_);
+  visitor->Trace(ml_context_mojo_);
   MLGraph::Trace(visitor);
 }
 
@@ -160,9 +150,8 @@
     return;
   }
   // Create `WebNNGraph` message pipe with `WebNNContext` mojo interface.
-  auto* script_state = resolver->GetScriptState();
-  ml_context_->CreateWebNNGraph(
-      script_state, std::move(graph_info.value()),
+  ml_context_mojo_->CreateWebNNGraph(
+      std::move(graph_info.value()),
       WTF::BindOnce(&MLGraphMojo::OnCreateWebNNGraph, WrapPersistent(this),
                     WrapPersistent(resolver)));
 }
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.h
index 3aed1f6..654f1101 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.h
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.h
@@ -7,7 +7,7 @@
 
 #include "services/webnn/public/mojom/webnn_context_provider.mojom-blink.h"
 #include "services/webnn/public/mojom/webnn_graph.mojom-blink.h"
-#include "third_party/blink/renderer/modules/ml/ml_context.h"
+#include "third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.h"
 #include "third_party/blink/renderer/modules/ml/webnn/ml_graph.h"
 #include "third_party/blink/renderer/modules/ml/webnn/ml_graph_utils.h"
 #include "third_party/blink/renderer/platform/heap/visitor.h"
@@ -25,11 +25,11 @@
   // this concrete object if the graph builds successfully out of renderer
   // process. Launch WebNN service and bind `WebNNContext` mojo interface
   // to create `WebNNGraph` message pipe if needed.
-  static void ValidateAndBuildAsync(MLContext* context,
+  static void ValidateAndBuildAsync(MLContextMojo* context,
                                     const MLNamedOperands& named_outputs,
                                     ScriptPromiseResolver* resolver);
 
-  MLGraphMojo(ScriptState* script_state, MLContext* context);
+  MLGraphMojo(ScriptState* script_state, MLContextMojo* context);
   ~MLGraphMojo() override;
 
   void Trace(Visitor* visitor) const override;
@@ -69,6 +69,8 @@
   void OnCreateWebNNGraph(ScriptPromiseResolver* resolver,
                           webnn::mojom::blink::CreateGraphResultPtr result);
 
+  Member<MLContextMojo> ml_context_mojo_;
+
   // The `WebNNGraph` is compiled graph that can be executed by the hardware
   // accelerated OS machine learning API.
   HeapMojoRemote<webnn::mojom::blink::WebNNGraph> remote_graph_;
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc
index bf5e360..02c7ade 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc
@@ -28,7 +28,9 @@
 
   void Test(MLGraphTest& helper, V8TestingScope& scope) {
     // Build the graph.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* lhs_operand = BuildInput(builder, "lhs", lhs.dimensions, lhs.type,
                                    scope.GetExceptionState());
     auto* rhs_operand = BuildInput(builder, "rhs", rhs.dimensions, rhs.type,
@@ -209,7 +211,9 @@
 
   void Test(MLGraphTest& helper, V8TestingScope& scope) {
     // Build the graph.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* lhs_operand = BuildInput(builder, "lhs", lhs.dimensions, lhs.type,
                                    scope.GetExceptionState());
     auto* rhs_operand = BuildConstant(builder, rhs.dimensions, rhs.type,
@@ -267,7 +271,9 @@
 
   void Test(MLGraphTest& helper, V8TestingScope& scope) {
     // Build the graph.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input_operand = BuildInput(builder, "input", input.dimensions,
                                      input.type, scope.GetExceptionState());
     MLOperand* output_operand = nullptr;
@@ -365,7 +371,9 @@
 
   void Test(MLGraphTest& helper, V8TestingScope& scope) {
     // Build the graph.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input_operand = BuildInput(builder, "input", input.dimensions,
                                      input.type, scope.GetExceptionState());
     auto* slope_operand =
@@ -431,7 +439,9 @@
 
   void Test(MLGraphTest& helper, V8TestingScope& scope) {
     // Build the graph.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input_operand = BuildInput(builder, "input", input.dimensions,
                                      input.type, scope.GetExceptionState());
     auto* output_operand =
@@ -501,7 +511,9 @@
             V8TestingScope& scope,
             MLLeakyReluOptions* options = MLLeakyReluOptions::Create()) {
     // Build the graph.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input_operand = BuildInput(builder, "input", input.dimensions,
                                      input.type, scope.GetExceptionState());
     auto* output_operand =
@@ -556,7 +568,9 @@
   void Test(MLGraphTest& helper,
             V8TestingScope& scope,
             MLReduceOptions* options = MLReduceOptions::Create()) {
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input_operand = BuildInput(builder, "input", input.dimensions,
                                      input.type, scope.GetExceptionState());
     auto* output_operand =
@@ -612,7 +626,9 @@
             V8TestingScope& scope,
             MLResample2dOptions* options = MLResample2dOptions::Create()) {
     // Build the graph.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input_operand = BuildInput(builder, "input", input.dimensions,
                                      input.type, scope.GetExceptionState());
     auto* output_operand =
@@ -676,7 +692,9 @@
             V8TestingScope& scope,
             MLClampOptions* options = MLClampOptions::Create()) {
     // Build the graph.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input_operand = BuildInput(builder, "input", input.dimensions,
                                      input.type, scope.GetExceptionState());
     auto* output_operand =
@@ -787,7 +805,9 @@
 
 TEST_P(MLGraphTest, Conv2dTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test conv2d operator for nhwc input layout and ohwi filter layout.
     auto* options = MLConv2dOptions::Create();
@@ -948,7 +968,9 @@
 
 TEST_P(MLGraphTest, ConvTranspose2dTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test convTranspose2d operator for nhwc input layout and ohwi filter
     // layout.
@@ -1109,7 +1131,9 @@
 
 TEST_P(MLGraphTest, GemmTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test gemm operator without operand c.
     GemmTester<float>{.a = {.type = V8MLOperandType::Enum::kFloat32,
@@ -1161,7 +1185,9 @@
 
   void Test(MLGraphTest& helper, V8TestingScope& scope) {
     // Build the graph.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input_operand = BuildInput(builder, "input", input.dimensions,
                                      input.type, scope.GetExceptionState());
     auto* output_operand =
@@ -1235,7 +1261,9 @@
   void Test(MLGraphTest& helper,
             V8TestingScope& scope,
             MLPool2dOptions* options = MLPool2dOptions::Create()) {
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input_operand = BuildInput(builder, "input", input.dimensions,
                                      input.type, scope.GetExceptionState());
     auto* output_operand =
@@ -1312,7 +1340,9 @@
 
   void Test(MLGraphTest& helper, V8TestingScope& scope) {
     // Build the graph.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input_operand = BuildInput(builder, "input", input.dimensions,
                                      input.type, scope.GetExceptionState());
     auto* output_operand =
@@ -1422,7 +1452,9 @@
 
 TEST_P(MLGraphTest, SplitTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test split operator with default options.
     auto* options = MLSplitOptions::Create();
@@ -1505,7 +1537,9 @@
 
 TEST_P(MLGraphTest, TransposeTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test transpose operator with default options.
     auto* options = MLTransposeOptions::Create();
@@ -1554,7 +1588,9 @@
 
   void Test(MLGraphTest& helper, V8TestingScope& scope) {
     // Build the graph.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     HeapVector<Member<MLOperand>> input_operands;
     String input_str = "input_";
     for (uint32_t i = 0; i < inputs.size(); ++i) {
@@ -1702,7 +1738,9 @@
 
 TEST_P(MLGraphTest, PadTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test pad operator with default options.
     auto* options = MLPadOptions::Create();
@@ -1765,7 +1803,9 @@
 
 TEST_P(MLGraphTest, SliceTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test slice with input_shape = {3, 4, 5}, starts = {0, 0, 1} and sizes =
     // {2, 3, 4}.
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_base.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_base.cc
index 8946a8d..7316311 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_base.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_base.cc
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
+#include "third_party/blink/renderer/modules/ml/ml.h"
 #include "third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h"
 
 namespace blink {
@@ -141,4 +142,24 @@
   }
 }
 
+ScriptPromise MLGraphTestBase::CreateContext(V8TestingScope& scope,
+                                             MLContextOptions* options) {
+  auto* ml = MakeGarbageCollected<ML>(scope.GetExecutionContext());
+  return ml->createContext(scope.GetScriptState(), options,
+                           scope.GetExceptionState());
+}
+
+// static
+MLGraphBuilder* MLGraphTestBase::CreateGraphBuilder(V8TestingScope& scope,
+                                                    MLContextOptions* options) {
+  ScriptPromiseTester tester(scope.GetScriptState(),
+                             CreateContext(scope, options));
+  tester.WaitUntilSettled();
+  CHECK(tester.IsFulfilled());
+
+  auto* context = NativeValueTraits<MLContext>::NativeValue(
+      scope.GetIsolate(), tester.Value().V8Value(), scope.GetExceptionState());
+  return MLGraphBuilder::Create(context);
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_base.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_base.h
index a560a20..c681bf1 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_base.h
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_base.h
@@ -59,6 +59,16 @@
                              MLNamedArrayBufferViews& inputs,
                              MLNamedArrayBufferViews& outputs);
 
+  // Helper method for testing both context and ML graph builder creation.
+  // If the context cannot be created for the graph, returns nullptr.
+  static MLGraphBuilder* CreateGraphBuilder(V8TestingScope& scope,
+                                            MLContextOptions* options);
+
+  // Helper method for testing only context creation.
+  static ScriptPromise CreateContext(
+      V8TestingScope& scope,
+      MLContextOptions* options = MLContextOptions::Create());
+
  private:
   // The execution mode for testing build and compute graph (e.g. async, sync.).
   ExecutionMode GetExecutionMode();
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_cros.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_cros.cc
index 8d7f0cf5..ca68d513 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_cros.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_cros.cc
@@ -208,7 +208,9 @@
     //            add
     //             |
     //          [output]
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input = BuildInput(builder, "input", lhs.dimensions, lhs.type,
                              scope.GetExceptionState());
     auto* constant = BuildConstant(builder, rhs.dimensions, rhs.type,
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_mojo.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_mojo.cc
index b05da71..f6ef9196a 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_mojo.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_mojo.cc
@@ -191,8 +191,15 @@
 // Build a simple MLGraph asynchronously with only one relu operator.
 ScriptPromise BuildSimpleGraph(V8TestingScope& scope,
                                MLContextOptions* context_options) {
-  auto* builder =
-      CreateMLGraphBuilder(scope.GetExecutionContext(), context_options);
+  auto* builder = MLGraphTestBase::CreateGraphBuilder(scope, context_options);
+  if (builder == nullptr) {
+    return ScriptPromise::RejectWithDOMException(
+        scope.GetScriptState(),
+        DOMException::Create(
+            "Unable to create graph builder.",
+            DOMException::GetErrorName(DOMExceptionCode::kOperationError)));
+  }
+
   auto* lhs_operand =
       BuildInput(builder, "lhs", {3, 4, 5}, V8MLOperandType::Enum::kFloat32,
                  scope.GetExceptionState());
@@ -311,7 +318,8 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
+  ASSERT_NE(builder, nullptr);
   {
     // Test clamp operator with default options that no minimum and maximum
     // values are defined.
@@ -428,7 +436,7 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
   {
     // Test concat operator with one input.
     ConcatTester{
@@ -640,7 +648,8 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
+  ASSERT_NE(builder, nullptr);
   {
     // Test conv2d with default options.
     Conv2dTester{
@@ -872,7 +881,8 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
+  ASSERT_NE(builder, nullptr);
   {
     // Test element-wise add operator for two 1-D tensors.
     ElementWiseBinaryTester{
@@ -1018,7 +1028,8 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
+  ASSERT_NE(builder, nullptr);
   {
     // Test building gemm with default option.
     GemmTester{
@@ -1219,7 +1230,8 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
+  ASSERT_NE(builder, nullptr);
   {
     // Test pool2d with default options.
     Pool2dTester{
@@ -1413,7 +1425,8 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
+  ASSERT_NE(builder, nullptr);
   {
     // Test relu operator for 1-D tensor.
     ReluTester{
@@ -1519,7 +1532,7 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
   {
     Resample2dTester{
         .input = {.type = V8MLOperandType::Enum::kFloat32,
@@ -1660,7 +1673,8 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
+  ASSERT_NE(builder, nullptr);
   {
     // Test reshaping 2-D tensor to 1-D tensor.
     ReshapeTester{.input = {.type = V8MLOperandType::Enum::kFloat32,
@@ -1756,7 +1770,7 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
   {
     SliceTester{
         .input = {.type = V8MLOperandType::Enum::kFloat32,
@@ -1821,7 +1835,8 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
+  ASSERT_NE(builder, nullptr);
   {
     // Test building softmax with float32 input.
     SoftmaxTester{.input = {.type = V8MLOperandType::Enum::kFloat32,
@@ -1905,7 +1920,7 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
   {
     // Test transpose operator with default options.
     TransposeTester{
@@ -1984,7 +1999,8 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
+  ASSERT_NE(builder, nullptr);
   {
     // Test Constant operand for Float32 data type.
     ConstantTester<float>{
@@ -2114,7 +2130,7 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
   using v8 = V8MLOperandType::Enum;
   using blink = blink_mojom::Operand::DataType;
   {
@@ -2152,7 +2168,8 @@
   auto* options = MLContextOptions::Create();
   // Create WebNN Context with GPU device preference.
   options->setDevicePreference(V8MLDevicePreference::Enum::kGpu);
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext(), options);
+  auto* builder = CreateGraphBuilder(scope, options);
+  ASSERT_NE(builder, nullptr);
   const Vector<uint32_t> dimensions = {3, 5};
   const wtf_size_t number_of_elements = base::checked_cast<wtf_size_t>(
       webnn::ValidateAndCalculateElementsNumber(dimensions).value());
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack_test.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack_test.cc
index b7dbc5b..eb81fe3 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack_test.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack_test.cc
@@ -34,7 +34,9 @@
     // Test building MLGraphXnnpack with default options. The promise should be
     // resoveld with an MLGraphXnnpack object. The XNNPACK library should be
     // initialized successfully.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input =
         BuildInput(builder, "input", {3, 4, 5}, V8MLOperandType::Enum::kFloat32,
                    scope.GetExceptionState());
@@ -49,8 +51,9 @@
     // should be initialized successfully.
     auto* context_options = MLContextOptions::Create();
     context_options->setDevicePreference(V8MLDevicePreference::Enum::kCpu);
-    auto* builder =
-        CreateMLGraphBuilder(scope.GetExecutionContext(), context_options);
+    auto* builder = CreateMLGraphBuilder(
+        scope.GetExecutionContext(), scope.GetScriptState(),
+        scope.GetExceptionState(), context_options);
     auto* input =
         BuildInput(builder, "input", {3, 4, 5}, V8MLOperandType::Enum::kFloat32,
                    scope.GetExceptionState());
@@ -63,7 +66,9 @@
 
 TEST_F(MLGraphXnnpackTest, TopoSortOperatorsTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   {
     // Test sorting a graph in the following topology:
     //   conv2d
@@ -125,7 +130,9 @@
 
 TEST_P(MLGraphXnnpackTest, DefineXnnpackValuesTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   Vector<uint32_t> shape({1, 4, 4, 3});
   // TODO(crbug.com/1273291): Test float16 data type once the XNNPACK Subgraph
   // Add Node supports it.
@@ -319,7 +326,9 @@
 // Add an unit test to validate the value of exponent for pow operator.
 TEST_P(MLGraphXnnpackTest, PowTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   auto* input0 =
       BuildInput(builder, "input0", {1, 2, 2, 1},
                  V8MLOperandType::Enum::kFloat32, scope.GetExceptionState());
@@ -335,7 +344,9 @@
 
 TEST_P(MLGraphXnnpackTest, InvokeXnnpackRuntimeTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   Vector<uint32_t> shape({1, 2, 2, 1});
   // Create an MLGraphXnnpack with the following topology:
   //       [input0] [input1]
@@ -454,7 +465,9 @@
 // name.
 TEST_P(MLGraphXnnpackTest, InputAndOutputUseSameNameTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   Vector<uint32_t> shape({1, 2, 2, 1});
   {
     // Create an MLGraphXnnpack with the following topology:
@@ -517,7 +530,9 @@
 
 TEST_F(MLGraphXnnpackTest, ComputeAsyncTest) {
   V8TestingScope scope;
-  auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
   // Build an MLGraphXnnpack with the following topology:
   //        [a]     [b]
   //           \    /
@@ -759,7 +774,9 @@
     xnnpack_output.Shrink(batch_size * channels);
 
     // Build WebNN graph with elu operator.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input_operand = BuildInput(builder, "input", input.dimensions,
                                      input.type, scope.GetExceptionState());
     auto* output_operand =
@@ -857,7 +874,9 @@
     xnnpack_output.Shrink(batch_size * channels);
 
     // Build WebNN graph with softmax operator.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input_operand = BuildInput(builder, "input", input.dimensions,
                                      input.type, scope.GetExceptionState());
     auto* output_operand =
@@ -955,7 +974,9 @@
     xnnpack_output.Shrink(batch_size * channels);
 
     // Build WebNN graph with sigmoid operator.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input_operand = BuildInput(builder, "input", input.dimensions,
                                      input.type, scope.GetExceptionState());
     auto* output_operand =
@@ -1067,7 +1088,9 @@
     xnnpack_output.Shrink(batch_size * channels);
 
     // Build WebNN graph with tanh operator.
-    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
     auto* input_operand = BuildInput(builder, "input", input.dimensions,
                                      input.type, scope.GetExceptionState());
     auto* output_operand =
@@ -1126,8 +1149,9 @@
 
     // Build a simple WebNN graph with the options. A pthreadpool will be
     // created internally with `num_threads`.
-    auto* builder =
-        CreateMLGraphBuilder(scope.GetExecutionContext(), context_options);
+    auto* builder = CreateMLGraphBuilder(
+        scope.GetExecutionContext(), scope.GetScriptState(),
+        scope.GetExceptionState(), context_options);
     auto* input_operand =
         BuildInput(builder, "input", {1, 2, 2, 1},
                    V8MLOperandType::Enum::kFloat32, scope.GetExceptionState());
diff --git a/third_party/blink/renderer/modules/payments/payment_manager.cc b/third_party/blink/renderer/modules/payments/payment_manager.cc
index df5bcf5..4987dd5 100644
--- a/third_party/blink/renderer/modules/payments/payment_manager.cc
+++ b/third_party/blink/renderer/modules/payments/payment_manager.cc
@@ -21,7 +21,7 @@
     instruments_ = MakeGarbageCollected<PaymentInstruments>(
         manager_, registration_->GetExecutionContext());
   }
-  return instruments_;
+  return instruments_.Get();
 }
 
 const String& PaymentManager::userHint() {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc b/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc
index 950c736..fd33ee404 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc
@@ -86,7 +86,7 @@
 }
 
 RTCIceTransport* RTCDtlsTransport::iceTransport() const {
-  return ice_transport_;
+  return ice_transport_.Get();
 }
 
 webrtc::DtlsTransportInterface* RTCDtlsTransport::native_transport() {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
index b68809a..f7ed9f8 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc
@@ -171,15 +171,15 @@
 }
 
 RTCIceCandidatePair* RTCIceTransport::getSelectedCandidatePair() const {
-  return selected_candidate_pair_;
+  return selected_candidate_pair_.Get();
 }
 
 RTCIceParameters* RTCIceTransport::getLocalParameters() const {
-  return local_parameters_;
+  return local_parameters_.Get();
 }
 
 RTCIceParameters* RTCIceTransport::getRemoteParameters() const {
-  return remote_parameters_;
+  return remote_parameters_.Get();
 }
 
 void RTCIceTransport::OnGatheringStateChanged(
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index 3c9e50c..32f688d 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -1042,11 +1042,11 @@
 }
 
 RTCSessionDescription* RTCPeerConnection::currentLocalDescription() const {
-  return current_local_description_;
+  return current_local_description_.Get();
 }
 
 RTCSessionDescription* RTCPeerConnection::pendingLocalDescription() const {
-  return pending_local_description_;
+  return pending_local_description_.Get();
 }
 
 ScriptPromise RTCPeerConnection::setRemoteDescription(
@@ -1148,11 +1148,11 @@
 }
 
 RTCSessionDescription* RTCPeerConnection::currentRemoteDescription() const {
-  return current_remote_description_;
+  return current_remote_description_.Get();
 }
 
 RTCSessionDescription* RTCPeerConnection::pendingRemoteDescription() const {
-  return pending_remote_description_;
+  return pending_remote_description_.Get();
 }
 
 RTCConfiguration* RTCPeerConnection::getConfiguration(
@@ -1609,7 +1609,7 @@
   for (const auto& rtp_receiver : rtp_receivers_) {
     for (const auto& stream : rtp_receiver->streams()) {
       if (stream->id() == id) {
-        return stream;
+        return stream.Get();
       }
     }
   }
@@ -1953,7 +1953,7 @@
 }
 
 RTCSctpTransport* RTCPeerConnection::sctp() const {
-  return sctp_transport_;
+  return sctp_transport_.Get();
 }
 
 RTCDataChannel* RTCPeerConnection::createDataChannel(
@@ -2037,7 +2037,7 @@
     MediaStreamComponent* component) const {
   auto it = tracks_.find(component);
   if (it != tracks_.end()) {
-    return it->value;
+    return it->value.Get();
   } else {
     return nullptr;
   }
@@ -2050,7 +2050,7 @@
     if (rtp_sender->track() == track) {
       auto streams = rtp_sender->streams();
       if (streams.size() == 1u && streams[0] == stream)
-        return rtp_sender;
+        return rtp_sender.Get();
     }
   }
   return nullptr;
@@ -2204,7 +2204,7 @@
         GetExecutionContext(), std::move(native_transport), ice_transport);
   }
   transport->ChangeState(information);
-  return transport;
+  return transport.Get();
 }
 
 RTCIceTransport* RTCPeerConnection::CreateOrUpdateIceTransport(
@@ -2219,7 +2219,7 @@
     transport = RTCIceTransport::Create(GetExecutionContext(),
                                         std::move(ice_transport), this);
   }
-  return transport;
+  return transport.Get();
 }
 
 RTCDTMFSender* RTCPeerConnection::createDTMFSender(
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
index f59a07e7..e6cdd7e 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
@@ -80,12 +80,12 @@
 
 MediaStreamTrack* RTCRtpReceiver::track() const {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  return track_;
+  return track_.Get();
 }
 
 RTCDtlsTransport* RTCRtpReceiver::transport() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  return transport_;
+  return transport_.Get();
 }
 
 RTCDtlsTransport* RTCRtpReceiver::rtcpTransport() {
@@ -163,7 +163,7 @@
   }
 
   InitializeEncodedAudioStreams(script_state);
-  return encoded_audio_streams_;
+  return encoded_audio_streams_.Get();
 }
 
 RTCInsertableStreams* RTCRtpReceiver::createEncodedVideoStreams(
@@ -183,7 +183,7 @@
   }
 
   InitializeEncodedVideoStreams(script_state);
-  return encoded_video_streams_;
+  return encoded_video_streams_.Get();
 }
 
 RTCRtpReceiverPlatform* RTCRtpReceiver::platform_receiver() {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
index 1644340..d7131fe 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
@@ -649,12 +649,12 @@
 
 MediaStreamTrack* RTCRtpSender::track() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  return track_;
+  return track_.Get();
 }
 
 RTCDtlsTransport* RTCRtpSender::transport() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  return transport_;
+  return transport_.Get();
 }
 
 RTCDtlsTransport* RTCRtpSender::rtcpTransport() {
@@ -894,7 +894,7 @@
     dtmf_ =
         RTCDTMFSender::Create(pc_->GetExecutionContext(), std::move(handler));
   }
-  return dtmf_;
+  return dtmf_.Get();
 }
 
 void RTCRtpSender::setStreams(HeapVector<Member<MediaStream>> streams,
@@ -940,7 +940,7 @@
   }
 
   InitializeEncodedAudioStreams(script_state);
-  return encoded_audio_streams_;
+  return encoded_audio_streams_.Get();
 }
 
 RTCInsertableStreams* RTCRtpSender::createEncodedVideoStreams(
@@ -960,7 +960,7 @@
   }
 
   InitializeEncodedVideoStreams(script_state);
-  return encoded_video_streams_;
+  return encoded_video_streams_.Get();
 }
 
 void RTCRtpSender::ContextDestroyed() {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc
index 0fde83a..c376d482 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc
@@ -134,11 +134,11 @@
 }
 
 RTCRtpSender* RTCRtpTransceiver::sender() const {
-  return sender_;
+  return sender_.Get();
 }
 
 RTCRtpReceiver* RTCRtpTransceiver::receiver() const {
-  return receiver_;
+  return receiver_.Get();
 }
 
 bool RTCRtpTransceiver::stopped() const {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.cc b/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.cc
index 50952dc..9dfe050 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.cc
@@ -110,7 +110,7 @@
 }
 
 RTCDtlsTransport* RTCSctpTransport::transport() const {
-  return dtls_transport_;
+  return dtls_transport_.Get();
 }
 
 rtc::scoped_refptr<webrtc::SctpTransportInterface>
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc b/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc
index 2230120..3f3b4ed 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc
@@ -47,11 +47,11 @@
 }
 
 bool RTCStatsRequestImpl::HasSelector() {
-  return component_;
+  return component_ != nullptr;
 }
 
 MediaStreamComponent* RTCStatsRequestImpl::Component() {
-  return component_;
+  return component_.Get();
 }
 
 void RTCStatsRequestImpl::RequestSucceeded(RTCStatsResponseBase* response) {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc b/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc
index f0dadd1..7780aca 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc
@@ -46,7 +46,7 @@
 }
 
 MediaStreamTrack* RTCTrackEvent::track() const {
-  return track_;
+  return track_.Get();
 }
 
 const HeapVector<Member<MediaStream>>& RTCTrackEvent::streams() const {
@@ -54,7 +54,7 @@
 }
 
 RTCRtpTransceiver* RTCTrackEvent::transceiver() const {
-  return transceiver_;
+  return transceiver_.Get();
 }
 
 void RTCTrackEvent::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/plugins/dom_mime_type_array.cc b/third_party/blink/renderer/modules/plugins/dom_mime_type_array.cc
index 27753c1..3813e55 100644
--- a/third_party/blink/renderer/modules/plugins/dom_mime_type_array.cc
+++ b/third_party/blink/renderer/modules/plugins/dom_mime_type_array.cc
@@ -59,14 +59,14 @@
         DomWindow(), *GetPluginData()->Mimes()[index]);
   }
 
-  return dom_mime_types_[index];
+  return dom_mime_types_[index].Get();
 }
 
 DOMMimeType* DOMMimeTypeArray::namedItem(const AtomicString& property_name) {
   if (should_return_fixed_plugin_data_) {
     for (const auto& mimetype : dom_mime_types_) {
       if (mimetype->type() == property_name)
-        return mimetype;
+        return mimetype.Get();
     }
     return nullptr;
   }
diff --git a/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc b/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc
index 392fcaa8..62c7f79 100644
--- a/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc
+++ b/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc
@@ -64,14 +64,14 @@
         DomWindow(), *GetPluginData()->Plugins()[index]);
   }
 
-  return dom_plugins_[index];
+  return dom_plugins_[index].Get();
 }
 
 DOMPlugin* DOMPluginArray::namedItem(const AtomicString& property_name) {
   if (should_return_fixed_plugin_data_) {
     for (const auto& plugin : dom_plugins_) {
       if (plugin->name() == property_name)
-        return plugin;
+        return plugin.Get();
     }
     return nullptr;
   }
diff --git a/third_party/blink/renderer/modules/presentation/presentation.cc b/third_party/blink/renderer/modules/presentation/presentation.cc
index 9fada844..1660ce0 100644
--- a/third_party/blink/renderer/modules/presentation/presentation.cc
+++ b/third_party/blink/renderer/modules/presentation/presentation.cc
@@ -55,7 +55,7 @@
 }
 
 PresentationRequest* Presentation::defaultRequest() const {
-  return default_request_;
+  return default_request_.Get();
 }
 
 void Presentation::setDefaultRequest(PresentationRequest* request) {
@@ -80,7 +80,7 @@
 
 PresentationReceiver* Presentation::receiver() {
   MaybeInitReceiver();
-  return receiver_;
+  return receiver_.Get();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/presentation/presentation_controller.cc b/third_party/blink/renderer/modules/presentation/presentation_controller.cc
index 4176962..f931959 100644
--- a/third_party/blink/renderer/modules/presentation/presentation_controller.cc
+++ b/third_party/blink/renderer/modules/presentation/presentation_controller.cc
@@ -69,7 +69,7 @@
         GetPresentationService().get());
   }
 
-  return availability_state_;
+  return availability_state_.Get();
 }
 
 void PresentationController::AddAvailabilityObserver(
diff --git a/third_party/blink/renderer/modules/push_messaging/push_subscription.cc b/third_party/blink/renderer/modules/push_messaging/push_subscription.cc
index de362de..6f1b8a60 100644
--- a/third_party/blink/renderer/modules/push_messaging/push_subscription.cc
+++ b/third_party/blink/renderer/modules/push_messaging/push_subscription.cc
@@ -106,9 +106,9 @@
 
 DOMArrayBuffer* PushSubscription::getKey(const AtomicString& name) const {
   if (name == "p256dh")
-    return p256dh_;
+    return p256dh_.Get();
   if (name == "auth")
-    return auth_;
+    return auth_.Get();
 
   return nullptr;
 }
diff --git a/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc b/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc
index 22438e2..f345c589 100644
--- a/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc
+++ b/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc
@@ -307,7 +307,7 @@
     CHECK(signal->HasFixedPriority());
     fixed_priority_task_signals_[index] = signal;
   }
-  return fixed_priority_task_signals_[index];
+  return fixed_priority_task_signals_[index].Get();
 }
 
 DOMScheduler::DOMTaskQueue* DOMScheduler::GetTaskQueue(
diff --git a/third_party/blink/renderer/modules/screen_details/screen_details.cc b/third_party/blink/renderer/modules/screen_details/screen_details.cc
index f966b15..2a545c5e 100644
--- a/third_party/blink/renderer/modules/screen_details/screen_details.cc
+++ b/third_party/blink/renderer/modules/screen_details/screen_details.cc
@@ -37,7 +37,7 @@
   auto* it = base::ranges::find(screens_, current_display_id_,
                                 &ScreenDetailed::DisplayId);
   DCHECK(it != screens_.end());
-  return *it;
+  return it->Get();
 }
 
 const AtomicString& ScreenDetails::InterfaceName() const {
diff --git a/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.cc b/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.cc
index 0273f55..8092ab4d 100644
--- a/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.cc
+++ b/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.cc
@@ -32,7 +32,7 @@
   if (!self.orientation_)
     self.orientation_ = ScreenOrientation::Create(window);
 
-  return self.orientation_;
+  return self.orientation_.Get();
 }
 
 const char ScreenScreenOrientation::kSupplementName[] =
diff --git a/third_party/blink/renderer/modules/serial/serial.cc b/third_party/blink/renderer/modules/serial/serial.cc
index 511ccf8..8c92302 100644
--- a/third_party/blink/renderer/modules/serial/serial.cc
+++ b/third_party/blink/renderer/modules/serial/serial.cc
@@ -340,7 +340,7 @@
 SerialPort* Serial::GetOrCreatePort(mojom::blink::SerialPortInfoPtr info) {
   auto it = port_cache_.find(TokenToString(info->token));
   if (it != port_cache_.end()) {
-    return it->value;
+    return it->value.Get();
   }
 
   SerialPort* port = MakeGarbageCollected<SerialPort>(this, std::move(info));
diff --git a/third_party/blink/renderer/modules/serial/serial_port.cc b/third_party/blink/renderer/modules/serial/serial_port.cc
index d2467e0..a7fdadc 100644
--- a/third_party/blink/renderer/modules/serial/serial_port.cc
+++ b/third_party/blink/renderer/modules/serial/serial_port.cc
@@ -240,7 +240,7 @@
 ReadableStream* SerialPort::readable(ScriptState* script_state,
                                      ExceptionState& exception_state) {
   if (readable_)
-    return readable_;
+    return readable_.Get();
 
   if (!port_.is_bound() || open_resolver_ || IsClosing() || read_fatal_)
     return nullptr;
@@ -260,13 +260,13 @@
       script_state, this, std::move(consumer));
   readable_ =
       ReadableStream::CreateByteStream(script_state, underlying_source_);
-  return readable_;
+  return readable_.Get();
 }
 
 WritableStream* SerialPort::writable(ScriptState* script_state,
                                      ExceptionState& exception_state) {
   if (writable_)
-    return writable_;
+    return writable_.Get();
 
   if (!port_.is_bound() || open_resolver_ || IsClosing() || write_fatal_)
     return nullptr;
@@ -291,7 +291,7 @@
   // extra layer of buffering.
   writable_ = WritableStream::CreateWithCountQueueingStrategy(
       script_state, underlying_sink_, /*high_water_mark=*/1);
-  return writable_;
+  return writable_.Get();
 }
 
 ScriptPromise SerialPort::getSignals(ScriptState* script_state,
diff --git a/third_party/blink/renderer/modules/serial/serial_port_underlying_source.cc b/third_party/blink/renderer/modules/serial/serial_port_underlying_source.cc
index 1f44400..28312e3 100644
--- a/third_party/blink/renderer/modules/serial/serial_port_underlying_source.cc
+++ b/third_party/blink/renderer/modules/serial/serial_port_underlying_source.cc
@@ -80,7 +80,7 @@
 }
 
 ScriptState* SerialPortUnderlyingSource::GetScriptState() {
-  return script_state_;
+  return script_state_.Get();
 }
 
 void SerialPortUnderlyingSource::ContextDestroyed() {
diff --git a/third_party/blink/renderer/modules/service_worker/fetch_event.cc b/third_party/blink/renderer/modules/service_worker/fetch_event.cc
index 7c38a88..d9023c89 100644
--- a/third_party/blink/renderer/modules/service_worker/fetch_event.cc
+++ b/third_party/blink/renderer/modules/service_worker/fetch_event.cc
@@ -39,7 +39,7 @@
 }
 
 Request* FetchEvent::request() const {
-  return request_;
+  return request_.Get();
 }
 
 String FetchEvent::clientId() const {
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_container.cc b/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
index 8917afb..18cd137bd 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
@@ -615,7 +615,7 @@
 
   auto it = service_worker_objects_.find(info.version_id);
   if (it != service_worker_objects_.end())
-    return it->value;
+    return it->value.Get();
 
   const int64_t version_id = info.version_id;
   ServiceWorker* worker = ServiceWorker::Create(
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
index d26ad7b..62e6edf 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -581,15 +581,15 @@
 ServiceWorkerClients* ServiceWorkerGlobalScope::clients() {
   if (!clients_)
     clients_ = ServiceWorkerClients::Create();
-  return clients_;
+  return clients_.Get();
 }
 
 ServiceWorkerRegistration* ServiceWorkerGlobalScope::registration() {
-  return registration_;
+  return registration_.Get();
 }
 
 ::blink::ServiceWorker* ServiceWorkerGlobalScope::serviceWorker() {
-  return service_worker_;
+  return service_worker_.Get();
 }
 
 ScriptPromise ServiceWorkerGlobalScope::skipWaiting(ScriptState* script_state) {
@@ -689,7 +689,7 @@
 
   auto it = service_worker_objects_.find(info.version_id);
   if (it != service_worker_objects_.end())
-    return it->value;
+    return it->value.Get();
 
   const int64_t version_id = info.version_id;
   ::blink::ServiceWorker* worker =
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc b/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
index 018ac01..8b69e7d8 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
@@ -220,7 +220,7 @@
 NavigationPreloadManager* ServiceWorkerRegistration::navigationPreload() {
   if (!navigation_preload_)
     navigation_preload_ = MakeGarbageCollected<NavigationPreloadManager>(this);
-  return navigation_preload_;
+  return navigation_preload_.Get();
 }
 
 String ServiceWorkerRegistration::scope() const {
diff --git a/third_party/blink/renderer/modules/shared_storage/window_shared_storage.cc b/third_party/blink/renderer/modules/shared_storage/window_shared_storage.cc
index 9ecdd19..f78e725 100644
--- a/third_party/blink/renderer/modules/shared_storage/window_shared_storage.cc
+++ b/third_party/blink/renderer/modules/shared_storage/window_shared_storage.cc
@@ -36,7 +36,7 @@
   SharedStorage* GetOrCreate(LocalDOMWindow& fetching_scope) {
     if (!shared_storage_)
       shared_storage_ = MakeGarbageCollected<SharedStorage>();
-    return shared_storage_;
+    return shared_storage_.Get();
   }
 
   void Trace(Visitor* visitor) const override {
diff --git a/third_party/blink/renderer/modules/speech/speech_synthesis.cc b/third_party/blink/renderer/modules/speech/speech_synthesis.cc
index 542388d..a55aea8 100644
--- a/third_party/blink/renderer/modules/speech/speech_synthesis.cc
+++ b/third_party/blink/renderer/modules/speech/speech_synthesis.cc
@@ -358,7 +358,7 @@
   if (utterance_queue_.empty())
     return nullptr;
 
-  return utterance_queue_.front();
+  return utterance_queue_.front().Get();
 }
 
 ExecutionContext* SpeechSynthesis::GetExecutionContext() const {
diff --git a/third_party/blink/renderer/modules/storage/dom_window_storage.cc b/third_party/blink/renderer/modules/storage/dom_window_storage.cc
index 5273c760..6df264c 100644
--- a/third_party/blink/renderer/modules/storage/dom_window_storage.cc
+++ b/third_party/blink/renderer/modules/storage/dom_window_storage.cc
@@ -130,7 +130,7 @@
   }
 
   if (session_storage_)
-    return session_storage_;
+    return session_storage_.Get();
 
   StorageNamespace* storage_namespace =
       StorageNamespace::From(window->GetFrame()->GetPage());
@@ -148,7 +148,7 @@
       StorageArea::Create(window, std::move(cached_storage_area),
                           StorageArea::StorageType::kSessionStorage);
 
-  return session_storage_;
+  return session_storage_.Get();
 }
 
 StorageArea* DOMWindowStorage::GetOrCreateLocalStorage(
@@ -175,13 +175,13 @@
     return nullptr;
 
   if (local_storage_)
-    return local_storage_;
+    return local_storage_.Get();
 
   auto storage_area = StorageController::GetInstance()->GetLocalStorageArea(
       window, std::move(storage_area_for_init));
   local_storage_ = StorageArea::Create(window, std::move(storage_area),
                                        StorageArea::StorageType::kLocalStorage);
-  return local_storage_;
+  return local_storage_.Get();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/storage/storage_controller.cc b/third_party/blink/renderer/modules/storage/storage_controller.cc
index 17d34788..882c74d 100644
--- a/third_party/blink/renderer/modules/storage/storage_controller.cc
+++ b/third_party/blink/renderer/modules/storage/storage_controller.cc
@@ -86,7 +86,7 @@
   // around.
   auto it = namespaces_->find(namespace_id);
   if (it != namespaces_->end())
-    return it->value;
+    return it->value.Get();
   StorageNamespace* ns =
       MakeGarbageCollected<StorageNamespace>(page, this, namespace_id);
   namespaces_->insert(namespace_id, ns);
diff --git a/third_party/blink/renderer/modules/storage/testing/fake_area_source.h b/third_party/blink/renderer/modules/storage/testing/fake_area_source.h
index 70804aa..9af3a31d 100644
--- a/third_party/blink/renderer/modules/storage/testing/fake_area_source.h
+++ b/third_party/blink/renderer/modules/storage/testing/fake_area_source.h
@@ -40,7 +40,7 @@
     return blink::WebScopedVirtualTimePauser();
   }
 
-  LocalDOMWindow* GetDOMWindow() override { return local_dom_window_; }
+  LocalDOMWindow* GetDOMWindow() override { return local_dom_window_.Get(); }
 
   struct Event {
     String key, old_value, new_value, url;
diff --git a/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.cc b/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.cc
index 76164fb..109262ca 100644
--- a/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.cc
+++ b/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.cc
@@ -70,7 +70,7 @@
 }
 
 DOMRect* VirtualKeyboard::boundingRect() const {
-  return bounding_rect_;
+  return bounding_rect_.Get();
 }
 
 void VirtualKeyboard::setOverlaysContent(bool overlays_content) {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc b/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc
index 566168c..71d398a 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc
@@ -127,11 +127,11 @@
 }
 
 AudioParam* AudioBufferSourceNode::playbackRate() const {
-  return playback_rate_;
+  return playback_rate_.Get();
 }
 
 AudioParam* AudioBufferSourceNode::detune() const {
-  return detune_;
+  return detune_.Get();
 }
 
 bool AudioBufferSourceNode::loop() const {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.cc b/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.cc
index 7900914..02d1853 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.cc
@@ -67,7 +67,7 @@
 BaseAudioContext* AudioGraphTracer::GetContextById(String contextId) {
   for (const auto& context : contexts_) {
     if (context->Uuid() == contextId) {
-      return context;
+      return context.Get();
     }
   }
 
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
index fca07d7..37b0bcb5 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
@@ -207,11 +207,11 @@
 }
 
 AudioParamMap* AudioWorkletNode::parameters() const {
-  return parameter_map_;
+  return parameter_map_.Get();
 }
 
 MessagePort* AudioWorkletNode::port() const {
-  return node_port_;
+  return node_port_.Get();
 }
 
 void AudioWorkletNode::FireProcessorError(
diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
index 04853c6d7..0f8d1a6 100644
--- a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
+++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc
@@ -219,7 +219,7 @@
   // Cannot be called from the audio thread because this method touches objects
   // managed by Oilpan, and the audio thread is not managed by Oilpan.
   DCHECK(!IsAudioThread());
-  return destination_node_;
+  return destination_node_.Get();
 }
 
 void BaseAudioContext::WarnIfContextClosed(const AudioHandler* handler) const {
@@ -625,25 +625,25 @@
       if (!periodic_wave_sine_) {
         periodic_wave_sine_ = PeriodicWave::CreateSine(sampleRate());
       }
-      return periodic_wave_sine_;
+      return periodic_wave_sine_.Get();
     case OscillatorHandler::SQUARE:
       // Initialize the table if necessary
       if (!periodic_wave_square_) {
         periodic_wave_square_ = PeriodicWave::CreateSquare(sampleRate());
       }
-      return periodic_wave_square_;
+      return periodic_wave_square_.Get();
     case OscillatorHandler::SAWTOOTH:
       // Initialize the table if necessary
       if (!periodic_wave_sawtooth_) {
         periodic_wave_sawtooth_ = PeriodicWave::CreateSawtooth(sampleRate());
       }
-      return periodic_wave_sawtooth_;
+      return periodic_wave_sawtooth_.Get();
     case OscillatorHandler::TRIANGLE:
       // Initialize the table if necessary
       if (!periodic_wave_triangle_) {
         periodic_wave_triangle_ = PeriodicWave::CreateTriangle(sampleRate());
       }
-      return periodic_wave_triangle_;
+      return periodic_wave_triangle_.Get();
     default:
       NOTREACHED();
       return nullptr;
diff --git a/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc b/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc
index 5ea4c3c..b374230 100644
--- a/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc
@@ -173,11 +173,11 @@
 }
 
 AudioParam* DynamicsCompressorNode::attack() const {
-  return attack_;
+  return attack_.Get();
 }
 
 AudioParam* DynamicsCompressorNode::release() const {
-  return release_;
+  return release_.Get();
 }
 
 void DynamicsCompressorNode::ReportDidCreate() {
diff --git a/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc b/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc
index 4ac19fa3..483efa81 100644
--- a/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc
+++ b/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc
@@ -97,7 +97,7 @@
 }
 
 HTMLMediaElement* MediaElementAudioSourceNode::mediaElement() const {
-  return media_element_;
+  return media_element_.Get();
 }
 
 void MediaElementAudioSourceNode::SetFormat(uint32_t number_of_channels,
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_inputs.proto b/third_party/blink/renderer/modules/webcodecs/fuzzer_inputs.proto
index 158ddaf..97f11a5 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_inputs.proto
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_inputs.proto
@@ -100,6 +100,13 @@
     REALTIME = 1;
   }
 
+  enum ContentHint {
+    NONE = 0;
+    MOTION = 1;
+    DETAIL = 2;
+    TEXT = 3;
+  }
+
   enum VideoEncoderBitrateMode {
     CONSTANT = 0;
     VARIABLE = 1;
@@ -132,6 +139,8 @@
   optional LatencyMode latency_mode = 11;
 
   optional AlphaOption alpha = 12;
+
+  optional ContentHint content_hint = 13;
 }
 
 message ConfigureAudioDecoder {
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_av1.textproto b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_av1.textproto
index 2c3f09d..597425b7 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_av1.textproto
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_av1.textproto
@@ -21,7 +21,8 @@
       bitrate_mode: CONSTANT,
       scalability_mode: L1T2,
       alpha: DISCARD,
-      latency_mode: REALTIME
+      latency_mode: REALTIME,
+      content_hint: TEXT
     }
   },
   {
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_h264.textproto b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_h264.textproto
index 2b6accdc..11c39c6 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_h264.textproto
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_h264.textproto
@@ -21,7 +21,8 @@
       bitrate_mode: CONSTANT,
       scalability_mode: L1T3,
       alpha: DISCARD,
-      latency_mode: QUALITY
+      latency_mode: QUALITY,
+      content_hint: MOTION
 
     }
   },
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp8.textproto b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp8.textproto
index 0949923..2d16833 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp8.textproto
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp8.textproto
@@ -21,7 +21,8 @@
       bitrate_mode: VARIABLE,
       scalability_mode: L1T3,
       alpha: DISCARD,
-      latency_mode: QUALITY
+      latency_mode: QUALITY,
+      content_hint: DETAIL
     }
   },
   {
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp9.textproto b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp9.textproto
index aa6158c..bcfecf4 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp9.textproto
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_seed_corpus/video_encoder/encode_vp9.textproto
@@ -21,7 +21,8 @@
       bitrate_mode: VARIABLE,
       scalability_mode: L1T1,
       alpha: KEEP,
-      latency_mode: QUALITY
+      latency_mode: QUALITY,
+      content_hint: TEXT
     }
   },
   {
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc
index 6b80855..7b7469e 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc
@@ -129,6 +129,10 @@
     config->setLatencyMode(ToLatencyMode(proto.latency_mode()));
   }
 
+  if (proto.has_content_hint()) {
+    config->setContentHint(ToContentHint(proto.content_hint()));
+  }
+
   // Bitrate is truly optional, so don't just take the proto default value.
   if (proto.has_bitrate())
     config->setBitrate(proto.bitrate());
@@ -200,6 +204,19 @@
   }
 }
 
+String ToContentHint(wc_fuzzer::ConfigureVideoEncoder_ContentHint hint) {
+  switch (hint) {
+    case wc_fuzzer::ConfigureVideoEncoder_ContentHint_NONE:
+      return "";
+    case wc_fuzzer::ConfigureVideoEncoder_ContentHint_TEXT:
+      return "text";
+    case wc_fuzzer::ConfigureVideoEncoder_ContentHint_MOTION:
+      return "motion";
+    case wc_fuzzer::ConfigureVideoEncoder_ContentHint_DETAIL:
+      return "detail";
+  }
+}
+
 String ToAlphaOption(wc_fuzzer::ConfigureVideoEncoder_AlphaOption option) {
   switch (option) {
     case wc_fuzzer::ConfigureVideoEncoder_AlphaOption_KEEP:
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h
index 2c7c0ef..f6af965 100644
--- a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h
+++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h
@@ -96,6 +96,8 @@
 
 String ToLatencyMode(wc_fuzzer::ConfigureVideoEncoder_LatencyMode mode);
 
+String ToContentHint(wc_fuzzer::ConfigureVideoEncoder_ContentHint hint);
+
 String ToAlphaOption(wc_fuzzer::ConfigureVideoEncoder_AlphaOption option);
 
 String ToAacFormat(wc_fuzzer::AacFormat format);
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
index b0f3235..88858729 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -250,6 +250,14 @@
           ? media::VideoEncoder::LatencyMode::Quality
           : media::VideoEncoder::LatencyMode::Realtime;
 
+  if (config->hasContentHint()) {
+    if (config->contentHint() == "detail" || config->contentHint() == "text") {
+      result->options.content_hint = media::VideoEncoder::ContentHint::Screen;
+    } else if (config->contentHint() == "motion") {
+      result->options.content_hint = media::VideoEncoder::ContentHint::Camera;
+    }
+  }
+
   if (config->hasBitrateMode() && config->bitrateMode() == "quantizer") {
     result->options.bitrate = media::Bitrate::ExternalRateControl();
   } else if (config->hasBitrate()) {
@@ -498,6 +506,10 @@
   if (config.hasLatencyMode())
     result->setLatencyMode(config.latencyMode());
 
+  if (config.hasContentHint()) {
+    result->setContentHint(config.contentHint());
+  }
+
   if (config.hasAvc() && config.avc()->hasFormat()) {
     auto* avc = AvcEncoderConfig::Create();
     avc->setFormat(config.avc()->format());
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder_config.idl b/third_party/blink/renderer/modules/webcodecs/video_encoder_config.idl
index 37febc16..4a3f077 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_encoder_config.idl
+++ b/third_party/blink/renderer/modules/webcodecs/video_encoder_config.idl
@@ -32,4 +32,8 @@
   DOMString scalabilityMode;
 
   LatencyMode latencyMode = "quality";
+
+  // MediaStreamTrack Content Hints (https://www.w3.org/TR/mst-content-hint/)
+  [RuntimeEnabled=WebCodecsContentHint]
+  DOMString contentHint = "";
 };
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame.cc b/third_party/blink/renderer/modules/webcodecs/video_frame.cc
index f5ee4850..e5860706 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_frame.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame.cc
@@ -991,7 +991,7 @@
         0, 0, local_frame->coded_size().width(),
         local_frame->coded_size().height());
   }
-  return coded_rect_;
+  return coded_rect_.Get();
 }
 
 DOMRectReadOnly* VideoFrame::visibleRect() {
@@ -1005,7 +1005,7 @@
         local_frame->visible_rect().width(),
         local_frame->visible_rect().height());
   }
-  return visible_rect_;
+  return visible_rect_.Get();
 }
 
 uint32_t VideoFrame::displayWidth() const {
@@ -1053,14 +1053,14 @@
     if (!empty_color_space_)
       empty_color_space_ = MakeGarbageCollected<VideoColorSpace>();
 
-    return empty_color_space_;
+    return empty_color_space_.Get();
   }
 
   if (!color_space_) {
     color_space_ =
         MakeGarbageCollected<VideoColorSpace>(local_frame->ColorSpace());
   }
-  return color_space_;
+  return color_space_.Get();
 }
 
 uint32_t VideoFrame::allocationSize(VideoFrameCopyToOptions* options,
diff --git a/third_party/blink/renderer/modules/webdatabase/sql_statement.cc b/third_party/blink/renderer/modules/webdatabase/sql_statement.cc
index f60ba24..c3c8233 100644
--- a/third_party/blink/renderer/modules/webdatabase/sql_statement.cc
+++ b/third_party/blink/renderer/modules/webdatabase/sql_statement.cc
@@ -105,11 +105,11 @@
 }
 
 bool SQLStatement::HasCallback() {
-  return success_callback_;
+  return success_callback_ != nullptr;
 }
 
 bool SQLStatement::HasErrorCallback() {
-  return error_callback_;
+  return error_callback_ != nullptr;
 }
 
 bool SQLStatement::PerformCallback(SQLTransaction* transaction) {
diff --git a/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc b/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc
index 84c3f38..efa4058 100644
--- a/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc
+++ b/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc
@@ -117,15 +117,15 @@
 }
 
 bool SQLTransaction::HasCallback() const {
-  return callback_;
+  return callback_ != nullptr;
 }
 
 bool SQLTransaction::HasSuccessCallback() const {
-  return success_callback_;
+  return success_callback_ != nullptr;
 }
 
 bool SQLTransaction::HasErrorCallback() const {
-  return error_callback_;
+  return error_callback_ != nullptr;
 }
 
 void SQLTransaction::SetBackend(SQLTransactionBackend* backend) {
diff --git a/third_party/blink/renderer/modules/webgl/webgl_program.cc b/third_party/blink/renderer/modules/webgl/webgl_program.cc
index 6798344..b734d00 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_program.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_program.cc
@@ -88,9 +88,9 @@
 WebGLShader* WebGLProgram::GetAttachedShader(GLenum type) {
   switch (type) {
     case GL_VERTEX_SHADER:
-      return vertex_shader_;
+      return vertex_shader_.Get();
     case GL_FRAGMENT_SHADER:
-      return fragment_shader_;
+      return fragment_shader_.Get();
     default:
       return nullptr;
   }
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
index 771f4dc0..96b069c 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
@@ -1035,7 +1035,7 @@
         extension_field_ = extension_;
       }
 
-      return extension_;
+      return extension_.Get();
     }
 
     bool Supported(WebGLRenderingContextBase* context) const override {
@@ -1053,7 +1053,7 @@
     }
 
     WebGLExtension* GetExtensionObjectIfAlreadyEnabled() override {
-      return extension_;
+      return extension_.Get();
     }
 
     void Trace(Visitor* visitor) const override {
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc
index e39b9ee1..8f2f5312 100644
--- a/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc
+++ b/third_party/blink/renderer/modules/webgpu/dawn_enum_conversions.cc
@@ -672,8 +672,8 @@
 
 WGPUFeatureName AsDawnEnum(const V8GPUFeatureName& webgpu_enum) {
   switch (webgpu_enum.AsEnum()) {
-    case V8GPUFeatureName::Enum::kPipelineStatisticsQuery:
-      return WGPUFeatureName_PipelineStatisticsQuery;
+    case V8GPUFeatureName::Enum::kChromiumExperimentalPipelineStatisticsQuery:
+      return WGPUFeatureName_ChromiumExperimentalPipelineStatisticsQuery;
     case V8GPUFeatureName::Enum::kTextureCompressionBc:
       return WGPUFeatureName_TextureCompressionBC;
     case V8GPUFeatureName::Enum::kTextureCompressionEtc2:
diff --git a/third_party/blink/renderer/modules/webgpu/gpu.cc b/third_party/blink/renderer/modules/webgpu/gpu.cc
index f2f4e8b..3067c9a 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu.cc
@@ -133,7 +133,7 @@
 GPU::~GPU() = default;
 
 WGSLLanguageFeatures* GPU::wgslLanguageFeatures() const {
-  return wgsl_language_features_;
+  return wgsl_language_features_.Get();
 }
 
 void GPU::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
index 70e6b212..0beff622 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
@@ -34,8 +34,9 @@
     case WGPUFeatureName_ChromiumExperimentalTimestampQueryInsidePasses:
       return V8GPUFeatureName::Enum::
           kChromiumExperimentalTimestampQueryInsidePasses;
-    case WGPUFeatureName_PipelineStatisticsQuery:
-      return V8GPUFeatureName::Enum::kPipelineStatisticsQuery;
+    case WGPUFeatureName_ChromiumExperimentalPipelineStatisticsQuery:
+      return V8GPUFeatureName::Enum::
+          kChromiumExperimentalPipelineStatisticsQuery;
     case WGPUFeatureName_TextureCompressionBC:
       return V8GPUFeatureName::Enum::kTextureCompressionBc;
     case WGPUFeatureName_TextureCompressionETC2:
@@ -147,7 +148,7 @@
 }
 
 GPUSupportedFeatures* GPUAdapter::features() const {
-  return features_;
+  return features_.Get();
 }
 
 bool GPUAdapter::isFallbackAdapter() const {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
index 8eed8e0d..d20a833c 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
@@ -555,7 +555,7 @@
   // time, the same texture should be returned. |texture_| is set to
   // null when presented so that we know we should create a new one.
   if (texture_ && !new_texture_required_) {
-    return texture_;
+    return texture_.Get();
   }
   new_texture_required_ = false;
 
@@ -589,7 +589,7 @@
     }
     texture_ = swap_texture_ =
         GPUTexture::CreateError(device_, &texture_descriptor_);
-    return texture_;
+    return texture_.Get();
   }
 
   mailbox_texture->SetNeedsPresent(true);
@@ -620,7 +620,7 @@
   UseCounter::Count(execution_context,
                     WebFeature::kWebGPUCanvasContextGetCurrentTexture);
 
-  return texture_;
+  return texture_.Get();
 }
 
 void GPUCanvasContext::ReplaceDrawingBuffer(bool destroy_swap_buffers) {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
index fc159b2..c59c65b 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_device.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -447,11 +447,11 @@
 }
 
 GPUAdapter* GPUDevice::adapter() const {
-  return adapter_;
+  return adapter_.Get();
 }
 
 GPUSupportedFeatures* GPUDevice::features() const {
-  return features_;
+  return features_.Get();
 }
 
 ScriptPromise GPUDevice::lost(ScriptState* script_state) {
@@ -459,7 +459,7 @@
 }
 
 GPUQueue* GPUDevice::queue() {
-  return queue_;
+  return queue_.Get();
 }
 
 bool GPUDevice::destroyed() const {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
index 24372d2..5674224 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
@@ -373,13 +373,8 @@
       BindWGPUOnceCallback(&GPUQueue::OnWorkDoneCallback, WrapPersistent(this),
                            WrapPersistent(resolver));
 
-#ifdef WGPU_BREAKING_WORK_DONE_SIGNAL_VALUE_CHANGE
   GetProcs().queueOnSubmittedWorkDone(GetHandle(), callback->UnboundCallback(),
                                       callback->AsUserdata());
-#else
-  GetProcs().queueOnSubmittedWorkDone(
-      GetHandle(), 0u, callback->UnboundCallback(), callback->AsUserdata());
-#endif
   // WebGPU guarantees that promises are resolved in finite time so we
   // need to ensure commands are flushed.
   EnsureFlush(ToEventLoop(script_state));
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl b/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl
index ab7895c7..628a51d 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl
+++ b/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl
@@ -18,7 +18,7 @@
     "float32-filterable",
 
     // Non-standard (not currently in the spec).
-    "pipeline-statistics-query",
+    "chromium-experimental-pipeline-statistics-query",
     "chromium-experimental-timestamp-query-inside-passes",
     "chromium-experimental-dp4a",
     "chromium-experimental-read-write-storage-texture",
diff --git a/third_party/blink/renderer/modules/websockets/websocket_stream.cc b/third_party/blink/renderer/modules/websockets/websocket_stream.cc
index 99e94793..33b8015 100644
--- a/third_party/blink/renderer/modules/websockets/websocket_stream.cc
+++ b/third_party/blink/renderer/modules/websockets/websocket_stream.cc
@@ -592,7 +592,7 @@
 }
 
 bool WebSocketStream::HasPendingActivity() const {
-  return channel_;
+  return channel_ != nullptr;
 }
 
 void WebSocketStream::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/modules/webtransport/incoming_stream.cc b/third_party/blink/renderer/modules/webtransport/incoming_stream.cc
index 38d3d4f..dac79ec 100644
--- a/third_party/blink/renderer/modules/webtransport/incoming_stream.cc
+++ b/third_party/blink/renderer/modules/webtransport/incoming_stream.cc
@@ -67,7 +67,7 @@
     return ScriptPromise::CastUndefined(script_state_);
   }
 
-  ScriptState* GetScriptState() override { return script_state_; }
+  ScriptState* GetScriptState() override { return script_state_.Get(); }
 
   void Trace(Visitor* visitor) const override {
     visitor->Trace(script_state_);
diff --git a/third_party/blink/renderer/modules/webtransport/web_transport.cc b/third_party/blink/renderer/modules/webtransport/web_transport.cc
index 2c5c55b..c18d4b9 100644
--- a/third_party/blink/renderer/modules/webtransport/web_transport.cc
+++ b/third_party/blink/renderer/modules/webtransport/web_transport.cc
@@ -309,7 +309,7 @@
     return ScriptPromise::CastUndefined(script_state_);
   }
 
-  ScriptState* GetScriptState() override { return script_state_; }
+  ScriptState* GetScriptState() override { return script_state_.Get(); }
 
   // Interface for use by WebTransport.
   void Close(ReadableByteStreamController* controller,
diff --git a/third_party/blink/renderer/modules/webusb/usb.cc b/third_party/blink/renderer/modules/webusb/usb.cc
index cf1efec0..7159804 100644
--- a/third_party/blink/renderer/modules/webusb/usb.cc
+++ b/third_party/blink/renderer/modules/webusb/usb.cc
@@ -279,7 +279,7 @@
 USBDevice* USB::GetOrCreateDevice(UsbDeviceInfoPtr device_info) {
   auto it = device_cache_.find(device_info->guid);
   if (it != device_cache_.end()) {
-    return it->value;
+    return it->value.Get();
   }
 
   String guid = device_info->guid;
diff --git a/third_party/blink/renderer/modules/webusb/usb_device.cc b/third_party/blink/renderer/modules/webusb/usb_device.cc
index 3d562fa..e9a573ee 100644
--- a/third_party/blink/renderer/modules/webusb/usb_device.cc
+++ b/third_party/blink/renderer/modules/webusb/usb_device.cc
@@ -157,7 +157,7 @@
   if (configuration_index_ == kNotFound)
     return nullptr;
   DCHECK_LT(configuration_index_, configurations_.size());
-  return configurations_[configuration_index_];
+  return configurations_[configuration_index_].Get();
 }
 
 HeapVector<Member<USBConfiguration>> USBDevice::configurations() const {
diff --git a/third_party/blink/renderer/modules/xr/xr_anchor.cc b/third_party/blink/renderer/modules/xr/xr_anchor.cc
index aa2d5a9b..b2c31183 100644
--- a/third_party/blink/renderer/modules/xr/xr_anchor.cc
+++ b/third_party/blink/renderer/modules/xr/xr_anchor.cc
@@ -60,7 +60,7 @@
         MakeGarbageCollected<XRObjectSpace<XRAnchor>>(session_, this);
   }
 
-  return anchor_space_;
+  return anchor_space_.Get();
 }
 
 device::mojom::blink::XRNativeOriginInformationPtr XRAnchor::NativeOrigin()
diff --git a/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc b/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc
index 922836c..206adab 100644
--- a/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc
+++ b/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc
@@ -96,7 +96,7 @@
 }
 
 XRInputSource* XRCanvasInputProvider::GetInputSource() {
-  return input_source_;
+  return input_source_.Get();
 }
 
 void XRCanvasInputProvider::UpdateInputSource(PointerEvent* event) {
diff --git a/third_party/blink/renderer/modules/xr/xr_image_tracking_result.cc b/third_party/blink/renderer/modules/xr/xr_image_tracking_result.cc
index 0df06f1..b4db94bb 100644
--- a/third_party/blink/renderer/modules/xr/xr_image_tracking_result.cc
+++ b/third_party/blink/renderer/modules/xr/xr_image_tracking_result.cc
@@ -42,7 +42,7 @@
         session_, this);
   }
 
-  return image_space_;
+  return image_space_.Get();
 }
 
 device::mojom::blink::XRNativeOriginInformationPtr
diff --git a/third_party/blink/renderer/modules/xr/xr_input_source.cc b/third_party/blink/renderer/modules/xr/xr_input_source.cc
index b28de70c..bdfcb488 100644
--- a/third_party/blink/renderer/modules/xr/xr_input_source.cc
+++ b/third_party/blink/renderer/modules/xr/xr_input_source.cc
@@ -164,7 +164,7 @@
 }
 
 XRSpace* XRInputSource::targetRaySpace() const {
-  return target_ray_space_;
+  return target_ray_space_.Get();
 }
 
 XRSpace* XRInputSource::gripSpace() const {
@@ -172,7 +172,7 @@
     return nullptr;
 
   if (state_.target_ray_mode == device::mojom::XRTargetRayMode::POINTING) {
-    return grip_space_;
+    return grip_space_.Get();
   }
 
   return nullptr;
diff --git a/third_party/blink/renderer/modules/xr/xr_light_probe.cc b/third_party/blink/renderer/modules/xr/xr_light_probe.cc
index a8bb9da..1c5da57 100644
--- a/third_party/blink/renderer/modules/xr/xr_light_probe.cc
+++ b/third_party/blink/renderer/modules/xr/xr_light_probe.cc
@@ -38,7 +38,7 @@
         MakeGarbageCollected<XRObjectSpace<XRLightProbe>>(session_, this);
   }
 
-  return probe_space_;
+  return probe_space_.Get();
 }
 
 device::mojom::blink::XRNativeOriginInformationPtr XRLightProbe::NativeOrigin()
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc
index 2952494..b8fc609f 100644
--- a/third_party/blink/renderer/modules/xr/xr_session.cc
+++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -799,7 +799,7 @@
     did_log_getInputSources_ = true;
   }
 
-  return input_sources_;
+  return input_sources_.Get();
 }
 
 ScriptPromise XRSession::requestHitTestSource(
diff --git a/third_party/blink/renderer/modules/xr/xr_system.cc b/third_party/blink/renderer/modules/xr/xr_system.cc
index d3ab23cd..d894855 100644
--- a/third_party/blink/renderer/modules/xr/xr_system.cc
+++ b/third_party/blink/renderer/modules/xr/xr_system.cc
@@ -834,7 +834,7 @@
     frame_provider_ = MakeGarbageCollected<XRFrameProvider>(this);
   }
 
-  return frame_provider_;
+  return frame_provider_.Get();
 }
 
 device::mojom::blink::XREnvironmentIntegrationProvider*
diff --git a/third_party/blink/renderer/modules/xr/xr_view.cc b/third_party/blink/renderer/modules/xr/xr_view.cc
index 1f04625a..4bf641ba 100644
--- a/third_party/blink/renderer/modules/xr/xr_view.cc
+++ b/third_party/blink/renderer/modules/xr/xr_view.cc
@@ -60,11 +60,11 @@
         viewport.height() * scale);
   }
 
-  return viewport_;
+  return viewport_.Get();
 }
 
 XRFrame* XRView::frame() const {
-  return frame_;
+  return frame_.Get();
 }
 
 XRSession* XRView::session() const {
@@ -79,7 +79,7 @@
     return nullptr;
   }
 
-  return projection_matrix_;
+  return projection_matrix_.Get();
 }
 
 XRViewData::XRViewData(const device::mojom::blink::XRViewPtr& view,
@@ -191,7 +191,7 @@
 }
 
 XRRigidTransform* XRView::refSpaceFromView() const {
-  return ref_space_from_view_;
+  return ref_space_from_view_.Get();
 }
 
 absl::optional<double> XRView::recommendedViewportScale() const {
diff --git a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
index 01e43a1..26c3a60 100644
--- a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
+++ b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
@@ -231,10 +231,10 @@
     UpdateViewports();
 
   if (eye == device::mojom::blink::XREye::kRight)
-    return right_viewport_;
+    return right_viewport_.Get();
 
   // This code path also handles an eye of "none".
-  return left_viewport_;
+  return left_viewport_.Get();
 }
 
 double XRWebGLLayer::getNativeFramebufferScaleFactor(XRSession* session) {
@@ -311,7 +311,7 @@
 
   // We already have a WebGL texture for the camera image - return it:
   if (camera_image_texture_) {
-    return camera_image_texture_;
+    return camera_image_texture_.Get();
   }
 
   // We don't have a WebGL texture, and we cannot create it - return null:
@@ -324,7 +324,7 @@
   camera_image_texture_ = MakeGarbageCollected<WebGLUnownedTexture>(
       webgl_context_, camera_image_texture_id_, GL_TEXTURE_2D);
 
-  return camera_image_texture_;
+  return camera_image_texture_.Get();
 }
 
 void XRWebGLLayer::OnFrameStart(
diff --git a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
index 65a0699..fffc24e 100644
--- a/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
+++ b/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h
@@ -17,6 +17,7 @@
 #include "third_party/blink/renderer/platform/graphics/paint/paint_property_node.h"
 #include "third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "ui/gfx/geometry/point3_f.h"
 #include "ui/gfx/geometry/transform.h"
@@ -76,8 +77,9 @@
  public:
   enum class BackfaceVisibility : unsigned char {
     // backface-visibility is not inherited per the css spec. However, for an
-    // element that don't create a new plane, for now we let the element
-    // inherit the parent backface-visibility.
+    // element that don't create a new plane, we let the element inherit the
+    // parent backface-visibility and use the parent's transform to determine
+    // whether the backface is facing forward.
     kInherited,
     // backface-visibility: hidden for the new plane.
     kHidden,
@@ -370,6 +372,9 @@
   }
 
   bool DelegatesToParentForBackface() const {
+    if (RuntimeEnabledFeatures::BackfaceVisibilityNewInheritanceEnabled()) {
+      return state_.backface_visibility == BackfaceVisibility::kInherited;
+    }
     return state_.flags.delegates_to_parent_for_backface;
   }
 
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc b/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc
index 1f844fb..f0fcc2a 100644
--- a/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc
+++ b/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc
@@ -50,8 +50,7 @@
   resource_updater_ = std::make_unique<media::VideoResourceUpdater>(
       media_context_provider, shared_bitmap_reporter, resource_provider_.get(),
       settings_.use_stream_video_draw_quad,
-      settings_.resource_settings.use_gpu_memory_buffer_resources,
-      settings_.resource_settings.use_r16_texture, max_texture_size);
+      settings_.use_gpu_memory_buffer_resources, max_texture_size);
 }
 
 void VideoFrameResourceProvider::OnContextLost() {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 87ec4ec..75fa005 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -406,6 +406,12 @@
     {
       name: "BackfaceVisibilityInterop",
     },
+    // This is a killswitch for the fix for crbug.com/954591 and should be
+    // removable a few weeks after M120 ships.
+    {
+      name: "BackfaceVisibilityNewInheritance",
+      status: "stable",
+    },
     {
       name: "BackForwardCache",
       base_feature: "none",
@@ -2947,12 +2953,6 @@
       status: "stable",
       base_feature: "none",
     },
-    // See https://crbug.com/1324111
-    {
-      name: "PermissionsPolicyUnload",
-      origin_trial_feature_name: "PermissionsPolicyUnload",
-      status: "stable",
-    },
     {
       name: "PermissionsRequestRevoke",
       status: "experimental",
@@ -4211,6 +4211,10 @@
       origin_trial_feature_name: "WebCodecs"
     },
     {
+      name: "WebCodecsContentHint",
+      status: "experimental",
+    },
+    {
       name: "WebCodecsDequeueEvent",
       status: "stable",
       base_feature: "none",
@@ -4278,7 +4282,7 @@
       public: true,
     },
     {
-      name: "WebIdentityMDocs",
+      name: "WebIdentityDigitalCredentials",
       depends_on: ["FedCm"],
       public: true,
       status: "test",
diff --git a/third_party/blink/renderer/platform/theme/web_theme_engine_default.cc b/third_party/blink/renderer/platform/theme/web_theme_engine_default.cc
index b908c1d..87e75201 100644
--- a/third_party/blink/renderer/platform/theme/web_theme_engine_default.cc
+++ b/third_party/blink/renderer/platform/theme/web_theme_engine_default.cc
@@ -180,6 +180,8 @@
       const auto& scrollbar_button =
           absl::get<WebThemeEngine::ScrollbarButtonExtraParams>(*extra_params);
       native_scrollbar_arrow.zoom = scrollbar_button.zoom;
+      native_scrollbar_arrow.needs_rounded_corner =
+          scrollbar_button.needs_rounded_corner;
       native_scrollbar_arrow.right_to_left = scrollbar_button.right_to_left;
       native_scrollbar_arrow.thumb_color = scrollbar_button.thumb_color;
       native_scrollbar_arrow.track_color = scrollbar_button.track_color;
diff --git a/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc b/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc
index ad1383af..035cd59 100644
--- a/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc
+++ b/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc
@@ -328,9 +328,6 @@
   settings.percent_based_scrolling =
       ::features::IsPercentBasedScrollingEnabled();
 
-  settings.resource_settings.use_r16_texture =
-      base::FeatureList::IsEnabled(media::kUseR16Texture);
-
   settings.commit_to_active_tree = !is_threaded;
   settings.is_for_embedded_frame = is_for_embedded_frame;
   settings.is_for_scalable_page = is_for_scalable_page;
@@ -459,7 +456,7 @@
   // Partial raster is not supported with RawDraw
   settings.use_partial_raster &= !::features::IsUsingRawDraw();
   settings.enable_elastic_overscroll = platform->IsElasticOverscrollEnabled();
-  settings.resource_settings.use_gpu_memory_buffer_resources =
+  settings.use_gpu_memory_buffer_resources =
       cmd.HasSwitch(switches::kEnableGpuMemoryBufferCompositorResources);
   settings.use_painted_device_scale_factor = true;
 
diff --git a/third_party/blink/tools/blinkpy/common/checkout/git.py b/third_party/blink/tools/blinkpy/common/checkout/git.py
index 4b67461..6e32f4dc2 100644
--- a/third_party/blink/tools/blinkpy/common/checkout/git.py
+++ b/third_party/blink/tools/blinkpy/common/checkout/git.py
@@ -285,6 +285,10 @@
         return self._run_status_and_extract_filenames(self.status_command(),
                                                       self._status_regexp('A'))
 
+    def deleted_files(self):
+        return self._run_status_and_extract_filenames(self.status_command(),
+                                                      self._status_regexp('D'))
+
     def _run_status_and_extract_filenames(self, status_command, status_regexp):
         filenames = []
         # We run with cwd=self.checkout_root so that returned-paths are root-relative.
diff --git a/third_party/blink/tools/blinkpy/common/checkout/git_unittest.py b/third_party/blink/tools/blinkpy/common/checkout/git_unittest.py
index c6307c3..25a05a4 100644
--- a/third_party/blink/tools/blinkpy/common/checkout/git_unittest.py
+++ b/third_party/blink/tools/blinkpy/common/checkout/git_unittest.py
@@ -93,6 +93,26 @@
         git.add_list(['added_dir/added_file'])
         self.assertIn('added_dir/added_file', git.added_files())
 
+    def test_added_files(self):
+        self._chdir(self.untracking_checkout_path)
+        git = self.untracking_git
+        self._write_text_file('cat_file', 'new stuff')
+        git.add_list(['cat_file'])
+        self.assertIn('cat_file', git.added_files())
+
+    def test_deleted_files(self):
+        self._chdir(self.untracking_checkout_path)
+        git = self.untracking_git
+        git.delete_list(['foo_file'])
+        self.assertIn('foo_file', git.deleted_files())
+
+    def test_added_deleted_files_with_rename(self):
+        self._chdir(self.untracking_checkout_path)
+        git = self.untracking_git
+        git.move('foo_file', 'bar_file')
+        self.assertIn('foo_file', git.deleted_files())
+        self.assertIn('bar_file', git.added_files())
+
     def test_delete_recursively(self):
         self._chdir(self.untracking_checkout_path)
         git = self.untracking_git
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer.py b/third_party/blink/tools/blinkpy/w3c/test_importer.py
index 7815637b..8bc19ab 100644
--- a/third_party/blink/tools/blinkpy/w3c/test_importer.py
+++ b/third_party/blink/tools/blinkpy/w3c/test_importer.py
@@ -172,6 +172,10 @@
         if not self._has_wpt_changes():
             _log.info('Only manifest or expectations was updated; skipping the import.')
             return 0
+        testlist_path = self.finder.path_from_web_tests(
+            "TestLists", "android.filter")
+        _log.info('Updating testlist based on file changes.')
+        self.update_testlist_with_idlharness_changes(testlist_path)
 
         self._commit_changes(commit_message)
         _log.info('Changes imported and committed.')
@@ -734,3 +738,75 @@
                       dry_run=not auto_file_bugs,
                       service_account_key_json=monorail_auth_json)
         return True
+
+    def update_testlist_with_idlharness_changes(self, testlist_path):
+        """Update testlist file to include idlharness test changes
+        """
+        added_files = self.chromium_git.added_files()
+        deleted_files = self.chromium_git.deleted_files()
+
+        # extract test name and filter for idlharness tests from file list
+        added_tests = list(
+            filter(Port.is_wpt_idlharness_test,
+                   map(self.finder.strip_web_tests_path, added_files)))
+        deleted_tests = list(
+            filter(Port.is_wpt_idlharness_test,
+                   map(self.finder.strip_web_tests_path, deleted_files)))
+
+        if added_files or deleted_files:
+            _log.info('Idlharness test changes:')
+            _log.info("Added tests:\n" + "\n".join(added_tests))
+            _log.info("Deleted tests:\n" + "\n".join(deleted_tests))
+        else:
+            _log.info(f'No idlharness changes. Skipping testlist update.')
+
+        with self.fs.open_text_file_for_reading(testlist_path) as f:
+            testlist_lines = f.read().split("\n")
+
+        new_testlist_lines = self.update_testlist_lines(
+            testlist_lines, added_tests, deleted_tests)
+
+        with self.fs.open_text_file_for_writing(testlist_path) as f:
+            f.write("\n".join(new_testlist_lines))
+        self.chromium_git.run(['add', testlist_path])
+
+    def update_testlist_lines(self, testlist_lines, added_tests,
+                              deleted_tests):
+        """Updates the lines from testlist to remove deleted tests,
+        and include the new tests"""
+        new_testlist_lines = []
+        for line in testlist_lines:
+            current_test = line.strip()
+            if current_test in deleted_tests:
+                continue
+            new_testlist_lines.append(line)
+        last_insertion_index = 0
+        # Pre-sort tests to be inserted
+        for new_test in sorted(added_tests):
+            insertion_index = self.find_insert_index_ignore_comments(
+                new_testlist_lines, new_test, start_index=last_insertion_index)
+            if (insertion_index < len(new_testlist_lines)
+                    and new_testlist_lines[insertion_index] == new_test):
+                _log.info(f'Skip duplicate test "{new_test}"')
+                continue
+            new_testlist_lines.insert(insertion_index, new_test)
+            last_insertion_index = insertion_index
+        return new_testlist_lines
+
+    def find_insert_index_ignore_comments(self,
+                                          targets_list,
+                                          insert_key,
+                                          start_index=0):
+        """Finds index where the insert key should be added.
+        The insert index points to the first item that is greater than
+        the insert key and is not comment (start with #) or empty line"""
+        last_insert_index = start_index
+        for index, target in enumerate(targets_list[start_index:],
+                                       start_index):
+            if not target.strip() or target.startswith("#"):
+                continue
+            elif insert_key <= target:
+                return index
+            else:
+                last_insert_index = index + 1
+        return last_insert_index
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py b/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
index 8b1b688..61f4e99 100644
--- a/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
+++ b/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
@@ -21,8 +21,9 @@
 from blinkpy.w3c.test_importer import TestImporter, ROTATIONS_URL, SHERIFF_EMAIL_FALLBACK, RUBBER_STAMPER_BOT
 from blinkpy.w3c.wpt_github_mock import MockWPTGitHub
 from blinkpy.w3c.wpt_manifest import BASE_MANIFEST_NAME
-from blinkpy.web_tests.port.android import ANDROID_DISABLED_TESTS
 from blinkpy.web_tests.builder_list import BuilderList
+from blinkpy.web_tests.port.android import ANDROID_DISABLED_TESTS
+from unittest.mock import patch
 
 MOCK_WEB_TESTS = '/mock-checkout/' + RELATIVE_WEB_TESTS
 MANIFEST_INSTALL_CMD = [
@@ -613,6 +614,211 @@
             RELATIVE_WEB_TESTS + 'external/' + BASE_MANIFEST_NAME]
         self.assertFalse(importer._has_wpt_changes())
 
+    def test_find_insert_index_ignore_pattern_empty_list(self):
+        host = self.mock_host()
+        test_importer = self._get_test_importer(host)
+
+        targets_list = []
+        insert_key = "test1"
+
+        insert_index = test_importer.find_insert_index_ignore_comments(
+            targets_list, insert_key)
+
+        self.assertEqual(insert_index, 0)
+
+    def test_find_insert_index_ignore_pattern_with_duplicate(self):
+        host = self.mock_host()
+        test_importer = self._get_test_importer(host)
+
+        targets_list = ["test1", "test2", "# test3", "test4", "test5"]
+        insert_key = "test2"
+
+        insert_index = test_importer.find_insert_index_ignore_comments(
+            targets_list, insert_key)
+
+        self.assertEqual(insert_index, 1)
+
+    def test_find_insert_index_ignore_comments_with_middle_start_index(self):
+        host = self.mock_host()
+        test_importer = self._get_test_importer(host)
+
+        targets_list = ["test1", "test2", "test3", "test4", "test5"]
+        insert_key = "test0"
+        start_index = 2
+
+        insert_index = test_importer.find_insert_index_ignore_comments(
+            targets_list, insert_key, start_index)
+
+        self.assertEqual(insert_index, 2)
+
+    def test_find_insert_index_ignore_comments_start_index_equal_to_list_length(
+            self):
+        host = self.mock_host()
+        test_importer = self._get_test_importer(host)
+
+        targets_list = ["test1", "test2", "test3", "test4", "test5"]
+
+        # smaller than last item
+        insert_index = test_importer.find_insert_index_ignore_comments(
+            targets_list, "test3", 5)
+        self.assertEqual(insert_index, 5)
+
+        # larger than last item
+
+        insert_index = test_importer.find_insert_index_ignore_comments(
+            targets_list, "test9", 5)
+        self.assertEqual(insert_index, 5)
+
+    def test_find_insert_index_ignore_comments_start_index_equal_to_last_index(
+            self):
+        host = self.mock_host()
+        test_importer = self._get_test_importer(host)
+
+        targets_list = ["test1", "test2", "test3", "test4", "test5"]
+
+        # smaller than last item
+        insert_index = test_importer.find_insert_index_ignore_comments(
+            targets_list, "test3", 4)
+        self.assertEqual(insert_index, 4)
+
+        # larger than last item
+        insert_index = test_importer.find_insert_index_ignore_comments(
+            targets_list, "test9", 4)
+        self.assertEqual(insert_index, 5)
+
+    def test_find_insert_index_ignore_pattern(self):
+        host = self.mock_host()
+        test_importer = self._get_test_importer(host)
+
+        targets_list = ["test1", "# test3", "test4", "test5"]
+        insert_key = "test2"
+        filter = lambda key: key.startswith("test")
+
+        insert_index = test_importer.find_insert_index_ignore_comments(
+            targets_list, insert_key)
+
+        self.assertEqual(insert_index, 2)
+
+    def test_update_testlist_lines(self):
+        host = self.mock_host()
+        test_importer = self._get_test_importer(host)
+
+        testlist_lines = [
+            "# comment",
+            "external/wpt/test1.html",
+            "# comment",
+            "external/wpt/test2.html",
+            "# comment",
+            "external/wpt/test3.html",
+            "# comment",
+        ]
+        added_tests = ["external/wpt/test4.html", "external/wpt/test5.html"]
+        deleted_tests = ["external/wpt/test2.html"]
+
+        new_testlist_lines = test_importer.update_testlist_lines(
+            testlist_lines, added_tests, deleted_tests)
+
+        expected_new_testlist_lines = [
+            "# comment",
+            "external/wpt/test1.html",
+            "# comment",
+            "# comment",
+            "external/wpt/test3.html",
+            "external/wpt/test4.html",
+            "external/wpt/test5.html",
+            "# comment",
+        ]
+
+        self.assertEqual(new_testlist_lines, expected_new_testlist_lines)
+
+    def test_update_testlist_with_idlharness_changes(self):
+        host = self.mock_host()
+        importer = self._get_test_importer(host)
+
+        def _git_added_files():
+            return [
+                MOCK_WEB_TESTS + "external/wpt/2_added_idlharness.html",
+                MOCK_WEB_TESTS + "external/wpt/3_duplicate_idlharness.html",
+                MOCK_WEB_TESTS + "external/wpt/4_new_idlharness.html",
+            ]
+
+        def _git_deleted_files():
+            return [
+                MOCK_WEB_TESTS + "external/wpt/5_old_idlharness.html",
+                MOCK_WEB_TESTS + "external/wpt/6_deleted_idlharness.html",
+            ]
+
+        importer.chromium_git.added_files = _git_added_files
+        importer.chromium_git.deleted_files = _git_deleted_files
+        importer.chromium_git._relative_to_web_test_dir = \
+            lambda test_path: test_path
+        testlist_path = importer.finder.path_from_web_tests(
+            "TestLists", "android.filter")
+        test_list_lines = [
+            'external/wpt/1_first_idlharness.html',
+            'external/wpt/3_duplicate_idlharness.html',
+            'external/wpt/5_old_idlharness.html',
+            'external/wpt/6_deleted_idlharness.html',
+            'external/wpt/7_last_idlharness.html',
+        ]
+        expected_test_list_lines = [
+            'external/wpt/1_first_idlharness.html',
+            'external/wpt/2_added_idlharness.html',
+            'external/wpt/3_duplicate_idlharness.html',
+            'external/wpt/4_new_idlharness.html',
+            'external/wpt/7_last_idlharness.html',
+        ]
+        host.filesystem.write_text_file(testlist_path,
+                                        "\n".join(test_list_lines))
+        with patch.object(importer.chromium_git, "run") as mock_git_run:
+            importer.update_testlist_with_idlharness_changes(testlist_path)
+            actual_test_list_lines = host.filesystem.open_text_file_for_reading(
+                testlist_path).read().split("\n")
+            self.assertEqual(actual_test_list_lines, expected_test_list_lines)
+            mock_git_run.assert_called_with(['add', testlist_path])
+
+    def test_update_testlist_with_idlharness_changes_with_comment(self):
+        host = self.mock_host()
+        importer = self._get_test_importer(host)
+
+        def _git_added_files():
+            return [
+                MOCK_WEB_TESTS + "external/wpt/9_added_idlharness.html",
+            ]
+
+        def _git_deleted_files():
+            return []
+
+        importer.chromium_git.added_files = _git_added_files
+        importer.chromium_git.deleted_files = _git_deleted_files
+        importer.chromium_git._relative_to_web_test_dir = \
+            lambda test_path: test_path
+        testlist_path = importer.finder.path_from_web_tests(
+            "TestLists", "android.filter")
+        test_list_lines = [
+            '# comment 1',
+            'external/wpt/1_first_idlharness.html',
+            '# comment 2',
+            'external/wpt/7_last_idlharness.html',
+            '# comment 3',
+        ]
+        expected_test_list_lines = [
+            '# comment 1',
+            'external/wpt/1_first_idlharness.html',
+            '# comment 2',
+            'external/wpt/7_last_idlharness.html',
+            "external/wpt/9_added_idlharness.html",
+            '# comment 3',
+        ]
+        host.filesystem.write_text_file(testlist_path,
+                                        "\n".join(test_list_lines))
+        with patch.object(importer.chromium_git, "run") as mock_git_run:
+            importer.update_testlist_with_idlharness_changes(testlist_path)
+            actual_test_list_lines = host.filesystem.open_text_file_for_reading(
+                testlist_path).read().split("\n")
+            self.assertEqual(actual_test_list_lines, expected_test_list_lines)
+            mock_git_run.assert_called_with(['add', testlist_path])
+
     def test_need_sheriff_attention(self):
         host = self.mock_host()
         importer = self._get_test_importer(host)
diff --git a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/queries.py b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/queries.py
index 3a6ea774..8eefb6768 100644
--- a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/queries.py
+++ b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/queries.py
@@ -66,6 +66,38 @@
   image_diff_total_pixels IS NOT NULL
 """
 
+# Gets all web test flaky bugs and their flaky tests from the past |sample_period|
+# days.
+# List of data selected from the database:
+# bug_id - bug id for the flaky tests, like chromium/1493418
+# create_time - the creation time of this bug, like 2023-10-16 21:55:00.474-07:00
+# test_ids - list of the test ids, like [ninja://:testA,ninja://:testB]
+WEB_TEST_FLAKY_BUGS_QUERY = """
+WITH
+  blink_flaky_bugs AS (
+    SELECT
+      bug.id,
+      create_time,
+      rule_id
+    FROM `luci-analysis.chromium.failure_association_rules`
+    WHERE project = "chromium" AND
+      is_active = TRUE AND
+    DATE(create_time) > DATE_SUB(CURRENT_DATE(), INTERVAL @sample_period DAY)
+  )
+  SELECT
+    blink_flaky_bugs.id AS bug_id,
+    blink_flaky_bugs.create_time,
+    ARRAY_AGG(DISTINCT failures_table.test_id LIMIT 10) AS test_ids
+  FROM blink_flaky_bugs JOIN `luci-analysis.chromium.clustered_failures` AS failures_table
+  ON failures_table.cluster_id = blink_flaky_bugs.rule_id
+  WHERE REGEXP_CONTAINS(
+          (SELECT value FROM UNNEST(failures_table.variant) WHERE key = 'test_suite' LIMIT 1),
+            'blink_w(pt|eb)_tests')
+    AND cluster_algorithm LIKE 'rules-%'
+  GROUP BY blink_flaky_bugs.id, blink_flaky_bugs.create_time
+"""
+
+
 class FuzzyDiffAnalyzerQuerier:
     def __init__(self, sample_period: int, billing_project: str):
         """Class for making calls to BigQuery for Fuzzy Diff Analyzer.
@@ -100,6 +132,16 @@
             CI_FAILED_IMAGE_COMPARISON_TEST_QUERY.format(
                 test_path_selector=test_path_selector))
 
+    def get_web_test_flaky_bugs(self) -> ct.QueryJsonType:
+        """Gets all web test flaky bugs from the database.
+
+        Returns:
+          A JSON representation of the BigQuery results containing all found
+          web test flaky bug information.
+        """
+
+        return self._get_json_results(WEB_TEST_FLAKY_BUGS_QUERY)
+
     def _get_json_results(self, query: str) -> ct.QueryJsonType:
         """Gets the JSON results from an input BigQuery query.
 
diff --git a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/queries_unittest.py b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/queries_unittest.py
index a6ecb2b6..2d9ab28 100644
--- a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/queries_unittest.py
+++ b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/queries_unittest.py
@@ -29,6 +29,16 @@
     'image_diff_total_pixels': 10,
 }]
 
+QUERY_DATA_2 = [{
+    'bug_id': 'chromium/1',
+    'create_time': '2023-10-16 21:55:00.474-07:00',
+    'test_ids': ['testA', 'testB'],
+}, {
+    'bug_id': 'chromium/2',
+    'create_time': '2023-10-15 21:55:00.474-07:00',
+    'test_ids': ['testC', 'testD', 'testE'],
+}]
+
 
 class FuzzyDiffAnalyzerQueriesUnittest(unittest.TestCase):
     def setUp(self) -> None:
@@ -53,3 +63,17 @@
             self._querier_instance.get_failed_image_comparison_ci_tests()
         self.assertEqual(result_query, QUERY_DATA)
         self.assertEqual(self._subprocess_mock.call_count, 1)
+
+    def testGetWebTestFlakyBugs(self) -> None:
+        """Tests that Fuzzy Diff Analyzer queries is sending the sql."""
+        def side_effect(*_, **kwargs) -> uu.FakeProcess:
+            query = kwargs['input']
+            self.assertEqual(query, queries.WEB_TEST_FLAKY_BUGS_QUERY)
+            query_result = QUERY_DATA_2
+            return uu.FakeProcess(stdout=json.dumps(query_result))
+
+        self._subprocess_mock.side_effect = side_effect
+        result_query = \
+            self._querier_instance.get_web_test_flaky_bugs()
+        self.assertEqual(result_query, QUERY_DATA_2)
+        self.assertEqual(self._subprocess_mock.call_count, 1)
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 99b4b12a2..379993b 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -650,12 +650,6 @@
 # Only one pixel difference (187,187,187) vs (188,188,188) occasionally.
 crbug.com/1207960 [ Linux ] compositing/perspective-interest-rect.html [ Failure Pass ]
 
-crbug.com/954591 external/wpt/css/css-transforms/composited-under-rotateY-180deg.html [ Failure ]
-crbug.com/954591 external/wpt/css/css-transforms/composited-under-rotateY-180deg-clip.html [ Failure ]
-
-crbug.com/1261905 external/wpt/css/css-transforms/backface-visibility-hidden-child-will-change-transform.html [ Failure ]
-crbug.com/1261905 virtual/backface-visibility-interop/external/wpt/css/css-transforms/backface-visibility-hidden-child-translate.html [ Failure ]
-
 # CompositeAfterPaint remaining failures
 # Outline paints incorrectly with columns. Needs LayoutNGBlockFragmentation.
 # Need to force the video to be composited in this case, or change pre-CAP
@@ -1968,13 +1962,6 @@
 crbug.com/1058772 external/wpt/css/css-fonts/test-synthetic-italic-2.html [ Failure ]
 crbug.com/1058772 external/wpt/css/css-fonts/test-synthetic-italic-3.html [ Failure ]
 
-# TODO(crbug.com/1492317): Clean up rounded corners of aura vertical scrollbar arrows
-crbug.com/1492317 [ Win ] svg/zoom/page/zoom-mask-with-percentages.svg [ Failure Pass ]
-crbug.com/1492317 [ Win ] virtual/scalefactor200/css3/filters/backdrop-filter-plus-mask-large.html [ Failure Pass ]
-crbug.com/1492317 [ Win ] virtual/scalefactor200/css3/filters/blur-filter-page-scroll-parents.html [ Failure Pass ]
-crbug.com/1492317 [ Win ] virtual/scalefactor200/css3/filters/blur-filter-page-scroll-self.html [ Failure Pass ]
-crbug.com/1492317 [ Win ] virtual/scalefactor200/css3/filters/blur-filter-page-scroll.html [ Failure Pass ]
-
 # CSS Font Feature Resolution is not implemented yet
 crbug.com/450619 external/wpt/css/css-fonts/font-feature-resolution-001.html [ Failure ]
 crbug.com/450619 external/wpt/css/css-fonts/font-feature-resolution-002.html [ Failure ]
@@ -2694,6 +2681,28 @@
 crbug.com/626703 [ Mac ] virtual/webcodecs-without-task-runner-with-custom-deleter/external/wpt/webcodecs/videoDecoder-codec-specific.https.any.worker.html?h265_hevc [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 external/wpt/css/css-backgrounds/border-image-image-type-001.htm [ Failure ]
+crbug.com/626703 external/wpt/css/css-backgrounds/border-image-image-type-004.htm [ Failure ]
+crbug.com/626703 external/wpt/css/css-backgrounds/border-image-image-type-005.htm [ Failure ]
+crbug.com/626703 virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-001.htm [ Failure ]
+crbug.com/626703 [ Mac11-arm64 ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-004.htm [ Failure ]
+crbug.com/626703 [ Linux ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-004.htm [ Failure ]
+crbug.com/626703 [ Mac13-arm64 ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-004.htm [ Failure ]
+crbug.com/626703 [ Mac11 ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-004.htm [ Failure ]
+crbug.com/626703 [ Mac12-arm64 ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-004.htm [ Failure ]
+crbug.com/626703 [ Mac13 ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-004.htm [ Failure ]
+crbug.com/626703 [ Mac12 ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-004.htm [ Failure ]
+crbug.com/626703 [ Win ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-004.htm [ Failure ]
+crbug.com/626703 [ Mac10.15 ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-004.htm [ Failure Timeout ]
+crbug.com/626703 [ Mac11-arm64 ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-005.htm [ Failure ]
+crbug.com/626703 [ Linux ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-005.htm [ Failure ]
+crbug.com/626703 [ Mac13-arm64 ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-005.htm [ Failure ]
+crbug.com/626703 [ Mac11 ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-005.htm [ Failure ]
+crbug.com/626703 [ Mac12-arm64 ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-005.htm [ Failure ]
+crbug.com/626703 [ Mac13 ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-005.htm [ Failure ]
+crbug.com/626703 [ Mac12 ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-005.htm [ Failure ]
+crbug.com/626703 [ Win ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-005.htm [ Failure ]
+crbug.com/626703 [ Mac10.15 ] virtual/threaded/external/wpt/css/css-backgrounds/border-image-image-type-005.htm [ Failure Timeout ]
 crbug.com/626703 external/wpt/css/css-contain/content-visibility/content-visibility-on-g.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-grid/subgrid/orthogonal-writing-mode-005.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-masking/mask-image/mask-clip-4.html [ Failure ]
@@ -2767,10 +2776,8 @@
 crbug.com/626703 [ Win ] virtual/shared-storage-fenced-frame-mparch-selecturl-limit/external/wpt/shared-storage-selecturl-limit/run-url-selection-operation-limit-multiple-origins.tentative.https.sub.html [ Timeout ]
 crbug.com/626703 [ Mac13 ] virtual/third-party-storage-partitioning/external/wpt/IndexedDB/idbobjectstore_getKey.any.html [ Timeout ]
 crbug.com/626703 external/wpt/css/css-transforms/backface-visibility-hidden-003.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-transforms/backface-visibility-hidden-005.html [ Failure ]
 crbug.com/626703 virtual/backface-visibility-interop/external/wpt/css/css-transforms/backface-visibility-hidden-003.html [ Failure ]
 crbug.com/626703 virtual/backface-visibility-interop/external/wpt/css/css-transforms/backface-visibility-hidden-004.html [ Failure ]
-crbug.com/626703 virtual/backface-visibility-interop/external/wpt/css/css-transforms/backface-visibility-hidden-005.html [ Failure ]
 crbug.com/626703 external/wpt/css/motion/offset-path-ray-022.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-text/white-space/white-space-collapse-discard-001.xht [ Failure ]
 crbug.com/626703 external/wpt/css/css-text/white-space/white-space-collapse-preserve-breaks-001.xht [ Failure ]
@@ -4308,10 +4315,6 @@
 crbug.com/1405829 [ Mac12-arm64 ] virtual/threaded/external/wpt/css/css-transforms/animation/canvas-webgl-translate-in-animation.html [ Failure Timeout ]
 crbug.com/1405829 [ Mac13-arm64 ] virtual/threaded/external/wpt/css/css-transforms/animation/canvas-webgl-translate-in-animation.html [ Failure Timeout ]
 
-crbug.com/1008483 virtual/backface-visibility-interop/external/wpt/css/css-transforms/backface-visibility-hidden-004.tentative.html [ Pass ]
-crbug.com/1008483 virtual/backface-visibility-interop/external/wpt/css/css-transforms/backface-visibility-hidden-005.tentative.html [ Pass ]
-crbug.com/1008483 virtual/backface-visibility-interop/external/wpt/css/css-transforms/backface-visibility-hidden-animated-002.html [ Pass ]
-
 # Tests that expect the DetailsStyling feature to be disabled:
 crbug.com/1469418 external/wpt/html/rendering/the-details-element/details-display-property-is-ignored.html [ Failure ]
 crbug.com/1469418 virtual/details-styling-disabled/external/wpt/html/rendering/the-details-element/details-display-property-is-ignored.html [ Pass ]
@@ -6430,6 +6433,172 @@
 crbug.com/1446037 [ Debug Mac13 ] external/wpt/css/css-tables/crashtests/textarea-intrinsic-size-crash.html [ Timeout ]
 crbug.com/1446038 [ Debug Mac13 ] external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworkletprocessor-process-frozen-array.https.html [ Crash Failure ]
 crbug.com/1446039 [ Debug Mac13 ] external/wpt/webtransport/streams-close.https.any.html [ Failure Pass ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/stability/animation-css-cancel-update-crash.html [ Skip Timeout ]
+[ Debug Mac13 ] jquery/traversing.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/html/interaction/focus/chrome-object-tab-focus-bug.html [ Failure ]
+[ Debug Mac13 ] virtual/fenced-frame-mparch/external/wpt/fenced-frame/sandbox-attribute.https.html [ Failure ]
+[ Debug Mac13 ] accessibility/selection-change-notification-on-selection-removed.html [ Failure ]
+[ Debug Mac13 ] external/wpt/webtransport/streams-close.https.any.worker.html [ Failure ]
+[ Debug Mac13 ] external/wpt/mediacapture-record/MediaRecorder-canvas-media-source.https.html [ Failure ]
+[ Debug Mac13 ] http/tests/devtools/sources/debugger-breakpoints/breakpoint-manager-listeners-count.js [ Failure ]
+[ Debug Mac13 ] virtual/unified-autoplay/external/wpt/feature-policy/feature-policy-frame-policy-timing.https.sub.html [ Failure ]
+[ Debug Mac13 ] http/tests/devtools/elements/edit/undo-dom-edits.js [ Skip Timeout ]
+[ Debug Mac13 ] media/video-source-error-no-candidate.html [ Failure ]
+[ Debug Mac13 ] external/wpt/permissions-policy/permissions-policy-frame-policy-timing.https.sub.html [ Failure ]
+[ Debug Mac13 ] external/wpt/feature-policy/feature-policy-frame-policy-timing.https.sub.html [ Failure ]
+[ Debug Mac13 ] external/wpt/html/cross-origin-opener-policy/reporting/access-reporting/access-from-coop-page-to-opener_coop-ro_cross-origin.https.html [ Failure ]
+[ Debug Mac13 ] external/wpt/html/semantics/embedded-content/media-elements/ready-states/autoplay-hidden.optional.html [ Failure Skip Timeout ]
+[ Debug Mac13 ] virtual/fenced-frame-mparch/external/wpt/fenced-frame/anchor-focus.https.html [ Failure ]
+[ Debug Mac13 ] animations/insert-composited-animation.html [ Skip Timeout ]
+[ Debug Mac13 ] storage/indexeddb/objectstore-cursor.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/network/download.js [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/runtime/runtime-localStorage-getProperties.js [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/html/semantics/embedded-content/the-img-element/invisible-image.html [ Failure ]
+[ Debug Mac13 ] media/video-source.html [ Failure ]
+[ Debug Mac13 ] virtual/disable-intersection-optimization/external/wpt/html/semantics/embedded-content/the-img-element/invisible-image.html [ Failure Skip Timeout ]
+[ Debug Mac13 ] fast/forms/focus-rect/radio-focus-ring.html [ Failure ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/interpolation/webkit-background-size-interpolation.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/resource-tree/resource-tree-non-unique-url.js [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/html/browsers/history/the-history-interface/history_go_undefined.html [ Failure ]
+[ Debug Mac13 ] virtual/keepalive-in-browser-migration/external/wpt/fetch/metadata/generated/element-meta-refresh.optional.sub.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url.tentative.html [ Failure ]
+[ Debug Mac13 ] http/tests/devtools/network/network-not-modified-images-mime-type.js [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/html/semantics/links/hyperlink-auditing/headers.optional.html [ Failure ]
+[ Debug Mac13 ] external/wpt/scroll-to-text-fragment/percent-encoding.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/fenced-frame-mparch/external/wpt/fenced-frame/disallowed-navigations-dangling-markup-urn.https.html [ Failure ]
+[ Debug Mac13 ] virtual/threaded-prefer-compositing/fast/scrolling/overflow-hidden-viewport-scrolling.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/fenced-frame-mparch/external/wpt/fenced-frame/can-load-api.https.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/content-security-policy/frame-src/frame-src-cross-origin-load.sub.html [ Failure ]
+[ Debug Mac13 ] virtual/pna-workers-disabled/external/wpt/fetch/private-network-access/mixed-content-fetch.tentative.https.window.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/webtransport/streams-close.https.any.serviceworker.html [ Failure ]
+[ Debug Mac13 ] virtual/threaded/transitions/retargeted-matching-rotation-transforms.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/dark-mode-default/dark-mode/images/pattern.html [ Skip Timeout ]
+[ Debug Mac13 ] jquery/event.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/elements/edit/undo-set-outer-html.js [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-prefer-compositing/fast/scroll-behavior/overflow-hidden-scrollBy.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/shared-storage-fenced-frame-mparch/external/wpt/shared-storage/shared-storage-writable-clear.tentative.https.sub.html [ Skip Timeout ]
+[ Debug Mac13 ] animations/composition/stroke-dasharray-composition.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-prefer-compositing/fast/scrolling/custom-scrollbar-inline-style-source.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded/animations/stability/base-render-style-body-crash.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-preload-scanner/external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/basic.any.sharedworker.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/preload/preload-dynamic-csp.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/svg-attribute-composition/svg-y-composition.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/indexeddb/resources-panel.js [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/runtime/runtime-es6-setSymbolPropertyValue.js [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/IndexedDB/idb-partitioned-coverage.tentative.sub.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/network/network-initiator.js [ Failure ]
+[ Debug Mac13 ] external/wpt/html/browsers/browsing-the-web/back-forward-cache/eligibility/inflight-fetch-1.html [ Failure ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/stability/deleted-image-set-transition-crash.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-prefer-compositing/fast/scroll-behavior/overflow-scroll-scrollTo.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/fenced-frame-mparch/external/wpt/fenced-frame/automatic-beacon-click-handler.https.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded/animations/stability/pause-set-current-time.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/css/css-color/parsing/color-computed-hsl.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/controls-refresh-hc/fast/forms/color-scheme/button/button-pressed-state.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/html/webappapis/dynamic-markup-insertion/html-unsafe-methods/Document-parseHTMLUnsafe-url-base.tentative.html [ Failure ]
+[ Debug Mac13 ] http/tests/devtools/profiler/heap-snapshot-comparison-sorting.js [ Skip Timeout ]
+[ Debug Mac13 ] virtual/compositor_threaded_scrollbar_scrolling/fast/scrolling/scrollbars/thumb-drag-mousemove-no-button.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/html/browsers/browsing-the-web/overlapping-navigations-and-traversals/same-document-traversal-cross-document-nav.html [ Failure ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/interpolation/text-decoration-color-interpolation.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/stability/pseudo-element-animation-with-marker-crash.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/css/css-grid/parsing/grid-template-columns-crash.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded/printing/tfoot-repeats-at-bottom-of-each-page-multiple-tables.html [ Skip Timeout ]
+[ Debug Mac13 ] fast/scroll-behavior/overflow-scroll-animates.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded/printing/css2.1/page-break-after-002.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/fenced-frame-mparch/external/wpt/html/anonymous-iframe/embedding.tentative.https.window.html?13-last [ Failure ]
+[ Debug Mac13 ] http/tests/devtools/profiler/heap-snapshot-containment-sorting.js [ Skip Timeout ]
+[ Debug Mac13 ] editing/selection/wrapped-line-caret-1.html [ Failure ]
+[ Debug Mac13 ] virtual/dark-color-scheme/fast/forms/color-scheme/media/video-playback-speed-menu.html [ Failure Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/persistence/persistence-tabbed-editor-tabs-order.js [ Skip Timeout ]
+[ Debug Mac13 ] fast/dom/shadow/selections-in-shadow.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/controls-refresh-hc/fast/forms/color-scheme/media/video-playback-speed-menu.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/keepalive-in-browser-migration/external/wpt/fetch/metadata/generated/element-iframe.https.sub.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/responsive/interpolation/background-position-responsive.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/elements/styles-4/styles-update-links-1.js [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/html/anonymous-iframe/embedding.tentative.https.window.html?10-10 [ Failure ]
+[ Debug Mac13 ] http/tests/devtools/console/console-tests.js [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/speculation-rules/prerender/response-code-successful.html?code=202 [ Failure ]
+[ Debug Mac13 ] virtual/threaded/animations/stability/zero-duration-large-start-delay.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/content-security-policy/resource-hints/prefetch-generate-directives.html [ Skip Timeout ]
+[ Debug Mac13 ] fast/forms/number/number-appearance-vertical.html [ Failure ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/svg-attribute-composition/svg-width-composition.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/elements/styles/updates-during-dom-traversal.js [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/svg-attribute-composition/svg-y-list-composition.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-prefer-compositing/fast/scrolling/scrollable-area-frame-scrolling-no-overried-inherited-visibility-hidden.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/indexeddb/database-refresh-view.js [ Skip Timeout ]
+[ Debug Mac13 ] virtual/dark-mode-images-filter-none/dark-mode/images/shadow.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/webtransport/streams-close.https.any.sharedworker.html [ Failure ]
+[ Debug Mac13 ] virtual/threaded/fast/idle-callback/idle_periods.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/console/console-eval-scoped.js [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/elements/distance/node-distances.js [ Skip Timeout ]
+[ Debug Mac13 ] animations/events/animation-iteration-event.html [ Skip Timeout ]
+[ Debug Mac13 ] animations/composition/y-composition.html [ Skip Timeout ]
+[ Debug Mac13 ] animations/interpolation/svg-cy-interpolation.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/fetch/metadata/generated/element-frame.https.sub.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded/http/tests/worklet/import-on-detached-iframe.html [ Skip Timeout ]
+[ Debug Mac13 ] fast/events/autoscroll-should-not-stop-on-keypress.html [ Failure ]
+[ Debug Mac13 ] http/tests/devtools/indexeddb/delete-entry.js [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/components/geometry.js [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/html/semantics/scripting-1/the-script-element/moving-between-documents/after-prepare-iframe-parse-error-external-module.html [ Failure ]
+[ Debug Mac13 ] virtual/keepalive-in-browser-migration/external/wpt/fetch/api/redirect/redirect-keepalive.any.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/svg-attribute-composition/svg-x-list-composition.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded/http/tests/worklet/animation-worklet-csp-eval.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded/printing/css2.1/page-break-after-000.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded/transitions/transition-shape-outside-crash.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/overrides/can-edit-iframe-html.js [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/html/browsers/history/the-history-interface/traverse_the_history_write_onload_1.html [ Failure ]
+[ Debug Mac13 ] animations/add-keyframes-recalc.html [ Failure ]
+[ Debug Mac13 ] http/tests/devtools/filtered-item-selection-dialog-rendering.js [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-Blob.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-prefer-compositing/fast/scroll-behavior/no-erroneous-auto-scroll-pinch-zoom.html [ Skip Timeout ]
+[ Debug Mac13 ] accessibility/aom-computed-int-properties.html [ Skip Timeout ]
+[ Debug Mac13 ] fast/scroll-behavior/overscroll-behavior.html [ Failure ]
+[ Debug Mac13 ] http/tests/devtools/elements/inspect-limited-children.js [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/responsive/responsive-neutral-keyframe.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/speculation-rules/prerender/response-code-successful.html?code=200 [ Failure ]
+[ Debug Mac13 ] virtual/portals/external/wpt/portals/portal-activate-data.html [ Skip Timeout ]
+[ Debug Mac13 ] accessibility/inline-text-word-boundary-causes-crash.html [ Skip Timeout ]
+[ Debug Mac13 ] animations/custom-properties/registered-var-to-registered-animating.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/custom-properties/registered-neutral-keyframe.html [ Crash ]
+[ Debug Mac13 ] virtual/controls-refresh-hc/fast/forms/color-scheme/time-picker/time-picker-appearance-after-closing-popup.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/svg-attribute-composition/svg-points-composition.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/network/oopif-content.js [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/security/origin-group-names-unique.js [ Skip Timeout ]
+[ Debug Mac13 ] virtual/controls-refresh-hc/fast/forms/color-scheme/suggestion-picker/datetimelocal-suggestion-picker-appearance.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/fetch/metadata/generated/element-iframe.sub.html [ Skip Timeout ]
+[ Debug Mac13 ] fast/canvas/OffscreenCanvas-copyImage.html [ Skip Timeout ]
+[ Debug Mac13 ] animations/unanimated-style.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/resource-tree/resource-tree-frame-in-crafted-frame.js [ Skip Timeout ]
+[ Debug Mac13 ] virtual/controls-refresh-hc/fast/forms/color-scheme/text/input-basic-box-appearance-basic.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/dark-color-scheme/fast/forms/color-scheme/range/range-appearance-basic.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/fetch/metadata/generated/element-embed.https.sub.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded/fast/events/pinch/pinch-zoom-pan-position-fixed.html [ Skip Timeout ]
+[ Debug Mac13 ] fullscreen/anonymous-block-merge-crash.html [ Failure ]
+[ Debug Mac13 ] http/tests/devtools/cache-storage/cache-entry-deletion.js [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/responsive/interpolation/box-shadow-responsive.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-prefer-compositing/fast/scroll-behavior/main-frame-scroll.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/storage-access-api/hasStorageAccess.sub.https.window.html [ Crash ]
+[ Debug Mac13 ] http/tests/devtools/elements/styles-4/styles-source-lines-inline.js [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded/printing/page-count-layout-overflow.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-no-composited-antialiasing/animations/interpolation/webkit-column-width-interpolation.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/service-workers/sw-navigate-useragent.js [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded/fast/idleToBlob/OffscreenCanvas-convertToBlob-2d-worker.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/soft-navigation-heuristics/back.tentative.html [ Skip Timeout ]
+[ Debug Mac13 ] fast/forms/label/label-event-order.html [ Failure ]
+[ Debug Mac13 ] virtual/threaded-prefer-compositing/fast/scroll-snap/root-scroller-snap-behaviour/smooth-scroll-snaps-visual-viewport.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded/animations/stability/keyframe-timing-function-unset-crash.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/view-transition-mpa-serialization/view-transition/parent-transition-cancels-child.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/elements/styles-3/styles-add-new-rule-colon.js [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/content-security-policy/embedded-enforcement/subsumption_algorithm-hashes.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded-preload-scanner/fast/dom/HTMLScriptElement/async-inline-script.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/dark-mode-classifier-transparency-and-num-colors/dark-mode/images/image.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded/transitions/svg-layout-transition-zoom.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/search/sources-search-scope-in-files.js [ Skip Timeout ]
+[ Debug Mac13 ] virtual/threaded/printing/page-height-zero.html [ Skip Timeout ]
+[ Debug Mac13 ] virtual/fenced-frame-mparch/external/wpt/fenced-frame/deep-copy-config.https.html [ Skip Timeout ]
+[ Debug Mac13 ] external/wpt/css/css-text/text-transform/text-transform-capitalize-003.html [ Failure ]
+[ Debug Mac13 ] virtual/threaded-prefer-compositing/fast/scrolling/scrollbar-prevent-default.html [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/elements/resolve-alien-node.js [ Skip Timeout ]
+[ Debug Mac13 ] http/tests/devtools/oopif/oopif-elements-inspect.js [ Skip Timeout ]
 crbug.com/1446040 [ Mac ] virtual/oopr-canvas2d/external/wpt/mediacapture-record/MediaRecorder-canvas-media-source.https.html [ Failure ]
 
 
@@ -6527,7 +6696,7 @@
 
 crbug.com/1455245 virtual/fedcm-multi-idp/external/wpt/credential-management/fedcm-multi-idp/abort-multiple-gets-through-first-idp.https.html [ Pass Timeout ]
 crbug.com/1455245 virtual/fedcm-multi-idp/external/wpt/credential-management/fedcm-multi-idp/abort-multiple-gets-through-second-idp.https.html [ Pass Timeout ]
-crbug.com/1455245 virtual/fedcm-multi-idp/external/wpt/credential-management/fedcm-multi-idp/get-before-and-after-onload.https.html [ Failure Timeout ]
+crbug.com/1455245 virtual/fedcm-multi-idp/external/wpt/credential-management/fedcm-multi-idp/get-before-and-after-onload.https.html [ Pass Failure Timeout ]
 crbug.com/1455245 virtual/fedcm-multi-idp/external/wpt/credential-management/fedcm-multi-idp/get-before-and-during-onload.https.html [ Pass Timeout ]
 crbug.com/1455245 virtual/fedcm-multi-idp/external/wpt/credential-management/fedcm-multi-idp/get-before-onload-and-during-dom-content-loaded.https.html [ Pass Timeout ]
 crbug.com/1455245 virtual/fedcm-multi-idp/external/wpt/credential-management/fedcm-multi-idp/multiple-gets-after-abort.https.html [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/TestLists/android.filter b/third_party/blink/web_tests/TestLists/android.filter
new file mode 100644
index 0000000..820d73f
--- /dev/null
+++ b/third_party/blink/web_tests/TestLists/android.filter
@@ -0,0 +1,323 @@
+# This file lists a limited set of web tests that are run on platforms where
+# executing all web tests is infeasible (usually due to performance or resource
+# constraints). This TestList will include all idlharness tests and minimal set
+# wpt tests that are needed to identify regression for
+# Chrome Android / Android Webview.
+#
+# Newly imported *idlharness* tests will be automatically added to this file
+# as part of third_party/blink/tools/blinkpy/w3c/test_importer.py
+#
+# Further documentation:
+# https://chromium.googlesource.com/chromium/src/+/main/docs/testing/web_test_expectations.md
+
+external/wpt/FileAPI/idlharness.any.html
+external/wpt/FileAPI/idlharness.any.worker.html
+external/wpt/FileAPI/idlharness.html
+external/wpt/FileAPI/idlharness.worker.html
+external/wpt/IndexedDB/idlharness.any.html
+external/wpt/IndexedDB/idlharness.any.serviceworker.html
+external/wpt/IndexedDB/idlharness.any.sharedworker.html
+external/wpt/IndexedDB/idlharness.any.worker.html
+external/wpt/WebCryptoAPI/idlharness.https.any.html
+external/wpt/WebCryptoAPI/idlharness.https.any.worker.html
+external/wpt/accelerometer/idlharness.https.window.html
+external/wpt/added_idlharness.html
+external/wpt/ambient-light/idlharness.https.window.html
+external/wpt/animation-worklet/idlharness.any.html
+external/wpt/animation-worklet/idlharness.any.worker.html
+external/wpt/audio-output/idlharness.https.window.html
+external/wpt/autoplay-policy-detection/idlharness.window.html
+external/wpt/background-fetch/idlharness.https.any.html
+external/wpt/background-fetch/idlharness.https.any.serviceworker.html
+external/wpt/background-fetch/idlharness.https.any.sharedworker.html
+external/wpt/background-fetch/idlharness.https.any.worker.html
+external/wpt/background-sync/idlharness.https.any.html
+external/wpt/background-sync/idlharness.https.any.worker.html
+external/wpt/badging/idlharness.https.any.html
+external/wpt/badging/idlharness.https.any.worker.html
+external/wpt/battery-status/idlharness.https.window.html
+external/wpt/beacon/idlharness.any.html
+external/wpt/beacon/idlharness.any.worker.html
+external/wpt/bluetooth/idl/idlharness.tentative.https.window.html
+external/wpt/captured-mouse-events/idlharness.https.window.html
+external/wpt/clipboard-apis/idlharness.https.window.html
+external/wpt/compat/idlharness.window.html
+external/wpt/compression/idlharness-shadowrealm.window.html
+external/wpt/compression/idlharness.https.any.html
+external/wpt/compression/idlharness.https.any.worker.html
+external/wpt/compute-pressure/idlharness.https.any.html
+external/wpt/compute-pressure/idlharness.https.any.sharedworker.html
+external/wpt/compute-pressure/idlharness.https.any.worker.html
+external/wpt/console/idlharness-shadowrealm.window.html
+external/wpt/console/idlharness.any.html
+external/wpt/console/idlharness.any.worker.html
+external/wpt/content-index/idlharness.https.any.html
+external/wpt/content-index/idlharness.https.any.serviceworker.html
+external/wpt/content-index/idlharness.https.any.sharedworker.html
+external/wpt/content-index/idlharness.https.any.worker.html
+external/wpt/content-security-policy/embedded-enforcement/idlharness.window.html
+external/wpt/content-security-policy/securitypolicyviolation/idlharness.window.html
+external/wpt/cookie-store/idlharness.tentative.https.any.html
+external/wpt/cookie-store/idlharness.tentative.https.any.serviceworker.html
+external/wpt/cookie-store/idlharness.tentative.https.any.sharedworker.html
+external/wpt/cookie-store/idlharness.tentative.https.any.worker.html
+external/wpt/credential-management/idlharness.https.window.html
+external/wpt/css/css-anchor-position/idlharness.html
+external/wpt/css/css-animations/idlharness.html
+external/wpt/css/css-cascade/idlharness.html
+external/wpt/css/css-conditional/idlharness.html
+external/wpt/css/css-contain/container-queries/idlharness.html
+external/wpt/css/css-counter-styles/idlharness.html
+external/wpt/css/css-font-loading/idlharness.https.html
+external/wpt/css/css-fonts/idlharness.html
+external/wpt/css/css-highlight-api/idlharness.window.html
+external/wpt/css/css-images/idlharness.html
+external/wpt/css/css-masking/idlharness.html
+external/wpt/css/css-paint-api/idlharness.html
+external/wpt/css/css-parser-api/idlharness.html
+external/wpt/css/css-properties-values-api/idlharness.html
+external/wpt/css/css-pseudo/idlharness.html
+external/wpt/css/css-shadow-parts/idlharness.html
+external/wpt/css/css-toggle/idlharness.tentative.html
+external/wpt/css/css-transitions/idlharness-2.html
+external/wpt/css/css-transitions/idlharness.html
+external/wpt/css/css-typed-om/idlharness.html
+external/wpt/css/cssom-view/idlharness.html
+external/wpt/css/cssom/idlharness.html
+external/wpt/css/filter-effects/idlharness.any.html
+external/wpt/css/filter-effects/idlharness.any.worker.html
+external/wpt/css/geometry/idlharness.any.html
+external/wpt/css/geometry/idlharness.any.worker.html
+external/wpt/custom-state-pseudo-class/idlharness.window.html
+external/wpt/deprecation-reporting/idlharness.any.html
+external/wpt/deprecation-reporting/idlharness.any.worker.html
+external/wpt/device-memory/idlharness.https.any.html
+external/wpt/device-memory/idlharness.https.any.worker.html
+external/wpt/dom/idlharness-shadowrealm.window.html
+external/wpt/dom/idlharness.any.serviceworker.html
+external/wpt/dom/idlharness.any.sharedworker.html
+external/wpt/dom/idlharness.any.worker.html
+external/wpt/dom/idlharness.window.html?exclude=Node
+external/wpt/dom/idlharness.window.html?include=Node
+external/wpt/domparsing/idlharness.window.html
+external/wpt/element-timing/idlharness.window.html
+external/wpt/encoding/idlharness-shadowrealm.window.html
+external/wpt/encoding/idlharness.any.html
+external/wpt/encoding/idlharness.any.serviceworker.html
+external/wpt/encoding/idlharness.any.sharedworker.html
+external/wpt/encoding/idlharness.any.worker.html
+external/wpt/encrypted-media/idlharness.https.htmlexternal/wpt/entries-api/idlharness.window.html
+external/wpt/event-timing/idlharness.any.html
+external/wpt/event-timing/idlharness.any.serviceworker.html
+external/wpt/event-timing/idlharness.any.sharedworker.html
+external/wpt/event-timing/idlharness.any.worker.html
+external/wpt/fetch/api/idlharness.any.html
+external/wpt/fetch/api/idlharness.any.serviceworker.html
+external/wpt/fetch/api/idlharness.any.sharedworker.html
+external/wpt/fetch/api/idlharness.any.worker.html
+external/wpt/file-system-access/idlharness.https.any.html
+external/wpt/file-system-access/idlharness.https.any.worker.html
+external/wpt/fs/idlharness.https.any.html
+external/wpt/fs/idlharness.https.any.worker.html
+external/wpt/fullscreen/idlharness.window.html
+external/wpt/gamepad/idlharness-extensions.https.window.html
+external/wpt/gamepad/idlharness.https.window.html
+external/wpt/generic-sensor/idlharness.https.window.html
+external/wpt/geolocation-API/idlharness.https.window.html
+external/wpt/geolocation-sensor/idlharness.https.window.html
+external/wpt/gyroscope/idlharness.https.window.html
+external/wpt/hr-time/idlharness-shadowrealm.window.html
+external/wpt/hr-time/idlharness.any.html
+external/wpt/hr-time/idlharness.any.serviceworker.html
+external/wpt/hr-time/idlharness.any.sharedworker.html
+external/wpt/hr-time/idlharness.any.worker.html
+external/wpt/html-media-capture/idlharness.window.html
+external/wpt/html/dom/idlharness-shadowrealm.window.html
+external/wpt/html/dom/idlharness.https.html?exclude=(Document|Window|HTML.*)
+external/wpt/html/dom/idlharness.https.html?include=(Document|Window)
+external/wpt/html/dom/idlharness.https.html?include=HTML.*
+external/wpt/html/dom/idlharness.worker.html
+external/wpt/idle-detection/idlharness-worker.https.window.html
+external/wpt/idle-detection/idlharness.https.window.html
+external/wpt/input-device-capabilities/idlharness.window.html
+external/wpt/input-events/idlharness.window.html
+external/wpt/installedapp/idlharness.https.window.html
+external/wpt/intersection-observer/idlharness.window.html
+external/wpt/intervention-reporting/idlharness.any.html
+external/wpt/intervention-reporting/idlharness.any.worker.html
+external/wpt/is-input-pending/idlharness.window.html
+external/wpt/js-self-profiling/idlharness.https.html
+external/wpt/keyboard-lock/idlharness.https.window.html
+external/wpt/keyboard-map/idlharness.https.window.html
+external/wpt/largest-contentful-paint/idlharness.html
+external/wpt/layout-instability/idlharness.html
+external/wpt/longtask-timing/idlharness.window.html
+external/wpt/magnetometer/idlharness.https.window.html
+external/wpt/measure-memory/idlharness.window.html
+external/wpt/media-capabilities/idlharness.any.html
+external/wpt/media-capabilities/idlharness.any.worker.html
+external/wpt/media-playback-quality/idlharness.window.html
+external/wpt/media-source/idlharness.window.html
+external/wpt/mediacapture-fromelement/idlharness.window.html
+external/wpt/mediacapture-image/idlharness.window.html
+external/wpt/mediacapture-record/idlharness.window.html
+external/wpt/mediacapture-streams/idlharness.https.window.html
+external/wpt/mediasession/idlharness.window.html
+external/wpt/mst-content-hint/idlharness.window.html
+external/wpt/navigation-timing/idlharness.window.html
+external/wpt/netinfo/idlharness.any.html
+external/wpt/netinfo/idlharness.any.worker.html
+external/wpt/notifications/idlharness.https.any.html
+external/wpt/notifications/idlharness.https.any.serviceworker.html
+external/wpt/notifications/idlharness.https.any.sharedworker.html
+external/wpt/notifications/idlharness.https.any.worker.html
+external/wpt/orientation-event/idlharness.https.window.html
+external/wpt/orientation-sensor/idlharness.https.window.html
+external/wpt/page-lifecycle/idlharness.html
+external/wpt/paint-timing/idlharness.window.html
+external/wpt/parakeet/idlharness.tentative.https.window.html
+external/wpt/payment-handler/idlharness.https.any.html
+external/wpt/payment-handler/idlharness.https.any.serviceworker.html
+external/wpt/payment-handler/idlharness.https.any.sharedworker.html
+external/wpt/payment-handler/idlharness.https.any.worker.html
+external/wpt/payment-request/idlharness.https.window.html
+external/wpt/performance-timeline/idlharness-shadowrealm.window.html
+external/wpt/performance-timeline/idlharness.any.html
+external/wpt/performance-timeline/idlharness.any.serviceworker.html
+external/wpt/performance-timeline/idlharness.any.sharedworker.html
+external/wpt/performance-timeline/idlharness.any.worker.html
+external/wpt/periodic-background-sync/idlharness.https.any.html
+external/wpt/periodic-background-sync/idlharness.https.any.worker.html
+external/wpt/permissions-policy/idlharness.window.html
+external/wpt/permissions-request/idlharness.any.html
+external/wpt/permissions-request/idlharness.any.worker.html
+external/wpt/permissions-revoke/idlharness.any.html
+external/wpt/permissions-revoke/idlharness.any.worker.html
+external/wpt/permissions/idlharness.any.html
+external/wpt/permissions/idlharness.any.worker.html
+external/wpt/picture-in-picture/idlharness.window.html
+external/wpt/pointerevents/
+external/wpt/pointerevents/idlharness.window.html
+external/wpt/pointerlock/idlharness.window.html
+external/wpt/portals/idlharness.window.html
+external/wpt/presentation-api/controlling-ua/idlharness.https.html
+external/wpt/private-click-measurement/idlharness.window.html
+external/wpt/push-api/idlharness.https.any.html
+external/wpt/push-api/idlharness.https.any.serviceworker.html
+external/wpt/push-api/idlharness.https.any.sharedworker.html
+external/wpt/push-api/idlharness.https.any.worker.html
+external/wpt/remote-playback/idlharness.window.html
+external/wpt/reporting/idlharness.any.html
+external/wpt/reporting/idlharness.any.worker.html
+external/wpt/requestidlecallback/idlharness.window.html
+external/wpt/resize-observer/idlharness.window.html
+external/wpt/resource-timing/idlharness.any.html
+external/wpt/resource-timing/idlharness.any.worker.html
+external/wpt/sanitizer-api/idlharness.https.window.html
+external/wpt/savedata/idlharness.any.html
+external/wpt/savedata/idlharness.any.worker.html
+external/wpt/screen-capture/idlharness.https.window.html
+external/wpt/screen-orientation/idlharness.window.html
+external/wpt/screen-wake-lock/idlharness.https.window.html
+external/wpt/scroll-animations/scroll-timelines/idlharness.window.html
+external/wpt/scroll-to-text-fragment/idlharness.window.html
+external/wpt/selection/idlharness.window.html
+external/wpt/serial/idlharness.https.any.html
+external/wpt/serial/idlharness.https.any.worker.html
+external/wpt/server-timing/idlharness.https.any.html
+external/wpt/server-timing/idlharness.https.any.worker.html
+external/wpt/service-workers/idlharness.https.any.html
+external/wpt/service-workers/idlharness.https.any.serviceworker.html
+external/wpt/service-workers/idlharness.https.any.sharedworker.html
+external/wpt/service-workers/idlharness.https.any.worker.html
+external/wpt/shape-detection/idlharness.https.any.html
+external/wpt/shape-detection/idlharness.https.any.serviceworker.html
+external/wpt/shape-detection/idlharness.https.any.sharedworker.html
+external/wpt/shape-detection/idlharness.https.any.worker.html
+external/wpt/speech-api/idlharness.window.html
+external/wpt/storage-access-api/idlharness.window.html
+external/wpt/storage/idlharness.https.any.html
+external/wpt/storage/idlharness.https.any.worker.html
+external/wpt/streams/idlharness-shadowrealm.window.html
+external/wpt/streams/idlharness.any.html
+external/wpt/streams/idlharness.any.serviceworker.html
+external/wpt/streams/idlharness.any.sharedworker.html
+external/wpt/streams/idlharness.any.worker.html
+external/wpt/subapps/idlharness.tentative.https.window.html
+external/wpt/svg/idlharness.window.html
+external/wpt/touch-events/external/wpt/touch-events/idlharness.window.html
+external/wpt/trusted-types/idlharness.tentative.window.html
+external/wpt/ua-client-hints/idlharness.https.any.html
+external/wpt/ua-client-hints/idlharness.https.any.worker.html
+external/wpt/uievents/idlharness.window.html
+external/wpt/url/idlharness-shadowrealm.window.html
+external/wpt/url/idlharness.any.html
+external/wpt/url/idlharness.any.worker.html
+external/wpt/user-timing/idlharness-shadowrealm.window.html
+external/wpt/user-timing/idlharness.any.html
+external/wpt/user-timing/idlharness.any.serviceworker.html
+external/wpt/user-timing/idlharness.any.sharedworker.html
+external/wpt/user-timing/idlharness.any.worker.html
+external/wpt/vibration/idlharness.window.html
+external/wpt/video-rvfc/idlharness.window.html
+external/wpt/virtual-keyboard/
+external/wpt/virtual-keyboard/idlharness.https.window.html
+external/wpt/visual-viewport/
+external/wpt/wasm/jsapi/idlharness.any.html
+external/wpt/wasm/jsapi/idlharness.any.worker.html
+external/wpt/wasm/webapi/idlharness.any.html
+external/wpt/wasm/webapi/idlharness.any.worker.html
+external/wpt/web-animations/idlharness.window.html
+external/wpt/web-locks/idlharness.tentative.https.any.html
+external/wpt/web-locks/idlharness.tentative.https.any.serviceworker.html
+external/wpt/web-locks/idlharness.tentative.https.any.sharedworker.html
+external/wpt/web-locks/idlharness.tentative.https.any.worker.html
+external/wpt/web-nfc/idlharness.https.window.html
+external/wpt/web-otp/idlharness.https.window.html
+external/wpt/web-share/idlharness.https.window.html
+external/wpt/webaudio/idlharness.https.window.html
+external/wpt/webauthn/idlharness.https.window.html
+external/wpt/webcodecs/idlharness.https.any.html
+external/wpt/webcodecs/idlharness.https.any.worker.html
+external/wpt/webdriver/tests/classic/idlharness.window.html
+external/wpt/webgl/idlharness.any.html
+external/wpt/webgl/idlharness.any.worker.html
+external/wpt/webhid/idlharness.https.window.html
+external/wpt/webidl/idlharness-shadowrealm.window.html
+external/wpt/webidl/idlharness.any.html
+external/wpt/webidl/idlharness.any.worker.html
+external/wpt/webmidi/idlharness.https.window.html
+external/wpt/webnn/idlharness.https.any.html
+external/wpt/webnn/idlharness.https.any.worker.html
+external/wpt/webrtc-encoded-transform/idlharness.https.window.html
+external/wpt/webrtc-identity/idlharness.https.window.html
+external/wpt/webrtc-stats/idlharness.window.html
+external/wpt/webrtc/idlharness.https.window.html
+external/wpt/websockets/idlharness.any.html
+external/wpt/websockets/idlharness.any.worker.html
+external/wpt/webtransport/idlharness.https.any.html
+external/wpt/webtransport/idlharness.https.any.serviceworker.html
+external/wpt/webtransport/idlharness.https.any.sharedworker.html
+external/wpt/webtransport/idlharness.https.any.worker.html
+external/wpt/webusb/idlharness.https.any.html
+external/wpt/webusb/idlharness.https.any.worker.html
+external/wpt/webvtt/api/idlharness.window.html
+external/wpt/webxr/anchors/idlharness.https.window.html
+external/wpt/webxr/ar-module/idlharness.https.window.html
+external/wpt/webxr/dom-overlay/idlharness.https.window.html
+external/wpt/webxr/gamepads-module/idlharness.https.window.html
+external/wpt/webxr/hand-input/idlharness.https.window.html
+external/wpt/webxr/hit-test/idlharness.https.html
+external/wpt/webxr/idlharness.https.window.html
+external/wpt/worklets/idlharness.https.any.html
+external/wpt/worklets/idlharness.https.any.worker.html
+external/wpt/xhr/idlharness.any.html
+external/wpt/xhr/idlharness.any.sharedworker.html
+external/wpt/xhr/idlharness.any.worker.html
+wpt_internal/sanitizer-api/idlharness.https.window.html
+wpt_internal/storage/buckets/idlharness-worker.https.any.html
+wpt_internal/storage/buckets/idlharness-worker.https.any.serviceworker.html
+wpt_internal/storage/buckets/idlharness-worker.https.any.sharedworker.html
+wpt_internal/storage/buckets/idlharness-worker.https.any.worker.html
+wpt_internal/system-wake-lock/idlharness-worker.https.window.html
+wpt_internal/system-wake-lock/idlharness.https.window.html
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index dab5787d..5a048b3d 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -5483,6 +5483,13 @@
        {}
       ]
      ],
+     "set-input-value-of-editing-host-after-changing-type.html": [
+      "34a15588965b1f1a975d7040f2d9a414c4d59da9",
+      [
+       null,
+       {}
+      ]
+     ],
      "textarea-will-be-blurred-by-focus-event-listener.html": [
       "bcb145c309901ce49369ae539fc338f1efb35656",
       [
@@ -84871,6 +84878,32 @@
        {}
       ]
      ],
+     "border-image-image-type-001.htm": [
+      "9486f0b8b6e2d5fcccda1e7d44084db4c6722219",
+      [
+       null,
+       [
+        [
+         "/css/css-backgrounds/reference/border-image-image-type-001-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "border-image-image-type-002.htm": [
+      "f365793e3f4c40fea9a51be8fd247855c77f76cc",
+      [
+       null,
+       [
+        [
+         "/css/css-backgrounds/reference/border-image-image-type-002-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "border-image-image-type-003.htm": [
       "b5a7543fcb845f6b54e22f37efdff55ed09d3ef4",
       [
@@ -84900,6 +84933,32 @@
        }
       ]
      ],
+     "border-image-image-type-004.htm": [
+      "1e6953eefab4c7e5ffb83824979edc0c4d1ef485",
+      [
+       null,
+       [
+        [
+         "/css/css-backgrounds/reference/border-image-image-type-004-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "border-image-image-type-005.htm": [
+      "0503b5af017c86b00eb4bd5fc345edc18d576854",
+      [
+       null,
+       [
+        [
+         "/css/css-backgrounds/reference/border-image-image-type-004-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "border-image-outset-003.html": [
       "27bc02682ca8d27a4f48997c3a8150438b33b86a",
       [
@@ -109708,6 +109767,19 @@
         {}
        ]
       ],
+      "content-visibility-on-root-svg.html": [
+       "440d1ad94bfe7bea06b5cd6a614019215ff62cc4",
+       [
+        null,
+        [
+         [
+          "/css/css-contain/content-visibility/content-visibility-on-root-svg-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "content-visibility-resize-observer-no-error.html": [
        "f323e606039e72a696d2de75eb0d43c7f9cab095",
        [
@@ -157454,6 +157526,19 @@
        {}
       ]
      ],
+     "move-with-text-after-paint.html": [
+      "1ea3d4b58bce1fe07a57faa05b008e426368925a",
+      [
+       null,
+       [
+        [
+         "/css/css-multicol/move-with-text-after-paint-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "multicol-basic-001.html": [
       "702cf549b1e572f4b6e17ba637603f5667d64b1c",
       [
@@ -161383,6 +161468,19 @@
        {}
       ]
      ],
+     "resize-with-text-after-paint.html": [
+      "9e0b31ddbe5aa0aea3303a1432af9c72a3158d4c",
+      [
+       null,
+       [
+        [
+         "/css/css-multicol/resize-with-text-after-paint-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "spanner-fragmentation-000.html": [
       "f700235621a5833a53185ef2ab12d31343c3d35c",
       [
@@ -193318,6 +193416,39 @@
         {}
        ]
       ],
+      "text-spacing-trim-narrow-001.html": [
+       "cd906770f8e99c81baad2f2fa41036a7cbae7c6b",
+       [
+        "css/css-text/text-spacing-trim/text-spacing-trim-narrow-001.html?class=chws,htb",
+        [
+         [
+          "/css/css-text/text-spacing-trim/text-spacing-trim-narrow-001-ref.html?class=chws,htb",
+          "=="
+         ]
+        ],
+        {}
+       ],
+       [
+        "css/css-text/text-spacing-trim/text-spacing-trim-narrow-001.html?class=halt,htb",
+        [
+         [
+          "/css/css-text/text-spacing-trim/text-spacing-trim-narrow-001-ref.html?class=halt,htb",
+          "=="
+         ]
+        ],
+        {}
+       ],
+       [
+        "css/css-text/text-spacing-trim/text-spacing-trim-narrow-001.html?class=halt,vrl",
+        [
+         [
+          "/css/css-text/text-spacing-trim/text-spacing-trim-narrow-001-ref.html?class=halt,vrl",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "text-spacing-trim-space-all-001.html": [
        "20e59c5a01aa5362a03c3fa021b5316be9f729d8",
        [
@@ -205351,6 +205482,19 @@
         }
        ]
       ],
+      "scale-and-rotate-both-specified-on-animation-keyframes.html": [
+       "708bfa49666d816a612fda6b7c5c6b13fbfc5956",
+       [
+        null,
+        [
+         [
+          "/css/css-transforms/animation/scale-and-rotate-both-specified-on-animation-keyframes-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "scale-animation-on-svg.html": [
        "8862545688ec7ece1e9e92d8843d48dd889a1dba",
        [
@@ -205666,6 +205810,19 @@
        {}
       ]
      ],
+     "backface-visibility-hidden-animated-002.html": [
+      "b3029f9e46535c4686f5e7bda567b1c7577d1cb6",
+      [
+       null,
+       [
+        [
+         "/css/css-transforms/backface-visibility-hidden-animated-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "backface-visibility-hidden-child-translate.html": [
       "f03d88f0187b746379e0a882b291411cb36ee1ad",
       [
@@ -205770,8 +205927,34 @@
        {}
       ]
      ],
+     "composited-under-rotateY-180deg-perspective.html": [
+      "c91e6f725f95bfe450f94a3b157d372cf21e02fb",
+      [
+       null,
+       [
+        [
+         "/css/css-transforms/composited-under-rotateY-180deg-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "composited-under-rotateY-180deg-preserve-3d.html": [
+      "282d0b1c95ab5fc1379aa3379779773ffc4cf912",
+      [
+       null,
+       [
+        [
+         "/css/css-transforms/composited-under-rotateY-180deg-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "composited-under-rotateY-180deg.html": [
-      "01ff42a98f4c09e7aebba5aafe91a8a726d648ff",
+      "674cc4492fc539251bcc10155a2199a912e2c71c",
       [
        null,
        [
@@ -284269,11 +284452,11 @@
   "support": {
    ".cache": {
     "gitignore2.json": [
-     "a95258555da80b468ec0d45fc2afff562f8bafbc",
+     "0839a9635eaa31f25d0012770ec7250c464b0319",
      []
     ],
     "mtime.json": [
-     "6c04507e9567022d50beb75ea228d5925424c4d1",
+     "bfe41c980abe016005e85d47d1eda3d3ddf1c72c",
      []
     ]
    },
@@ -292303,16 +292486,16 @@
       "d9adcaa762909e0ddef54daa989848169ede25dc",
       []
      ],
-     "mark_signedin.headers": [
-      "a482da4fdde66594b8777a1652105b7554c4fc11",
+     "mark_signedin.sub.headers": [
+      "b87b36fa3b39fb75b986cb89d228841de6535ede",
       []
      ],
      "mark_signedout": [
       "d9adcaa762909e0ddef54daa989848169ede25dc",
       []
      ],
-     "mark_signedout.headers": [
-      "191058847c219032089ea1c12114466c4a9ffe79",
+     "mark_signedout.sub.headers": [
+      "46a8c34b2180c78ed66800d860beaa052e6c1eee",
       []
      ],
      "otpcredential-helper.js": [
@@ -303158,10 +303341,22 @@
        "789afe1a7a2f784244dec64796b3f4ee04121390",
        []
       ],
+      "border-image-image-type-001-ref.html": [
+       "feb1301847661cc33dda4acfb38e77f8574b4e95",
+       []
+      ],
+      "border-image-image-type-002-ref.html": [
+       "3fc7646417f51e0bb8f30cdbda567c451cee6896",
+       []
+      ],
       "border-image-image-type-003-ref.html": [
        "690f9ad11ad0e63d57c8c7ee10737690b7c8a061",
        []
       ],
+      "border-image-image-type-004-ref.html": [
+       "b1266827bfa366cfc055c7f5a15cdcbec960cec6",
+       []
+      ],
       "border-image-repeat-002-ref.html": [
        "e295a5c65dc1f864adffffe2d9c12fdee0a97a6e",
        []
@@ -303558,6 +303753,14 @@
        "b3c8cf3eb4c89bd8f2d1ffde051856f375e3a3de",
        []
       ],
+      "9-colored-areas-40-30-20-10.png": [
+       "3f640c76049ff37391ca8059b0bf7601ae456876",
+       []
+      ],
+      "9-colored-areas-40-30-20-10.svg": [
+       "c5896a9255a80d8b98c81f820d3c98effd8f45a1",
+       []
+      ],
       "9-colored-areas.png": [
        "93f566194785c0bbe7fc9767dda86fd7ae62acf1",
        []
@@ -306584,6 +306787,10 @@
        "e93425d5ff8afb0cd77a8492c12b36013211bf25",
        []
       ],
+      "content-visibility-on-root-svg-ref.html": [
+       "258cdfacab67cd5cc0bc4a468474f8b039517b10",
+       []
+      ],
       "content-visibility-resize-observer-no-error-ref.html": [
        "228eebfaa6b6018dc60db090971f2f8176614a27",
        []
@@ -312373,11 +312580,11 @@
        []
       ],
       "font-size-adjust-computed-expected.txt": [
-       "d757cc249f535751e707bc458d53bd366958a319",
+       "2670ec5a3dcf3cf6e533de71b162a0aa4fce4fdb",
        []
       ],
       "font-size-adjust-computed.html.ini": [
-       "b15c93413f62dc4cf86e8912ec845fceaf0c21a8",
+       "d7c7a84852d340bacff3b963d2f62a9b34b60c0d",
        []
       ],
       "font-size-adjust-valid-expected.txt": [
@@ -318897,7 +319104,7 @@
        []
       ],
       "font-style-parsing-expected.txt": [
-       "5b1e86049edc24e7b0eee48066b23b5e85e279ea",
+       "519fefa03614ea2f7fa0785b0c768ffd38310d62",
        []
       ],
       "font-style-parsing.html.ini": [
@@ -325321,6 +325528,10 @@
       "963f584f17d502f6d693dfe8d662ec2b3978f4ff",
       []
      ],
+     "move-with-text-after-paint-ref.html": [
+      "bb5d56f26b1792aea07d83710961f07572f5399d",
+      []
+     ],
      "moz-multicol3-column-balancing-break-inside-avoid-1-ref.html": [
       "c39deb12f00b2a201b09a38d3847fc80b5055c5e",
       []
@@ -326109,6 +326320,10 @@
       "02a5ec0f439bbffbb05973c4193c9a849d6d6211",
       []
      ],
+     "resize-with-text-after-paint-ref.html": [
+      "2876b93f37b7f11392ee27c9d3d145908d7ba0bb",
+      []
+     ],
      "spanner-fragmentation-012.html.ini": [
       "03a9e748dc96842d0ef7771f61bd9c7b0a68f6ba",
       []
@@ -336556,6 +336771,10 @@
        "86b61e064076ab4224a65021e31b5678a54e3ec0",
        []
       ],
+      "text-spacing-trim-narrow-001-ref.html": [
+       "0aef32b55386fa803483fa4a394b08bf59a1bb81",
+       []
+      ],
       "text-spacing-trim-space-all-001-ref.html": [
        "d33e3b62edd31029751ac32bcbdb6178df90d563",
        []
@@ -339970,6 +340189,10 @@
        "e95e62be888216d9bcd2487c54c1da602973de75",
        []
       ],
+      "scale-and-rotate-both-specified-on-animation-keyframes-ref.html": [
+       "e3cf99f9f21bbaf4ba7afb2e192619395ff0bc7e",
+       []
+      ],
       "scale-animation-on-svg-ref.html": [
        "d555a5fbe5c9b348992d7a5246a3efa2f6031d46",
        []
@@ -340029,10 +340252,6 @@
       "bba35ec8fe659eb0a640ca874b454b70ce7531b2",
       []
      ],
-     "backface-visibility-hidden-005.html.ini": [
-      "ac8498a18f3b3d98dadb44c7b7b3b48012671996",
-      []
-     ],
      "backface-visibility-hidden-006-ref.html": [
       "a9584d2329fb6184b26a4e0033d2ba454d5ce043",
       []
@@ -340045,10 +340264,6 @@
       "eea90636c838a9c71154f6b3e32a91ee4c16e1b1",
       []
      ],
-     "backface-visibility-hidden-child-will-change-transform.html.ini": [
-      "179228c8b3d5aae0d6270f5b9d2269319742bfc9",
-      []
-     ],
      "change-scale-wide-range-ref.html": [
       "264c6b6f25a27f36cdd3ea0bce92c4edb6a2a6aa",
       []
@@ -340061,18 +340276,10 @@
       "ebd2d860cec74ba0d535637934aca8dadf90571d",
       []
      ],
-     "composited-under-rotateY-180deg-clip.html.ini": [
-      "6b095a080afadcba820e248d6aec8b5601f53e05",
-      []
-     ],
      "composited-under-rotateY-180deg-ref.html": [
       "ebd2d860cec74ba0d535637934aca8dadf90571d",
       []
      ],
-     "composited-under-rotateY-180deg.html.ini": [
-      "ea54133730e754167ee8435110439cb42494d51e",
-      []
-     ],
      "containing-block-dynamic-1-ref.html": [
       "34b66abdb143f3566cadba64d3fd8f66511528f3",
       []
@@ -354731,7 +354938,7 @@
      ]
     },
     "event-expected.txt": [
-     "81b42c5bded0eb05272b19f706cb2213a569f607",
+     "e30fb1db3385e588781cee6198af7908dd16021b",
      []
     ],
     "event.html.ini": [
@@ -354766,7 +354973,7 @@
     },
     "other": {
      "cefalse-boundaries-deletion-expected.txt": [
-      "3701059f97542b7fc704604773b4b6c6b9cc251c",
+      "0f10390b423903f8907ffd8df0e3ab013da35a43",
       []
      ],
      "cefalse-boundaries-deletion.html.ini": [
@@ -354774,7 +354981,7 @@
       []
      ],
      "cloning-attributes-at-splitting-element.tentative-expected.txt": [
-      "8dd8941c9325787e1c06bc234276eba7d95dc8bd",
+      "83d2fe76d782c6dd9b5c17a13a152ab5a4325fb7",
       []
      ],
      "cloning-attributes-at-splitting-element.tentative.html.ini": [
@@ -354782,7 +354989,7 @@
       []
      ],
      "delete-expected.txt": [
-      "89588ded82a8b2e0b68476dcdd352f6221233599",
+      "077672f44d12ed427747a0551ea2284add322026",
       []
      ],
      "delete-in-child-of-head.tentative.html.ini": [
@@ -354790,19 +354997,19 @@
       []
      ],
      "delete-in-child-of-head.tentative_designMode=off_method=backspace-expected.txt": [
-      "344c727a7f6da75e7a575bf7b1449a9feb95133c",
+      "1a9f17c8636c56619e9d5a707036dbc2bd5d1fa0",
       []
      ],
      "delete-in-child-of-head.tentative_designMode=off_method=forwarddelete-expected.txt": [
-      "001e6cc7ee69a1ce336a1b2ff46642dbae94320c",
+      "0431e644a21e5bbf050d6001ac8c519b8bb99809",
       []
      ],
      "delete-in-child-of-head.tentative_designMode=on_method=backspace-expected.txt": [
-      "344c727a7f6da75e7a575bf7b1449a9feb95133c",
+      "1a9f17c8636c56619e9d5a707036dbc2bd5d1fa0",
       []
      ],
      "delete-in-child-of-head.tentative_designMode=on_method=forwarddelete-expected.txt": [
-      "001e6cc7ee69a1ce336a1b2ff46642dbae94320c",
+      "0431e644a21e5bbf050d6001ac8c519b8bb99809",
       []
      ],
      "delete-in-child-of-html.tentative.html.ini": [
@@ -354810,19 +355017,19 @@
       []
      ],
      "delete-in-child-of-html.tentative_designMode=off_method=backspace-expected.txt": [
-      "704074834667dc2d75a4633c72ec74b0a33ef442",
+      "4efcde37ccb6919c31729b273d05ca6fffc84d31",
       []
      ],
      "delete-in-child-of-html.tentative_designMode=off_method=forwarddelete-expected.txt": [
-      "1a4f1eaf1f2d280831d183202d083acf3d742834",
+      "a2bed838f7e7b16ad2b02b6d551cbdf6326ca5ce",
       []
      ],
      "delete-in-child-of-html.tentative_designMode=on_method=backspace-expected.txt": [
-      "704074834667dc2d75a4633c72ec74b0a33ef442",
+      "4efcde37ccb6919c31729b273d05ca6fffc84d31",
       []
      ],
      "delete-in-child-of-html.tentative_designMode=on_method=forwarddelete-expected.txt": [
-      "1a4f1eaf1f2d280831d183202d083acf3d742834",
+      "a2bed838f7e7b16ad2b02b6d551cbdf6326ca5ce",
       []
      ],
      "delete-in-last-definition-list-item-when-parent-list-is-editing-host.html.ini": [
@@ -354830,11 +355037,11 @@
       []
      ],
      "delete-in-last-definition-list-item-when-parent-list-is-editing-host_action=Backspace-expected.txt": [
-      "52487f21f1f87b428fa83d64a4b4917fa09873bc",
+      "a687a3f08f4af7afcc6beb05382e45d19d51535f",
       []
      ],
      "delete-in-last-definition-list-item-when-parent-list-is-editing-host_action=Delete-expected.txt": [
-      "462d8549accd0bd35d61afcdc89f8b4c458c6534",
+      "2e5b533579fbbc24fe81f5e0a83825d74f326943",
       []
      ],
      "delete-in-last-list-item-when-parent-list-is-editing-host.html.ini": [
@@ -354842,19 +355049,19 @@
       []
      ],
      "delete-in-last-list-item-when-parent-list-is-editing-host_list=ol_action=Backspace-expected.txt": [
-      "c469e3fd19041bfdef642eebb1f694160d64ab15",
+      "9ab1a3e9ff64435444f7a5a955d24f1885c2003b",
       []
      ],
      "delete-in-last-list-item-when-parent-list-is-editing-host_list=ol_action=Delete-expected.txt": [
-      "9f3708103e11b6838040db0f2eff939fd582c70f",
+      "089d045c39607dec9f1429426a9f0192c1e85165",
       []
      ],
      "delete-in-last-list-item-when-parent-list-is-editing-host_list=ul_action=Backspace-expected.txt": [
-      "22ed07ed3201f1eb826dde5e411af4e72556a5be",
+      "cbcc5cfd76d245112fcc0d555334019fc32e41ae",
       []
      ],
      "delete-in-last-list-item-when-parent-list-is-editing-host_list=ul_action=Delete-expected.txt": [
-      "b0e904668f82d473647871a06744b98dfc904846",
+      "ffedd7f58b07d50a7bd66d621a3e48ec5371b9c2",
       []
      ],
      "delete.html.ini": [
@@ -354870,47 +355077,43 @@
       []
      ],
      "editing-around-select-element.tentative_delete-expected.txt": [
-      "6c018e9e1a8bcff1c72b6cd7b04b2c31938bfe92",
+      "81218619e3252bc08fce881ff852f436499ad88a",
       []
      ],
      "editing-around-select-element.tentative_forwardDelete-expected.txt": [
-      "6ff62fa91259ae63fbb7a4ac56d6e9d41618d3eb",
+      "b0fcc670bc256e27e842db37dde84a53d0ea8d51",
       []
      ],
      "editing-around-select-element.tentative_insertText-expected.txt": [
-      "249bdd21cbc4ae057e34ede45d0cce41e66fc7be",
+      "86cb6571aa7fd3d16cede116457a3942b0007c77",
       []
      ],
      "empty-elements-insertion-expected.txt": [
-      "74501eab59da19551d8500949035f9ab32db747e",
+      "99645129d6985064e0514fa8355e91a153a220cd",
       []
      ],
      "empty-elements-insertion.html.ini": [
       "94ebae8c6ff6a0bff8aaa799f7d9ae2daf80a914",
       []
      ],
-     "exec-command-with-text-editor.tentative-expected.txt": [
-      "d2e8d68a70b8421fe6ee47531194aac439fb2ece",
-      []
-     ],
      "exec-command-with-text-editor.tentative.html.ini": [
       "085e2f1aea3b872071c696a8b8b669cdc53cc60c",
       []
      ],
      "exec-command-with-text-editor.tentative_type=password-expected.txt": [
-      "4b3e8a4cc6e48d7eafaed3f8003681ede1b7b8c1",
+      "4b205ff0b476dea60dc65d532076f5694f117d8a",
       []
      ],
      "exec-command-with-text-editor.tentative_type=text-expected.txt": [
-      "39d9207db41bc0d5ea67a67a4ee2f207f100e4bc",
+      "46084253f9dfe5a2e1952de02194e7495c64d7bd",
       []
      ],
      "exec-command-with-text-editor.tentative_type=textarea-expected.txt": [
-      "29413f2612811455f16b1442848411a46359ab43",
+      "676df0e237da1736fa36ea8c799f69aed76cf332",
       []
      ],
      "exec-command-without-editable-element.tentative-expected.txt": [
-      "209f848b4ed269496cc05f69d10a0a9fb297ebef",
+      "97cc0e8925c228ada662b068dd9c680806dd7c21",
       []
      ],
      "exec-command-without-editable-element.tentative.html.ini": [
@@ -354918,7 +355121,7 @@
       []
      ],
      "extra-text-nodes-expected.txt": [
-      "6a59f713223e2451fbf6fad78fb6375a434e7803",
+      "c964a0d6d7f741658c8e057f1c1680aebf3f5abf",
       []
      ],
      "extra-text-nodes.html.ini": [
@@ -354930,63 +355133,63 @@
       []
      ],
      "formatblock-preserving-selection.tentative_styleWithCSS=false_block=address-expected.txt": [
-      "6009f23505ed5e420d3669092293f5d9ff1decf2",
+      "6b2897555aab4dc08a1e620826c2bdcd0debd94f",
       []
      ],
      "formatblock-preserving-selection.tentative_styleWithCSS=false_block=article-expected.txt": [
-      "59aba98a8ce6b5703079869aa4a030e53f6cec5a",
+      "7834f60146cb995576e071ac2fbebbbfa8f31dca",
       []
      ],
      "formatblock-preserving-selection.tentative_styleWithCSS=false_block=blockquote-expected.txt": [
-      "71423c0e41ea5480e8cb37c23be51c1d8bee60f7",
+      "8a6a8ea53e599ae00ee61b691461aa616977bb3c",
       []
      ],
      "formatblock-preserving-selection.tentative_styleWithCSS=false_block=dd-expected.txt": [
-      "2830c1d477b6cefd91852ee45423c4a992abe6df",
+      "c07ee7aa4d0c3a968b25bbc8b381de5f3aeba663",
       []
      ],
      "formatblock-preserving-selection.tentative_styleWithCSS=false_block=dt-expected.txt": [
-      "5216aef7563ce1367b8e00c8773d17a3ca3deda8",
+      "cb4af47db3a940db6868de0fdded0a34ce7a91a4",
       []
      ],
      "formatblock-preserving-selection.tentative_styleWithCSS=false_block=h1-expected.txt": [
-      "7d23deffd51c5cff120adfa2aa540d0463cac87e",
+      "fce797b6dae9a7556f49d39d18398ec7a877a06a",
       []
      ],
      "formatblock-preserving-selection.tentative_styleWithCSS=false_block=pre-expected.txt": [
-      "e43f514418d7d9425765c30fd21da6e417b7cb8f",
+      "b82553d98e351c36640a80635e74844f48acb06b",
       []
      ],
      "formatblock-preserving-selection.tentative_styleWithCSS=true_block=address-expected.txt": [
-      "6009f23505ed5e420d3669092293f5d9ff1decf2",
+      "6b2897555aab4dc08a1e620826c2bdcd0debd94f",
       []
      ],
      "formatblock-preserving-selection.tentative_styleWithCSS=true_block=article-expected.txt": [
-      "59aba98a8ce6b5703079869aa4a030e53f6cec5a",
+      "7834f60146cb995576e071ac2fbebbbfa8f31dca",
       []
      ],
      "formatblock-preserving-selection.tentative_styleWithCSS=true_block=blockquote-expected.txt": [
-      "71423c0e41ea5480e8cb37c23be51c1d8bee60f7",
+      "8a6a8ea53e599ae00ee61b691461aa616977bb3c",
       []
      ],
      "formatblock-preserving-selection.tentative_styleWithCSS=true_block=dd-expected.txt": [
-      "2830c1d477b6cefd91852ee45423c4a992abe6df",
+      "c07ee7aa4d0c3a968b25bbc8b381de5f3aeba663",
       []
      ],
      "formatblock-preserving-selection.tentative_styleWithCSS=true_block=dt-expected.txt": [
-      "5216aef7563ce1367b8e00c8773d17a3ca3deda8",
+      "cb4af47db3a940db6868de0fdded0a34ce7a91a4",
       []
      ],
      "formatblock-preserving-selection.tentative_styleWithCSS=true_block=h1-expected.txt": [
-      "7d23deffd51c5cff120adfa2aa540d0463cac87e",
+      "fce797b6dae9a7556f49d39d18398ec7a877a06a",
       []
      ],
      "formatblock-preserving-selection.tentative_styleWithCSS=true_block=pre-expected.txt": [
-      "e43f514418d7d9425765c30fd21da6e417b7cb8f",
+      "b82553d98e351c36640a80635e74844f48acb06b",
       []
      ],
      "insert-paragraph-in-void-element.tentative-expected.txt": [
-      "7bcb233f3cf0975396e2296e21fb721d15e1fc95",
+      "fd98b18313a14000770b0dfa0ae3bc988ffc7f3d",
       []
      ],
      "insert-paragraph-in-void-element.tentative.html.ini": [
@@ -354994,7 +355197,7 @@
       []
      ],
      "insert-text-in-void-element.tentative-expected.txt": [
-      "c287839fd756bc9abc36ac1906343e47f43c9784",
+      "b77630b2bfe5cf4dcb68331203027f55214b9b6f",
       []
      ],
      "insert-text-in-void-element.tentative.html.ini": [
@@ -355006,7 +355209,7 @@
       []
      ],
      "inserthtml-do-not-preserve-inline-styles_stylesAtInsertionPoint=bold_stylesInserting=hilitecolor-expected.txt": [
-      "3403979f5573c92654caae50d7291c864011a42c",
+      "6ff9d4160b6129e2ffd5fe245259a30a0a408f17",
       []
      ],
      "insertlinebreak-with-white-space-style.tentative.html.ini": [
@@ -355018,35 +355221,35 @@
       []
      ],
      "insertparagraph-in-child-of-head.tentative_designMode=off_white-space=normal-expected.txt": [
-      "6825d488faae05b437d3cf7ab968da704a0cc190",
+      "28f8f8d3f6fb8b24bdd743bf5d5d9dea92d5536a",
       []
      ],
      "insertparagraph-in-child-of-head.tentative_designMode=off_white-space=pre-expected.txt": [
-      "fd66d58810ca6c605ad7f7567d8079dcf58ec94e",
+      "ed3ec583b47cafcc80b08f8cd698cd4bce5baba7",
       []
      ],
      "insertparagraph-in-child-of-head.tentative_designMode=off_white-space=pre-line-expected.txt": [
-      "8d618511d7e58e32fe0b26e4b6ed85da7cf43c68",
+      "e77cbc4b3853247393d3548658ed8ff75031ed07",
       []
      ],
      "insertparagraph-in-child-of-head.tentative_designMode=off_white-space=pre-wrap-expected.txt": [
-      "0c858b17844c64a82b1ea1c39c2b65ec7b8f3f89",
+      "fd602f905cd36cf06dfb039f8336f45963c33e44",
       []
      ],
      "insertparagraph-in-child-of-head.tentative_designMode=on_white-space=normal-expected.txt": [
-      "6825d488faae05b437d3cf7ab968da704a0cc190",
+      "28f8f8d3f6fb8b24bdd743bf5d5d9dea92d5536a",
       []
      ],
      "insertparagraph-in-child-of-head.tentative_designMode=on_white-space=pre-expected.txt": [
-      "fd66d58810ca6c605ad7f7567d8079dcf58ec94e",
+      "ed3ec583b47cafcc80b08f8cd698cd4bce5baba7",
       []
      ],
      "insertparagraph-in-child-of-head.tentative_designMode=on_white-space=pre-line-expected.txt": [
-      "8d618511d7e58e32fe0b26e4b6ed85da7cf43c68",
+      "e77cbc4b3853247393d3548658ed8ff75031ed07",
       []
      ],
      "insertparagraph-in-child-of-head.tentative_designMode=on_white-space=pre-wrap-expected.txt": [
-      "0c858b17844c64a82b1ea1c39c2b65ec7b8f3f89",
+      "fd602f905cd36cf06dfb039f8336f45963c33e44",
       []
      ],
      "insertparagraph-in-child-of-html.tentative.html.ini": [
@@ -355054,179 +355257,35 @@
       []
      ],
      "insertparagraph-in-child-of-html.tentative_designMode=off_white-space=normal-expected.txt": [
-      "02e01d11b2ee2d7a522735e4ed4d00d2d0a86acb",
+      "3a4c8200d9f48b134e7ce639240f6fb7b1a86030",
       []
      ],
      "insertparagraph-in-child-of-html.tentative_designMode=off_white-space=pre-expected.txt": [
-      "f8c8bbd5fa74ffd55e549bf5dd30f73293cb3c38",
+      "f48bdfffe8fe4151a9692ad57fb7e57f44df3d18",
       []
      ],
      "insertparagraph-in-child-of-html.tentative_designMode=off_white-space=pre-line-expected.txt": [
-      "50673c67ad746664fc9d42ca0cf3d0babeaff660",
+      "8fe60a2215de09f0cff5a66ce497f7361e2471d8",
       []
      ],
      "insertparagraph-in-child-of-html.tentative_designMode=off_white-space=pre-wrap-expected.txt": [
-      "df6c9eb6866a5ab41819e21976532ae0b216c240",
+      "3856512a80c2da1d4aa83e2b2d53d3c99b77c9ed",
       []
      ],
      "insertparagraph-in-child-of-html.tentative_designMode=on_white-space=normal-expected.txt": [
-      "02e01d11b2ee2d7a522735e4ed4d00d2d0a86acb",
+      "3a4c8200d9f48b134e7ce639240f6fb7b1a86030",
       []
      ],
      "insertparagraph-in-child-of-html.tentative_designMode=on_white-space=pre-expected.txt": [
-      "f8c8bbd5fa74ffd55e549bf5dd30f73293cb3c38",
+      "f48bdfffe8fe4151a9692ad57fb7e57f44df3d18",
       []
      ],
      "insertparagraph-in-child-of-html.tentative_designMode=on_white-space=pre-line-expected.txt": [
-      "50673c67ad746664fc9d42ca0cf3d0babeaff660",
+      "8fe60a2215de09f0cff5a66ce497f7361e2471d8",
       []
      ],
      "insertparagraph-in-child-of-html.tentative_designMode=on_white-space=pre-wrap-expected.txt": [
-      "df6c9eb6866a5ab41819e21976532ae0b216c240",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=p_white-space=normal_display=block_command=insertParagraph-expected.txt": [
-      "f8324a1bdaac4ad7b074f6c65f3814969546cd3d",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=p_white-space=normal_display=block_command=insertText-expected.txt": [
-      "f8324a1bdaac4ad7b074f6c65f3814969546cd3d",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=p_white-space=normal_display=inline-block_command=insertParagraph-expected.txt": [
-      "8499f0e51a7c56c4941fb5dd6ee8f6538693c1dd",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=p_white-space=normal_display=inline-block_command=insertText-expected.txt": [
-      "8499f0e51a7c56c4941fb5dd6ee8f6538693c1dd",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=p_white-space=normal_display=inline_command=insertParagraph-expected.txt": [
-      "52b06182648d93b6b14ad8ade07ee1a724f6c209",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=p_white-space=normal_display=inline_command=insertText-expected.txt": [
-      "52b06182648d93b6b14ad8ade07ee1a724f6c209",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=p_white-space=pre-line_display=block_command=insertParagraph-expected.txt": [
-      "7531dbc4d0f9822db25ddc5326db5a71d5bfc556",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=p_white-space=pre-line_display=block_command=insertText-expected.txt": [
-      "7531dbc4d0f9822db25ddc5326db5a71d5bfc556",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=p_white-space=pre-wrap_display=block_command=insertParagraph-expected.txt": [
-      "e50758f83411d4e5e0b9eb1a3d6ef54a3a8a9ccc",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=p_white-space=pre-wrap_display=block_command=insertText-expected.txt": [
-      "e50758f83411d4e5e0b9eb1a3d6ef54a3a8a9ccc",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=p_white-space=pre_display=block_command=insertParagraph-expected.txt": [
-      "e854cf34089e6889b2d6a89fc9f04c5c81f7d649",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=p_white-space=pre_display=block_command=insertText-expected.txt": [
-      "e854cf34089e6889b2d6a89fc9f04c5c81f7d649",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=normal_display=block_command=insertParagraph-expected.txt": [
-      "067c59e3d13a47b0da664e81c44a3bebbd0400a4",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=normal_display=block_command=insertText-expected.txt": [
-      "067c59e3d13a47b0da664e81c44a3bebbd0400a4",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=normal_display=inline-block_command=insertParagraph-expected.txt": [
-      "604bb7b89d5c5a98170d102d6ca92b92eeed90b7",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=normal_display=inline-block_command=insertText-expected.txt": [
-      "604bb7b89d5c5a98170d102d6ca92b92eeed90b7",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=normal_display=inline_command=insertParagraph-expected.txt": [
-      "d316c4c994abfe6c005a082644f88ed914c6b68e",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=normal_display=inline_command=insertText-expected.txt": [
-      "d316c4c994abfe6c005a082644f88ed914c6b68e",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre-line_display=block_command=insertParagraph-expected.txt": [
-      "784e4b93c1926beeb37c150614b4b5cad5376216",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre-line_display=block_command=insertText-expected.txt": [
-      "784e4b93c1926beeb37c150614b4b5cad5376216",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre-line_display=inline-block_command=insertParagraph-expected.txt": [
-      "8a631f6efe8a5b5e3686b2b921efeab37823567d",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre-line_display=inline-block_command=insertText-expected.txt": [
-      "8a631f6efe8a5b5e3686b2b921efeab37823567d",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre-line_display=inline_command=insertParagraph-expected.txt": [
-      "0436f800b8ed48d3d015b9487b531028ad571040",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre-line_display=inline_command=insertText-expected.txt": [
-      "0436f800b8ed48d3d015b9487b531028ad571040",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre-wrap_display=block_command=insertParagraph-expected.txt": [
-      "f07298cc500035a51a2e220aed9fff3b8dfd9c89",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre-wrap_display=block_command=insertText-expected.txt": [
-      "f07298cc500035a51a2e220aed9fff3b8dfd9c89",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre-wrap_display=inline-block_command=insertParagraph-expected.txt": [
-      "0faefb6949208fb8c510155f12fb34169a0f2478",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre-wrap_display=inline-block_command=insertText-expected.txt": [
-      "0faefb6949208fb8c510155f12fb34169a0f2478",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre-wrap_display=inline_command=insertParagraph-expected.txt": [
-      "69118094799ffde31a65ba0c93d792b324066960",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre-wrap_display=inline_command=insertText-expected.txt": [
-      "69118094799ffde31a65ba0c93d792b324066960",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre_display=block_command=insertParagraph-expected.txt": [
-      "6bcc7a55d558bd70c2d4ad723629ef4a095f4979",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre_display=block_command=insertText-expected.txt": [
-      "6bcc7a55d558bd70c2d4ad723629ef4a095f4979",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre_display=inline-block_command=insertParagraph-expected.txt": [
-      "dda7a1e546f4c1d53574228bd2c002cd4f7a8b56",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre_display=inline-block_command=insertText-expected.txt": [
-      "dda7a1e546f4c1d53574228bd2c002cd4f7a8b56",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre_display=inline_command=insertParagraph-expected.txt": [
-      "0cb366e5d13f1430df975a57e8032e3e4e544e68",
-      []
-     ],
-     "insertparagraph-in-editing-host-cannot-have-div.tentative_host=span_white-space=pre_display=inline_command=insertText-expected.txt": [
-      "0cb366e5d13f1430df975a57e8032e3e4e544e68",
+      "3856512a80c2da1d4aa83e2b2d53d3c99b77c9ed",
       []
      ],
      "insertparagraph-in-inline-editing-host.tentative.html.ini": [
@@ -355234,7 +355293,7 @@
       []
      ],
      "insertparagraph-in-non-splittable-element-expected.txt": [
-      "97250e4115f0937543cd883015052007a42b0984",
+      "864a71efd0e546d2956557539548cd95246fed69",
       []
      ],
      "insertparagraph-in-non-splittable-element.html.ini": [
@@ -355246,35 +355305,35 @@
       []
      ],
      "insertparagraph-with-white-space-style.tentative_white-space=nowrap_command=insertParagraph-expected.txt": [
-      "738dd31dfdffd232ba28d279dbb9d84ef6d372d6",
+      "d9bedbef4c00848371156aaa6dc43c2ca1a09c54",
       []
      ],
      "insertparagraph-with-white-space-style.tentative_white-space=nowrap_command=insertText-expected.txt": [
-      "738dd31dfdffd232ba28d279dbb9d84ef6d372d6",
+      "d9bedbef4c00848371156aaa6dc43c2ca1a09c54",
       []
      ],
      "insertparagraph-with-white-space-style.tentative_white-space=pre-line_command=insertParagraph-expected.txt": [
-      "b32c16d94bcf3e93cd5992a2572480c9de9d00cf",
+      "928ac6685145189a7bec8d43908c2c04748f85b1",
       []
      ],
      "insertparagraph-with-white-space-style.tentative_white-space=pre-line_command=insertText-expected.txt": [
-      "b32c16d94bcf3e93cd5992a2572480c9de9d00cf",
+      "928ac6685145189a7bec8d43908c2c04748f85b1",
       []
      ],
      "insertparagraph-with-white-space-style.tentative_white-space=pre-wrap_command=insertParagraph-expected.txt": [
-      "0f6dfca232047aed6b0515e6fd0bc008eacb059b",
+      "b8dee8a31017e738c49dd783eda312f028637584",
       []
      ],
      "insertparagraph-with-white-space-style.tentative_white-space=pre-wrap_command=insertText-expected.txt": [
-      "0f6dfca232047aed6b0515e6fd0bc008eacb059b",
+      "b8dee8a31017e738c49dd783eda312f028637584",
       []
      ],
      "insertparagraph-with-white-space-style.tentative_white-space=pre_command=insertParagraph-expected.txt": [
-      "1ff43946d13d1fbf234c4d0bf4c5e94d9cb6422d",
+      "c20f6012561ec768c98359d61f2f422e3d314161",
       []
      ],
      "insertparagraph-with-white-space-style.tentative_white-space=pre_command=insertText-expected.txt": [
-      "1ff43946d13d1fbf234c4d0bf4c5e94d9cb6422d",
+      "c20f6012561ec768c98359d61f2f422e3d314161",
       []
      ],
      "join-different-white-space-style-left-line-and-right-paragraph.html.ini": [
@@ -355290,147 +355349,147 @@
       []
      ],
      "join-different-white-space-style-paragraphs_method=backspace_left-white-space=normal_right-white-space=nowrap-expected.txt": [
-      "c51f49c988e0fa8a9021c584bf7b69f6890924f0",
+      "a4a9d155a50a2b7697b736ca5caec3f0536387ad",
       []
      ],
      "join-different-white-space-style-paragraphs_method=backspace_left-white-space=normal_right-white-space=pre-line-expected.txt": [
-      "9e994b9bab7cd47228b12ed9f3294770da8bc2b5",
+      "565a1c0985957e3eef036fef7da25119daa0f5b3",
       []
      ],
      "join-different-white-space-style-paragraphs_method=backspace_left-white-space=normal_right-white-space=pre-wrap-expected.txt": [
-      "55b01ae94bf28be0ab9963d82ed74e9c2d93f9e8",
+      "874798e302ed0fe75747a1f67e370b32dc9ab7a5",
       []
      ],
      "join-different-white-space-style-paragraphs_method=backspace_left-white-space=nowrap_right-white-space=normal-expected.txt": [
-      "112c6732154d8c319f51f16ebdd973e9521dd0a8",
+      "73b1693151362a5c886478bb1fa61eb64fa1a24b",
       []
      ],
      "join-different-white-space-style-paragraphs_method=backspace_left-white-space=nowrap_right-white-space=pre-expected.txt": [
-      "665a3d6483090f36a3befb7a22168dbfe7340783",
+      "38bfcfb03c739c23ab5cc7bd919b791da163090f",
       []
      ],
      "join-different-white-space-style-paragraphs_method=backspace_left-white-space=pre-line_right-white-space=normal-expected.txt": [
-      "b0282f64ce39c86e56ec9d1bf539832b8801af8d",
+      "aab2bafc07469eec35f773425814c95a2350fc7c",
       []
      ],
      "join-different-white-space-style-paragraphs_method=backspace_left-white-space=pre-line_right-white-space=pre-wrap-expected.txt": [
-      "a99654346eebc80ceedbcfe1d1074e4a98f6b4e0",
+      "74da83da3f87e98f62b9ba58ffca76ca54a89505",
       []
      ],
      "join-different-white-space-style-paragraphs_method=backspace_left-white-space=pre-wrap_right-white-space=normal-expected.txt": [
-      "2fb4ceb9188a44907c79379e790cd885d5978a13",
+      "ad689c1d7819eb342fb50a6044a684f3b8aa603e",
       []
      ],
      "join-different-white-space-style-paragraphs_method=backspace_left-white-space=pre-wrap_right-white-space=pre-expected.txt": [
-      "3c1b52aed8cf5a0dec46c581c11db277a433ee48",
+      "76581cd4d65ef37509a0ff46c69ca643497f9c76",
       []
      ],
      "join-different-white-space-style-paragraphs_method=backspace_left-white-space=pre-wrap_right-white-space=pre-line-expected.txt": [
-      "18dccde0d696511ef53941dd88f567a78ab1d67e",
+      "6f3e7a8594ebd9ba5195ba53e68930533c4bae95",
       []
      ],
      "join-different-white-space-style-paragraphs_method=backspace_left-white-space=pre_right-white-space=nowrap-expected.txt": [
-      "48837cc9dc35edec9e425c99856120e779f1d38a",
+      "fc82e925e110857128d3e9555b20c7998418ff61",
       []
      ],
      "join-different-white-space-style-paragraphs_method=backspace_left-white-space=pre_right-white-space=pre-wrap-expected.txt": [
-      "01d6b2cb36f825cd811e29870a3fc06361a83efd",
+      "feab26edf6447b6e6d3e2f0118cccf6e5065e80d",
       []
      ],
      "join-different-white-space-style-paragraphs_method=forwarddelete_left-white-space=normal_right-white-space=nowrap-expected.txt": [
-      "8ba3ff61880ccc80f4db4febc02d89adfa984e8f",
+      "7a54dfef8ce27671e21027a2d45f6667c337a023",
       []
      ],
      "join-different-white-space-style-paragraphs_method=forwarddelete_left-white-space=normal_right-white-space=pre-line-expected.txt": [
-      "703f17d847c1d1b613d4df5fc8ec7d2218f04124",
+      "ffdd6a063d3f16e3a85dbe8c92f8b56d22fe1753",
       []
      ],
      "join-different-white-space-style-paragraphs_method=forwarddelete_left-white-space=normal_right-white-space=pre-wrap-expected.txt": [
-      "076531357c176c2ba3b85a42b0751cc1e48307d0",
+      "6e4690c0b64c996eeb742a1e95a823532b37c893",
       []
      ],
      "join-different-white-space-style-paragraphs_method=forwarddelete_left-white-space=nowrap_right-white-space=normal-expected.txt": [
-      "28cd96c46bf12ee3b3cae8d4b8d8a3576fc71e38",
+      "eb27c80c0c7ef415f1456568fa0d7d375817e479",
       []
      ],
      "join-different-white-space-style-paragraphs_method=forwarddelete_left-white-space=nowrap_right-white-space=pre-expected.txt": [
-      "acff8637214deddad29dd74a0feb59b4bcf16f10",
+      "12e217e7dc36b733d613531cad66ac16a9cb21ed",
       []
      ],
      "join-different-white-space-style-paragraphs_method=forwarddelete_left-white-space=pre-line_right-white-space=normal-expected.txt": [
-      "bb3ed1f316877e28448638c5068f5c92f415ceac",
+      "f6b9d243fd631760d92a9e9264334d6fea05aef9",
       []
      ],
      "join-different-white-space-style-paragraphs_method=forwarddelete_left-white-space=pre-line_right-white-space=pre-wrap-expected.txt": [
-      "b75f410acb65a6f27bf25a01e174e7098c87668a",
+      "3dbefebeef9f8aeabca8c206d8245e0886bc66dd",
       []
      ],
      "join-different-white-space-style-paragraphs_method=forwarddelete_left-white-space=pre-wrap_right-white-space=normal-expected.txt": [
-      "29c71489e9f088b64df82ff7dfc443eb412ea0cb",
+      "00e2baaa8e96b22c242825a06e82eaa46912dde0",
       []
      ],
      "join-different-white-space-style-paragraphs_method=forwarddelete_left-white-space=pre-wrap_right-white-space=pre-expected.txt": [
-      "93207e5eb1531b214283d6d0237616b241ae23e9",
+      "4978049ce3d547b518470cd843fd918cde202ef8",
       []
      ],
      "join-different-white-space-style-paragraphs_method=forwarddelete_left-white-space=pre-wrap_right-white-space=pre-line-expected.txt": [
-      "7f9148b593bdde833b2c6cdf663d0e4a95537b78",
+      "26cdec8dc1470543083b1ea98ca35f101d2e0533",
       []
      ],
      "join-different-white-space-style-paragraphs_method=forwarddelete_left-white-space=pre_right-white-space=nowrap-expected.txt": [
-      "ae57f8b93f6512886f550b721c15d27cb4794a55",
+      "ae9059c0a69d0330218ebbf2024c5dfcb890704e",
       []
      ],
      "join-different-white-space-style-paragraphs_method=forwarddelete_left-white-space=pre_right-white-space=pre-wrap-expected.txt": [
-      "1f0dc96a9c6eeb06d31c84e904dbdc1f9e64ce42",
+      "8e028254113bc0f9ed65d6405a726c1f79e0ffac",
       []
      ],
      "join-different-white-space-style-paragraphs_method=select-boundary_left-white-space=normal_right-white-space=nowrap-expected.txt": [
-      "94068a107b09446c0f52eac9ad4494497820c81b",
+      "c2702df4dbf05521d3c88bc5d27935511c5ad3d9",
       []
      ],
      "join-different-white-space-style-paragraphs_method=select-boundary_left-white-space=normal_right-white-space=pre-line-expected.txt": [
-      "437c55ab4d54169dd760fc6fceb4ba8991ca6258",
+      "2d0dc1de09fda8329de51e7191a61b61ed93323f",
       []
      ],
      "join-different-white-space-style-paragraphs_method=select-boundary_left-white-space=normal_right-white-space=pre-wrap-expected.txt": [
-      "2bdac31f16b97fc9fdc01c72074b90d628bd8e73",
+      "fc4de2e3df6c3c688591adf39e866c64ae7cf97e",
       []
      ],
      "join-different-white-space-style-paragraphs_method=select-boundary_left-white-space=nowrap_right-white-space=normal-expected.txt": [
-      "eeffe18ecd0a187c4f420ce3dbf5b8fe933cf420",
+      "17aaf765622b73406592970fb9048731d74de696",
       []
      ],
      "join-different-white-space-style-paragraphs_method=select-boundary_left-white-space=nowrap_right-white-space=pre-expected.txt": [
-      "dc9222d55006e1ceb4479d1281b9354ed6832a71",
+      "8faf65a7317993492461d84962d665d351c99dd8",
       []
      ],
      "join-different-white-space-style-paragraphs_method=select-boundary_left-white-space=pre-line_right-white-space=normal-expected.txt": [
-      "f034f3a67391625385f0c06211fa95bb30b0e780",
+      "e0c273b9257d80dbb481f09aed196911f5ed3e10",
       []
      ],
      "join-different-white-space-style-paragraphs_method=select-boundary_left-white-space=pre-line_right-white-space=pre-wrap-expected.txt": [
-      "1626295a3ccb54f70367b867650f573daaf74542",
+      "045af2bd273186e4000b9d575ad34e3b450bd78c",
       []
      ],
      "join-different-white-space-style-paragraphs_method=select-boundary_left-white-space=pre-wrap_right-white-space=normal-expected.txt": [
-      "c66d0bc40059e4ece8e92da6367a4f029a1e8834",
+      "f8f90f60a357d27bc226a3ca4f4f6b6af2a002b4",
       []
      ],
      "join-different-white-space-style-paragraphs_method=select-boundary_left-white-space=pre-wrap_right-white-space=pre-expected.txt": [
-      "85d36c2637a785efa44f04fd261a44a53bf092da",
+      "ed14c3eda5e7d1dfae3e9683a7d60991cbafd11c",
       []
      ],
      "join-different-white-space-style-paragraphs_method=select-boundary_left-white-space=pre-wrap_right-white-space=pre-line-expected.txt": [
-      "46bad199bc987c2012e5d8106bf5098f41502f4b",
+      "e4c02e1507408283371a775a23edb49365eef48f",
       []
      ],
      "join-different-white-space-style-paragraphs_method=select-boundary_left-white-space=pre_right-white-space=nowrap-expected.txt": [
-      "708f4697c18afa05190c5a3d97c241853a933ed3",
+      "c201dda56893ed7faed7bde70374206d2cc4b7ae",
       []
      ],
      "join-different-white-space-style-paragraphs_method=select-boundary_left-white-space=pre_right-white-space=pre-wrap-expected.txt": [
-      "dd0debe70471584855545c4d76deb61c20189b83",
+      "a2f0a34d1eaf974bc3b82a4d5693c5011f55123e",
       []
      ],
      "join-pre-and-other-block.html.ini": [
@@ -355438,7 +355497,7 @@
       []
      ],
      "link-boundaries-insertion-expected.txt": [
-      "8f1664dddb31d10b8eff253a2304f280d023b668",
+      "d4eff9d116410742b7a62e406decbc75c8ffe492",
       []
      ],
      "link-boundaries-insertion.html.ini": [
@@ -355446,7 +355505,7 @@
       []
      ],
      "restoration-expected.txt": [
-      "a8d74b3eb1e0a59f0c5b5989c60349720487a00b",
+      "004d4cbb499145fc2b5377e9c4a7099b7e41111f",
       []
      ],
      "restoration.html.ini": [
@@ -355458,7 +355517,7 @@
       []
      ],
      "selectall-in-editinghost-expected.txt": [
-      "8feb63d41d883a7b8fb1736348cf6d3cf22bf0c6",
+      "680025b8ac06eec5a8b26010589060c278e93b4e",
       []
      ],
      "selectall-in-editinghost.html.ini": [
@@ -355466,7 +355525,7 @@
       []
      ],
      "selectall-without-focus-expected.txt": [
-      "59bb588da2d7edb0b800b5d4c514679818f55369",
+      "891ef65cb2ead2df52886bc37054407a07115ae3",
       []
      ],
      "selectall-without-focus.html.ini": [
@@ -355478,11 +355537,11 @@
       []
      ],
      "typing-around-link-element-after-joining-paragraphs_action=Backspace-expected.txt": [
-      "616c2502e1554dab795ce38cacbabd92919767d4",
+      "ca28dfe9b034b8ce02ec2baf937210fca373121d",
       []
      ],
      "typing-around-link-element-after-joining-paragraphs_action=Delete-expected.txt": [
-      "10fbea7d114cf3ce03130b7b51185eaf57337a5a",
+      "c3c9e5e821e2bc7bcb3dd9934784f3f6cf16cc75",
       []
      ],
      "typing-around-link-element-at-collapsed-selection.tentative.html.ini": [
@@ -355490,19 +355549,19 @@
       []
      ],
      "typing-around-link-element-at-collapsed-selection.tentative_target=DesignMode-expected.txt": [
-      "742c413805ff50e8e8e64d60aba233a5459cb6f7",
+      "bbe92b66831da8ae81eee3fc9a2569fd84b219da",
       []
      ],
      "typing-around-link-element-at-collapsed-selection.tentative_target=DesignMode_child=b-expected.txt": [
-      "a37ba54e691622ab44d71449d5e73a33db6397c1",
+      "ad8b7e52027567ad1e36d7cc454fcc01a5cd86ff",
       []
      ],
      "typing-around-link-element-at-collapsed-selection.tentative_target=DesignMode_parent=b-expected.txt": [
-      "e1650ef1273746daa7e436c57a271bf8d33f5183",
+      "fc28545bbbd440bd2274591418d95e79e5802b91",
       []
      ],
      "typing-around-link-element-at-collapsed-selection.tentative_target=DesignMode_parent=b_child=i-expected.txt": [
-      "3b5409670c382c6cbef8e32e3d4007545ef7cf35",
+      "7b9312f58414de58600d2a8c204171e2439f3f39",
       []
      ],
      "typing-around-link-element-at-non-collapsed-selection.tentative.html.ini": [
@@ -355510,23 +355569,23 @@
       []
      ],
      "typing-around-link-element-at-non-collapsed-selection.tentative_target=DesignMode-expected.txt": [
-      "1fcba89f7c02a1c2d3ede9d783f5053debb9fb9a",
+      "1f08ed4d5ee478f9d7b75a11a5df358b324d95f0",
       []
      ],
      "typing-around-link-element-at-non-collapsed-selection.tentative_target=DesignMode_child=b-expected.txt": [
-      "77f3c248657dece3c668f361514df098471c21f7",
+      "bdd0056185e942d816c5e1f8682827ce3828b8a6",
       []
      ],
      "typing-around-link-element-at-non-collapsed-selection.tentative_target=DesignMode_parent=b-expected.txt": [
-      "d41cb6d72e1ec3cb1fa4838a70bbaaa337ad588a",
+      "94114e42036d9781b83939ee9413095f50ad4cdf",
       []
      ],
      "typing-around-link-element-at-non-collapsed-selection.tentative_target=DesignMode_parent=b_child=i-expected.txt": [
-      "1770c575a0145cda53407c611084336b1d9b1c02",
+      "c688ae42571cdcd4be12ee5daebcdc5dc3891871",
       []
      ],
      "typing-space-in-editable-button.tentative-expected.txt": [
-      "99ebd5af13c499d804a75e169f0fec7af2df2379",
+      "60f6d2ad98403a1230d43f2348d3b02e72c2c42f",
       []
      ],
      "typing-space-in-editable-button.tentative.html.ini": [
@@ -355534,7 +355593,7 @@
       []
      ],
      "typing-space-in-editable-summary.tentative-expected.txt": [
-      "1d1111c0c3f69589ed7442aaf1461bf3b50f624a",
+      "3d827859c8ae06d12b0d3fcdc92740e110502de2",
       []
      ],
      "typing-space-in-editable-summary.tentative.html.ini": [
@@ -355544,7 +355603,7 @@
     },
     "run": {
      "backcolor-expected.txt": [
-      "a29f88f6737cc8f9f7c7d44007f1df00e875b360",
+      "1210f039da41c8e830f757ce029740db49eb6249",
       []
      ],
      "backcolor.html.ini": [
@@ -355556,59 +355615,47 @@
       []
      ],
      "bold_3001-last-expected.txt": [
-      "fa6898d217699a1b777052b0cf07d07733f43847",
+      "3e2a022fa0d639030e5c3ac0f5e931479a4be9e1",
       []
      ],
      "createlink-expected.txt": [
-      "4865ecf24d113b2969dce718a2561f15dbd665ae",
+      "f3dd19a7a62ac919b337e2ca53330c7a816a8627",
       []
      ],
      "createlink.html.ini": [
       "a037e69d55ada045e764997b276b33bd7b2f222a",
       []
      ],
-     "delete-expected.txt": [
-      "ca99aaf78f305842ff699084aa812a4a5d4537e8",
-      []
-     ],
      "delete.html.ini": [
       "dfde04d67ae924cd8d5878546a943f790f075ba1",
       []
      ],
      "delete_1-1000-expected.txt": [
-      "fcfe40546453a72ba733484998b311dee0df872b",
+      "d1a7944eb028dd32717b25b1292bf4f90b75b0c6",
       []
      ],
      "delete_2001-3000-expected.txt": [
-      "b7e34a81b4db237a444b8e93f97f6a04ad985f37",
+      "dc8b7da1302b5910e0c8d79a97d8a6d42e1c97c7",
       []
      ],
      "delete_3001-4000-expected.txt": [
-      "b46b5048fba6d82ce4cee01e31e39beb923d4e0a",
+      "73dcbb2170b20992da00b960dec6ec323c663835",
       []
      ],
      "delete_4001-5000-expected.txt": [
-      "a3d2198da70b27d1f6a10c86e767b48d5c66c4ff",
+      "628b3f40eee096a5a7ba2bd0222b791c1dcf1965",
       []
      ],
      "delete_5001-6000-expected.txt": [
-      "699e4ef25de0e47e4ed2cdd217db617e5fac390e",
+      "baac17ce9c04a8b37e182fabeb4a58fc6f204e8c",
       []
      ],
      "delete_6001-7000-expected.txt": [
-      "473aea3778cbec1bda0ae362449fc916e84afcab",
-      []
-     ],
-     "delete_6001-last-expected.txt": [
-      "e8432ad328f421dc8619273a926651ee4170913b",
+      "dc7b78f7f24478d31af6cb06865ef60ec07b909d",
       []
      ],
      "delete_7001-last-expected.txt": [
-      "de90821c16cd263bf876e31077bd39a2da12d172",
-      []
-     ],
-     "fontname-expected.txt": [
-      "368bd6bd2d11ccb79cc7e78acbf4c468ea820ae6",
+      "55443b4b1301ecb4870116681b0cb9fa5fbe0d1d",
       []
      ],
      "fontname.html.ini": [
@@ -355616,19 +355663,15 @@
       []
      ],
      "fontname_1-1000-expected.txt": [
-      "319e6c3bfa64cc736b399d3bd8df86889cb9e977",
+      "c48cc0396ff495a5282ea9b0e98ac9b1d16e5c04",
       []
      ],
      "fontname_1001-2000-expected.txt": [
-      "9a4438582c599010349e995abf25d346bbe38dc4",
+      "0cd85ce4ec4d66e412ec321fc54f9d07475628e3",
       []
      ],
      "fontname_2001-last-expected.txt": [
-      "143171bb964dfcf4628de0b81629ebd817d54bc5",
-      []
-     ],
-     "fontsize-expected.txt": [
-      "a42af6dd884818083b53a21f8eb796db03d81ae6",
+      "c6c577a2ad4982fd13b0cbba035895d0c627f388",
       []
      ],
      "fontsize.html.ini": [
@@ -355636,39 +355679,27 @@
       []
      ],
      "fontsize_1-1000-expected.txt": [
-      "e01ad861c16d229d87c543b860d51ec5c9e518c3",
+      "2b98d16054da8624b17834a43f2cb89f33ed745e",
       []
      ],
      "fontsize_1001-2000-expected.txt": [
-      "d8455b06ace636d621cca13e551877c5b6b589b6",
+      "27c0454497a918c4c8276a2ad913f0e63113b2fd",
       []
      ],
      "fontsize_2001-last-expected.txt": [
-      "8e9d63a78aad6ef2791f2327897238dc3e57e0d3",
-      []
-     ],
-     "forecolor-expected.txt": [
-      "9eae526c002e50046711e1a726f34e931f293f13",
+      "05b65dc12b16bc6091ff42639cf2c3b99ab1a026",
       []
      ],
      "forecolor.html.ini": [
       "0e9aaaf9dacfbcbd2bdf554b4cf11bcd6f2c1fbb",
       []
      ],
-     "forecolor_1-1000-expected.txt": [
-      "e6ab8fef3163a4952d665106f70f96eee3b8c76b",
-      []
-     ],
      "forecolor_1001-2000-expected.txt": [
-      "5e20e78791743e48e62b1781ea803fcba389f677",
+      "b593b39658cb2cb01c3ce410e0c7ca059fc0789e",
       []
      ],
      "forecolor_2001-last-expected.txt": [
-      "d550fce53264b62d3c72a8736e4119d4aeb01c25",
-      []
-     ],
-     "formatblock-expected.txt": [
-      "efeea67a55d8001bbf545b8a127033527288e753",
+      "955801f776617ce74f291fb12df493f7a8624abb",
       []
      ],
      "formatblock.html.ini": [
@@ -355676,27 +355707,23 @@
       []
      ],
      "formatblock_1-1000-expected.txt": [
-      "5f548f92b5c79a43309c37738253ae4b3ac8eba4",
+      "2b3bd42723b1c54196146ca75ed43037f076e75f",
       []
      ],
      "formatblock_1001-2000-expected.txt": [
-      "70b736bf9412f84c4e652ddab0db6b349ddb3116",
+      "cf571efe66ddc7432e96a682728962691c58830d",
       []
      ],
      "formatblock_2001-3000-expected.txt": [
-      "a2b5025084b2df48efb4a0fda1f91102c8e63964",
+      "634b7f01b61ce07f89495008ba4ef497401a41c2",
       []
      ],
      "formatblock_3001-4000-expected.txt": [
-      "79114485b9a3ce1688a6550326df91dcec1acdbd",
+      "6b32d88b69f980b1ae4fc37d163c029f38292546",
       []
      ],
      "formatblock_4001-last-expected.txt": [
-      "1550aecaf8e8cd03c1002963883e7cf49f46c5db",
-      []
-     ],
-     "forwarddelete-expected.txt": [
-      "ae737fe8f7105379cb8bbd81fdd12b229a078bbd",
+      "c3e528673629a57e0526774c12a5201ffde7924b",
       []
      ],
      "forwarddelete.html.ini": [
@@ -355704,43 +355731,39 @@
       []
      ],
      "forwarddelete_1-1000-expected.txt": [
-      "447a710d3cb9ecda220337ab15519182c13de559",
+      "2e13bad3d1bdee682b53cc8260718c47f8e06f00",
       []
      ],
      "forwarddelete_1001-2000-expected.txt": [
-      "ed1ddf353a041f8b076c03b4fe1ef380bc8dc3cd",
+      "6212e8e18793014e9c73c0b4e5fdd0eef48eb7fb",
       []
      ],
      "forwarddelete_2001-3000-expected.txt": [
-      "a35fc9c5d6cb7e4a86db5fe593ab8d89a8641533",
+      "01d3419245143fb0f112f52603125c93f92d71d6",
       []
      ],
      "forwarddelete_3001-4000-expected.txt": [
-      "b41fd0e28780c420e8ef378a734e41a02ac90500",
+      "eb53f5a10a818d068871363ce3606c967d043cde",
       []
      ],
      "forwarddelete_4001-5000-expected.txt": [
-      "6c16fef7e1ef2bdf97269b69d6f2be58c3d40c09",
+      "efcafa7aa2e39d44b40f8911760cdec4d64af069",
       []
      ],
      "forwarddelete_5001-6000-expected.txt": [
-      "e4d171b105114b634553bb41106847f6147d4321",
+      "f585c75e305768259dd9700f3e5eefa3cdbc7f80",
       []
      ],
      "forwarddelete_6001-7000-expected.txt": [
-      "581b7777980b439e6891fc4136c355126576a4bf",
-      []
-     ],
-     "forwarddelete_6001-last-expected.txt": [
-      "15ce25f101bd31659cd400950d523295f7e38e26",
+      "afcf62a00bf7d57c8a11c255a8799ba93b6b359c",
       []
      ],
      "forwarddelete_7001-last-expected.txt": [
-      "b7980274e70f8bc608472a2594b221f223370ade",
+      "3fb0abbbd8863a3f024c796cbfef2e1871a542c5",
       []
      ],
      "hilitecolor-expected.txt": [
-      "60784cdbac66f6030f0aae6fca20a3cc97668fa6",
+      "429032df316dc084e01383805c233a665b930a2d",
       []
      ],
      "hilitecolor.html.ini": [
@@ -355748,7 +355771,7 @@
       []
      ],
      "indent-expected.txt": [
-      "355ee1b13332dcb80ec3ce112d287a584ea073b0",
+      "bfa0cb63e100c24c15f5906b5cd6f6cbcc45edff",
       []
      ],
      "indent.html.ini": [
@@ -355756,7 +355779,7 @@
       []
      ],
      "insert-list-items-in-table-cell-expected.txt": [
-      "f2dc4c641be0322d8d5bfa9e5d0cc12ec16cec44",
+      "f3c4339340df96067c14e6f34dc545f764888a9f",
       []
      ],
      "insert-list-items-in-table-cell.html.ini": [
@@ -355764,7 +355787,7 @@
       []
      ],
      "inserthorizontalrule-expected.txt": [
-      "330fbd74381880e47e2977c1faa7b0033099a913",
+      "849cffbe951da711aa4b346e7608d75d5707ed2d",
       []
      ],
      "inserthorizontalrule.html.ini": [
@@ -355772,7 +355795,7 @@
       []
      ],
      "inserthtml-expected.txt": [
-      "8629d0ac24d9321ffe065d0ec6b3dff084a721c6",
+      "d57e5681eead4c4b08a464cc3a3cbbf1fe8811a6",
       []
      ],
      "inserthtml.html.ini": [
@@ -355780,7 +355803,7 @@
       []
      ],
      "insertimage-expected.txt": [
-      "64584ff9b6ec49990054bfb672c5f87d89c159f0",
+      "7694082981ab89336efc3de74e83b44c02919b2e",
       []
      ],
      "insertimage.html.ini": [
@@ -355788,31 +355811,23 @@
       []
      ],
      "insertlinebreak-expected.txt": [
-      "7cc8915477a736717a129a526764dab1bb8226d2",
+      "5e970c913e3361126804c71994a19824cf72c853",
       []
      ],
      "insertlinebreak.html.ini": [
       "8e2e7cb918e4494adf499818da365aa04080440e",
       []
      ],
-     "insertorderedlist-expected.txt": [
-      "abcefa3bcbf38eaa22c12a69bd261192ee9d9619",
-      []
-     ],
      "insertorderedlist.html.ini": [
       "83923252dfcc52626ab2b1c0608e6f8008006370",
       []
      ],
      "insertorderedlist_1-1000-expected.txt": [
-      "1907bc5203bba0227e76349db01589e034d2d195",
+      "5edada2d9e75e67fda504c8c10e4f6ee45b3ae76",
       []
      ],
      "insertorderedlist_1001-last-expected.txt": [
-      "158fc5aa13d20d37bd3fbceeab90d64836047037",
-      []
-     ],
-     "insertparagraph-expected.txt": [
-      "f26eb9c80a8ef961c5d8adf5cef78dc734f61e64",
+      "de7aee8c45a80b0ff77afac2ec5bd51097e31644",
       []
      ],
      "insertparagraph.html.ini": [
@@ -355820,35 +355835,31 @@
       []
      ],
      "insertparagraph_1-1000-expected.txt": [
-      "474ffa54a7714c62868ed28c113f04c8f8e776fe",
+      "ded6227279c63c44c9add6e2815bf8a497e83c9e",
       []
      ],
      "insertparagraph_1001-2000-expected.txt": [
-      "10e046462bdd0097863822aee484a0b7ea31183f",
+      "4918f4dee4081ca7e97a99a475887382f299f7c4",
       []
      ],
      "insertparagraph_2001-3000-expected.txt": [
-      "9e916dd47bcc8c948c28a8e2cbf4ad34172a6fc8",
+      "22aeee531fd42053964adfd31f60770169a0d61d",
       []
      ],
      "insertparagraph_3001-4000-expected.txt": [
-      "13b39c6b0ca61b628ecb810307fe9a38d6bb3bea",
+      "e5dfc7dc3033816f7eed0adfcb450487cbfde682",
       []
      ],
      "insertparagraph_4001-5000-expected.txt": [
-      "71d7c450df7a96b287147d6002218d3fce0cd64e",
+      "98557d34b16b74e050f0f7bad60c539935a15c8a",
       []
      ],
      "insertparagraph_5001-6000-expected.txt": [
-      "53888f9f38247ae19d2404fc3c3ff8b7732d51e9",
+      "98d097e3be823e76776a82cf37a127e46fdc9e9a",
       []
      ],
      "insertparagraph_6001-last-expected.txt": [
-      "23fdfdbfb30f0e61ec83773a1c8a829617c16291",
-      []
-     ],
-     "inserttext-expected.txt": [
-      "58fa611b76771bd281ab597538e5f65ae8ff68da",
+      "e2db4af5226ab1f2a42cdd3d3c42d2d6d84d849a",
       []
      ],
      "inserttext.html.ini": [
@@ -355856,19 +355867,11 @@
       []
      ],
      "inserttext_1-1000-expected.txt": [
-      "7184cfd8d5a1ac7eb46a9383b8d6ebd2babcc09a",
+      "89d8a734c16d0d908c53b936d89d7c08b79aa0c2",
       []
      ],
      "inserttext_1001-2000-expected.txt": [
-      "c88d4a2d5a2e17a34604e8a5735e2be486b06323",
-      []
-     ],
-     "inserttext_2001-last-expected.txt": [
-      "2515b50422d57a48840f2e686435483c2aa0c07c",
-      []
-     ],
-     "insertunorderedlist-expected.txt": [
-      "2a9fb242863312695e01b64938e3aea093022726",
+      "f990a095569d7943d371558d9a5fe4b96a42e0e2",
       []
      ],
      "insertunorderedlist.html.ini": [
@@ -355876,15 +355879,15 @@
       []
      ],
      "insertunorderedlist_1-1000-expected.txt": [
-      "76a7180065db0dda311a14029c4a9d634088fb12",
+      "1210d25c2219532ae730b5429d48673bcb0317a3",
       []
      ],
      "insertunorderedlist_1001-2000-expected.txt": [
-      "5f4d99f57996b0aa173eb950cd706cd3cfdb5537",
+      "5d0e51b5759df6d23f93f24625e86b89df361e6f",
       []
      ],
      "insertunorderedlist_2001-last-expected.txt": [
-      "975cf9b4ecfdbb88aed6748a2ae829dbbebf57d6",
+      "0f14c0247cf31f91abcc7dfc6d67b47ad09ded83",
       []
      ],
      "italic.html.ini": [
@@ -355892,7 +355895,7 @@
       []
      ],
      "italic_2001-last-expected.txt": [
-      "b04b0abd2f8beeba796f11b63285bf53cec2bea4",
+      "734ed3b6207241659e6130c0164d1cf8160876e3",
       []
      ],
      "justifycenter.html.ini": [
@@ -355900,15 +355903,15 @@
       []
      ],
      "justifycenter_1-1000-expected.txt": [
-      "c487aff34e95f5686f1a3dbfe6cd13a66014b932",
+      "48246ac78071df3f0f9af7d739cb85f26feb26c3",
       []
      ],
      "justifycenter_3001-4000-expected.txt": [
-      "914fe275a0a58bfcb38da778e0054c61b346330b",
+      "dafee9c8af32cc8cdde63b313f5e230aab057bf3",
       []
      ],
      "justifycenter_6001-last-expected.txt": [
-      "f04cff0502acd9b2deab319c2798dddf4e4a8c5f",
+      "8f7faea9d3af135df97dd29e49fea174b438b0c7",
       []
      ],
      "justifyfull.html.ini": [
@@ -355916,15 +355919,11 @@
       []
      ],
      "justifyfull_1-1000-expected.txt": [
-      "526554204f0055442d50a6072e33a170b1ed16f0",
+      "a6e6ce5affcb4c4dee77320b046260e57a9d744a",
       []
      ],
      "justifyfull_3001-4000-expected.txt": [
-      "ead980a8efa68cda458e60a786d19216607793e2",
-      []
-     ],
-     "justifyleft-expected.txt": [
-      "9179dc65d880805c6f65f86946dd4379c69f38c5",
+      "d4c4f265e00e88b60d20300406e914fdb8291c03",
       []
      ],
      "justifyleft.html.ini": [
@@ -355932,15 +355931,15 @@
       []
      ],
      "justifyleft_1-1000-expected.txt": [
-      "6d5f06632030297b80122551348afbec4986b84f",
+      "d60f0df511e25ba602b69cd0f8885a476dee3abd",
       []
      ],
      "justifyleft_1001-2000-expected.txt": [
-      "db45f952d56d7bbb2693c0dbfaeeefc97532f2cb",
+      "59f2efa9a6bea075ae26b6f1c83a419ee0184e78",
       []
      ],
      "justifyleft_2001-last-expected.txt": [
-      "38fcc2eb96118a775473c4e324555113088c85c0",
+      "3c2e526fd920127fa4b5d245e6211d151f30118b",
       []
      ],
      "justifyright.html.ini": [
@@ -355948,75 +355947,63 @@
       []
      ],
      "justifyright_1-1000-expected.txt": [
-      "cef9dfe65cfec5847668cdac3d52ed59b8d55a2b",
+      "033f1fe6b34feb368b1dbee57037d6f7e1d78d5d",
       []
      ],
      "justifyright_3001-4000-expected.txt": [
-      "a03176b9880655577bf674d15994a55f98937228",
-      []
-     ],
-     "justifyright_4001-last-expected.txt": [
-      "4e79c28ca7083c4cbb4d0ac018cbaf77a760b652",
+      "f7cd955b020af6f7b7be6ca591f5adab9220b084",
       []
      ],
      "misc-expected.txt": [
-      "0d601ee3934bd605b61d3964fe81be2316b40ac1",
+      "24316864133e448d77f716e521a00e474b974da0",
       []
      ],
      "misc.html.ini": [
       "d3442d59fa467fa8824fd90cd4970771eb78165f",
       []
      ],
-     "multitest-expected.txt": [
-      "0b485bf315e8e98cc7b796579b86f3be9469953e",
-      []
-     ],
      "multitest.html.ini": [
       "3d43df3658c8b2b678ad54216289f8e3967909bf",
       []
      ],
      "multitest_1-1000-expected.txt": [
-      "54857049aa64ed87bb7a643ebbfc2550074c4dd9",
+      "7c486f3c920b783df7b0b5748a98a7986319ead0",
       []
      ],
      "multitest_1001-2000-expected.txt": [
-      "a078f01e86412a722ea3c5e5788c6a06abf92702",
+      "eb7926048cb0726e6e2ad092a320c95486983083",
       []
      ],
      "multitest_2001-3000-expected.txt": [
-      "6f5d84e234b25687b9902a5d706294f0da894968",
+      "fb21dfc3009f31cf0051b1cbf9f25b2b41ce0c9b",
       []
      ],
      "multitest_3001-4000-expected.txt": [
-      "5665567a7c675f5c9879ac9e63678d8e7695d902",
+      "6de4aba2048dfeeb488c5b0cb01f3025b1e031b5",
       []
      ],
      "multitest_4001-5000-expected.txt": [
-      "119fde11bc120e45d97add438b3ef9199a11357c",
+      "4ea7a951663be9f555bbd1219cc8e6ea2a584c98",
       []
      ],
      "multitest_5001-6000-expected.txt": [
-      "7ec3428e0ac7f4b4bc152ed5adda9fac5a987b5b",
+      "1d6cfe3aab21811d1fbc3b2e4d59d7d30175ae78",
       []
      ],
      "multitest_6001-7000-expected.txt": [
-      "f1edbe2c1494cad58369e986a0277daaa4895094",
+      "2b4b87982c27855dbf52132eeabaa205954c6535",
       []
      ],
      "multitest_7001-8000-expected.txt": [
-      "195a104ed3bfd3b3ef8ffe4ded3cdbc48a9487c6",
+      "ee3365ef2c3e24febe24bb079e9167156c1d300a",
       []
      ],
      "multitest_8001-9000-expected.txt": [
-      "dc70a74c099106d635c485f5653723f11e2f46a3",
+      "4c75d3b06cd3d3d4e3badda12447ee5ed5f6dacf",
       []
      ],
      "multitest_9001-last-expected.txt": [
-      "fd0d1441c35223cc29f0192cabfc4592e1f6434d",
-      []
-     ],
-     "outdent-expected.txt": [
-      "75d313500151ff082fcac4a83abc5b0e859c9ac9",
+      "0e4485316c77799acdd7c5a62703283fe6e3d8fa",
       []
      ],
      "outdent.html.ini": [
@@ -356024,19 +356011,19 @@
       []
      ],
      "outdent_1-1000-expected.txt": [
-      "2d19436750b3a078de134f783edcf40b6b8f027c",
+      "1f65c854dee77526da0fa8d5b21b284e39224fc6",
       []
      ],
      "outdent_1001-2000-expected.txt": [
-      "e9cce26d26d3cb3796054105cda03d5a1f0b4a0e",
+      "2f6acce4060178e0d457b620249bc8de050b6f8b",
       []
      ],
      "outdent_2001-last-expected.txt": [
-      "f25b169c55873cebd55561b5b7da36f6490880a9",
+      "8488646b3327633111c1fa555b1424cf2f8a6627",
       []
      ],
      "removeformat-expected.txt": [
-      "b7d784a786c5a12b7c1b8e492cb363b2b57a79ee",
+      "a3021dda3625b1d0404bc5a2b5d42d91b8dc8d74",
       []
      ],
      "removeformat.html.ini": [
@@ -356048,7 +356035,7 @@
       []
      ],
      "strikethrough_1-1000-expected.txt": [
-      "459bfa7fc5ec5c09574f751d5dc9466d1c34ce4d",
+      "4dc2ee0b510c27c094f89c324505c9fe41d13e31",
       []
      ],
      "subscript.html.ini": [
@@ -356064,11 +356051,11 @@
       []
      ],
      "underline_1-1000-expected.txt": [
-      "4e2714ede2b811c71fbd12d9da7c788da114f2db",
+      "f4215dd94fd9e1a1a7c47a64c6a514494f232d92",
       []
      ],
      "undo-redo-after-mutation-expected.txt": [
-      "5d971acbcb43deed7548308d5772b0864ee1753b",
+      "6f963ca5cbfe117adac600a67466666cc0a527e7",
       []
      ],
      "undo-redo-after-mutation.html.ini": [
@@ -356076,7 +356063,7 @@
       []
      ],
      "unlink-expected.txt": [
-      "b56797780a84cd556200fab2aabb8a4e48027e2d",
+      "2d416ba7c4cb2111ac5f70d8856d9d591d40dd34",
       []
      ],
      "unlink.html.ini": [
@@ -359779,7 +359766,7 @@
     "api": {
      "abort": {
       "general.any-expected.txt": [
-       "bcc2ab3650758c34f1c77908aba6d2c634810d4e",
+       "e40c3fadbbd0329cbbab313e60bd1a22ea83386e",
        []
       ],
       "general.any.js.ini": [
@@ -359787,19 +359774,19 @@
        []
       ],
       "general.any.serviceworker-expected.txt": [
-       "bcc2ab3650758c34f1c77908aba6d2c634810d4e",
+       "e40c3fadbbd0329cbbab313e60bd1a22ea83386e",
        []
       ],
       "general.any.sharedworker-expected.txt": [
-       "bcc2ab3650758c34f1c77908aba6d2c634810d4e",
+       "e40c3fadbbd0329cbbab313e60bd1a22ea83386e",
        []
       ],
       "general.any.worker-expected.txt": [
-       "bcc2ab3650758c34f1c77908aba6d2c634810d4e",
+       "e40c3fadbbd0329cbbab313e60bd1a22ea83386e",
        []
       ],
       "request.any-expected.txt": [
-       "b5c62553e1c85e15a48365a5aef586cbc34cb9f3",
+       "acfe55436eae326938cc9db9904625fa0c782463",
        []
       ],
       "request.any.js.ini": [
@@ -359807,15 +359794,15 @@
        []
       ],
       "request.any.serviceworker-expected.txt": [
-       "b5c62553e1c85e15a48365a5aef586cbc34cb9f3",
+       "acfe55436eae326938cc9db9904625fa0c782463",
        []
       ],
       "request.any.sharedworker-expected.txt": [
-       "b5c62553e1c85e15a48365a5aef586cbc34cb9f3",
+       "acfe55436eae326938cc9db9904625fa0c782463",
        []
       ],
       "request.any.worker-expected.txt": [
-       "b5c62553e1c85e15a48365a5aef586cbc34cb9f3",
+       "acfe55436eae326938cc9db9904625fa0c782463",
        []
       ],
       "serviceworker-intercepted.https.html.ini": [
@@ -359833,11 +359820,11 @@
        []
       ],
       "header-value-combining.any.serviceworker-expected.txt": [
-       "8298561c690746c205266fc0ece3f6c7df4feb27",
+       "3c7ae983b201fc566fea8ae086f6289eb674a595",
        []
       ],
       "http-response-code.any-expected.txt": [
-       "dad8083eda643cfbf24e7fca2fcd0d947029cc96",
+       "4045507e6fcd9a6c77922648c8437ffb5ef413dd",
        []
       ],
       "http-response-code.any.js.ini": [
@@ -359845,43 +359832,27 @@
        []
       ],
       "http-response-code.any.serviceworker-expected.txt": [
-       "dad8083eda643cfbf24e7fca2fcd0d947029cc96",
+       "4045507e6fcd9a6c77922648c8437ffb5ef413dd",
        []
       ],
       "http-response-code.any.sharedworker-expected.txt": [
-       "dad8083eda643cfbf24e7fca2fcd0d947029cc96",
+       "4045507e6fcd9a6c77922648c8437ffb5ef413dd",
        []
       ],
       "http-response-code.any.worker-expected.txt": [
-       "dad8083eda643cfbf24e7fca2fcd0d947029cc96",
+       "4045507e6fcd9a6c77922648c8437ffb5ef413dd",
        []
       ],
       "keepalive.any.js.ini": [
        "c928fc36a1aea86c6d409aff651730def242d36b",
        []
       ],
-      "response-null-body.any-expected.txt": [
-       "fa818f443d303b3903069f46bc8824dd2bf8bb27",
-       []
-      ],
       "response-null-body.any.js.ini": [
        "1a623948a5e63fba491dd628a8272d1ee3d95768",
        []
       ],
-      "response-null-body.any.serviceworker-expected.txt": [
-       "fa818f443d303b3903069f46bc8824dd2bf8bb27",
-       []
-      ],
-      "response-null-body.any.sharedworker-expected.txt": [
-       "fa818f443d303b3903069f46bc8824dd2bf8bb27",
-       []
-      ],
-      "response-null-body.any.worker-expected.txt": [
-       "fa818f443d303b3903069f46bc8824dd2bf8bb27",
-       []
-      ],
       "scheme-blob.sub.any-expected.txt": [
-       "fadb5a64d31cde0656f3cd2a6feb5ea2026b5d56",
+       "ce1c62948aa12cb3b74046fb8fbd127693d38bd8",
        []
       ],
       "scheme-blob.sub.any.js.ini": [
@@ -359889,7 +359860,7 @@
        []
       ],
       "scheme-blob.sub.any.worker-expected.txt": [
-       "fadb5a64d31cde0656f3cd2a6feb5ea2026b5d56",
+       "ce1c62948aa12cb3b74046fb8fbd127693d38bd8",
        []
       ],
       "url-parsing.sub.html.ini": [
@@ -359897,11 +359868,11 @@
        []
       ],
       "url-parsing.sub_encoding=windows-1252-expected.txt": [
-       "b9f855c9e37fa0380ff08a15a82d14ea4b22a62d",
+       "660055a82bff4a35c78cd6ece6d13bb17a6b5e9b",
        []
       ],
       "url-parsing.sub_encoding=x-cp1251-expected.txt": [
-       "3659cd5f364d8a9a96fc04584532101682b7d65e",
+       "520d5a789bdfd51ffa22fa52eeed4d4f6620e413",
        []
       ]
      },
@@ -359911,7 +359882,7 @@
        []
       ],
       "formdata.any-expected.txt": [
-       "ecd514be687ea819305f110860de33a661714793",
+       "9f062f528c0e54c669a71aa52e43f68bc8466c98",
        []
       ],
       "formdata.any.js.ini": [
@@ -359919,11 +359890,11 @@
        []
       ],
       "formdata.any.worker-expected.txt": [
-       "ecd514be687ea819305f110860de33a661714793",
+       "9f062f528c0e54c669a71aa52e43f68bc8466c98",
        []
       ],
       "mime-type.any-expected.txt": [
-       "bf411db6068d19f84eebf1d3cbe7bf2777746b24",
+       "cc5ce09daee68882a3e1b2047ba1c705598f1008",
        []
       ],
       "mime-type.any.js.ini": [
@@ -359931,7 +359902,7 @@
        []
       ],
       "mime-type.any.worker-expected.txt": [
-       "bf411db6068d19f84eebf1d3cbe7bf2777746b24",
+       "cc5ce09daee68882a3e1b2047ba1c705598f1008",
        []
       ]
      },
@@ -359941,7 +359912,7 @@
        []
       ],
       "cors-preflight-redirect.any-expected.txt": [
-       "1130f249e167d39118bfc9eb330b2690b2fa7cce",
+       "788e62a174f3f6ec7506fc3525cebcc9dcccde63",
        []
       ],
       "cors-preflight-redirect.any.js.ini": [
@@ -359949,15 +359920,15 @@
        []
       ],
       "cors-preflight-redirect.any.sharedworker-expected.txt": [
-       "1130f249e167d39118bfc9eb330b2690b2fa7cce",
+       "788e62a174f3f6ec7506fc3525cebcc9dcccde63",
        []
       ],
       "cors-preflight-redirect.any.worker-expected.txt": [
-       "1130f249e167d39118bfc9eb330b2690b2fa7cce",
+       "788e62a174f3f6ec7506fc3525cebcc9dcccde63",
        []
       ],
       "cors-preflight-star.any-expected.txt": [
-       "bc35e3d30981dd8a121832c193ed6ee870d77242",
+       "c04199ec10149169f2678c0524bf88c547a52ae7",
        []
       ],
       "cors-preflight-star.any.js.ini": [
@@ -359965,11 +359936,11 @@
        []
       ],
       "cors-preflight-star.any.worker-expected.txt": [
-       "bc35e3d30981dd8a121832c193ed6ee870d77242",
+       "c04199ec10149169f2678c0524bf88c547a52ae7",
        []
       ],
       "cors-preflight.any-expected.txt": [
-       "d82e2352d1c1a0fdea4530b98cbe1de96fd314b4",
+       "43ce956a813e1ccf4c91278da70b7f63b4a61a2c",
        []
       ],
       "cors-preflight.any.js.ini": [
@@ -359977,7 +359948,7 @@
        []
       ],
       "cors-preflight.any.worker-expected.txt": [
-       "d82e2352d1c1a0fdea4530b98cbe1de96fd314b4",
+       "43ce956a813e1ccf4c91278da70b7f63b4a61a2c",
        []
       ],
       "resources": {
@@ -360004,7 +359975,7 @@
       ]
      },
      "idlharness.any-expected.txt": [
-      "ebbca70aae72c4f27054f5364b4c2e2215b8b51c",
+      "20046efbb61e2740eec066852bd58ff659df2290",
       []
      ],
      "idlharness.any.js.ini": [
@@ -360012,15 +359983,15 @@
       []
      ],
      "idlharness.any.serviceworker-expected.txt": [
-      "1f4d6199cba3d7e458e30fba6914a589c336ca7d",
+      "aa3f2057842e7f8c526c9ad34b96e98aed68b942",
       []
      ],
      "idlharness.any.sharedworker-expected.txt": [
-      "1f4d6199cba3d7e458e30fba6914a589c336ca7d",
+      "aa3f2057842e7f8c526c9ad34b96e98aed68b942",
       []
      ],
      "idlharness.any.worker-expected.txt": [
-      "1f4d6199cba3d7e458e30fba6914a589c336ca7d",
+      "aa3f2057842e7f8c526c9ad34b96e98aed68b942",
       []
      ],
      "policies": {
@@ -360057,7 +360028,7 @@
        []
       ],
       "referrer-origin-when-cross-origin-service-worker.https-expected.txt": [
-       "5826fb328be576189a361a092663a7cfc681c921",
+       "37296a24c634476167dbcbd96f4dc17fd5c30d96",
        []
       ],
       "referrer-origin-when-cross-origin-service-worker.https.html.ini": [
@@ -360107,7 +360078,7 @@
        []
       ],
       "redirect-empty-location.any-expected.txt": [
-       "9b61ad26fe81f240de05edbcf3ffad870fa81788",
+       "c1d357663bcfcf97023c51a16f49c60c19d17eab",
        []
       ],
       "redirect-empty-location.any.js.ini": [
@@ -360115,15 +360086,15 @@
        []
       ],
       "redirect-empty-location.any.serviceworker-expected.txt": [
-       "9b61ad26fe81f240de05edbcf3ffad870fa81788",
+       "c1d357663bcfcf97023c51a16f49c60c19d17eab",
        []
       ],
       "redirect-empty-location.any.sharedworker-expected.txt": [
-       "9b61ad26fe81f240de05edbcf3ffad870fa81788",
+       "c1d357663bcfcf97023c51a16f49c60c19d17eab",
        []
       ],
       "redirect-empty-location.any.worker-expected.txt": [
-       "9b61ad26fe81f240de05edbcf3ffad870fa81788",
+       "c1d357663bcfcf97023c51a16f49c60c19d17eab",
        []
       ],
       "redirect-keepalive.any.js.ini": [
@@ -360131,7 +360102,7 @@
        []
       ],
       "redirect-location.any-expected.txt": [
-       "c7453a08fd4fa458722b3db22e2c816434fca39d",
+       "6ad2d8680a7859de2e45aaf0a74a43750fb5df8d",
        []
       ],
       "redirect-location.any.js.ini": [
@@ -360139,42 +360110,34 @@
        []
       ],
       "redirect-location.any.serviceworker-expected.txt": [
-       "c7453a08fd4fa458722b3db22e2c816434fca39d",
+       "6ad2d8680a7859de2e45aaf0a74a43750fb5df8d",
        []
       ],
       "redirect-location.any.sharedworker-expected.txt": [
-       "c7453a08fd4fa458722b3db22e2c816434fca39d",
+       "6ad2d8680a7859de2e45aaf0a74a43750fb5df8d",
        []
       ],
       "redirect-location.any.worker-expected.txt": [
-       "c7453a08fd4fa458722b3db22e2c816434fca39d",
+       "6ad2d8680a7859de2e45aaf0a74a43750fb5df8d",
        []
       ],
       "redirect-origin.any-expected.txt": [
-       "5ef3698dab5a9e0e2f6c1e2800fe7c6e4907f1a7",
+       "fdeea6db2dec781068593d88f2d6eacf6d49e9a5",
        []
       ],
       "redirect-origin.any.js.ini": [
        "dfb19ded1c6652c0fac826ccfb4551c29a793f17",
        []
       ],
-      "redirect-origin.any.serviceworker-expected.txt": [
-       "5ef3698dab5a9e0e2f6c1e2800fe7c6e4907f1a7",
-       []
-      ],
-      "redirect-origin.any.sharedworker-expected.txt": [
-       "5ef3698dab5a9e0e2f6c1e2800fe7c6e4907f1a7",
-       []
-      ],
       "redirect-origin.any.worker-expected.txt": [
-       "5ef3698dab5a9e0e2f6c1e2800fe7c6e4907f1a7",
+       "fdeea6db2dec781068593d88f2d6eacf6d49e9a5",
        []
       ]
      },
      "request": {
       "destination": {
        "fetch-destination.https-expected.txt": [
-        "2bd30f220de26d5ab75ba3ffd8534ea0222c346b",
+        "b431104ab05705aae7d86e4f822ab95c35c0dd44",
         []
        ],
        "fetch-destination.https.html.ini": [
@@ -360270,12 +360233,8 @@
        "f2fbecf496929194a7a30ef9d59ad5ec9189c5db",
        []
       ],
-      "request-consume-empty-expected.txt": [
-       "9c23dfe384cb702447c902896f99568d44c468ba",
-       []
-      ],
       "request-consume-empty.any-expected.txt": [
-       "9c23dfe384cb702447c902896f99568d44c468ba",
+       "0a59d8055a7c0d4dfcfe24533d09f4270abc027c",
        []
       ],
       "request-consume-empty.any.js.ini": [
@@ -360283,23 +360242,19 @@
        []
       ],
       "request-consume-empty.any.serviceworker-expected.txt": [
-       "9c23dfe384cb702447c902896f99568d44c468ba",
+       "0a59d8055a7c0d4dfcfe24533d09f4270abc027c",
        []
       ],
       "request-consume-empty.any.sharedworker-expected.txt": [
-       "9c23dfe384cb702447c902896f99568d44c468ba",
+       "0a59d8055a7c0d4dfcfe24533d09f4270abc027c",
        []
       ],
       "request-consume-empty.any.worker-expected.txt": [
-       "9c23dfe384cb702447c902896f99568d44c468ba",
-       []
-      ],
-      "request-disturbed-expected.txt": [
-       "d46bdb8c09e8fdcfee2df0b8baf77766c9f1655b",
+       "0a59d8055a7c0d4dfcfe24533d09f4270abc027c",
        []
       ],
       "request-disturbed.any-expected.txt": [
-       "d46bdb8c09e8fdcfee2df0b8baf77766c9f1655b",
+       "a8e90f20282f02cc78a50c76b34fddae8134cd3b",
        []
       ],
       "request-disturbed.any.js.ini": [
@@ -360307,23 +360262,19 @@
        []
       ],
       "request-disturbed.any.serviceworker-expected.txt": [
-       "d46bdb8c09e8fdcfee2df0b8baf77766c9f1655b",
+       "a8e90f20282f02cc78a50c76b34fddae8134cd3b",
        []
       ],
       "request-disturbed.any.sharedworker-expected.txt": [
-       "d46bdb8c09e8fdcfee2df0b8baf77766c9f1655b",
+       "a8e90f20282f02cc78a50c76b34fddae8134cd3b",
        []
       ],
       "request-disturbed.any.worker-expected.txt": [
-       "d46bdb8c09e8fdcfee2df0b8baf77766c9f1655b",
-       []
-      ],
-      "request-error-expected.txt": [
-       "f3363b8565beda7f4c79e0ad792b657ca8b80372",
+       "a8e90f20282f02cc78a50c76b34fddae8134cd3b",
        []
       ],
       "request-error.any-expected.txt": [
-       "75d188920c88272091fd41e7754548686339a510",
+       "a25ff6d136414056420f77ac7e42d68e347ea7cb",
        []
       ],
       "request-error.any.js.ini": [
@@ -360331,15 +360282,15 @@
        []
       ],
       "request-error.any.serviceworker-expected.txt": [
-       "75d188920c88272091fd41e7754548686339a510",
+       "a25ff6d136414056420f77ac7e42d68e347ea7cb",
        []
       ],
       "request-error.any.sharedworker-expected.txt": [
-       "75d188920c88272091fd41e7754548686339a510",
+       "a25ff6d136414056420f77ac7e42d68e347ea7cb",
        []
       ],
       "request-error.any.worker-expected.txt": [
-       "75d188920c88272091fd41e7754548686339a510",
+       "a25ff6d136414056420f77ac7e42d68e347ea7cb",
        []
       ],
       "request-error.js": [
@@ -360347,7 +360298,7 @@
        []
       ],
       "request-headers.any-expected.txt": [
-       "343ad8228825e345330c1d9155bea82ddbc16f2f",
+       "bf4f97bdde642838e1dff8b51cb0901b66ea91d2",
        []
       ],
       "request-headers.any.js.ini": [
@@ -360355,31 +360306,27 @@
        []
       ],
       "request-headers.any.serviceworker-expected.txt": [
-       "343ad8228825e345330c1d9155bea82ddbc16f2f",
+       "bf4f97bdde642838e1dff8b51cb0901b66ea91d2",
        []
       ],
       "request-headers.any.sharedworker-expected.txt": [
-       "343ad8228825e345330c1d9155bea82ddbc16f2f",
+       "bf4f97bdde642838e1dff8b51cb0901b66ea91d2",
        []
       ],
       "request-headers.any.worker-expected.txt": [
-       "343ad8228825e345330c1d9155bea82ddbc16f2f",
+       "bf4f97bdde642838e1dff8b51cb0901b66ea91d2",
        []
       ],
       "request-reset-attributes.https-expected.txt": [
-       "8634fe00edeb764533d6c025d4d3a04ba3e398ea",
+       "f5a821e984c7c14d91c206638a24a7fd115a6c01",
        []
       ],
       "request-reset-attributes.https.html.ini": [
        "ce8bcc4278908f52bf437dd1947f9049462d6257",
        []
       ],
-      "request-structure-expected.txt": [
-       "a99fb7451a776e1544d686e51b27703f629ee3ef",
-       []
-      ],
       "request-structure.any-expected.txt": [
-       "46c2a5e70cedec28cf1b4bb6cd05af0eb3642e9a",
+       "250de279026e89b818507254dab87387af64c1e2",
        []
       ],
       "request-structure.any.js.ini": [
@@ -360387,15 +360334,15 @@
        []
       ],
       "request-structure.any.serviceworker-expected.txt": [
-       "46c2a5e70cedec28cf1b4bb6cd05af0eb3642e9a",
+       "250de279026e89b818507254dab87387af64c1e2",
        []
       ],
       "request-structure.any.sharedworker-expected.txt": [
-       "46c2a5e70cedec28cf1b4bb6cd05af0eb3642e9a",
+       "250de279026e89b818507254dab87387af64c1e2",
        []
       ],
       "request-structure.any.worker-expected.txt": [
-       "46c2a5e70cedec28cf1b4bb6cd05af0eb3642e9a",
+       "250de279026e89b818507254dab87387af64c1e2",
        []
       ],
       "resources": {
@@ -360569,27 +360516,19 @@
        }
       },
       "response-body-read-task-handling-expected.txt": [
-       "2a32db64c24a1080139d56c7cffa58326d3df9e9",
+       "d3e6e39b37ff74f5fe7bfc6e493d189c373c2fb4",
        []
       ],
       "response-body-read-task-handling.html.ini": [
        "a3259f28639b0c5ea8c4ae4a3d5859062a62900d",
        []
       ],
-      "response-clone-expected.txt": [
-       "6ff0e7113920bf7e56cc385b1b2a5be8e29804f1",
-       []
-      ],
       "response-clone.any.js.ini": [
        "b7b39270572152b7b5b225ec808870963cf90490",
        []
       ],
-      "response-consume-empty-expected.txt": [
-       "5b0426fa4dca632bb0e8992fbae4109c2388f83a",
-       []
-      ],
       "response-consume-empty.any-expected.txt": [
-       "5b0426fa4dca632bb0e8992fbae4109c2388f83a",
+       "7eb798b83dfe5ed448f62ed41fbe1947b2ff04ae",
        []
       ],
       "response-consume-empty.any.js.ini": [
@@ -360597,27 +360536,23 @@
        []
       ],
       "response-consume-empty.any.serviceworker-expected.txt": [
-       "5b0426fa4dca632bb0e8992fbae4109c2388f83a",
+       "7eb798b83dfe5ed448f62ed41fbe1947b2ff04ae",
        []
       ],
       "response-consume-empty.any.sharedworker-expected.txt": [
-       "5b0426fa4dca632bb0e8992fbae4109c2388f83a",
+       "7eb798b83dfe5ed448f62ed41fbe1947b2ff04ae",
        []
       ],
       "response-consume-empty.any.worker-expected.txt": [
-       "5b0426fa4dca632bb0e8992fbae4109c2388f83a",
+       "7eb798b83dfe5ed448f62ed41fbe1947b2ff04ae",
        []
       ],
       "response-consume-stream.any.js.ini": [
        "a448d746efed32961360159a1044da24aeb84dda",
        []
       ],
-      "response-error-from-stream-expected.txt": [
-       "fd1e6908bfaeab27815e9edc02eaf51624d6320a",
-       []
-      ],
       "response-error-from-stream.any-expected.txt": [
-       "fd1e6908bfaeab27815e9edc02eaf51624d6320a",
+       "ba2c5e41e45b1919940492cf9a3fc97acd093007",
        []
       ],
       "response-error-from-stream.any.js.ini": [
@@ -360625,19 +360560,19 @@
        []
       ],
       "response-error-from-stream.any.serviceworker-expected.txt": [
-       "fd1e6908bfaeab27815e9edc02eaf51624d6320a",
+       "ba2c5e41e45b1919940492cf9a3fc97acd093007",
        []
       ],
       "response-error-from-stream.any.sharedworker-expected.txt": [
-       "fd1e6908bfaeab27815e9edc02eaf51624d6320a",
+       "ba2c5e41e45b1919940492cf9a3fc97acd093007",
        []
       ],
       "response-error-from-stream.any.worker-expected.txt": [
-       "fd1e6908bfaeab27815e9edc02eaf51624d6320a",
+       "ba2c5e41e45b1919940492cf9a3fc97acd093007",
        []
       ],
       "response-stream-disturbed-by-pipe.any-expected.txt": [
-       "7ee0f33a4ef947aa168fb4334899a47e94eaff3a",
+       "9ba9214aa43b03f6482517feccba2c880ac7e93a",
        []
       ],
       "response-stream-disturbed-by-pipe.any.js.ini": [
@@ -360645,15 +360580,15 @@
        []
       ],
       "response-stream-disturbed-by-pipe.any.serviceworker-expected.txt": [
-       "7ee0f33a4ef947aa168fb4334899a47e94eaff3a",
+       "9ba9214aa43b03f6482517feccba2c880ac7e93a",
        []
       ],
       "response-stream-disturbed-by-pipe.any.sharedworker-expected.txt": [
-       "7ee0f33a4ef947aa168fb4334899a47e94eaff3a",
+       "9ba9214aa43b03f6482517feccba2c880ac7e93a",
        []
       ],
       "response-stream-disturbed-by-pipe.any.worker-expected.txt": [
-       "7ee0f33a4ef947aa168fb4334899a47e94eaff3a",
+       "9ba9214aa43b03f6482517feccba2c880ac7e93a",
        []
       ],
       "response-stream-disturbed-util.js": [
@@ -360770,7 +360705,7 @@
       []
      ],
      "script.window-expected.txt": [
-      "c425ce77dbe85f8561e6e6a7b1df8a341d2c5b9f",
+      "557127b2aeaa82894487c3301010dd93747f504d",
       []
      ],
      "script.window.js.ini": [
@@ -360978,7 +360913,7 @@
       ]
      },
      "response_block.tentative.https-expected.txt": [
-      "e3e161bd457df9a8267ee0920bfeb7d05aec84e0",
+      "62cf3eafe0e905df544232613714f27c7e5a077c",
       []
      ],
      "response_block.tentative.https.html.ini": [
@@ -361040,7 +360975,7 @@
       []
      ],
      "processing.any-expected.txt": [
-      "3ac9e12bcce1bc06631eee1bee1e271648a439eb",
+      "6106e8434e327a82a978c5dce01f314f14146ef7",
       []
      ],
      "processing.any.js.ini": [
@@ -361048,15 +360983,15 @@
       []
      ],
      "processing.any.serviceworker-expected.txt": [
-      "3ac9e12bcce1bc06631eee1bee1e271648a439eb",
+      "6106e8434e327a82a978c5dce01f314f14146ef7",
       []
      ],
      "processing.any.sharedworker-expected.txt": [
-      "3ac9e12bcce1bc06631eee1bee1e271648a439eb",
+      "6106e8434e327a82a978c5dce01f314f14146ef7",
       []
      ],
      "processing.any.worker-expected.txt": [
-      "3ac9e12bcce1bc06631eee1bee1e271648a439eb",
+      "6106e8434e327a82a978c5dce01f314f14146ef7",
       []
      ],
      "resources": {
@@ -361083,10 +361018,6 @@
       "c999ef6e52ba0a9213cc5633080cbb5606078aa2",
       []
      ],
-     "basic.tentative.https.window-expected.txt": [
-      "a9102ca3f1a6ea69188e37e998683b9518bbb678",
-      []
-     ],
      "basic.tentative.https.window.js.ini": [
       "23e03fa5377aad04473d88506db734bb1c0457f6",
       []
@@ -361095,25 +361026,9 @@
       "f234c4d449fece770c500ed068d14160b6efd62e",
       []
      ],
-     "quota.tentative.https.window-expected.txt": [
-      "91b157a2e9e5fdab0552ae191a3a4442e5c6a9cc",
-      []
-     ],
-     "send-on-deactivate.tentative.https.window-expected.txt": [
-      "496d4fb598ffbc428dcc9a363be3f57dad0a1d63",
-      []
-     ],
-     "send-on-discard.tentative.https.window-expected.txt": [
-      "a0e5cd7dfdd4b8fcf0fdc6f19ee4d5da9cf2e45b",
-      []
-     ],
      "send-on-discard.tentative.https.window.js.ini": [
       "c1ffe0a63a318214f2c3c8f2e3309c417ad584a6",
       []
-     ],
-     "timeout.tentative.https.window-expected.txt": [
-      "62e2e7d910dd0b7ddcb31ee7810496023de946a8",
-      []
      ]
     },
     "h1-parsing": {
@@ -361122,7 +361037,7 @@
       []
      ],
      "lone-cr.window-expected.txt": [
-      "0d22a3d08bc60f821cb91631f3fa6a861a7bd885",
+      "4318be095eedc33fb1643b7e87453376590e7a64",
       []
      ],
      "lone-cr.window.js.ini": [
@@ -361156,7 +361071,7 @@
       ]
      },
      "status-code.window-expected.txt": [
-      "9427e2a9f0202bbdd7889c6dad257957423fc294",
+      "1776609f58e48584eb8cb45d7e7fe7a9b2d8fc6f",
       []
      ],
      "status-code.window.js.ini": [
@@ -361177,174 +361092,38 @@
       "288dafb8d6b6a0ae2837c3a0ba459737c03fe97d",
       []
      ],
-     "cache-mode-expected.txt": [
-      "bee27041d4637ef2ed19aeff4ce0f514c1fd19b5",
-      []
-     ],
-     "cache-mode.any-expected.txt": [
-      "bee27041d4637ef2ed19aeff4ce0f514c1fd19b5",
-      []
-     ],
      "cache-mode.any.js.ini": [
       "fd89e2c701365feefc488a8dbb0a9f395c2d2c81",
       []
      ],
-     "cache-mode.any.serviceworker-expected.txt": [
-      "bee27041d4637ef2ed19aeff4ce0f514c1fd19b5",
-      []
-     ],
-     "cache-mode.any.sharedworker-expected.txt": [
-      "bee27041d4637ef2ed19aeff4ce0f514c1fd19b5",
-      []
-     ],
-     "cache-mode.any.worker-expected.txt": [
-      "bee27041d4637ef2ed19aeff4ce0f514c1fd19b5",
-      []
-     ],
-     "cc-request-expected.txt": [
-      "10e574ea6c106f29cb5ce22d5ce08417c5a0e6cc",
-      []
-     ],
-     "cc-request.any-expected.txt": [
-      "10e574ea6c106f29cb5ce22d5ce08417c5a0e6cc",
-      []
-     ],
      "cc-request.any.js.ini": [
       "5ed7bfef908a650731f1bda16f5a8872e40e0cca",
       []
      ],
-     "cc-request.any.serviceworker-expected.txt": [
-      "10e574ea6c106f29cb5ce22d5ce08417c5a0e6cc",
-      []
-     ],
-     "cc-request.any.sharedworker-expected.txt": [
-      "10e574ea6c106f29cb5ce22d5ce08417c5a0e6cc",
-      []
-     ],
-     "cc-request.any.worker-expected.txt": [
-      "10e574ea6c106f29cb5ce22d5ce08417c5a0e6cc",
-      []
-     ],
-     "credentials.tentative.any-expected.txt": [
-      "fa94b8ca4ffdd9fb95429f56163a45f03016d07a",
-      []
-     ],
      "credentials.tentative.any.js.ini": [
       "2e190642b350fe82945679081c0d23f0ee52e400",
       []
      ],
-     "credentials.tentative.any.serviceworker-expected.txt": [
-      "fa94b8ca4ffdd9fb95429f56163a45f03016d07a",
-      []
-     ],
-     "credentials.tentative.any.sharedworker-expected.txt": [
-      "fa94b8ca4ffdd9fb95429f56163a45f03016d07a",
-      []
-     ],
-     "credentials.tentative.any.worker-expected.txt": [
-      "fa94b8ca4ffdd9fb95429f56163a45f03016d07a",
-      []
-     ],
-     "heuristic-expected.txt": [
-      "e31950283c1246188ef891cabfd4e80b5044e354",
-      []
-     ],
-     "heuristic.any-expected.txt": [
-      "e31950283c1246188ef891cabfd4e80b5044e354",
-      []
-     ],
      "heuristic.any.js.ini": [
       "4bd668ca0e6e97e8d7e1d36365ce7e2a2314a984",
       []
      ],
-     "heuristic.any.serviceworker-expected.txt": [
-      "e31950283c1246188ef891cabfd4e80b5044e354",
-      []
-     ],
-     "heuristic.any.sharedworker-expected.txt": [
-      "e31950283c1246188ef891cabfd4e80b5044e354",
-      []
-     ],
-     "heuristic.any.worker-expected.txt": [
-      "e31950283c1246188ef891cabfd4e80b5044e354",
-      []
-     ],
      "http-cache.js": [
       "19f1ca9b2bcce2dbe1120ceeb4c5283103d5d105",
       []
      ],
-     "invalidate-expected.txt": [
-      "9f29bc55f9b0857a93440eebf80fa7000459c069",
-      []
-     ],
-     "invalidate.any-expected.txt": [
-      "9f29bc55f9b0857a93440eebf80fa7000459c069",
-      []
-     ],
      "invalidate.any.js.ini": [
       "92c7c2164dfd8fe6ba63b7fd8ef5b793db504484",
       []
      ],
-     "invalidate.any.serviceworker-expected.txt": [
-      "9f29bc55f9b0857a93440eebf80fa7000459c069",
-      []
-     ],
-     "invalidate.any.sharedworker-expected.txt": [
-      "9f29bc55f9b0857a93440eebf80fa7000459c069",
-      []
-     ],
-     "invalidate.any.worker-expected.txt": [
-      "9f29bc55f9b0857a93440eebf80fa7000459c069",
-      []
-     ],
-     "partial-expected.txt": [
-      "759cb5d39fb19ace224984b994579fcf812ba487",
-      []
-     ],
-     "partial.any-expected.txt": [
-      "7e66ac17d032d3eb13ef307f927570cfe267a4d2",
-      []
-     ],
      "partial.any.js.ini": [
       "7dee61c91f33f8473b1f1d4a79c85648cd473233",
       []
      ],
-     "partial.any.serviceworker-expected.txt": [
-      "7e66ac17d032d3eb13ef307f927570cfe267a4d2",
-      []
-     ],
-     "partial.any.sharedworker-expected.txt": [
-      "7e66ac17d032d3eb13ef307f927570cfe267a4d2",
-      []
-     ],
-     "partial.any.worker-expected.txt": [
-      "7e66ac17d032d3eb13ef307f927570cfe267a4d2",
-      []
-     ],
-     "post-patch-expected.txt": [
-      "3a5cd58915539e5a42fbdd03f474da40f2b268c5",
-      []
-     ],
-     "post-patch.any-expected.txt": [
-      "3a5cd58915539e5a42fbdd03f474da40f2b268c5",
-      []
-     ],
      "post-patch.any.js.ini": [
       "fa75dc5c21be144eb9372165be795afe7066a080",
       []
      ],
-     "post-patch.any.serviceworker-expected.txt": [
-      "3a5cd58915539e5a42fbdd03f474da40f2b268c5",
-      []
-     ],
-     "post-patch.any.sharedworker-expected.txt": [
-      "3a5cd58915539e5a42fbdd03f474da40f2b268c5",
-      []
-     ],
-     "post-patch.any.worker-expected.txt": [
-      "3a5cd58915539e5a42fbdd03f474da40f2b268c5",
-      []
-     ],
      "resources": {
       "http-cache.py": [
        "3ab610dd1421cea5289ad14a8ef472ade27f07f1",
@@ -361367,29 +361146,9 @@
       "5b98ed89bb2da9ae7f0f3c9ce5861679493c5f70",
       []
      ],
-     "vary-expected.txt": [
-      "5cfb7f71a1517441a64c250c8acca1bfa4049288",
-      []
-     ],
-     "vary.any-expected.txt": [
-      "5cfb7f71a1517441a64c250c8acca1bfa4049288",
-      []
-     ],
      "vary.any.js.ini": [
       "7afc48c011d33ab9cb6392231648ad1c9a444db9",
       []
-     ],
-     "vary.any.serviceworker-expected.txt": [
-      "5cfb7f71a1517441a64c250c8acca1bfa4049288",
-      []
-     ],
-     "vary.any.sharedworker-expected.txt": [
-      "5cfb7f71a1517441a64c250c8acca1bfa4049288",
-      []
-     ],
-     "vary.any.worker-expected.txt": [
-      "5cfb7f71a1517441a64c250c8acca1bfa4049288",
-      []
      ]
     },
     "metadata": {
@@ -361403,7 +361162,7 @@
      ],
      "generated": {
       "appcache-manifest.https.sub-expected.txt": [
-       "beb0188c763b37f3d682c3d968ee4cb9ed957fde",
+       "135e79c8a97a81dd4ae3df7ca863fdf2ba79d5ea",
        []
       ],
       "appcache-manifest.https.sub.html.ini": [
@@ -361423,7 +361182,7 @@
        []
       ],
       "element-a.https.sub-expected.txt": [
-       "35073ced9c8b18d64c9f433bff61a665b389bbfb",
+       "734a24dba6be4cd2df979a2b65f168a17396761e",
        []
       ],
       "element-a.https.sub.html.ini": [
@@ -361431,7 +361190,7 @@
        []
       ],
       "element-area.https.sub-expected.txt": [
-       "35073ced9c8b18d64c9f433bff61a665b389bbfb",
+       "734a24dba6be4cd2df979a2b65f168a17396761e",
        []
       ],
       "element-area.https.sub.html.ini": [
@@ -361439,7 +361198,7 @@
        []
       ],
       "element-audio.https.sub-expected.txt": [
-       "4c45c0778c86e0291ad028fd99cd24f5d4d4fa83",
+       "f4ad6cd64aece504195fce14548e7714df0343b0",
        []
       ],
       "element-audio.https.sub.html.ini": [
@@ -361447,7 +361206,7 @@
        []
       ],
       "element-embed.https.sub-expected.txt": [
-       "7f2149147693f574837d31ae422e37628d446ccc",
+       "5a66126f272442cdcf2840768a1544144807fa67",
        []
       ],
       "element-embed.https.sub.html.ini": [
@@ -361455,7 +361214,7 @@
        []
       ],
       "element-img.https.sub-expected.txt": [
-       "29e4523c58dde765efc4e569551f8232d864c694",
+       "a1048747e4f5988565e846230b0321c5829dafb1",
        []
       ],
       "element-img.https.sub.html.ini": [
@@ -361463,7 +361222,7 @@
        []
       ],
       "element-input-image.https.sub-expected.txt": [
-       "b90f0a996bc8819c9abab77c7d7ded158c9ef5fa",
+       "29c85be0f890a222fd6bc57427650d6f25536c40",
        []
       ],
       "element-input-image.https.sub.html.ini": [
@@ -361479,7 +361238,7 @@
        []
       ],
       "element-link-prefetch.https.optional.sub-expected.txt": [
-       "74d3d9cee5c9613f2d46f4ab45883e7c90121254",
+       "6990ffe9363569a517c80e18fbdcb588819ab773",
        []
       ],
       "element-link-prefetch.https.optional.sub.html.ini": [
@@ -361495,7 +361254,7 @@
        []
       ],
       "element-video.https.sub-expected.txt": [
-       "4c45c0778c86e0291ad028fd99cd24f5d4d4fa83",
+       "f4ad6cd64aece504195fce14548e7714df0343b0",
        []
       ],
       "element-video.https.sub.html.ini": [
@@ -361503,7 +361262,7 @@
        []
       ],
       "header-link.https.sub-expected.txt": [
-       "cfc69a50fd7ea5e620b619cce5d472035c43eccd",
+       "697de4e31e2c43041c38355e9071cb8594e85987",
        []
       ],
       "header-link.https.sub.html.ini": [
@@ -361511,7 +361270,7 @@
        []
       ],
       "header-link.https.sub.tentative-expected.txt": [
-       "dc0b314022ac1a696df7cc3b47657a4c1ba034fe",
+       "15ad83a39b6d6328d3232929f977f3793126d59a",
        []
       ],
       "header-link.https.sub.tentative.html.ini": [
@@ -361519,7 +361278,7 @@
        []
       ],
       "header-link.sub-expected.txt": [
-       "499f2be5aed63be5bfb0d3114b5af3b66f9f2c66",
+       "d2e8dd294707e6deb6d3baeb80519bcb8ae7446b",
        []
       ],
       "header-link.sub.html.ini": [
@@ -361527,7 +361286,7 @@
        []
       ],
       "svg-image.https.sub-expected.txt": [
-       "1d86875e2b3405fc8f083933692f44b88bf4364e",
+       "ce7a3e353aaf4dd4f532ae49b3356c676c11d6d4",
        []
       ],
       "svg-image.https.sub.html.ini": [
@@ -361792,7 +361551,7 @@
       []
      ],
      "parsing-nosniff.window-expected.txt": [
-      "4af3e7607f8120740abd695e1f0d15a89943fe20",
+      "9ba9e8cc6580dfc798438adf370e162ccc08e3e5",
       []
      ],
      "parsing-nosniff.window.js.ini": [
@@ -361907,7 +361666,7 @@
      },
      "tentative": {
       "content-range.sub.any-expected.txt": [
-       "8f1ebdafed9df78563f82c67db0217fb8a61b0b5",
+       "7655f2c74afc3da50b2f03f29d00874b6b1e83db",
        []
       ],
       "content-range.sub.any.js.ini": [
@@ -361915,11 +361674,11 @@
        []
       ],
       "content-range.sub.any.worker-expected.txt": [
-       "8f1ebdafed9df78563f82c67db0217fb8a61b0b5",
+       "7655f2c74afc3da50b2f03f29d00874b6b1e83db",
        []
       ],
       "img-mime-types-coverage.tentative.sub-expected.txt": [
-       "0ace58c3df95639cb99630cb1c1536c51f351f28",
+       "6929736c22360e3ddfb6b43b56bda51fa8a87ebd",
        []
       ],
       "img-mime-types-coverage.tentative.sub.html.ini": [
@@ -361934,20 +361693,16 @@
        "2d5e3bb8b58610ae8fd36d9c98ff6d08c6d4cb8b",
        []
       ],
-      "known-mime-type.sub.any-expected.txt": [
-       "5644dfad72ef5d33e53033573b31a198f62916cb",
-       []
-      ],
       "known-mime-type.sub.any.js.ini": [
        "2f5c7eb837180066fc8227b298f2a528b064d117",
        []
       ],
       "known-mime-type.sub.any.worker-expected.txt": [
-       "29f3a6a8feed2398a06592d9da40f33681545eb6",
+       "e8b252a01cc24321ea6939bf2e877684a320b80b",
        []
       ],
       "nosniff.sub.any-expected.txt": [
-       "1c3f36303fc96ea09361506cd666382392f818fd",
+       "a1ca07359cf1339cf53ac9e954c15a9e1297c88d",
        []
       ],
       "nosniff.sub.any.js.ini": [
@@ -361955,11 +361710,11 @@
        []
       ],
       "nosniff.sub.any.worker-expected.txt": [
-       "d6b58c329dfeaa0a7c9dd0a6301bf22f368b0991",
+       "1237de691173a567041ccd0c632b6d05e698eaa7",
        []
       ],
       "status.sub.any-expected.txt": [
-       "75926b33a6e2fc1e1afea025bd43a5bb59e45324",
+       "453f5201f6cf91d6b2ef6e85eb044a235a25bd6b",
        []
       ],
       "status.sub.any.js.ini": [
@@ -361967,7 +361722,7 @@
        []
       ],
       "status.sub.any.worker-expected.txt": [
-       "1c7fd71c1dc5e58c44943907c255ba4aa92ab127",
+       "14efc9a52844912681a8c1b94cde6109b3259a6f",
        []
       ],
       "unknown-mime-type.sub.any.js.ini": [
@@ -361978,7 +361733,7 @@
     },
     "origin": {
      "assorted.window-expected.txt": [
-      "1c2da8742f2a7f567e614b507a7a6d1abde66c40",
+      "d16b8901123bc1de5e0f464e916b99bbce1cdb5b",
       []
      ],
      "assorted.window.js.ini": [
@@ -362006,7 +361761,7 @@
       []
      ],
      "fenced-frame-no-preflight-required.tentative.https.window-expected.txt": [
-      "957a37471f16e32e1b48c069cedbb93070d992a6",
+      "6147aa02f7b7477becffd62a447d310908a7bc4b",
       []
      ],
      "fenced-frame-no-preflight-required.tentative.https.window.js.ini": [
@@ -362018,23 +361773,23 @@
       []
      ],
      "fenced-frame-subresource-fetch.tentative.https.window_include=baseline-expected.txt": [
-      "51f700f5e2f5d7702ebc735529d86a9fa5947018",
+      "5200da46e9f407d2875a4637564f9839e9fc1eb1",
       []
      ],
      "fenced-frame-subresource-fetch.tentative.https.window_include=from-local-expected.txt": [
-      "00f16ca182bddd9e77056fa112d2bf44a8f1ff1d",
+      "e9891e500ddbf99c947326b1f2e4bd29ea516d5c",
       []
      ],
      "fenced-frame-subresource-fetch.tentative.https.window_include=from-private-expected.txt": [
-      "d2f2c1f3cd1013b3f842bf9b33c820bd0e531d81",
+      "47b7d2107640935d7f46d22ee4b61a005859013a",
       []
      ],
      "fenced-frame-subresource-fetch.tentative.https.window_include=from-public-expected.txt": [
-      "b91e15d1580a558df8497f9ad294a3b0716a634d",
+      "7f1a81cb72cabb8c7083cf77f694b57336f83379",
       []
      ],
      "fenced-frame.tentative.https.window-expected.txt": [
-      "9307d674a0ab72110c72355f9e054bcc15c65af9",
+      "3371a0693de7d064c062747ff06f52e0e3caf0ce",
       []
      ],
      "fenced-frame.tentative.https.window.js.ini": [
@@ -362054,23 +361809,23 @@
       []
      ],
      "iframe.tentative.https.window_include=from-private-expected.txt": [
-      "f94c4c9b21f89c9332580a4ad696ee85b2397c1d",
+      "a676e9a67d68677447e86bcf39c3dd72d59d870a",
       []
      ],
      "iframe.tentative.https.window_include=from-public-expected.txt": [
-      "0e025ef3603a80e060304eff5ba3e99cb3bacb04",
+      "076e53c7fde5b910178ffa6b00377d8e583d2d44",
       []
      ],
      "iframe.tentative.https.window_include=from-treat-as-public-expected.txt": [
-      "7f3d4a264960488e073f9c2e31f9fe2502bf12e5",
+      "f2021f00376968f1da1ec8838aee7fca6e218705",
       []
      ],
      "iframe.tentative.https.window_include=grandparent-expected.txt": [
-      "5843a88c670182a82a0e1a658a84af9d43cb7caa",
+      "c66848441cffdea2ed5d249f80e95e1498ff8e4d",
       []
      ],
      "iframe.tentative.window-expected.txt": [
-      "864b48d4d35dfa0f344bf2eef496f6f9a5ae5de8",
+      "151b47919202bbd5de47a3afa67253c2aaedac72",
       []
      ],
      "iframe.tentative.window.js.ini": [
@@ -362078,27 +361833,15 @@
       []
      ],
      "mixed-content-fetch.tentative.https.window-expected.txt": [
-      "75548db207be4eed89934de400c76809ee73c002",
+      "41cbfe637868f0820c1cef0c96646b759049ad51",
       []
      ],
      "mixed-content-fetch.tentative.https.window.js.ini": [
       "ac94c74c7826052b5db546b25640ed0007d57cad",
       []
      ],
-     "mixed-content-fetch.tentative.https.window_include=from-private-expected.txt": [
-      "2be30f6cf7c4302b2a91705e7fa53dfb432de879",
-      []
-     ],
-     "mixed-content-fetch.tentative.https.window_include=from-public-expected.txt": [
-      "dbd89ca75519fa39e0708a2e3bd18df0eb438439",
-      []
-     ],
-     "mixed-content-fetch.tentative.https.window_include=from-treat-as-public-expected.txt": [
-      "3218128f8e691209609c0665601492b993081243",
-      []
-     ],
      "nested-worker.tentative.https.window-expected.txt": [
-      "8718ffde7bc70a2802ec04ecd5c1e3b42e0dca32",
+      "8f48b11f954f3816fe13ac0da0461a27f83532ca",
       []
      ],
      "nested-worker.tentative.https.window.js.ini": [
@@ -362106,7 +361849,7 @@
       []
      ],
      "nested-worker.tentative.window-expected.txt": [
-      "8718ffde7bc70a2802ec04ecd5c1e3b42e0dca32",
+      "8f48b11f954f3816fe13ac0da0461a27f83532ca",
       []
      ],
      "nested-worker.tentative.window.js.ini": [
@@ -362216,11 +361959,11 @@
       []
      ],
      "service-worker-fetch.tentative.https.window_1-8-expected.txt": [
-      "afb1dd167a994c1f0f0fcca86b84939968e2d1d0",
+      "5671141a17aad3452854c295dffca3714597cd10",
       []
      ],
      "service-worker-fetch.tentative.https.window_9-last-expected.txt": [
-      "ec3b5c1515edb7f3cb1afcf4efdfd14b5e66244f",
+      "417e722958f28a0a5cd21179c756f1f3a3e7b9b2",
       []
      ],
      "service-worker-update.tentative.https.window.js.ini": [
@@ -362232,7 +361975,7 @@
       []
      ],
      "shared-worker-blob-fetch.tentative.https.window-expected.txt": [
-      "2fa1ec2bbc20620b6b949dcea8257109e55aa118",
+      "29635d0d48ce9a53d14621ef56971a142657ab95",
       []
      ],
      "shared-worker-blob-fetch.tentative.https.window.js.ini": [
@@ -362240,7 +361983,7 @@
       []
      ],
      "shared-worker-blob-fetch.tentative.window-expected.txt": [
-      "c6368e6354de6f00438e758b290621add7be3f78",
+      "20860b6b73bf9eb798e14eb5d2160deda7cca2f3",
       []
      ],
      "shared-worker-blob-fetch.tentative.window.js.ini": [
@@ -362248,7 +361991,7 @@
       []
      ],
      "shared-worker-fetch.tentative.https.window-expected.txt": [
-      "614004f0837c38ec8adbdb4c8eb9fce88c1e6877",
+      "7667981729ce591d061e57b715d0070db039e90f",
       []
      ],
      "shared-worker-fetch.tentative.https.window.js.ini": [
@@ -362256,7 +361999,7 @@
       []
      ],
      "shared-worker-fetch.tentative.window-expected.txt": [
-      "27ca7e55b73e1908f085c56aaf18094723171f89",
+      "04a806e05c3c67f4559115a8591299d13bdff631",
       []
      ],
      "shared-worker-fetch.tentative.window.js.ini": [
@@ -362268,7 +362011,7 @@
       []
      ],
      "shared-worker.tentative.window-expected.txt": [
-      "8718ffde7bc70a2802ec04ecd5c1e3b42e0dca32",
+      "8f48b11f954f3816fe13ac0da0461a27f83532ca",
       []
      ],
      "shared-worker.tentative.window.js.ini": [
@@ -362276,7 +362019,7 @@
       []
      ],
      "websocket.tentative.window-expected.txt": [
-      "11e2dcac903cb8fb7f68563036c4b8a4a9c1a9e7",
+      "70da776c601858829245342c4a5d3bf8997327d5",
       []
      ],
      "websocket.tentative.window.js.ini": [
@@ -362288,7 +362031,7 @@
       []
      ],
      "worker-fetch.tentative.https.window-expected.txt": [
-      "c4e0af3e551c20ffcdcd9905691c0bdc7a4d5e10",
+      "6e53b793db22fb8406a038fed82b25702ca5bf18",
       []
      ],
      "worker-fetch.tentative.https.window.js.ini": [
@@ -362296,7 +362039,7 @@
       []
      ],
      "worker-fetch.tentative.window-expected.txt": [
-      "704fdf845ae321cec9e5d9577c0de494d34484c0",
+      "6d2c599aad2f70fe401868fbd302f5079b6155fc",
       []
      ],
      "worker-fetch.tentative.window.js.ini": [
@@ -362314,7 +362057,7 @@
     },
     "range": {
      "blob.any-expected.txt": [
-      "c9ae33e25d29da8b9d030e11e561de1dfc95519f",
+      "31f5b198430ead56b4a2e1edf0b260bf2327d010",
       []
      ],
      "blob.any.js.ini": [
@@ -362322,7 +362065,7 @@
       []
      ],
      "blob.any.worker-expected.txt": [
-      "c9ae33e25d29da8b9d030e11e561de1dfc95519f",
+      "31f5b198430ead56b4a2e1edf0b260bf2327d010",
       []
      ],
      "general.any.js.ini": [
@@ -362330,11 +362073,11 @@
       []
      ],
      "general.any.serviceworker-expected.txt": [
-      "61126fdaf3eaaebfbee0d435c749a4920f489a81",
+      "4ff6aa5877e62a9f33d5506050e358dfe0fa26f5",
       []
      ],
      "general.window-expected.txt": [
-      "d15469b170082ed0d182f611184954647d90379a",
+      "f2820746c06bf58acba80c8a9928f531c3034eb0",
       []
      ],
      "general.window.js.ini": [
@@ -362376,7 +362119,7 @@
       ]
      },
      "sw.https.window-expected.txt": [
-      "a9577f01727678cd7a76bcc65e132fd6fcb230ac",
+      "5e45e3234c9e70de009c8c3889780b21a3226b15",
       []
      ],
      "sw.https.window.js.ini": [
@@ -362398,7 +362141,7 @@
     },
     "redirects": {
      "subresource-fragments-expected.txt": [
-      "9a9f722921640c5d74d38d2a753b4cb8d971d328",
+      "80423c072f6f5add53a570ac7ec6e3a01bd2d18d",
       []
      ],
      "subresource-fragments.html.ini": [
@@ -362408,7 +362151,7 @@
     },
     "security": {
      "1xx-response.any-expected.txt": [
-      "6ac068363a83816939013bbde88a7584aca4f307",
+      "9222ab11a20066606af0439583f0a9b57b68da45",
       []
      ],
      "1xx-response.any.js.ini": [
@@ -362416,7 +362159,7 @@
       []
      ],
      "1xx-response.any.worker-expected.txt": [
-      "6ac068363a83816939013bbde88a7584aca4f307",
+      "9222ab11a20066606af0439583f0a9b57b68da45",
       []
      ],
      "redirect-to-url-with-credentials.https.html.ini": [
@@ -362522,7 +362265,7 @@
    "fledge": {
     "tentative": {
      "TODO": [
-      "3ab741890a8089869d73c75d8146c237e173331a",
+      "8217bdc924ef1c14d7a1719516463c63e758cc51",
       []
      ],
      "auction-config.https.window.js.ini": [
@@ -362579,7 +362322,7 @@
        []
       ],
       "fledge-util.sub.js": [
-       "4a8a087ada05b5f8c157e7bfca15f623256cd94a",
+       "ffe7468c94854300d2b323bed4895d1549ec87cc",
        []
       ],
       "request-tracker.py": [
@@ -388910,10 +388653,6 @@
      "f3d500a5711d393e72975d212f1654dd9c93f8e4",
      []
     ],
-    "storage-buckets.tentative.idl": [
-     "73d72ceab9805195704bbc63fca6ba658018784f",
-     []
-    ],
     "storage.idl": [
      "d47e37c40e88e4e448f25e4044359fd87ffecad7",
      []
@@ -392430,6 +392169,10 @@
     },
     "mse-for-webcodecs": {
      "tentative": {
+      "media-source-webcodecs-util.js": [
+       "f581da77b213eb9257f6441966f6a1bdbf7d8637",
+       []
+      ],
       "mediasource-webcodecs-appendencodedchunks-play.html.ini": [
        "1a18d440df1567ee8d84b74a2c1afd272b1845af",
        []
@@ -392540,6 +392283,10 @@
     }
    },
    "mediacapture-extensions": {
+    "GUM-faceFraming.https-expected.txt": [
+     "5af2f0cfcd911230acd72b3cd50426cf0f70d966",
+     []
+    ],
     "MediaStreamTrack-video-stats.https.html.ini": [
      "617cf295acf4b5d9ac4bf3750cf47f45ca1a7b14",
      []
@@ -401358,7 +401105,7 @@
       []
      ],
      "cache-add.https.any-expected.txt": [
-      "3d82496870edb6921cc927be315fb6db78bc5ad4",
+      "b305d3a8c07a75d4629702ce3f98d44bd914072d",
       []
      ],
      "cache-add.https.any.js.ini": [
@@ -401366,19 +401113,19 @@
       []
      ],
      "cache-add.https.any.serviceworker-expected.txt": [
-      "3d82496870edb6921cc927be315fb6db78bc5ad4",
+      "b305d3a8c07a75d4629702ce3f98d44bd914072d",
       []
      ],
      "cache-add.https.any.sharedworker-expected.txt": [
-      "3d82496870edb6921cc927be315fb6db78bc5ad4",
+      "b305d3a8c07a75d4629702ce3f98d44bd914072d",
       []
      ],
      "cache-add.https.any.worker-expected.txt": [
-      "3d82496870edb6921cc927be315fb6db78bc5ad4",
+      "b305d3a8c07a75d4629702ce3f98d44bd914072d",
       []
      ],
      "cache-keys-attributes-for-service-worker.https-expected.txt": [
-      "452fa9f031ea6bd368b357cf30629498c633399b",
+      "c0b00dd1f2e40ee8ee23a189cb758f075c01bce6",
       []
      ],
      "cache-keys-attributes-for-service-worker.https.html.ini": [
@@ -401386,7 +401133,7 @@
       []
      ],
      "cache-keys.https.any-expected.txt": [
-      "cfd4098aa4635d68e8550034a6c40582de362909",
+      "60d3b7b944b9b95dcf5af3bb61a28a73b0c4d62a",
       []
      ],
      "cache-keys.https.any.js.ini": [
@@ -401394,19 +401141,19 @@
       []
      ],
      "cache-keys.https.any.serviceworker-expected.txt": [
-      "cfd4098aa4635d68e8550034a6c40582de362909",
+      "60d3b7b944b9b95dcf5af3bb61a28a73b0c4d62a",
       []
      ],
      "cache-keys.https.any.sharedworker-expected.txt": [
-      "cfd4098aa4635d68e8550034a6c40582de362909",
+      "60d3b7b944b9b95dcf5af3bb61a28a73b0c4d62a",
       []
      ],
      "cache-keys.https.any.worker-expected.txt": [
-      "cfd4098aa4635d68e8550034a6c40582de362909",
+      "60d3b7b944b9b95dcf5af3bb61a28a73b0c4d62a",
       []
      ],
      "cache-match.https.any-expected.txt": [
-      "07557f11a9c0fe2abaf363c568c8b2a81349c8be",
+      "491bb75c46c0c2f9c4eb56613cc9a4d4a9fa0c8d",
       []
      ],
      "cache-match.https.any.js.ini": [
@@ -401414,19 +401161,19 @@
       []
      ],
      "cache-match.https.any.serviceworker-expected.txt": [
-      "07557f11a9c0fe2abaf363c568c8b2a81349c8be",
+      "491bb75c46c0c2f9c4eb56613cc9a4d4a9fa0c8d",
       []
      ],
      "cache-match.https.any.sharedworker-expected.txt": [
-      "07557f11a9c0fe2abaf363c568c8b2a81349c8be",
+      "491bb75c46c0c2f9c4eb56613cc9a4d4a9fa0c8d",
       []
      ],
      "cache-match.https.any.worker-expected.txt": [
-      "07557f11a9c0fe2abaf363c568c8b2a81349c8be",
+      "491bb75c46c0c2f9c4eb56613cc9a4d4a9fa0c8d",
       []
      ],
      "cache-matchAll.https.any-expected.txt": [
-      "391a706b5bda0b78cc4cab483f5f70a719fc1f94",
+      "27d8fdcb8160ba9370299aa019cff47e9cf90480",
       []
      ],
      "cache-matchAll.https.any.js.ini": [
@@ -401434,19 +401181,19 @@
       []
      ],
      "cache-matchAll.https.any.serviceworker-expected.txt": [
-      "391a706b5bda0b78cc4cab483f5f70a719fc1f94",
+      "27d8fdcb8160ba9370299aa019cff47e9cf90480",
       []
      ],
      "cache-matchAll.https.any.sharedworker-expected.txt": [
-      "391a706b5bda0b78cc4cab483f5f70a719fc1f94",
+      "27d8fdcb8160ba9370299aa019cff47e9cf90480",
       []
      ],
      "cache-matchAll.https.any.worker-expected.txt": [
-      "391a706b5bda0b78cc4cab483f5f70a719fc1f94",
+      "27d8fdcb8160ba9370299aa019cff47e9cf90480",
       []
      ],
      "cache-storage.https.any-expected.txt": [
-      "d1c62496bacf4b31a2cf5671693042fba8abfef4",
+      "9d4852c29f329a6618cfd3727028e700b4f2dc54",
       []
      ],
      "cache-storage.https.any.js.ini": [
@@ -401454,15 +401201,15 @@
       []
      ],
      "cache-storage.https.any.serviceworker-expected.txt": [
-      "d1c62496bacf4b31a2cf5671693042fba8abfef4",
+      "9d4852c29f329a6618cfd3727028e700b4f2dc54",
       []
      ],
      "cache-storage.https.any.sharedworker-expected.txt": [
-      "d1c62496bacf4b31a2cf5671693042fba8abfef4",
+      "9d4852c29f329a6618cfd3727028e700b4f2dc54",
       []
      ],
      "cache-storage.https.any.worker-expected.txt": [
-      "d1c62496bacf4b31a2cf5671693042fba8abfef4",
+      "9d4852c29f329a6618cfd3727028e700b4f2dc54",
       []
      ],
      "crashtests": {
@@ -401514,7 +401261,7 @@
       ]
      },
      "sandboxed-iframes.https-expected.txt": [
-      "a0a646099cfa729b63cc3bd1f56bfb4dedd94b46",
+      "e2f2f01326d11403180c9da8b96d39ee74335b6f",
       []
      ],
      "sandboxed-iframes.https.html.ini": [
@@ -401527,15 +401274,15 @@
      []
     ],
     "idlharness.https.any.serviceworker-expected.txt": [
-     "cc464f51a494ffa581d445bdf9aeb8fe718d17de",
+     "7553bf527838f83a1a0ac38774cd24d28ce477d2",
      []
     ],
     "idlharness.https.any.sharedworker-expected.txt": [
-     "fbda117156cf162afd3c57ce3326bccec535816a",
+     "003a608a5023ac70e4681441c16cc2e024f3ba8e",
      []
     ],
     "idlharness.https.any.worker-expected.txt": [
-     "fbda117156cf162afd3c57ce3326bccec535816a",
+     "003a608a5023ac70e4681441c16cc2e024f3ba8e",
      []
     ],
     "service-worker": {
@@ -401616,7 +401363,7 @@
       }
      },
      "about-blank-replacement.https-expected.txt": [
-      "9aa4a28996b56e4303a741353f626591b56802af",
+      "6eb70e36439733b9233c3fd9b97957e30dd56304",
       []
      ],
      "about-blank-replacement.https.html.ini": [
@@ -401628,7 +401375,7 @@
       []
      ],
      "client-url-of-blob-url-worker.https-expected.txt": [
-      "bc07e042a2626d0bf8c80179df67cfd90d4a5463",
+      "36cb81122141a9bc9ec0ae60f1cb656562c5d716",
       []
      ],
      "client-url-of-blob-url-worker.https.html.ini": [
@@ -401636,7 +401383,7 @@
       []
      ],
      "clients-get-client-types.https-expected.txt": [
-      "58bae3013f3e9b54f93bad719971ffcaf2a09b26",
+      "d594d08428a93838883075179a5ef9d43c24d9d6",
       []
      ],
      "clients-get-client-types.https.html.ini": [
@@ -401644,7 +401391,7 @@
       []
      ],
      "clients-matchall-blob-url-worker.https-expected.txt": [
-      "0065aa4ad95bafe37955a86b9ba9397d760dfa4c",
+      "3ffdbfed8d2c1c380b4387f98783c6616a50b448",
       []
      ],
      "clients-matchall-blob-url-worker.https.html.ini": [
@@ -401652,7 +401399,7 @@
       []
      ],
      "clients-matchall-client-types.https-expected.txt": [
-      "a5702d0326367c8a1552bbd99d98bb3d0c12cb7c",
+      "688c093c50434065750b03a23c6871a71f878fff",
       []
      ],
      "clients-matchall-client-types.https.html.ini": [
@@ -401664,7 +401411,7 @@
       []
      ],
      "clients-matchall-order.https-expected.txt": [
-      "78737fe4f60050c6e8cd4762d776fa8518e91225",
+      "bc5ecc0e314d095e310a7e5f19615f9d2be11840",
       []
      ],
      "clients-matchall-order.https.html.ini": [
@@ -401680,7 +401427,7 @@
       []
      ],
      "dedicated-worker-service-worker-interception.https-expected.txt": [
-      "e6e6986dc00a2077b683c28c4b9d639ef0f2d949",
+      "f00908fdb999a5c85767f8a17f21afe29cfd7950",
       []
      ],
      "dedicated-worker-service-worker-interception.https.html.ini": [
@@ -401692,7 +401439,7 @@
       []
      ],
      "fetch-event-redirect.https-expected.txt": [
-      "44bbf2436f4689cc37efcc086bcb5e1171da14ec",
+      "ca711835efaf67167a5ab2ea4d1ff927f2303e84",
       []
      ],
      "fetch-event-redirect.https.html.ini": [
@@ -401704,7 +401451,7 @@
       []
      ],
      "fetch-event.https-expected.txt": [
-      "3967218b3f3c218bcd17b84bfc6c7a6de8f8a8e2",
+      "f4e62c0f9e89e400bf1988dfa008d12613c4b1cc",
       []
      ],
      "fetch-event.https.html.ini": [
@@ -401716,7 +401463,7 @@
       []
      ],
      "fetch-request-xhr-sync-error.https.window-expected.txt": [
-      "f9ed9ece338caa4fe85b2af0bae8ea5c15c4789f",
+      "9ecce228f9a4638edaf7b78853ab974975e0bb89",
       []
      ],
      "fetch-request-xhr-sync-error.https.window.js.ini": [
@@ -401724,7 +401471,7 @@
       []
      ],
      "fetch-request-xhr-sync.https-expected.txt": [
-      "724b7d8ec2c7c76893f2de28d79d3838742336a7",
+      "14c09fc63f8262d2e274a442957f8c7a23a13ba2",
       []
      ],
      "fetch-request-xhr-sync.https.html.ini": [
@@ -401732,7 +401479,7 @@
       []
      ],
      "fetch-request-xhr.https-expected.txt": [
-      "71bc4c0ad08a96413c30d5721afa0e73315cb0d0",
+      "a4c1cc213420a18285fb5ebe3b23bc87b5c429d9",
       []
      ],
      "fetch-request-xhr.https.html.ini": [
@@ -401740,7 +401487,7 @@
       []
      ],
      "fetch-waits-for-activate.https-expected.txt": [
-      "c764406f53967fc33cecb47c72fc94f39325c510",
+      "1904fbd10278a28349c436562837b5a7ab4a74a7",
       []
      ],
      "fetch-waits-for-activate.https.html.ini": [
@@ -401751,24 +401498,12 @@
       "d5756c5bda9bca4b26e7c466da3c783364bf39c0",
       []
      ],
-     "idlharness-sw.https-expected.txt": [
-      "f3ad33fb2ad58ef798d7b30185d4cb0bbf20d1a1",
-      []
-     ],
-     "import-module-scripts.https-expected.txt": [
-      "ea80ea9c5258e768f4fe2b5611f7fb052274d092",
-      []
-     ],
-     "import-scripts-redirect.https-expected.txt": [
-      "54836e4b4571ec6e7a194c1f4520abbebe9b98a3",
-      []
-     ],
      "import-scripts-redirect.https.html.ini": [
       "ca6800b0c556c50af18ade353bc4c24e8dd7ff05",
       []
      ],
      "interface-requirements-sw.https-expected.txt": [
-      "42f0b416105ad4f8e380c533efca92f325c88097",
+      "4e1cc153253af3c4a32c0f984b5b2046c9625ffe",
       []
      ],
      "interface-requirements-sw.https.html.ini": [
@@ -401776,7 +401511,7 @@
       []
      ],
      "local-url-inherit-controller.https-expected.txt": [
-      "afcb9a7acb6e6686c227e1a20808f79b973bf314",
+      "8e8673397b7e0d71072773ea3128089731386132",
       []
      ],
      "local-url-inherit-controller.https.html.ini": [
@@ -401824,7 +401559,7 @@
       []
      ],
      "navigate-window.https-expected.txt": [
-      "d70dc6978166229ebdce79328e1300779e41995a",
+      "f46e952faf4b489fafdcf9265054fd7f4d317c0e",
       []
      ],
      "navigate-window.https.html.ini": [
@@ -401920,7 +401655,7 @@
       }
      },
      "navigation-redirect-resolution.https-expected.txt": [
-      "5f2fb74a840b0a71d3026b1104422f19e55ab928",
+      "3753e5b2cf9b242da1d8c3c69cc206ee0309e20e",
       []
      ],
      "navigation-redirect-resolution.https.html.ini": [
@@ -401932,7 +401667,7 @@
       []
      ],
      "next-hop-protocol.https-expected.txt": [
-      "c6d12e4eb7e735632515bb1894d874417eb39a35",
+      "b44c2b2e7cae72ff71d62bc997a1c55c54061f3e",
       []
      ],
      "next-hop-protocol.https.html.ini": [
@@ -401963,16 +401698,12 @@
       "64d944d2b5466a466214ba5be94bab42c07a364e",
       []
      ],
-     "ready.https-expected.txt": [
-      "d29a2b4e58b5319d7034e7be26cc0f2e4821e9fe",
-      []
-     ],
      "ready.https.window.js.ini": [
       "f1b25bda36a5d9bb144c57fdfd7b6e543b013d11",
       []
      ],
      "redirected-response.https-expected.txt": [
-      "30d7aadd70f7c54f072decece791a9474e4a4d42",
+      "9eb87bc1db66218d8155787fd4d0a999954fcad0",
       []
      ],
      "redirected-response.https.html.ini": [
@@ -401980,7 +401711,7 @@
       []
      ],
      "registration-scope-module-static-import.https-expected.txt": [
-      "f2c497809b013369c7e8145fa0e670d03c2a669e",
+      "eb7ea1c69c78e2318ab164805e20eaaccb6bce2e",
       []
      ],
      "registration-scope-module-static-import.https.html.ini": [
@@ -401988,7 +401719,7 @@
       []
      ],
      "registration-updateviacache.https-expected.txt": [
-      "002474415b16b6a2fadc92c78ba872760e0e90ae",
+      "98b3094dacccde43d8812ea9ab145f24183a4370",
       []
      ],
      "registration-updateviacache.https.html.ini": [
@@ -401999,10 +401730,6 @@
       "c219b15a1d45c724bba9b5f3c675242ec074b76e",
       []
      ],
-     "resource-timing-fetch-variants.https-expected.txt": [
-      "9166fc4ca8b5f871a390c16fc033e373d86602e2",
-      []
-     ],
      "resource-timing-fetch-variants.https.html.ini": [
       "74659ab72cf47f01e323a51126410ea0da041bc9",
       []
@@ -403572,7 +403299,7 @@
       ]
      },
      "same-site-cookies.https-expected.txt": [
-      "053575901afb447b9c3bc86d7518e41b626b63ac",
+      "eac574e5327ecab14f5d8b8fcbfc401a7d40ea25",
       []
      ],
      "same-site-cookies.https.html.ini": [
@@ -403648,7 +403375,7 @@
       []
      ],
      "unregister-then-register-new-script.https-expected.txt": [
-      "20a0fa54cfae3d2a7d0ff65e59ac01ec39af3975",
+      "1fabde69af7953fa312b47921d7546062625b2de",
       []
      ],
      "unregister-then-register-new-script.https.html.ini": [
@@ -403656,23 +403383,19 @@
       []
      ],
      "unregister-then-register.https-expected.txt": [
-      "30d5ef10791adf1c3f48fd8d04e7c048171d26a0",
+      "8f60e9bb3ed78969bcf9efef1afdd9aae5dfaf5a",
       []
      ],
      "unregister-then-register.https.html.ini": [
       "1fb78b47e7663d9cf764863edb39cad8b89806cd",
       []
      ],
-     "update-after-oneday.https-expected.txt": [
-      "e4f15c8e5a409a16b47ae2cd7c0ba878310d61e4",
-      []
-     ],
      "update-after-oneday.https.html.ini": [
       "fef5fb2a892636926a68bda221d426eadfedc6fb",
       []
      ],
      "update-recovery.https-expected.txt": [
-      "5d5d7709db811247a16006da329d8f867a0319d1",
+      "32c47f97e48987387b87c9cb116cd5a4f96d9d1e",
       []
      ],
      "update-recovery.https.html.ini": [
@@ -403684,32 +403407,24 @@
       []
      ],
      "worker-interception-redirect.https-expected.txt": [
-      "6ebfc05e07493232ef0f3d8a9f06e2605b54c558",
+      "23027580a24763e2219dbd62f6be371882e3e6f3",
       []
      ],
      "worker-interception-redirect.https.html.ini": [
       "c740393a4f254d784246c4d32b4f090c98e6b06f",
       []
      ],
-     "worker-interception.https-expected.txt": [
-      "dba3694a6f928b5d0802aabda02604ae19797663",
-      []
-     ],
      "worker-interception.https.html.ini": [
       "6f70d96c44f49bc8ee8f819b813b04da2b6f9f9c",
       []
      ],
      "xhr-content-length.https.window-expected.txt": [
-      "7222d7db6c1fb7b320277932e925a6ddc6b5f3cd",
+      "a83de08b63978f60a591464e86210e656cf14a20",
       []
      ],
      "xhr-content-length.https.window.js.ini": [
       "4873bc7f68aead1d062b8dd315780b1969f1ca23",
       []
-     ],
-     "xhr-content-length.window-expected.txt": [
-      "52c2f67b739998c645b4df6909c7c16a9832d010",
-      []
      ]
     }
    },
@@ -411515,11 +411230,11 @@
        []
       ],
       "accumulation-per-property-002-expected.txt": [
-       "040921d2984ae2dbacef7a3a702d1cde9411a717",
+       "eed46339310dd96a50cff305ccfc815565bfcdf4",
        []
       ],
       "accumulation-per-property-002.html.ini": [
-       "6b7f8557f0f4c16c137c3bdb4353394eda43f3cb",
+       "22882944cd1f841b0fb26ec7fc9ab26ce6b0676d",
        []
       ],
       "addition-per-property-001-expected.txt": [
@@ -411531,11 +411246,11 @@
        []
       ],
       "addition-per-property-002-expected.txt": [
-       "0f91f5c694ff4c78c1c74945951ddd3a161f9236",
+       "1715091cd547049b04d497370e7721e6ace15c41",
        []
       ],
       "addition-per-property-002.html.ini": [
-       "a552f3fba31758047bb0bc477d3eee5e022e5970",
+       "ffdca5bd769f1d69664fd4fb532292b6bb53cfb6",
        []
       ],
       "interpolation-per-property-001-expected.txt": [
@@ -411547,11 +411262,11 @@
        []
       ],
       "interpolation-per-property-002-expected.txt": [
-       "ed17ed82500b8dc89316716c84ec05434995a0d8",
+       "973bbe87bc7f5e828b9dba4ae5ec7f9d7de3d14c",
        []
       ],
       "interpolation-per-property-002.html.ini": [
-       "35decaa5860104e8242386c1d35abef441539612",
+       "2ded0b72e33e02038334f39a0d2052f73dc006f1",
        []
       ],
       "property-list.js": [
@@ -412935,6 +412650,10 @@
         "6a8144b3ccfa8892efef71d921dad7ed4b0e1f88",
         []
        ],
+       "register-processor-typeerrors.js": [
+        "93894842fcf01a68dd73dbbc72950ae2fcba26ca",
+        []
+       ],
        "sharedarraybuffer-processor.js": [
         "2ccacccd4bb0a4d289ddccd9cafa4e29a0484730",
         []
@@ -413654,7 +413373,7 @@
       },
       "network": {
        "__init__.py": [
-        "cab997d14d9e20d954ad814055b6e546da0807f6",
+        "7ec80ac36b7ec0624c7426d62c0706aa3379be12",
         []
        ],
        "add_intercept": {
@@ -413723,7 +413442,7 @@
          []
         ],
         "response_completed.py.ini": [
-         "4f5b547772ad7ffb1c05f668b52e5e8154214370",
+         "f39d03befa1d6edc4b07d5431c8d074ec66be07d",
          []
         ],
         "response_completed_cached.py.ini": [
@@ -415282,26 +415001,50 @@
      "4cf6bf101f10375549bf83519eb90eebe0476a21",
      []
     ],
+    "conv2d.https.any-expected.txt": [
+     "a056b2b08ae638dc829f827f5335edef8e63ebf4",
+     []
+    ],
     "conv2d.https.any.js.ini": [
      "0d40d828b6156b265ef14de71fe4452e536882af",
      []
     ],
+    "conv_transpose2d.https.any-expected.txt": [
+     "4cd757a69366bdf399bfa25f6ea10f5b1228eec8",
+     []
+    ],
     "conv_transpose2d.https.any.js.ini": [
      "52bb18ba778b767dbe83816553aeca29100d7685",
      []
     ],
+    "elementwise_binary.https.any-expected.txt": [
+     "e11060576c7d4a4dd0a19b489334903b984c1955",
+     []
+    ],
     "elementwise_binary.https.any.js.ini": [
      "d728c8f2c39395b23be735f77b2af4a45f82476d",
      []
     ],
+    "elementwise_unary.https.any-expected.txt": [
+     "b6de16198da15d0a9afeccd2affce304c231d5b2",
+     []
+    ],
     "elementwise_unary.https.any.js.ini": [
      "6a4e236829aa66e9712a5bb2b88c1b9e1079d6c2",
      []
     ],
+    "elu.https.any-expected.txt": [
+     "b9cada90250c1952448e761bc19afdb6c6d79d39",
+     []
+    ],
     "elu.https.any.js.ini": [
      "3d8375a4d8202a75e91146661baa24201fda6cc0",
      []
     ],
+    "gemm.https.any-expected.txt": [
+     "e27839b80e518a13851ad4a76292acbb59f0bb1f",
+     []
+    ],
     "gemm.https.any.js.ini": [
      "b33ebb8f2bfa17e8cc33a6ec75d8d358b01e2b9f",
      []
@@ -415322,6 +415065,10 @@
      "1d4d2d09471f27b2286b7dd04b2572bafe20b8ff",
      []
     ],
+    "idlharness.https.any-expected.txt": [
+     "5913346b5b111764ceb1b9fda995220c0a00f4a5",
+     []
+    ],
     "idlharness.https.any.js.ini": [
      "c2b96c4b662bb4652df091b275e2bc2b98917119",
      []
@@ -415354,18 +415101,34 @@
      "5109b167cbdb7b80b7808ed068d1e4fa0c592a37",
      []
     ],
+    "pad.https.any-expected.txt": [
+     "b35360cb508e5db6e80fc1658b6830728183519a",
+     []
+    ],
     "pad.https.any.js.ini": [
      "e8ae5506b90dadc37431af931c14e17f0b4ba2e5",
      []
     ],
+    "pooling.https.any-expected.txt": [
+     "ceebd4358dd7ba3044358fe74b4009e703c5926a",
+     []
+    ],
     "pooling.https.any.js.ini": [
      "84de391397eff5f76f98b80e5988d4fc37c478f0",
      []
     ],
+    "prelu.https.any-expected.txt": [
+     "3626b67272e323d2ad2fc6c09a885589b0532f82",
+     []
+    ],
     "prelu.https.any.js.ini": [
      "bc4a57987192f46a65f5209048546d800b21f1f6",
      []
     ],
+    "reduction.https.any-expected.txt": [
+     "2b495398f2de2a158ab959c3b35299ad96bce1e1",
+     []
+    ],
     "reduction.https.any.js.ini": [
      "9b400d86c7a54101ee26670cda42c749f5a837dd",
      []
@@ -416643,39 +416406,31 @@
    },
    "websockets": {
     "Close-1000-reason.any.worker_wpt_flags=h2-expected.txt": [
-     "dc3fa03f41a6dc06e8090b12530547a7a53df8c4",
+     "59016eccdcd0bb69f82e0e3b56311fa0580f551e",
      []
     ],
     "Close-1000-reason.any_wpt_flags=h2-expected.txt": [
-     "dc3fa03f41a6dc06e8090b12530547a7a53df8c4",
+     "59016eccdcd0bb69f82e0e3b56311fa0580f551e",
      []
     ],
     "Close-2999-reason.any_wpt_flags=h2-expected.txt": [
-     "f1e9dc8eaa6e604c2f181899426f845841c54938",
+     "847cc82151dd6e759d65820181eb95b40b8f978a",
      []
     ],
     "Close-delayed.any.worker_wpt_flags=h2-expected.txt": [
-     "302107b06f56b36134f0c7ec17e061653ece344a",
+     "0cc474cbceebe3561f11d4231fe09e8da957364a",
      []
     ],
     "Close-delayed.any_wpt_flags=h2-expected.txt": [
-     "302107b06f56b36134f0c7ec17e061653ece344a",
+     "0cc474cbceebe3561f11d4231fe09e8da957364a",
      []
     ],
     "Close-server-initiated-close.any.worker_wpt_flags=h2-expected.txt": [
-     "1711963fad1a24be03c4fb528e4dd142be9bdbbe",
-     []
-    ],
-    "Create-Secure-url-with-space.any-expected.txt": [
-     "6e141336536a22be05d71b3764743f3ff6c65dce",
-     []
-    ],
-    "Create-Secure-url-with-space.any.worker-expected.txt": [
-     "6e141336536a22be05d71b3764743f3ff6c65dce",
+     "68ef88d73c8ebe57159805ae81e705077fb15c36",
      []
     ],
     "Create-http-urls.any-expected.txt": [
-     "9412ba1b2a8047fff31a642449abf6be01b60ffe",
+     "4ade8bbffb91d6f34966d5f401a1685b02e5453a",
      []
     ],
     "Create-http-urls.any.js.ini": [
@@ -416683,11 +416438,11 @@
      []
     ],
     "Create-http-urls.any.worker-expected.txt": [
-     "9412ba1b2a8047fff31a642449abf6be01b60ffe",
+     "4ade8bbffb91d6f34966d5f401a1685b02e5453a",
      []
     ],
     "Create-invalid-urls.any-expected.txt": [
-     "851aded595c9cea34f9a5c0eb691be12b9fa17ef",
+     "5ff3f4eff7a8a6e1fae2cd2156eb4c0d9321ad9d",
      []
     ],
     "Create-invalid-urls.any.js.ini": [
@@ -416695,11 +416450,11 @@
      []
     ],
     "Create-invalid-urls.any.worker-expected.txt": [
-     "851aded595c9cea34f9a5c0eb691be12b9fa17ef",
+     "5ff3f4eff7a8a6e1fae2cd2156eb4c0d9321ad9d",
      []
     ],
     "Create-non-absolute-url.any-expected.txt": [
-     "cd6dc873bab35a4a5c2e7b2de60690269b0cc66e",
+     "d8bc89cfa8d2fda7885113a9bb20efdd5ed3f570",
      []
     ],
     "Create-non-absolute-url.any.js.ini": [
@@ -416707,7 +416462,7 @@
      []
     ],
     "Create-non-absolute-url.any.worker-expected.txt": [
-     "cd6dc873bab35a4a5c2e7b2de60690269b0cc66e",
+     "d8bc89cfa8d2fda7885113a9bb20efdd5ed3f570",
      []
     ],
     "Create-on-worker-shutdown.any.js.ini": [
@@ -416719,27 +416474,27 @@
      []
     ],
     "Create-protocols-repeated-case-insensitive.any.worker_default-expected.txt": [
-     "27b7a39581cd9d7febf84202e40b876107833f87",
+     "91b1b294528057d338657f46e10e5fd133110058",
      []
     ],
     "Create-protocols-repeated-case-insensitive.any.worker_wpt_flags=h2-expected.txt": [
-     "27b7a39581cd9d7febf84202e40b876107833f87",
+     "91b1b294528057d338657f46e10e5fd133110058",
      []
     ],
     "Create-protocols-repeated-case-insensitive.any.worker_wss-expected.txt": [
-     "27b7a39581cd9d7febf84202e40b876107833f87",
+     "91b1b294528057d338657f46e10e5fd133110058",
      []
     ],
     "Create-protocols-repeated-case-insensitive.any_default-expected.txt": [
-     "27b7a39581cd9d7febf84202e40b876107833f87",
+     "91b1b294528057d338657f46e10e5fd133110058",
      []
     ],
     "Create-protocols-repeated-case-insensitive.any_wpt_flags=h2-expected.txt": [
-     "27b7a39581cd9d7febf84202e40b876107833f87",
+     "91b1b294528057d338657f46e10e5fd133110058",
      []
     ],
     "Create-protocols-repeated-case-insensitive.any_wss-expected.txt": [
-     "27b7a39581cd9d7febf84202e40b876107833f87",
+     "91b1b294528057d338657f46e10e5fd133110058",
      []
     ],
     "Create-url-with-space.any.js.ini": [
@@ -416747,31 +416502,31 @@
      []
     ],
     "Create-url-with-space.any.worker_default-expected.txt": [
-     "d3d8e9b9ac357ea5f1649d4d5018412eb15b083b",
+     "e7dfa97c9c6e699bc2ee39d2a50b68826def1114",
      []
     ],
     "Create-url-with-space.any.worker_wpt_flags=h2-expected.txt": [
-     "d3d8e9b9ac357ea5f1649d4d5018412eb15b083b",
+     "e7dfa97c9c6e699bc2ee39d2a50b68826def1114",
      []
     ],
     "Create-url-with-space.any.worker_wss-expected.txt": [
-     "d3d8e9b9ac357ea5f1649d4d5018412eb15b083b",
+     "e7dfa97c9c6e699bc2ee39d2a50b68826def1114",
      []
     ],
     "Create-url-with-space.any_default-expected.txt": [
-     "d3d8e9b9ac357ea5f1649d4d5018412eb15b083b",
+     "e7dfa97c9c6e699bc2ee39d2a50b68826def1114",
      []
     ],
     "Create-url-with-space.any_wpt_flags=h2-expected.txt": [
-     "d3d8e9b9ac357ea5f1649d4d5018412eb15b083b",
+     "e7dfa97c9c6e699bc2ee39d2a50b68826def1114",
      []
     ],
     "Create-url-with-space.any_wss-expected.txt": [
-     "d3d8e9b9ac357ea5f1649d4d5018412eb15b083b",
+     "e7dfa97c9c6e699bc2ee39d2a50b68826def1114",
      []
     ],
     "Create-url-with-windows-1252-encoding-expected.txt": [
-     "e1df1c29f73b9d0d6b01e34b364e94a27d639d4b",
+     "076d3a7539b5b2f57293601f9c6ba3bf5c7cf15c",
      []
     ],
     "Create-url-with-windows-1252-encoding.html.ini": [
@@ -416779,15 +416534,11 @@
      []
     ],
     "Create-valid-url-array-protocols.any.worker_wpt_flags=h2-expected.txt": [
-     "f7aa3bd5bccb2e3af5ef7021922abc56b8e7fe31",
+     "1faa9cfed368976c20843cf57cbfdb4c64787fbb",
      []
     ],
     "Create-valid-url-protocol-string.any.worker_wpt_flags=h2-expected.txt": [
-     "eab04c00bd59ba36c51aebf967429135f1080426",
-     []
-    ],
-    "Create-valid-url-protocol.any.worker_wpt_flags=h2-expected.txt": [
-     "d46b601c572b4dbbca4711f6b9c995d6371e6245",
+     "8582ca1f1fa5cd5d757f61c683d2db3a8072a848",
      []
     ],
     "DIR_METADATA": [
@@ -416803,35 +416554,31 @@
      []
     ],
     "Send-0byte-data.any.worker_wpt_flags=h2-expected.txt": [
-     "13ac904c58ed0f1335e3ed1a222b0124db46bf94",
+     "15e25a4195a5a7466717b3b49728d928ef0b0f48",
      []
     ],
     "Send-binary-arraybufferview-float64.any_wpt_flags=h2-expected.txt": [
-     "51f63a3b3133d313edf5ef5506bd5f8bc80d1ad9",
+     "7aefdc05c60ad3485d2528e432b66c374c95199e",
      []
     ],
     "Send-binary-arraybufferview-int16-offset.any.worker_wpt_flags=h2-expected.txt": [
-     "5cf6c4531f85ec1c36bba96d3c0ce797d7f3272e",
+     "6778f1a09be0c99ea442ab19c2696bd73cc287fa",
      []
     ],
     "Send-binary-arraybufferview-int16-offset.any_wpt_flags=h2-expected.txt": [
-     "5cf6c4531f85ec1c36bba96d3c0ce797d7f3272e",
+     "6778f1a09be0c99ea442ab19c2696bd73cc287fa",
      []
     ],
     "Send-binary-arraybufferview-uint32-offset.any_wpt_flags=h2-expected.txt": [
-     "29a3626c1391d8e3e9e250471c31aa278c012a6d",
+     "f6158906475a7e4dd480f3ac8c1569406985ef75",
      []
     ],
     "Send-unpaired-surrogates.any.worker_wpt_flags=h2-expected.txt": [
-     "69f784da7be837dd93f4c3dae5236fd6a1960ad9",
-     []
-    ],
-    "Send-unpaired-surrogates.any_wpt_flags=h2-expected.txt": [
-     "69f784da7be837dd93f4c3dae5236fd6a1960ad9",
+     "6558a55fe8c7c98eacea55b28f0f466ab709a554",
      []
     ],
     "back-forward-cache-with-closed-websocket-connection-ccns.tentative.window-expected.txt": [
-     "444dc8aecae2bd54de7432ad5233547746ff15a4",
+     "5636f8fa1c23f49e0b0db852b4d8e822fddec536",
      []
     ],
     "back-forward-cache-with-closed-websocket-connection-ccns.tentative.window.js.ini": [
@@ -416843,7 +416590,7 @@
      []
     ],
     "back-forward-cache-with-open-websocket-connection-ccns.tentative.window-expected.txt": [
-     "d8c0770c15d3082a6181732a011b203d531f7a9f",
+     "e35106d24f5eb18ca90141827dd8d24764aee490",
      []
     ],
     "back-forward-cache-with-open-websocket-connection-ccns.tentative.window.js.ini": [
@@ -416855,44 +416602,44 @@
      []
     ],
     "basic-auth.any.serviceworker_wpt_flags=h2-expected.txt": [
-     "97ce540c19fb64c36397c257b4a2a42fac1b8eeb",
+     "406a7ff7d2626da16932da7673302ddd3472d253",
      []
     ],
     "basic-auth.any.sharedworker_wpt_flags=h2-expected.txt": [
-     "97ce540c19fb64c36397c257b4a2a42fac1b8eeb",
+     "406a7ff7d2626da16932da7673302ddd3472d253",
      []
     ],
     "basic-auth.any.worker_wpt_flags=h2-expected.txt": [
-     "97ce540c19fb64c36397c257b4a2a42fac1b8eeb",
+     "406a7ff7d2626da16932da7673302ddd3472d253",
      []
     ],
     "basic-auth.any_wpt_flags=h2-expected.txt": [
-     "97ce540c19fb64c36397c257b4a2a42fac1b8eeb",
+     "406a7ff7d2626da16932da7673302ddd3472d253",
      []
     ],
     "bufferedAmount-unchanged-by-sync-xhr.any.sharedworker_wpt_flags=h2-expected.txt": [
-     "638bdf455cbafd9e69d6ac9496d3d5c5c859a4f3",
+     "bdefc8a204f238f54114f0992cdb9fad73ae65fc",
      []
     ],
     "bufferedAmount-unchanged-by-sync-xhr.any.worker_wpt_flags=h2-expected.txt": [
-     "638bdf455cbafd9e69d6ac9496d3d5c5c859a4f3",
+     "bdefc8a204f238f54114f0992cdb9fad73ae65fc",
      []
     ],
     "bufferedAmount-unchanged-by-sync-xhr.any_wpt_flags=h2-expected.txt": [
-     "638bdf455cbafd9e69d6ac9496d3d5c5c859a4f3",
+     "bdefc8a204f238f54114f0992cdb9fad73ae65fc",
      []
     ],
     "closing-handshake": {
      "002_wpt_flags=h2-expected.txt": [
-      "ccb3a2e8a20917bedc08900f075f5e5a3bbf0807",
+      "d7b469ea78ce6682d825ec24da446c6239f0f49c",
       []
      ],
      "003_wpt_flags=h2-expected.txt": [
-      "9fd9e495a60ce86d7b6ab284d257b10dbe8e162a",
+      "a2a65a975b6e980499147818c5a44500a9a68f0e",
       []
      ],
      "004_wpt_flags=h2-expected.txt": [
-      "c9026b544020d15d76bfed51564d899d18107af3",
+      "6187d5f2ef16d128ebdac02165890e7e57c8cdc0",
       []
      ]
     },
@@ -416901,66 +416648,58 @@
      []
     ],
     "constructor": {
-     "002-expected.txt": [
-      "283195c46953c3316edc4b755737a466938acec5",
-      []
-     ],
-     "002_wpt_flags=h2-expected.txt": [
-      "283195c46953c3316edc4b755737a466938acec5",
-      []
-     ],
      "006_wpt_flags=h2-expected.txt": [
-      "0ad976a4280b35a778cd2e3ff7abc1667d2e9950",
+      "700b4a31a4bae2d9fb94e88164160091794370d6",
       []
      ],
      "009_wpt_flags=h2-expected.txt": [
-      "31ce2c601d88468fdf8b6817afd3eeaf49ce87db",
+      "02d6bc586c37ee7fe2359280371dc11dd9ff720d",
       []
      ],
      "013_wpt_flags=h2-expected.txt": [
-      "f78e8dde2fc4f604c78363238e4f2f1db76be7d3",
+      "fde1f324ea664830cf91437e9f726b405602d3e4",
       []
      ],
      "016_wpt_flags=h2-expected.txt": [
-      "fc4a33f8485512952cf0183a082fa50981fe08fa",
+      "8d310634b9ebfe0a7743674ecc84cbb1cb36038a",
       []
      ],
      "018_wpt_flags=h2-expected.txt": [
-      "4b452358fe9e768034c90098ba530b7b8d8a1950",
+      "6516b7fdf34e04184b9c2364710f5f140ce6a5d6",
       []
      ],
      "019_wpt_flags=h2-expected.txt": [
-      "887475f20e1968a3040a1c57953e58dfc4e22b45",
+      "9d14ea73c17e725a40b0ced2a00ea9f352b6278e",
       []
      ],
      "020_wpt_flags=h2-expected.txt": [
-      "0fc1ac2ffce1d2974aeb040d2a61b0a3cc51994f",
+      "fe914fbd768914cfbd900c0812bcbef83d1842e5",
       []
      ],
      "022_wpt_flags=h2-expected.txt": [
-      "f9ebad13531264d88d32248dc49ca119dadfa1f0",
+      "e449b7511ab240bb9b2199da3d0028e7ab976f2a",
       []
      ]
     },
     "cookies": {
      "001_wpt_flags=h2-expected.txt": [
-      "5c10cb5e8768fd91d549b2da17e3d4002771e7df",
+      "642c8265878b3bba861dbe1b8ffa7ba5bf420db0",
       []
      ],
      "002_wpt_flags=h2-expected.txt": [
-      "ae76b8d067cf98c54e3e9839abcdc7787bc6eda1",
+      "b993c256f4f8be287ab5bbe1b400a606a0cd4898",
       []
      ],
      "003_wpt_flags=h2-expected.txt": [
-      "45c8430ac83a8512a6e9cc33c3699280c47d0942",
+      "2b19e10518643d14a178e9a0c32595b6f525c94a",
       []
      ],
      "006_wpt_flags=h2-expected.txt": [
-      "43826ac152c7787201ac996ae04f2875b4b8fd9e",
+      "c60b34a535fea54826a233a6360ddf7b783fa955",
       []
      ],
      "006_wss_wpt_flags=https-expected.txt": [
-      "5cd37f416058b1e1982f5ecbb95b85489eb9617a",
+      "07c0600881310a25b8369bd2ae2b7dd769bd1dbc",
       []
      ],
      "007.html.ini": [
@@ -416968,15 +416707,11 @@
       []
      ],
      "007_default-expected.txt": [
-      "31f81ab668a73ac19650d1fb4730f66ec4711489",
+      "2c576976391c1c0d58b3d9283364e043f5c5ae60",
       []
      ],
      "007_wpt_flags=h2-expected.txt": [
-      "292e01330f408f178a0df6700ac984df17a61b50",
-      []
-     ],
-     "007_wss-expected.txt": [
-      "31f81ab668a73ac19650d1fb4730f66ec4711489",
+      "b89fbc37540db5837cc9705201c6d2abbe921e43",
       []
      ],
      "support": {
@@ -417123,18 +416858,18 @@
     "interfaces": {
      "CloseEvent": {
       "clean-close_wpt_flags=h2-expected.txt": [
-       "828cd2fa4475f4765b4f4e1ceb1b3ab5ea86648f",
+       "fdce3d184846eb60265c780e190c0639d6685442",
        []
       ]
      },
      "WebSocket": {
       "bufferedAmount": {
        "bufferedAmount-getting_wpt_flags=h2-expected.txt": [
-        "0eef06727c15c4c2b3cab9caa943d822ad85058b",
+        "6a40c7abdd4b42380e577900c9393912a8af2db3",
         []
        ],
        "bufferedAmount-unicode_wpt_flags=h2-expected.txt": [
-        "5defd8842bc9ff1225bc0a5cc7afae14ad3a918a",
+        "66d2aa61046f9c33fb876ab256a6a4847af40486",
         []
        ]
       },
@@ -417150,11 +416885,11 @@
       },
       "events": {
        "016_wpt_flags=h2-expected.txt": [
-        "d7808b6401aefe917b9faa0de2b3cc6c82f1cf36",
+        "69578b92ec6f3241de6e980a89824787c932db45",
         []
        ],
        "018_wpt_flags=h2-expected.txt": [
-        "bb4458e51593c2e41410455577c1abd3da8fdda9",
+        "2a0e7953f3c642eb39d9b51223b715bc30a2e401",
         []
        ]
       },
@@ -417166,19 +416901,19 @@
       },
       "send": {
        "007_wpt_flags=h2-expected.txt": [
-        "00923e854c688a4f15b08e65a3ce174dbec96e5b",
+        "9f254bc9ee99f237e7284823b04b22dea719d5f7",
         []
        ],
        "009_wpt_flags=h2-expected.txt": [
-        "1b093bb240a3cba073fbdc598c5806f35d46f39e",
+        "7c04a7ff66d9126d5e042671bc488a222cde8fe7",
         []
        ],
        "011_wpt_flags=h2-expected.txt": [
-        "bf6f468afb52b805b3f66ead8a12874b4d28dc10",
+        "9f5433be8c501bdb63706530374b6a81e803231e",
         []
        ],
        "012_wpt_flags=h2-expected.txt": [
-        "13975df1338229db05ed0aae8ff15ed93a7614b5",
+        "87f71c2ae97a732bff1418036bcdf421f06f2a12",
         []
        ]
       }
@@ -417186,7 +416921,7 @@
     },
     "keeping-connection-open": {
      "001_wpt_flags=h2-expected.txt": [
-      "52f298c1807acc639a185729d7bfcbe86a0c747f",
+      "cf854c421e9a73beb4bcc1a96523a9db8b249203",
       []
      ]
     },
@@ -417195,7 +416930,7 @@
      []
     ],
     "mixed-content.https.any.sharedworker-expected.txt": [
-     "bfe24740c143e4bd7b5a1b199f4371150ff4dfbc",
+     "5c182f772edbbdcfd92df31139bb1ec29879ce92",
      []
     ],
     "multi-globals": {
@@ -417223,7 +416958,7 @@
        ]
       },
       "url-parsing-expected.txt": [
-       "4b8e0fb25350d7c9bbc21c2aa342bdcf62e753ff",
+       "101896de0d1729afad1bfa2f73fa93b859d3e792",
        []
       ],
       "url-parsing.html.ini": [
@@ -417234,7 +416969,7 @@
     },
     "opening-handshake": {
      "002_wpt_flags=h2-expected.txt": [
-      "fbd877855525fa83da2da8b0204d66941f78e6de",
+      "664b724b2876d755f486b2f3513aa71fcdb54c16",
       []
      ]
     },
@@ -417255,19 +416990,19 @@
      []
     ],
     "send-many-64K-messages-with-backpressure.any.serviceworker_wpt_flags=h2-expected.txt": [
-     "f589fdd474ab316c633bdddb443fb366f81cac3b",
+     "349eb1a0cac7e84cc84443b10d3fbdd7e0bc8d5c",
      []
     ],
     "send-many-64K-messages-with-backpressure.any.sharedworker_wpt_flags=h2-expected.txt": [
-     "f589fdd474ab316c633bdddb443fb366f81cac3b",
+     "349eb1a0cac7e84cc84443b10d3fbdd7e0bc8d5c",
      []
     ],
     "send-many-64K-messages-with-backpressure.any.worker_wpt_flags=h2-expected.txt": [
-     "f589fdd474ab316c633bdddb443fb366f81cac3b",
+     "349eb1a0cac7e84cc84443b10d3fbdd7e0bc8d5c",
      []
     ],
     "send-many-64K-messages-with-backpressure.any_wpt_flags=h2-expected.txt": [
-     "f589fdd474ab316c633bdddb443fb366f81cac3b",
+     "349eb1a0cac7e84cc84443b10d3fbdd7e0bc8d5c",
      []
     ],
     "stream": {
@@ -417277,35 +417012,31 @@
        []
       ],
       "abort.any.serviceworker_wpt_flags=h2-expected.txt": [
-       "dc14c816526d9598d74410321e307ff441b48c40",
+       "c2727496c9efd03c35fdf2f6c8a1112ab96b1438",
        []
       ],
       "abort.any.sharedworker_wpt_flags=h2-expected.txt": [
-       "dc14c816526d9598d74410321e307ff441b48c40",
+       "c2727496c9efd03c35fdf2f6c8a1112ab96b1438",
        []
       ],
       "abort.any.worker_wpt_flags=h2-expected.txt": [
-       "dc14c816526d9598d74410321e307ff441b48c40",
+       "c2727496c9efd03c35fdf2f6c8a1112ab96b1438",
        []
       ],
       "abort.any_wpt_flags=h2-expected.txt": [
-       "dc14c816526d9598d74410321e307ff441b48c40",
-       []
-      ],
-      "backpressure-receive.any.serviceworker_wpt_flags=h2-expected.txt": [
-       "f6919e924d47316fe1b4159c89723babcdcb5b3e",
+       "c2727496c9efd03c35fdf2f6c8a1112ab96b1438",
        []
       ],
       "backpressure-receive.any.sharedworker_wpt_flags=h2-expected.txt": [
-       "f6919e924d47316fe1b4159c89723babcdcb5b3e",
+       "9db766c05661edc426ec217ddc81e3cb7e19d986",
        []
       ],
       "backpressure-receive.any.worker_wpt_flags=h2-expected.txt": [
-       "f6919e924d47316fe1b4159c89723babcdcb5b3e",
+       "9db766c05661edc426ec217ddc81e3cb7e19d986",
        []
       ],
       "backpressure-receive.any_wpt_flags=h2-expected.txt": [
-       "f6919e924d47316fe1b4159c89723babcdcb5b3e",
+       "9db766c05661edc426ec217ddc81e3cb7e19d986",
        []
       ],
       "backpressure-send.any.js.ini": [
@@ -417313,15 +417044,15 @@
        []
       ],
       "backpressure-send.any.sharedworker_wpt_flags=h2-expected.txt": [
-       "f453bf19e7850b844e8afaa0ca2aebae8602d779",
+       "3e276159bb14578ed46833a69d62f3920ad66848",
        []
       ],
       "backpressure-send.any.worker_wpt_flags=h2-expected.txt": [
-       "f453bf19e7850b844e8afaa0ca2aebae8602d779",
+       "3e276159bb14578ed46833a69d62f3920ad66848",
        []
       ],
       "backpressure-send.any_wpt_flags=h2-expected.txt": [
-       "f453bf19e7850b844e8afaa0ca2aebae8602d779",
+       "3e276159bb14578ed46833a69d62f3920ad66848",
        []
       ],
       "close.any.js.ini": [
@@ -417333,19 +417064,19 @@
        []
       ],
       "constructor.any.serviceworker_wpt_flags=h2-expected.txt": [
-       "1841a3ded5b72bba7b904a2912287b859506e321",
+       "32c34ab447f98577b0fd3eac7c861449da46c8cd",
        []
       ],
       "constructor.any.sharedworker_wpt_flags=h2-expected.txt": [
-       "1841a3ded5b72bba7b904a2912287b859506e321",
+       "32c34ab447f98577b0fd3eac7c861449da46c8cd",
        []
       ],
       "constructor.any.worker_wpt_flags=h2-expected.txt": [
-       "1841a3ded5b72bba7b904a2912287b859506e321",
+       "32c34ab447f98577b0fd3eac7c861449da46c8cd",
        []
       ],
       "constructor.any_wpt_flags=h2-expected.txt": [
-       "1841a3ded5b72bba7b904a2912287b859506e321",
+       "32c34ab447f98577b0fd3eac7c861449da46c8cd",
        []
       ],
       "resources": {
@@ -417366,7 +417097,7 @@
       []
      ],
      "001_wpt_flags=h2-expected.txt": [
-      "aa0c1e593d42ed9fbb8bdf8d9edc83cbd6b6f0cd",
+      "9a20095a80b5e1eb616e90c71189a18cbc2f924d",
       []
      ],
      "002-1.html": [
@@ -417382,19 +417113,15 @@
       []
      ],
      "002_default-expected.txt": [
-      "1da3d918cc7a5d19defaf83597f2ad43524b53ae",
+      "c69e6b0af4e6c1718d396644caec4afab69988ba",
       []
      ],
      "002_wpt_flags=h2-expected.txt": [
-      "186cb19c8271c5a43cef08cc34f759dc7374ff49",
-      []
-     ],
-     "002_wss-expected.txt": [
-      "99bc35549b21eea376fb8cfa288e2f04b53205a2",
+      "0d29f4b2bd7837f577e67f151e8c5c0e30db7eb2",
       []
      ],
      "004-expected.txt": [
-      "108c294cf8342f337aeccad7d9c2b60a8c484843",
+      "acbbbc4a708d6dd061a953ac3639d6d9866f5d01",
       []
      ],
      "004.html.ini": [
@@ -417406,7 +417133,7 @@
       []
      ],
      "005_wpt_flags=h2-expected.txt": [
-      "3092338fc8f49b13698f93f3de3c5e75839daf58",
+      "34118a8b53bc7bd077f8db1126ba81524f3be718",
       []
      ]
     }
@@ -458220,6 +457947,15 @@
        }
       ]
      ],
+     "cross-origin-status.https.html": [
+      "a01eb27b5a60164fe0a3cd5ad6b16293902736f9",
+      [
+       null,
+       {
+        "testdriver": true
+       }
+      ]
+     ],
      "logged-out.https.html": [
       "09750ff0968a76b47815a0c299d1bb3bc535733f",
       [
@@ -469030,7 +468766,7 @@
        ]
       ],
       "font-style-parsing.html": [
-       "57384eaba33170f7c39450fcf0aa595e3f3190fb",
+       "8a9ad50b931188fda49a4eaacc64742e287edd74",
        [
         null,
         {}
@@ -492318,7 +492054,7 @@
       ]
      ],
      "checkVisibility.html": [
-      "3ab1cc7dc2e366302607dda7091ce3513810d112",
+      "20fb767bc91330a56a71a1f9b205260f9c493219",
       [
        null,
        {}
@@ -534821,6 +534557,185 @@
        }
       ]
      ],
+     "clear-origin-joined-ad-interest-groups.https.window.js": [
+      "7d6e715ac45d979b541cfb50f2044ef34178df26",
+      [
+       "fledge/tentative/clear-origin-joined-ad-interest-groups.https.window.html?1-4",
+       {
+        "script_metadata": [
+         [
+          "script",
+          "/resources/testdriver.js"
+         ],
+         [
+          "script",
+          "/common/utils.js"
+         ],
+         [
+          "script",
+          "resources/fledge-util.sub.js"
+         ],
+         [
+          "script",
+          "/common/subset-tests.js"
+         ],
+         [
+          "timeout",
+          "long"
+         ],
+         [
+          "variant",
+          "?1-4"
+         ],
+         [
+          "variant",
+          "?5-8"
+         ],
+         [
+          "variant",
+          "?9-12"
+         ],
+         [
+          "variant",
+          "?13-last"
+         ]
+        ],
+        "timeout": "long"
+       }
+      ],
+      [
+       "fledge/tentative/clear-origin-joined-ad-interest-groups.https.window.html?13-last",
+       {
+        "script_metadata": [
+         [
+          "script",
+          "/resources/testdriver.js"
+         ],
+         [
+          "script",
+          "/common/utils.js"
+         ],
+         [
+          "script",
+          "resources/fledge-util.sub.js"
+         ],
+         [
+          "script",
+          "/common/subset-tests.js"
+         ],
+         [
+          "timeout",
+          "long"
+         ],
+         [
+          "variant",
+          "?1-4"
+         ],
+         [
+          "variant",
+          "?5-8"
+         ],
+         [
+          "variant",
+          "?9-12"
+         ],
+         [
+          "variant",
+          "?13-last"
+         ]
+        ],
+        "timeout": "long"
+       }
+      ],
+      [
+       "fledge/tentative/clear-origin-joined-ad-interest-groups.https.window.html?5-8",
+       {
+        "script_metadata": [
+         [
+          "script",
+          "/resources/testdriver.js"
+         ],
+         [
+          "script",
+          "/common/utils.js"
+         ],
+         [
+          "script",
+          "resources/fledge-util.sub.js"
+         ],
+         [
+          "script",
+          "/common/subset-tests.js"
+         ],
+         [
+          "timeout",
+          "long"
+         ],
+         [
+          "variant",
+          "?1-4"
+         ],
+         [
+          "variant",
+          "?5-8"
+         ],
+         [
+          "variant",
+          "?9-12"
+         ],
+         [
+          "variant",
+          "?13-last"
+         ]
+        ],
+        "timeout": "long"
+       }
+      ],
+      [
+       "fledge/tentative/clear-origin-joined-ad-interest-groups.https.window.html?9-12",
+       {
+        "script_metadata": [
+         [
+          "script",
+          "/resources/testdriver.js"
+         ],
+         [
+          "script",
+          "/common/utils.js"
+         ],
+         [
+          "script",
+          "resources/fledge-util.sub.js"
+         ],
+         [
+          "script",
+          "/common/subset-tests.js"
+         ],
+         [
+          "timeout",
+          "long"
+         ],
+         [
+          "variant",
+          "?1-4"
+         ],
+         [
+          "variant",
+          "?5-8"
+         ],
+         [
+          "variant",
+          "?9-12"
+         ],
+         [
+          "variant",
+          "?13-last"
+         ]
+        ],
+        "timeout": "long"
+       }
+      ]
+     ],
      "component-ads.https.window.js": [
       "fb59045572ff7305ca107eeb5c190ee74d64277d",
       [
@@ -573735,7 +573650,7 @@
     },
     "dom": {
      "aria-attribute-reflection.html": [
-      "afcee82eda17358177b890784eb30d4ce5de173d",
+      "e201d4660eb754b9560d1b48f22dd2c063d04658",
       [
        null,
        {}
@@ -574273,8 +574188,8 @@
          {}
         ]
        ],
-       "dir-slots-directionality.tentative.html": [
-        "5e8cedb9c156f7c3f83d6e22af46e31cc1ed5874",
+       "dir-slots-directionality.html": [
+        "db783fc55ca3493e75d10f3e8f6d400e5187e531",
         [
          null,
          {}
@@ -604961,6 +604876,13 @@
     ],
     "mse-for-webcodecs": {
      "tentative": {
+      "mediasource-encrypted-webcodecs-appendencodedchunks-play.https.html": [
+       "47238af30d4f6cf2e104c4989fde877686e0958f",
+       [
+        null,
+        {}
+       ]
+      ],
       "mediasource-webcodecs-addsourcebuffer.html": [
        "e29600f99c6b4b1fc5ca0e8c9b0cd939cb27c1e1",
        [
@@ -604969,7 +604891,7 @@
        ]
       ],
       "mediasource-webcodecs-appendencodedchunks-play.html": [
-       "4df317a537ea0f6929caaf94a3d9f8009cf4f656",
+       "f93f5a9883fba258abda03079d6b9af276c8b138",
        [
         null,
         {}
@@ -604986,11 +604908,19 @@
       {}
      ]
     ],
+    "GUM-faceFraming.https.html": [
+     "ef457206215d52824b1d38128fec4794c37ca45e",
+     [
+      null,
+      {}
+     ]
+    ],
     "MediaStreamTrack-video-stats.https.html": [
-     "0f85f75b665b53fece76902410a7227e28caeab5",
+     "6901ed84e39cc081c9bda6f614e0906e71baf47f",
      [
       null,
       {
+       "testdriver": true,
        "timeout": "long"
       }
      ]
@@ -667500,6 +667430,13 @@
         {}
        ]
       ],
+      "audioworklet-registerprocessor-constructor.https.window.js": [
+       "679480b480d64d19e825f63ad3798a50d0e3204b",
+       [
+        "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-registerprocessor-constructor.https.window.html",
+        {}
+       ]
+      ],
       "audioworklet-registerprocessor-dynamic.https.html": [
        "de31f71427d5cd29e61935e8f82217e1c8bc0341",
        [
@@ -711699,20 +711636,6 @@
        {}
       ]
      ],
-     "border-image-image-type-001.htm": [
-      "ebc152fe74bd165b68cda0953ce3ef5545aa998d",
-      [
-       null,
-       {}
-      ]
-     ],
-     "border-image-image-type-002.htm": [
-      "39adbb34d0bbc93b2375240bb75873c167c5282c",
-      [
-       null,
-       {}
-      ]
-     ],
      "border-image-outset-001.htm": [
       "db0a8f5f6bb7ecfa034ae0d53f1833e26cc45fc3",
       [
@@ -715284,7 +715207,7 @@
        },
        "response_started": {
         "response_started.py": [
-         "d3a84fd6f9711738a453d205d17f316271b9686c",
+         "2af26974b4578dbd1fb5dcfe651d672160660f86",
          [
           null,
           {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-image-type-001.htm b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-image-type-001.htm
index ebc152f..9486f0b8 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-image-type-001.htm
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-image-type-001.htm
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-image-type-002.htm b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-image-type-002.htm
index 39adbb34d..f365793 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-image-type-002.htm
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-image-type-002.htm
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-image-type-004.htm b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-image-type-004.htm
new file mode 100644
index 0000000..1e6953e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-image-type-004.htm
@@ -0,0 +1,44 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+        <title>CSS Backgrounds and Borders Test: The 'border-image-source' property with an SVG image as a value and the 'border-image-slice' property with four number values</title>
+        <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" />
+        <link rel="help" href="http://www.w3.org/TR/css3-background/#the-border-image-slice" />
+        <link rel="match" href="reference/border-image-image-type-004-ref.html" />
+        <meta name="flags" content="svg" />
+        <meta name="assert" content="This test checks that the SVG image used for the border image is sliced into nine regions with inward offsets of: '40 30 20 10' vector coordinates from the top, right, bottom, and left edges of the image set by the 'border-image-slice' property." />
+        <style type="text/css">
+            div
+            {
+                border: 50px double red;
+                border-image-slice: 40 30 20 10;
+                border-image-source: url("support/9-colored-areas-40-30-20-10.svg");
+                height: 0px;
+                width: 0px;
+            }
+        </style>
+    </head>
+    <body>
+          <p>Test passes if there is a filled yellow square, then, on its right-hand side, a contiguous filled aqua square, then, below, a contiguous filled fuchsia square and finally a filled black square and <strong>no red</strong>.</p>
+        <div></div>
+
+  <!--
+
+  Expected result:
+
+ (0,100) (50,100) (100,100)
+   + - - - - - - -+
+   |       ^      |
+   |Yellow50 Aqua |
+   |       v      |
+   | - - - - - - -|
+   |       ^      |
+   |Fuchsi50 Black|
+   |       v      |
+   | - - - - - - -|
+ (0,0)          (100,0)
+
+  -->
+
+    </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-image-type-005.htm b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-image-type-005.htm
new file mode 100644
index 0000000..0503b5a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/border-image-image-type-005.htm
@@ -0,0 +1,44 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+        <title>CSS Backgrounds and Borders Test: The 'border-image-source' property with an SVG image as a value and the 'border-image-slice' property with percentage values</title>
+        <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" />
+        <link rel="help" href="http://www.w3.org/TR/css3-background/#the-border-image-slice" />
+        <link rel="match" href="reference/border-image-image-type-004-ref.html" />
+        <meta name="flags" content="svg" />
+        <meta name="assert" content="This test checks that border image is sliced into nine regions with inward offsets of: '40% 30% 20% 10%' from the top, right, bottom, and left edges of the image. Percentages are relative to the size of the image: the width of the image for the horizontal offsets, the height for vertical offsets." />
+        <style type="text/css">
+            div
+            {
+                border: 50px double red;
+                border-image-slice: 40% 30% 20% 10%;
+                border-image-source: url("support/9-colored-areas-40-30-20-10.svg");
+                height: 0px;
+                width: 0px;
+            }
+        </style>
+    </head>
+    <body>
+        <p>Test passes if there is a filled yellow square, then, on its right-hand side, a contiguous filled aqua square, then, below, a contiguous filled fuchsia square and finally a filled black square and <strong>no red</strong>.</p>
+        <div></div>
+
+  <!--
+
+  Expected result:
+
+ (0,100) (50,100) (100,100)
+   + - - - - - - -+
+   |       ^      |
+   |Yellow50 Aqua |
+   |       v      |
+   | - - - - - - -|
+   |       ^      |
+   |Fuchsi50 Black|
+   |       v      |
+   | - - - - - - -|
+ (0,0)          (100,0)
+
+  -->
+
+    </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/border-image-image-type-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/border-image-image-type-001-ref.html
new file mode 100644
index 0000000..feb13018
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/border-image-image-type-001-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+
+  <meta charset="UTF-8">
+
+  <title>CSS Reftest reference</title>
+
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+
+  <style>
+  div
+    {
+      border: 50px double red;
+      border-image-slice: 20 15 10 5;
+      border-image-source: url("../support/9-colored-areas-40-30-20-10.png");
+      height: 100px;
+      width: 100px;
+    }
+  </style>
+
+  <p>Test passes if there is an hollow square with thick borders made of 8 different colors (yellow, blue, aqua, orange, teal, fuchsia, purple and black) and if there is <strong>no red</strong>.
+
+  <div></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/border-image-image-type-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/border-image-image-type-002-ref.html
new file mode 100644
index 0000000..3fc7646
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/border-image-image-type-002-ref.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+
+  <meta charset="UTF-8">
+
+  <title>CSS Reftest reference</title>
+
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+
+  <style>
+  div
+    {
+      border: 50px double red;
+      border-image-slice: 40% 30% 20% 10%;
+      border-image-source: url("../support/9-colored-areas-40-30-20-10.png");
+      height: 100px;
+      width: 100px;
+    }
+  </style>
+
+  <p>Test passes if there is an hollow square with thick borders made of 8 different colors (yellow, blue, aqua, orange, teal, fuchsia, purple and black) and if there is <strong>no red</strong>.
+
+  <!--
+
+  Expected result:
+
+  +------------------+
+  |yel|   blue   |aqu|
+  |- - - - - - - - - |
+  |or |          | t |
+  | a |          | e |
+  | n |          | a |
+  |ge |          | l |
+  |- - - - - - - - - |
+  |fuc|  purple  |bla|
+  +------------------+
+
+  -->
+
+  <div></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/border-image-image-type-004-ref.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/border-image-image-type-004-ref.html
new file mode 100644
index 0000000..b126682
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/border-image-image-type-004-ref.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+
+  <meta charset="UTF-8">
+
+  <title>CSS Reftest reference</title>
+
+  <link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
+
+  <style>
+  div
+    {
+      border: 50px double red;
+      border-image-slice: 40 30 20 10;
+      border-image-source: url("../support/9-colored-areas-40-30-20-10.png");
+      height: 0px;
+      width: 0px;
+    }
+  </style>
+
+  <p>Test passes if there is a filled yellow square, then, on its right-hand side, a contiguous filled aqua square, then, below, a contiguous filled fuchsia square and finally a filled black square and <strong>no red</strong>.
+
+  <div></div>
+
+  <!--
+
+  Expected result:
+
+ (0,100) (50,100) (100,100)
+   + - - - - - - -+
+   |       ^      |
+   |Yellow50 Aqua |
+   |       v      |
+   | - - - - - - -|
+   |       ^      |
+   |Fuchsi50 Black|
+   |       v      |
+   | - - - - - - -|
+ (0,0)          (100,0)
+
+  -->
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/support/9-colored-areas-40-30-20-10.png b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/support/9-colored-areas-40-30-20-10.png
new file mode 100644
index 0000000..3f640c7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/support/9-colored-areas-40-30-20-10.png
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/support/9-colored-areas-40-30-20-10.svg b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/support/9-colored-areas-40-30-20-10.svg
new file mode 100644
index 0000000..c5896a9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/support/9-colored-areas-40-30-20-10.svg
@@ -0,0 +1,32 @@
+
+<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
+
+  <!--
+
+  Author: Gérard Talbot
+
+  Created: August 9th 2023
+
+  Last modified: October 5th 2023
+
+  -->
+
+    <rect x="0" y="0" width="10" height="40" fill="yellow" />
+
+    <rect x="10" y="0" width="60" height="40" fill="blue" />
+
+    <rect x="70" y="0" width="30" height="40" fill="aqua" />
+
+    <rect x="0" y="40" width="10" height="40" fill="orange" />
+
+    <rect x="10" y="40" width="60" height="40" fill="red" />
+
+    <rect x="70" y="40" width="30" height="40" fill="teal" />
+
+    <rect x="0" y="80" width="10" height="20" fill="fuchsia" />
+
+    <rect x="10" y="80" width="60" height="20" fill="purple" />
+
+    <rect x="70" y="80" width="30" height="20" fill="black" />
+
+</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-on-root-svg-ref.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-on-root-svg-ref.html
new file mode 100644
index 0000000..258cdfac
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-on-root-svg-ref.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<title>CSS Content Visibility: effect on root <svg> element (reference)</title>
+<link rel="author" href="mailto:rbuis@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-on-root-svg.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-on-root-svg.html
new file mode 100644
index 0000000..440d1ad
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-on-root-svg.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>CSS Content Visibility: effect on root <svg> element</title>
+<link rel="author" href="mailto:rbuis@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
+<link rel="match" href="content-visibility-on-root-svg-ref.html">
+<meta name="assert" content="content-visibility hidden has an effect on root svg element">
+
+<div>
+  <svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" style="content-visibility:hidden">
+    <g>
+      <text x="5" y="16" transform="scale(2, 2)">Hello World!</text>
+      <text x="8" y="32" transform="translate(0 20) scale(1.25 1)">Hello World Again!</text>
+    </g>
+  </svg>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/variations/font-style-parsing-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-fonts/variations/font-style-parsing-expected.txt
index 5b1e860..519fefa 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-fonts/variations/font-style-parsing-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/variations/font-style-parsing-expected.txt
@@ -33,7 +33,7 @@
   assert_equals: Font-style computed style: 'oblique' followed by zero degrees is valid expected "oblique 0deg" but got "normal"
 [PASS] Font-style (computed): 'oblique' followed by positive angle in degrees is valid
 [FAIL] Font-style (computed): 'oblique' followed by positive angle in radians is valid
-  assert_equals: Font-style computed style: 'oblique' followed by positive angle in radians is valid expected "oblique 28.6479deg" but got "oblique 28.5deg"
+  assert_regexp_match: Font-style computed style: 'oblique' followed by positive angle in radians is valid expected object "/^oblique 28\.64\d*deg$/" but got "oblique 28.5deg"
 [PASS] Font-style (computed): 'oblique' followed by positive angle in gradians is valid
 [PASS] Font-style (computed): 'oblique' followed by positive angle in turns is valid
 [PASS] Font-style (computed): 'oblique' followed by negative angle is valid
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/variations/font-style-parsing.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/variations/font-style-parsing.html
index 57384ea..8a9ad50 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-fonts/variations/font-style-parsing.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/variations/font-style-parsing.html
@@ -16,7 +16,7 @@
             { style: "oblique",                     expectedResult: true,   message: "'oblique' is valid" },
             { style: "oblique 0deg",                expectedResult: true,   message: "'oblique' followed by zero degrees is valid" },
             { style: "oblique 20deg",               expectedResult: true,   message: "'oblique' followed by positive angle in degrees is valid" },
-            { style: "oblique 0.5rad",              expectedResult: true,   message: "'oblique' followed by positive angle in radians is valid",    expectedValue: "oblique 28.6479deg" },
+            { style: "oblique 0.5rad",              expectedResult: true,   message: "'oblique' followed by positive angle in radians is valid",    expectedValue: /^oblique 28\.64\d*deg$/ },
             { style: "oblique 20grad",              expectedResult: true,   message: "'oblique' followed by positive angle in gradians is valid",   expectedValue: "oblique 18deg" },
             { style: "oblique 0.1turn",             expectedResult: true,   message: "'oblique' followed by positive angle in turns is valid",      expectedValue: "oblique 36deg" },
             { style: "oblique 20px",                expectedResult: false,  message: "'oblique' followed by number with invalid unit type is in valid" },
@@ -50,8 +50,10 @@
                 test(() => {
                     let element = document.getElementById("test");
                     element.style = "font-style: " + testCase.style;
-                    let expectedValue = (testCase.expectedValue) ? testCase.expectedValue : testCase.style;
-                    assert_equals(window.getComputedStyle(element).fontStyle, expectedValue, "Font-style computed style: " + testCase.message);
+                    let actualValue = getComputedStyle(element).fontStyle;
+                    let expectedValue = testCase.expectedValue ?? testCase.style;
+                    let assert_fn = expectedValue instanceof RegExp ? assert_regexp_match : assert_equals;
+                    assert_fn(actualValue, expectedValue, "Font-style computed style: " + testCase.message);
                 }, "Font-style (computed): " + testCase.message);
             }
         });
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-8-ref.html b/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-8-ref.html
new file mode 100644
index 0000000..d7276bd6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-8-ref.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <style type="text/css">
+      div.outer {
+        /*
+         * content box: 40 x 20
+         * padding box: 52 x 38
+         * border  box: 60 x 50
+         * margin  box: 66 x 54
+         */
+        background-color: purple;
+        position: absolute;
+        top: 10px;
+        margin: 1px 2px 3px 4px;
+        border: solid transparent;
+        border-width: 8px 2px 4px 6px;
+        padding: 6px 9px 12px 3px;
+        width: 40px;
+        height: 20px;
+        mask-size: 100% 100%;
+        mask-image: url(support/transparent-100x50-blue-100x50.svg);
+      }
+
+      div.first {
+        left: 10px;
+        mask-origin: border-box;
+      }
+
+      div.second {
+        left: 110px;
+        mask-origin: border-box;
+      }
+
+      div.third {
+        left: 210px;
+        mask-origin: content-box;
+      }
+
+    </style>
+  </head>
+  <body>
+    <div class="outer mask first"></div>
+    <div class="outer mask second"></div>
+    <div class="outer mask third"></div>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-8.html b/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-8.html
new file mode 100644
index 0000000..924920f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-masking/mask-image/mask-clip-8.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>CSS Masking: mask-clip: clip mask image</title>
+    <link rel="help" href="http://www.w3.org/TR/css-masking-1/#the-mask-clip">
+    <link rel="match" href="mask-clip-8-ref.html">
+    <meta name="assert" content="Check fall back values for fill-box (:content-box), stroke-box and view-box (:border-box).">
+    <style type="text/css">
+      div.outer {
+        /*
+         * content box: 40 x 20
+         * padding box: 52 x 38
+         * border  box: 60 x 50
+         * margin  box: 66 x 54
+         */
+        background-color: purple;
+        position: absolute;
+        top: 10px;
+        margin: 1px 2px 3px 4px;
+        border: solid transparent;
+        border-width: 8px 2px 4px 6px;
+        padding: 6px 9px 12px 3px;
+        width: 40px;
+        height: 20px;
+        mask-size: 100% 100%;
+        mask-image: url(support/transparent-100x50-blue-100x50.svg);
+      }
+
+      div.first {
+        left: 10px;
+        mask-origin: stroke-box;
+      }
+
+      div.second {
+        left: 110px;
+        mask-origin: view-box;
+      }
+
+      div.third {
+        left: 210px;
+        mask-origin: fill-box;
+      }
+
+    </style>
+  </head>
+  <body>
+    <div class="outer mask first"></div>
+    <div class="outer mask second"></div>
+    <div class="outer mask third"></div>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-margin-auto-001.html b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-margin-auto-001.html
new file mode 100644
index 0000000..9ec1c3f0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-position/position-absolute-margin-auto-001.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>Tests the calculation of negative auto margins of absolutely positioned element</title>
+<link rel="help" href="https://drafts.csswg.org/css-position/#abspos-margins">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1492323">
+<link rel="author" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<style>
+.cb {
+  position: relative;
+  width: 400px;
+  height: 400px;
+  outline: 1px dashed black;
+}
+
+.target {
+  writing-mode: vertical-lr;
+  position: absolute;
+  background: green;
+  width: calc(100% - 100px);
+  height: calc(100% - 100px);
+  inset: 100px;
+  margin: auto;
+}
+</style>
+
+<body onload="checkLayout('.target')">
+  <div class="cb">
+    <div class="target"
+         data-expected-margin-top="-50" data-expected-margin-bottom="-50"
+         data-expected-margin-left="0" data-expected-margin-right="-100"></div>
+  </div>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/scale-and-rotate-both-specified-on-animation-keyframes-ref.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/scale-and-rotate-both-specified-on-animation-keyframes-ref.html
new file mode 100644
index 0000000..e3cf99f9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/scale-and-rotate-both-specified-on-animation-keyframes-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Animating both the "scale" and "rotate" property</title>
+<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
+
+<style>
+
+#target {
+    position: absolute;
+    width: 100px;
+    height: 100px;
+    background-color: black;
+
+    transform-origin: bottom left;
+    rotate: 90deg;
+}
+
+</style>
+</head>
+<body>
+<div id="target"></div>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/scale-and-rotate-both-specified-on-animation-keyframes.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/scale-and-rotate-both-specified-on-animation-keyframes.html
new file mode 100644
index 0000000..708bfa49
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/animation/scale-and-rotate-both-specified-on-animation-keyframes.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+<title>Animating both the "scale" and "rotate" property</title>
+<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
+<link rel="match" href="scale-and-rotate-both-specified-on-animation-keyframes-ref.html">
+
+<style>
+
+@keyframes scale-and-rotate-animation {
+    0%      { scale: 1.5; rotate: 0deg; }
+    0.001%  { scale: 1; rotate: 90deg; }
+    100%    { scale: 1; rotate: 90deg; }
+}
+
+#target {
+    position: absolute;
+    width: 100px;
+    height: 100px;
+    background-color: black;
+
+    transform-origin: bottom left;
+    animation: scale-and-rotate-animation linear 100s;
+}
+
+</style>
+</head>
+<body>
+<div id="target"></div>
+
+<script>
+
+(async function() {
+    // We need to wait for the animation to have started and progressed for one frame
+    // before taking the snapshot.
+    await Promise.all(document.getAnimations().map(animation => animation.ready));
+    await new Promise(requestAnimationFrame);
+    document.documentElement.classList.remove("reftest-wait");
+})();
+
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/backface-visibility-hidden-005.html.ini b/third_party/blink/web_tests/external/wpt/css/css-transforms/backface-visibility-hidden-005.html.ini
deleted file mode 100644
index ac8498a..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-transforms/backface-visibility-hidden-005.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[backface-visibility-hidden-005.html]
-  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/backface-visibility-hidden-animated-002.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/backface-visibility-hidden-animated-002.html
new file mode 100644
index 0000000..b3029f9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/backface-visibility-hidden-animated-002.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<html class=reftest-wait>
+  <link rel="author" title="Xianzhu Wang" href="mailto:wangxianzhu@chromium.org">
+  <link rel="help" href="https://drafts.csswg.org/css-transforms-2/#propdef-backface-visibility">
+  <link rel="match" href="backface-visibility-hidden-animated-ref.html">
+  <style>
+    @keyframes show-backface {
+      0% { transform: rotateY(60deg); }
+      0.01% { transform: rotateY(180deg); }
+      100% { transform: rotateY(180deg); }
+    }
+
+    .flip {
+      animation: 10s linear 0s infinite forwards show-backface;
+      height: 100px;
+      width: 100px;
+      transform: rotateY(60deg);
+      transform-style: preserve-3d;
+    }
+
+    #back {
+      background: lightblue;
+      transform: rotateY(180deg);
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 200px;
+      height: 200px;
+      backface-visibility: hidden;
+    }
+
+    #posabs {
+      position: absolute;
+      /* This is the only difference from backface-visibility-hidden-animated-001.html. */
+      will-change: transform;
+      bottom: 0;
+      right: 0;
+      background: yellow;
+    }
+  </style>
+  <div id="flip">
+    <div id="back">
+      <i id="posabs">Text</i>
+    </div>
+  </div>
+  <script>
+    onload = () => requestAnimationFrame(() => requestAnimationFrame(() => {
+      flip.classList.add("flip");
+      requestAnimationFrame(() => requestAnimationFrame(() =>
+          document.documentElement.classList.remove("reftest-wait")));
+    }));
+  </script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/backface-visibility-hidden-child-will-change-transform.html.ini b/third_party/blink/web_tests/external/wpt/css/css-transforms/backface-visibility-hidden-child-will-change-transform.html.ini
deleted file mode 100644
index 179228c..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-transforms/backface-visibility-hidden-child-will-change-transform.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[backface-visibility-hidden-child-will-change-transform.html]
-  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-clip.html.ini b/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-clip.html.ini
deleted file mode 100644
index 6b095a0..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-clip.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[composited-under-rotateY-180deg-clip.html]
-  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-perspective.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-perspective.html
new file mode 100644
index 0000000..c91e6f7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-perspective.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<title>CSS Test (Transforms): composited under rotateY(180deg)</title>
+<link rel="help" href="http://www.w3.org/TR/css-transforms-2">
+<meta name="assert" content="This tests that a composited element with default
+  backface-visibility is visible under rotateY(180deg) and perspective,
+  and invisible under rotateY(180deg), perspective and backface-visibility:hidden.">
+<link rel="match" href="composited-under-rotateY-180deg-ref.html">
+<div style="transform: rotateY(180deg); width: 100px; perspective: 10px">
+  <div style="width: 100px; height: 100px; background: green; will-change: transform"></div>
+</div>
+<div style="transform: rotateY(180deg); width: 100px; backface-visibility: hidden; perspective: 10px">
+  <div style="width: 100px; height: 100px; background: red; will-change: transform"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-preserve-3d.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-preserve-3d.html
new file mode 100644
index 0000000..282d0b1c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg-preserve-3d.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>CSS Test (Transforms): composited under backface-visibility:hidden, rotateY(180deg) and preserve-3d</title>
+<link rel="help" href="http://www.w3.org/TR/css-transforms-2">
+<meta name="assert" content="This tests that a composited element with default
+  backface-visibility is visible under backface-visibility:hidden, rotateY(180deg) and preserve-3d.">
+<link rel="match" href="composited-under-rotateY-180deg-ref.html">
+<div style="transform: rotateY(180deg); width: 100px; backface-visibility: hidden; transform-style: preserve-3d">
+  <div style="width: 100px; height: 100px; background: green; will-change: transform"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg.html
index 01ff42a..674cc449 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg.html
@@ -2,7 +2,7 @@
 <title>CSS Test (Transforms): composited under rotateY(180deg)</title>
 <link rel="help" href="http://www.w3.org/TR/css-transforms-2">
 <meta name="assert" content="This tests that a composited element with default
-  backface-visibility is visible under rotateY(180deg).">
+  backface-visibility is visible under rotateY(180deg), and invisible under rotateY(180deg) and backface-visibility:hidden.">
 <link rel="match" href="composited-under-rotateY-180deg-ref.html">
 <div style="transform: rotateY(180deg); width: 100px">
   <div style="width: 100px; height: 100px; background: green; will-change: transform"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg.html.ini b/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg.html.ini
deleted file mode 100644
index ea54133730..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-transforms/composited-under-rotateY-180deg.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[composited-under-rotateY-180deg.html]
-  expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/checkVisibility.html b/third_party/blink/web_tests/external/wpt/css/cssom-view/checkVisibility.html
index 3ab1cc7..20fb767 100644
--- a/third_party/blink/web_tests/external/wpt/css/cssom-view/checkVisibility.html
+++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/checkVisibility.html
@@ -16,6 +16,10 @@
 
 <div id=displaynone style="display:none">hello</div>
 
+<div id=displaycontents style="display:contents">
+  <div id=displaycontentschild>hello</div>
+</div>
+
 <div id=opacityzero style="opacity:0">hello</div>
 
 <div style="content-visibility:hidden">
@@ -67,6 +71,11 @@
 }, 'checkVisibility on display:none element.');
 
 test(() => {
+  assert_false(displaycontents.checkVisibility());
+  assert_true(displaycontentschild.checkVisibility());
+}, 'checkVisibility on display:contents element.');
+
+test(() => {
   assert_false(opacityzero.checkVisibility({
     checkOpacity: true
   }), 'checkOpacity:true');
diff --git a/third_party/blink/web_tests/external/wpt/css/printing/page-margin-005-print-ref.html b/third_party/blink/web_tests/external/wpt/css/printing/page-margin-005-print-ref.html
new file mode 100644
index 0000000..bd1829b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/printing/page-margin-005-print-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+  @page {
+    size: 600px 300px;
+    margin: 30px;
+  }
+  body {
+    margin: 0;
+    background: cyan;
+  }
+</style>
+The page margins should be the same on every side (30px).<br>
+There's a 30px square in the bottom right corner.
+<div style="position:fixed; right:0; bottom:0; width:30px; height:30px; background:hotpink;"></div>
+<div style="break-before:page;">
+  Same on the second page.
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/printing/page-margin-005-print.html b/third_party/blink/web_tests/external/wpt/css/printing/page-margin-005-print.html
new file mode 100644
index 0000000..8ca80bc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/printing/page-margin-005-print.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<title>Percentage-based @page margins should resolve against the correct dimension</title>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-page-3/#page-properties">
+<link rel="match" href="page-margin-005-print-ref.html">
+<style>
+  @page {
+    size: 600px 300px;
+    margin: 10% 5%;
+  }
+  body {
+    margin: 0;
+    background: cyan;
+  }
+</style>
+The page margins should be the same on every side (30px).<br>
+There's a 30px square in the bottom right corner.
+<div style="position:fixed; right:0; bottom:0; width:30px; height:30px; background:hotpink;"></div>
+<div style="break-before:page;">
+  Same on the second page.
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/editing/crashtests/set-input-value-of-editing-host-after-changing-type.html b/third_party/blink/web_tests/external/wpt/editing/crashtests/set-input-value-of-editing-host-after-changing-type.html
new file mode 100644
index 0000000..34a1558
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/editing/crashtests/set-input-value-of-editing-host-after-changing-type.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<script>
+document.addEventListener("DOMContentLoaded", () => {
+  const input = document.querySelector("input");
+  input.focus();
+  input.type = "text";
+  input.value = "new value";
+}, {once: true});
+</script>
+</head>
+<body><input type="button" contenteditable></body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/TODO b/third_party/blink/web_tests/external/wpt/fledge/tentative/TODO
index 3ab7418..8217bdc9 100644
--- a/third_party/blink/web_tests/external/wpt/fledge/tentative/TODO
+++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/TODO
@@ -31,7 +31,6 @@
 * adAuctionConfig passed to reportResult().
 * Component auctions.
   * Including cross-origin sellers.
-* clearOriginJoinedInterestGroups.
 * browserSignals fields in scoring/bidding methods.
 * In reporting methods, browserSignals fields: dataVersion, topLevelSeller,
     componentSeller, modifiedBid, adCost, madeHighestScoringOtherBid
@@ -57,10 +56,17 @@
   * etc.
 * Test that await is not needed for same-origin interest groups
   * Verify that's still in the spec/explainer first.
+* executionMode
+  * Including cross-origin join/leave behavior with "group-by-origin" mode.
+* Make sure state is not shared.
+  * Across scoreAd() / generateBid() calls, and with report calls.
+  * In "group-by-origin" execution mode across IGs joined from different
+      origins, and between generateBid() and reportWin().
 
 If possible:
 * Aggregate reporting.
-* Join/leave permission delegation via .well-known files.
+* Join/leave permission delegation via .well-known files
+  * Including tests for clearOriginJoinedInterestGroups().
 * k-anonymity.
 * Signals request batching. This is an optional feature, so can't require it,
     but maybe a test where batching could be used, and make sure things work,
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/clear-origin-joined-ad-interest-groups.https.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/clear-origin-joined-ad-interest-groups.https.window.js
new file mode 100644
index 0000000..7d6e715
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/clear-origin-joined-ad-interest-groups.https.window.js
@@ -0,0 +1,312 @@
+// META: script=/resources/testdriver.js
+// META: script=/common/utils.js
+// META: script=resources/fledge-util.sub.js
+// META: script=/common/subset-tests.js
+// META: timeout=long
+// META: variant=?1-4
+// META: variant=?5-8
+// META: variant=?9-12
+// META: variant=?13-last
+
+"use strict;"
+
+///////////////////////////////////////////////////////////////////////////////
+// Basic tests with no interest groups joined.
+///////////////////////////////////////////////////////////////////////////////
+
+subsetTest(promise_test, async test => {
+  await navigator.clearOriginJoinedAdInterestGroups(window.location.origin);
+}, 'clearOriginJoinedAdInterestGroups(), no groups joined, no group list.');
+
+subsetTest(promise_test, async test => {
+  await navigator.clearOriginJoinedAdInterestGroups(window.location.origin, []);
+}, 'clearOriginJoinedAdInterestGroups(), no groups joined, group list.');
+
+subsetTest(promise_test, async test => {
+  try {
+    await navigator.clearOriginJoinedAdInterestGroups(OTHER_ORIGIN1);
+    throw 'Exception unexpectedly not thrown';
+  } catch (e) {
+    if (!(e instanceof DOMException) || e.name !== 'NotAllowedError') {
+      throw 'Wrong exception thrown: ' + e.toString();
+    }
+  }
+}, 'clearOriginJoinedAdInterestGroups(), cross-origin, no groups joined, no group list.');
+
+subsetTest(promise_test, async test => {
+  try {
+    await navigator.clearOriginJoinedAdInterestGroups(OTHER_ORIGIN1, []);
+    throw 'Exception unexpectedly not thrown';
+  } catch (e) {
+    if (!(e instanceof DOMException) || e.name !== 'NotAllowedError') {
+      throw 'Wrong exception thrown: ' + e.toString();
+    }
+  }
+}, 'clearOriginJoinedAdInterestGroups(), cross-origin, no groups joined, group list.');
+
+///////////////////////////////////////////////////////////////////////////////
+// Tests where interest groups are all owned by document.location.origin.
+///////////////////////////////////////////////////////////////////////////////
+
+subsetTest(promise_test, async test => {
+  const uuid = generateUuid(test);
+
+  // Join 3 groups.
+  await joinInterestGroup(test, uuid);
+  await joinInterestGroup(test, uuid, {name: 'group 2'});
+  await joinInterestGroup(test, uuid, {name: 'group 3'});
+
+  // A single clear should leave them all.
+  await navigator.clearOriginJoinedAdInterestGroups(window.location.origin);
+
+  // Confirm that they were left.
+  await runBasicFledgeTestExpectingNoWinner(test, uuid);
+}, 'clearOriginJoinedAdInterestGroups(), multiple groups joined, no group list.');
+
+subsetTest(promise_test, async test => {
+  const uuid = generateUuid(test);
+
+  let group1ReportURL = createBidderReportURL(uuid, /*id=*/'1');
+  let group2ReportURL = createBidderReportURL(uuid, /*id=*/'2');
+  let group3ReportURL = createBidderReportURL(uuid, /*id=*/'3');
+
+  // Join 3 groups, with distinct report URLs and increasing bid amounts.
+  // Set "executionMode" to "group-by-origin" for two of them, since cross-origin
+  // leaves removes all groups joined from the other origin with that execution
+  // mode. Since clearOriginJoinedAdInterestGroups() only leaves interest
+  // groups joined on the current origin, the executionMode should not matter.
+  await joinInterestGroup(
+      test, uuid,
+      { name: 'group 1',
+        executionMode: 'group-by-origin',
+        biddingLogicURL: createBiddingScriptURL(
+            { bid: 1, reportWin: `sendReportTo("${group1ReportURL}");`})});
+  await joinInterestGroup(
+      test, uuid,
+      { name: 'group 2',
+        biddingLogicURL: createBiddingScriptURL(
+            { bid: 2, reportWin: `sendReportTo("${group2ReportURL}");`})});
+  await joinInterestGroup(
+      test, uuid,
+      { name: 'group 3',
+        executionMode: 'group-by-origin',
+        biddingLogicURL: createBiddingScriptURL(
+            { bid: 3, reportWin: `sendReportTo("${group3ReportURL}");`})});
+
+  // Group 3 should win an auction, since it bids the most.
+  await runBasicFledgeAuctionAndNavigate(test, uuid);
+  await waitForObservedRequests(
+      uuid, [group3ReportURL, createSellerReportURL(uuid)]);
+  await fetch(createCleanupURL(uuid));
+
+  // Clear, leaving group 1 in place, and run an auction, which group 1 should win.
+  await navigator.clearOriginJoinedAdInterestGroups(
+      window.location.origin, ['group 1']);
+  await runBasicFledgeAuctionAndNavigate(test, uuid);
+  await waitForObservedRequests(
+      uuid, [group1ReportURL, createSellerReportURL(uuid)]);
+
+  // Clear with an empty list, which should leave group 1 as well. Verify it can't
+  // win an auction.
+  await navigator.clearOriginJoinedAdInterestGroups(window.location.origin, []);
+  await runBasicFledgeTestExpectingNoWinner(test, uuid);
+}, 'clearOriginJoinedAdInterestGroups(), multiple groups joined, group list.');
+
+subsetTest(promise_test, async test => {
+  const uuid = generateUuid(test);
+
+  // Join an interest group in a same-origin top-level window.
+  await joinInterestGroupInTopLevelWindow(test, uuid, window.location.origin);
+
+  // Make sure it was joined.
+  await runBasicFledgeTestExpectingWinner(test, uuid);
+
+  // Call "clearOriginJoinedAdInterestGroups()", which should leave the interest
+  // group, since it was joined from a same-origin main frame.
+  await navigator.clearOriginJoinedAdInterestGroups(window.location.origin);
+
+  // Make sure group was left.
+  await runBasicFledgeTestExpectingNoWinner(test, uuid);
+}, 'clearOriginJoinedAdInterestGroups(), group joined from same-origin top-level context.');
+
+subsetTest(promise_test, async test => {
+  const uuid = generateUuid(test);
+
+  // Create top-level browsing context for another origin, and have it join an
+  // interest group owned by this document's origin.
+  let topLevelWindow = await createTopLevelWindow(test, OTHER_ORIGIN1);
+  let interestGroup = JSON.stringify(
+      createInterestGroupForOrigin(uuid, window.location.origin));
+  await runInFrame(test, topLevelWindow,
+                   `await joinCrossOriginInterestGroup(test_instance, "${uuid}",
+                                                       "${window.location.origin}",
+                                                       ${interestGroup});`);
+
+  // Call "clearOriginJoinedAdInterestGroups()", which should not leave the interest
+  // group, since it was joined from a cross-origin main frame.
+  await navigator.clearOriginJoinedAdInterestGroups(window.location.origin);
+
+  // Make sure group was not left.
+  await runBasicFledgeTestExpectingWinner(test, uuid);
+}, 'clearOriginJoinedAdInterestGroups(), group joined from cross-origin top-level context.');
+
+subsetTest(promise_test, async test => {
+  const uuid = generateUuid(test);
+
+  await joinInterestGroup(test, uuid);
+
+  // In a cross-origin iframe, call clearOriginJoinedAdInterestGroups() both for the
+  // iframe's origin and for the main frame's origin. The latter should throw an
+  // exception, and neither should manage to leave the interest group.
+  let iframe = await createIframe(test, OTHER_ORIGIN1, 'join-ad-interest-group');
+  await runInFrame(test, iframe,
+                   `// Call clearOriginJoinedAdInterestGroups() with the iframe's origin.
+                    await navigator.clearOriginJoinedAdInterestGroups(window.location.origin);
+                    try {
+                      // Call clearOriginJoinedAdInterestGroups() with the main frame's origin.
+                      await navigator.clearOriginJoinedAdInterestGroups("${window.location.origin}");
+                    } catch (e) {
+                      assert_true(e instanceof DOMException, "DOMException thrown");
+                      assert_equals(e.name, "NotAllowedError", "NotAllowedError DOMException thrown");
+                      return {result: "success"};
+                    }
+                    throw "Exception unexpectedly not thrown";`);
+
+  // Confirm that the interest group was not left.
+  await runBasicFledgeTestExpectingWinner(test, uuid);
+}, "clearOriginJoinedAdInterestGroups(), cross-origin iframe tries to leave parent frame's group.");
+
+subsetTest(promise_test, async test => {
+  const uuid = generateUuid(test);
+
+  // The possible results of calling clearOriginJoinedAdInterestGroups():
+
+  // Doesn't throw an exception.
+  const noExpectionURL = createTrackerURL(origin, uuid, "track_get", "no_exception");
+  // Throws the exception it's expected to.
+  const exceptionURL = createTrackerURL(origin, uuid, "track_get", "exception");
+  // Throws the wrong exception.
+  const badExpectionURL = createTrackerURL(origin, uuid, "track_get", "bad_exception");
+
+  // Create a render URL that calls clearOriginJoinedAdInterestGroups() and
+  // then requests one of the above tracking URLs, based on the resulting
+  // behaviot.
+  const renderURL = createRenderURL(
+      uuid,
+      `async function TryClear() {
+         try {
+           await navigator.clearOriginJoinedAdInterestGroups(
+               "${window.location.origin}");
+           await fetch("${noExpectionURL}");
+         } catch (e) {
+           if (e instanceof DOMException && e.name === "NotAllowedError") {
+             await fetch("${exceptionURL}");
+           } else {
+             await fetch("${badExpectionURL}");
+           }
+         }
+       }
+
+       TryClear();`);
+
+  await joinInterestGroup(
+      test, uuid,
+      {ads: [{ renderURL: renderURL}]});
+
+  await runBasicFledgeAuctionAndNavigate(test, uuid);
+
+  // This should wait until the clear call has thrown an exception.
+  await waitForObservedRequests(
+      uuid,
+      [createBidderReportURL(uuid), createSellerReportURL(uuid), exceptionURL]);
+
+  // Check the interest group was not left.
+  await runBasicFledgeTestExpectingWinner(test, uuid);
+}, 'clearOriginJoinedAdInterestGroups() in ad fenced frame throws an exception.');
+
+///////////////////////////////////////////////////////////////////////////////
+// Tests where some interest groups are owned by another origin.
+///////////////////////////////////////////////////////////////////////////////
+
+subsetTest(promise_test, async test => {
+  const uuid = generateUuid(test);
+
+  // Join interest group in iframe and make sure it was joined.
+  let iframe = await createIframe(test, OTHER_ORIGIN1, 'join-ad-interest-group');
+  await runInFrame(test, iframe,
+                   `await joinInterestGroup(test_instance, "${uuid}");
+                    await runBasicFledgeTestExpectingWinner(test_instance, "${uuid}");`);
+
+  // In the main frame, Call clearOriginJoinedAdInterestGroups() for both the main
+  // frame's origin, and the origin of the iframe / joined interest group. Neither
+  // should leave the group, and the second should throw.
+  await navigator.clearOriginJoinedAdInterestGroups(window.location.origin);
+  try {
+    await navigator.clearOriginJoinedAdInterestGroups(OTHER_ORIGIN1);
+    throw 'Exception unexpectedly not thrown';
+  } catch (e) {
+    if (!(e instanceof DOMException) || e.name !== 'NotAllowedError') {
+      throw 'Wrong exception thrown: ' + e.toString();
+    }
+  }
+
+  // In an iframe, confirm the group was never left.
+  await runInFrame(test, iframe,
+      `await runBasicFledgeTestExpectingWinner(test_instance, "${uuid}");`);
+}, 'clearOriginJoinedAdInterestGroups(). Cross-origin interest group joined in iframe, try to clear in main frame.');
+
+subsetTest(promise_test, async test => {
+  const uuid = generateUuid(test);
+
+  let iframe = await createIframe(test, OTHER_ORIGIN1, 'join-ad-interest-group');
+  await runInFrame(test, iframe,
+                   `await joinInterestGroup(test_instance, "${uuid}");
+
+                    // Confirm that trying to clear the interest group using the main frame's
+                    // origin throws, and does not leave the group.
+                    try {
+                      await navigator.clearOriginJoinedAdInterestGroups("${window.location.origin}");
+                      throw 'Exception unexpectedly not thrown';
+                    } catch (e) {
+                      if (!(e instanceof DOMException) || e.name !== 'NotAllowedError') {
+                        throw 'Wrong exception thrown: ' + e.toString();
+                      }
+                    }
+                    await runBasicFledgeTestExpectingWinner(test_instance, "${uuid}");`);
+}, 'clearOriginJoinedAdInterestGroups(). Cross-origin interest group joined in iframe, clear call in iframe passing main frame origin.');
+
+subsetTest(promise_test, async test => {
+  const uuid = generateUuid(test);
+
+  let iframe = await createIframe(test, OTHER_ORIGIN1, 'join-ad-interest-group');
+  await runInFrame(test, iframe,
+                   `await joinInterestGroup(test_instance, "${uuid}");
+
+                    // Clear call with the origin of the cross-origin iframe.
+                    // This should successfully leave the interest group.
+                    await navigator.clearOriginJoinedAdInterestGroups("${OTHER_ORIGIN1}");
+
+                    // Verify the group was left.
+                    await runBasicFledgeTestExpectingNoWinner(test_instance, "${uuid}");`);
+}, 'clearOriginJoinedAdInterestGroups(). Cross-origin interest group joined in iframe, clear call in iframe passing iframe origin.');
+
+subsetTest(promise_test, async test => {
+  const uuid = generateUuid(test);
+
+  // Join an OTHER_ORIGIN1 interest group in an OTHER_ORIGIN1 main frame.
+  let topLevelWindow = await createTopLevelWindow(test, OTHER_ORIGIN1);
+  await runInFrame(test, topLevelWindow,
+                   `await joinInterestGroup(test_instance, "${uuid}");`);
+
+  let iframe = await createIframe(test, OTHER_ORIGIN1, 'join-ad-interest-group');
+
+  await runInFrame(test, iframe,
+                   `// Clear call from an OTHER_ORIGIN1 iframe on a different
+                    // origin's main frame. This should not clear the interest
+                    // group that was just joined, because the joining origin
+                    // does not match.
+                    await navigator.clearOriginJoinedAdInterestGroups("${OTHER_ORIGIN1}");
+
+                    // Verify the group was not left.
+                    await runBasicFledgeTestExpectingWinner(test_instance, "${uuid}");`);
+}, 'clearOriginJoinedAdInterestGroups(). Cross-origin interest group joined from another joining origin, clear call in iframe.');
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.sub.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.sub.js
index 4a8a087ad..ffe7468c 100644
--- a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.sub.js
+++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.sub.js
@@ -40,6 +40,13 @@
   return url.toString();
 }
 
+// Create a URL that when fetches clears tracked URLs. Note that the origin
+// doesn't matter - it will clean up all tracked URLs with the provided uuid,
+// regardless of origin they were fetched from.
+function createCleanupURL(uuid) {
+  return createTrackerURL(window.location.origin, uuid, 'clean_up');
+}
+
 // Create tracked bidder/seller URLs. The only difference is the prefix added
 // to the `id` passed to createTrackerURL. The optional `id` field allows
 // multiple bidder/seller report URLs to be distinguishable from each other.
@@ -65,8 +72,8 @@
 function generateUuid(test) {
   let uuid = token();
   test.add_cleanup(async () => {
-    let cleanupURL = createTrackerURL(window.location.origin, uuid, 'clean_up');
-    let response = await fetch(cleanupURL, {credentials: 'omit', mode: 'cors'});
+    let response = await fetch(createCleanupURL(uuid),
+                               {credentials: 'omit', mode: 'cors'});
     assert_equals(await response.text(), 'cleanup complete',
                   `Sever state cleanup failed`);
   });
@@ -479,8 +486,13 @@
 
 // Wrapper around createFrame() that creates an iframe and optionally sets
 // permissions.
-async function createIframe(test, origin, permissions) {
-  return createFrame(test, origin, /*is_iframe=*/ true, permissions);
+async function createIframe(test, origin, permissions = null) {
+  return await createFrame(test, origin, /*is_iframe=*/true, permissions);
+}
+
+// Wrapper around createFrame() that creates a top-level window.
+async function createTopLevelWindow(test, origin) {
+  return await createFrame(test, origin, /*is_iframe=*/false);
 }
 
 // Joins a cross-origin interest group. Currently does this by joining the
@@ -495,3 +507,15 @@
   await runInFrame(test, iframe,
                    `await joinInterestGroup(test_instance, "${uuid}", ${interestGroup})`);
 }
+
+// Joins an interest group in a top-level window, which has the same origin
+// as the joined interest group.
+async function joinInterestGroupInTopLevelWindow(
+    test, uuid, origin, interestGroupOverrides = {}) {
+  let interestGroup = JSON.stringify(
+      createInterestGroupForOrigin(uuid, origin, interestGroupOverrides));
+
+  let topLeveWindow = await createTopLevelWindow(test, origin);
+  await runInFrame(test, topLeveWindow,
+                   `await joinInterestGroup(test_instance, "${uuid}", ${interestGroup})`);
+}
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/aria-attribute-reflection.html b/third_party/blink/web_tests/external/wpt/html/dom/aria-attribute-reflection.html
index afcee82e..e201d46 100644
--- a/third_party/blink/web_tests/external/wpt/html/dom/aria-attribute-reflection.html
+++ b/third_party/blink/web_tests/external/wpt/html/dom/aria-attribute-reflection.html
@@ -6,6 +6,14 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 
+<script>
+function testNullable(element, jsAttr, contentAttr) {
+    element[jsAttr] = null;
+    assert_equals(element[jsAttr], null);
+    assert_false(element.hasAttribute(contentAttr));
+}
+</script>
+
 <div id="role" role="button"></div>
 <script>
 test(function(t) {
@@ -13,6 +21,7 @@
     assert_equals(element.role, "button");
     element.role = "checkbox";
     assert_equals(element.getAttribute("role"), "checkbox");
+    testNullable(element, "role", "role");
 }, "role attribute reflects.");
 </script>
 
@@ -23,6 +32,7 @@
     assert_equals(element.ariaAtomic, "true");
     element.ariaAtomic = "false";
     assert_equals(element.getAttribute("aria-atomic"), "false");
+    testNullable(element, "ariaAtomic", "aria-atomic");
 }, "aria-atomic attribute reflects.");
 </script>
 
@@ -33,6 +43,7 @@
     assert_equals(element.ariaAutoComplete, "list");
     element.ariaAutoComplete = "inline";
     assert_equals(element.getAttribute("aria-autocomplete"), "inline");
+    testNullable(element, "ariaAutoComplete", "aria-autocomplete");
 }, "aria-autocomplete attribute reflects.");
 </script>
 
@@ -43,6 +54,7 @@
     assert_equals(element.ariaBusy, "true");
     element.ariaBusy = "false";
     assert_equals(element.getAttribute("aria-busy"), "false");
+    testNullable(element, "ariaBusy", "aria-busy");
 }, "aria-busy attribute reflects.");
 </script>
 
@@ -53,6 +65,7 @@
     assert_equals(element.ariaChecked, "mixed");
     element.ariaChecked = "true";
     assert_equals(element.getAttribute("aria-checked"), "true");
+    testNullable(element, "ariaChecked", "aria-checked");
 }, "aria-checked attribute reflects.");
 </script>
 
@@ -63,6 +76,7 @@
     assert_equals(element.ariaColCount, "5");
     element.ariaColCount = "6";
     assert_equals(element.getAttribute("aria-colcount"), "6");
+    testNullable(element, "ariaColCount", "aria-colcount");
 }, "aria-colcount attribute reflects.");
 </script>
 
@@ -73,6 +87,7 @@
     assert_equals(element.ariaColIndex, "1");
     element.ariaColIndex = "2";
     assert_equals(element.getAttribute("aria-colindex"), "2");
+    testNullable(element, "ariaColIndex", "aria-colindex");
 }, "aria-colindex attribute reflects.");
 </script>
 
@@ -83,6 +98,7 @@
     assert_equals(element.ariaColSpan, "2");
     element.ariaColSpan = "3";
     assert_equals(element.getAttribute("aria-colspan"), "3");
+    testNullable(element, "ariaColSpan", "aria-colspan");
 }, "aria-colspan attribute reflects.");
 </script>
 
@@ -93,6 +109,7 @@
     assert_equals(element.ariaCurrent, "page");
     element.ariaCurrent = "step";
     assert_equals(element.getAttribute("aria-current"), "step");
+    testNullable(element, "ariaCurrent", "aria-current");
 }, "aria-current attribute reflects.");
 </script>
 
@@ -105,6 +122,7 @@
     assert_equals(element.ariaDescription, "cold as ice");
     element.ariaDescription = "hot as fire";
     assert_equals(element.getAttribute("aria-description"), "hot as fire");
+    testNullable(element, "ariaDescription", "aria-description");
 }, "aria-description attribute reflects.");
 </script>
 
@@ -114,6 +132,7 @@
     assert_equals(element.ariaDisabled, "true");
     element.ariaDisabled = "false";
     assert_equals(element.getAttribute("aria-disabled"), "false");
+    testNullable(element, "ariaDisabled", "aria-disabled");
 }, "aria-disabled attribute reflects.");
 </script>
 
@@ -124,6 +143,7 @@
     assert_equals(element.ariaExpanded, "true");
     element.ariaExpanded = "false";
     assert_equals(element.getAttribute("aria-expanded"), "false");
+    testNullable(element, "ariaExpanded", "aria-expanded");
 }, "aria-expanded attribute reflects.");
 </script>
 
@@ -134,6 +154,7 @@
     assert_equals(element.ariaHasPopup, "menu");
     element.ariaHasPopup = "listbox";
     assert_equals(element.getAttribute("aria-haspopup"), "listbox");
+    testNullable(element, "ariaHasPopup", "aria-haspopup");
 }, "aria-haspopup attribute reflects.");
 </script>
 
@@ -144,6 +165,7 @@
     assert_equals(element.ariaHidden, "true");
     element.ariaHidden = "false";
     assert_equals(element.getAttribute("aria-hidden"), "false");
+    testNullable(element, "ariaHidden", "aria-hidden");
 }, "aria-hidden attribute reflects.");
 </script>
 
@@ -154,6 +176,7 @@
     assert_equals(element.ariaInvalid, "true");
     element.ariaInvalid = "grammar";
     assert_equals(element.getAttribute("aria-invalid"), "grammar");
+    testNullable(element, "ariaInvalid", "aria-invalid");
 }, "aria-invalid attribute reflects.");
 </script>
 
@@ -164,6 +187,7 @@
     assert_equals(element.ariaKeyShortcuts, "x");
     element.ariaKeyShortcuts = "y";
     assert_equals(element.getAttribute("aria-keyshortcuts"), "y");
+    testNullable(element, "ariaKeyShortcuts", "aria-keyshortcuts");
 }, "aria-keyshortcuts attribute reflects.");
 </script>
 
@@ -174,6 +198,7 @@
     assert_equals(element.ariaLabel, "x");
     element.ariaLabel = "y";
     assert_equals(element.getAttribute("aria-label"), "y");
+    testNullable(element, "ariaLabel", "aria-label");
 }, "aria-label attribute reflects.");
 </script>
 
@@ -184,6 +209,7 @@
     assert_equals(element.ariaLevel, "1");
     element.ariaLevel = "2";
     assert_equals(element.getAttribute("aria-level"), "2");
+    testNullable(element, "ariaLevel", "aria-level");
 }, "aria-level attribute reflects.");
 </script>
 
@@ -194,6 +220,7 @@
     assert_equals(element.ariaLive, "polite");
     element.ariaLive = "assertive";
     assert_equals(element.getAttribute("aria-live"), "assertive");
+    testNullable(element, "ariaLive", "aria-live");
 }, "aria-live attribute reflects.");
 </script>
 
@@ -204,6 +231,7 @@
     assert_equals(element.ariaModal, "true");
     element.ariaModal = "false";
     assert_equals(element.getAttribute("aria-modal"), "false");
+    testNullable(element, "ariaModal", "aria-modal");
 }, "aria-modal attribute reflects.");
 </script>
 
@@ -214,6 +242,7 @@
     assert_equals(element.ariaMultiLine, "true");
     element.ariaMultiLine = "false";
     assert_equals(element.getAttribute("aria-multiline"), "false");
+    testNullable(element, "ariaMultiLine", "aria-multiline");
 }, "aria-multiline attribute reflects.");
 </script>
 
@@ -224,6 +253,7 @@
     assert_equals(element.ariaMultiSelectable, "true");
     element.ariaMultiSelectable = "false";
     assert_equals(element.getAttribute("aria-multiselectable"), "false");
+    testNullable(element, "ariaMultiSelectable", "aria-multiselectable");
 }, "aria-multiselectable attribute reflects.");
 </script>
 
@@ -234,6 +264,7 @@
     assert_equals(element.ariaOrientation, "vertical");
     element.ariaOrientation = "horizontal";
     assert_equals(element.getAttribute("aria-orientation"), "horizontal");
+    testNullable(element, "ariaOrientation", "aria-orientation");
 }, "aria-orientation attribute reflects.");
 </script>
 
@@ -244,6 +275,7 @@
     assert_equals(element.ariaPlaceholder, "x");
     element.ariaPlaceholder = "y";
     assert_equals(element.getAttribute("aria-placeholder"), "y");
+    testNullable(element, "ariaPlaceholder", "aria-placeholder");
 }, "aria-placeholder attribute reflects.");
 </script>
 
@@ -254,6 +286,7 @@
     assert_equals(element.ariaPosInSet, "10");
     element.ariaPosInSet = "11";
     assert_equals(element.getAttribute("aria-posinset"), "11");
+    testNullable(element, "ariaPosInSet", "aria-posinset");
 }, "aria-posinset attribute reflects.");
 </script>
 
@@ -265,6 +298,7 @@
     assert_equals(element.ariaPressed, "true");
     element.ariaPressed = "false";
     assert_equals(element.getAttribute("aria-pressed"), "false");
+    testNullable(element, "ariaPressed", "aria-pressed");
 }, "aria-pressed attribute reflects.");
 </script>
 
@@ -275,6 +309,7 @@
     assert_equals(element.ariaReadOnly, "true");
     element.ariaReadOnly = "false";
     assert_equals(element.getAttribute("aria-readonly"), "false");
+    testNullable(element, "ariaReadOnly", "aria-readonly");
 }, "aria-readonly attribute reflects.");
 </script>
 
@@ -285,6 +320,7 @@
     assert_equals(element.ariaRelevant, "text");
     element.ariaRelevant = "removals";
     assert_equals(element.getAttribute("aria-relevant"), "removals");
+    testNullable(element, "ariaRelevant", "aria-relevant");
 }, "aria-relevant attribute reflects.");
 </script>
 
@@ -295,6 +331,7 @@
     assert_equals(element.ariaRequired, "true");
     element.ariaRequired = "false";
     assert_equals(element.getAttribute("aria-required"), "false");
+    testNullable(element, "ariaRequired", "aria-required");
 }, "aria-required attribute reflects.");
 </script>
 
@@ -305,6 +342,7 @@
     assert_equals(element.ariaRoleDescription, "x");
     element.ariaRoleDescription = "y";
     assert_equals(element.getAttribute("aria-roledescription"), "y");
+    testNullable(element, "ariaRoleDescription", "aria-roledescription");
 }, "aria-roledescription attribute reflects.");
 </script>
 
@@ -315,6 +353,7 @@
     assert_equals(element.ariaRowCount, "10");
     element.ariaRowCount = "11";
     assert_equals(element.getAttribute("aria-rowcount"), "11");
+    testNullable(element, "ariaRowCount", "aria-rowcount");
 }, "aria-rowcount attribute reflects.");
 </script>
 
@@ -325,6 +364,7 @@
     assert_equals(element.ariaRowIndex, "1");
     element.ariaRowIndex = "2";
     assert_equals(element.getAttribute("aria-rowindex"), "2");
+    testNullable(element, "ariaRowIndex", "aria-rowindex");
 }, "aria-rowindex attribute reflects.");
 </script>
 
@@ -335,6 +375,7 @@
     assert_equals(element.ariaRowSpan, "2");
     element.ariaRowSpan = "3";
     assert_equals(element.getAttribute("aria-rowspan"), "3");
+    testNullable(element, "ariaRowSpan", "aria-rowspan");
 }, "aria-rowspan attribute reflects.");
 </script>
 
@@ -345,6 +386,7 @@
     assert_equals(element.ariaSelected, "true");
     element.ariaSelected = "false";
     assert_equals(element.getAttribute("aria-selected"), "false");
+    testNullable(element, "ariaSelected", "aria-selected");
 }, "aria-selected attribute reflects.");
 </script>
 
@@ -355,6 +397,7 @@
     assert_equals(element.ariaSetSize, "10");
     element.ariaSetSize = "11";
     assert_equals(element.getAttribute("aria-setsize"), "11");
+    testNullable(element, "ariaSetSize", "aria-setsize");
 }, "aria-setsize attribute reflects.");
 </script>
 
@@ -365,6 +408,7 @@
     assert_equals(element.ariaSort, "descending");
     element.ariaSort = "ascending";
     assert_equals(element.getAttribute("aria-sort"), "ascending");
+    testNullable(element, "ariaSort", "aria-sort");
 }, "aria-sort attribute reflects.");
 </script>
 
@@ -375,6 +419,7 @@
     assert_equals(element.ariaValueMax, "99");
     element.ariaValueMax = "100";
     assert_equals(element.getAttribute("aria-valuemax"), "100");
+    testNullable(element, "ariaValueMax", "aria-valuemax");
 }, "aria-valuemax attribute reflects.");
 </script>
 
@@ -385,6 +430,7 @@
     assert_equals(element.ariaValueMin, "3");
     element.ariaValueMin = "2";
     assert_equals(element.getAttribute("aria-valuemin"), "2");
+    testNullable(element, "ariaValueMin", "aria-valuemin");
 }, "aria-valuemin attribute reflects.");
 </script>
 
@@ -395,6 +441,7 @@
     assert_equals(element.ariaValueNow, "50");
     element.ariaValueNow = "51";
     assert_equals(element.getAttribute("aria-valuenow"), "51");
+    testNullable(element, "ariaValueNow", "aria-valuenow");
 }, "aria-valuenow attribute reflects.");
 </script>
 
@@ -405,6 +452,7 @@
     assert_equals(element.ariaValueText, "50%");
     element.ariaValueText = "51%";
     assert_equals(element.getAttribute("aria-valuetext"), "51%");
+    testNullable(element, "ariaValueText", "aria-valuetext");
 }, "aria-valuetext attribute reflects.");
 </script>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/elements/global-attributes/dir-slots-directionality.html b/third_party/blink/web_tests/external/wpt/html/dom/elements/global-attributes/dir-slots-directionality.html
index 5e8cedb..db783fc 100644
--- a/third_party/blink/web_tests/external/wpt/html/dom/elements/global-attributes/dir-slots-directionality.html
+++ b/third_party/blink/web_tests/external/wpt/html/dom/elements/global-attributes/dir-slots-directionality.html
@@ -51,8 +51,8 @@
   let root5 = host5.attachShadow({mode:"open"});
   root5.innerHTML = '<span dir="auto"><slot>اختبر</slot></span>';
   let span = root5.querySelector("span");
-  assert_equals(getComputedStyle(span).direction, "rtl");
-  assert_true(span.matches(":dir(rtl)"));
+  assert_equals(getComputedStyle(span).direction, "ltr");
+  assert_true(span.matches(":dir(ltr)"));
 }, 'Slots: Directionality: dir=auto in shadow tree with Arabic shadow tree content');
 
 test(() => {
@@ -63,4 +63,35 @@
   assert_true(span.matches(":dir(rtl)"));
 }, 'Slots: Directionality: dir=auto on slot with Arabic light tree content');
 
+test(() => {
+  let host = document.createElement("div");
+  host.dir = "rtl";
+  document.body.appendChild(host);
+  let root = host.attachShadow({mode:"open"});
+  root.innerHTML = '<section dir="ltr"><div dir="auto"><slot></slot>A</div></section>';
+  let div = root.querySelector("div");
+  assert_true(div.matches(":dir(rtl)"));
+  host.remove();
+}, 'slot provides its directionality (from host) to a dir=auto container');
+
+test(() => {
+  let host = document.createElement("div");
+  document.body.appendChild(host);
+  let root = host.attachShadow({mode:"open"});
+  root.innerHTML = '<div dir="auto"><span dir="ltr">A</span>\u05D0</div><slot></slot>';
+  let div = root.querySelector("div");
+  assert_true(div.matches(":dir(rtl)"));
+  host.remove();
+}, 'children with dir attribute are skipped by dir=auto');
+
+test(() => {
+  let host = document.createElement("div");
+  document.body.appendChild(host);
+  let root = host.attachShadow({mode:"open"});
+  root.innerHTML = '<div dir="auto"><slot dir="ltr"></slot>\u05D0</div>';
+  let div = root.querySelector("div");
+  assert_true(div.matches(":dir(rtl)"));
+  host.remove();
+}, 'slot with dir attribute is skipped by dir=auto');
+
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any-expected.txt
index 3d82496..b305d3a 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any-expected.txt
@@ -1,25 +1,26 @@
 This is a testharness.js-based test.
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.addAll with opaque-filtered 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice promise_rejects_dom: Cache.addAll should throw InvalidStateError if the same request is added twice. function "function() { throw e }" threw object "TypeError: Failed to execute 'addAll' on 'Cache': Request failed" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
-PASS Cache.addAll should succeed when entries differ by vary header
-PASS Cache.addAll should reject when entries are duplicate by vary header
-PASS Cache.addAll should reject when one entry has a vary header matching another entry
+[PASS] Cache.add called with no arguments
+[PASS] Cache.add called with relative URL specified as a string
+[PASS] Cache.add called with non-HTTP/HTTPS URL
+[PASS] Cache.add called with Request object
+[PASS] Cache.add called with POST request
+[PASS] Cache.add called twice with the same Request object
+[PASS] Cache.add with request with null body (not consumed)
+[PASS] Cache.add with 206 response
+[PASS] Cache.addAll with 206 response
+[PASS] Cache.addAll with opaque-filtered 206 response
+[PASS] Cache.add with request that results in a status of 404
+[PASS] Cache.add with request that results in a status of 500
+[PASS] Cache.addAll with no arguments
+[PASS] Cache.addAll with a mix of valid and undefined arguments
+[PASS] Cache.addAll with an empty array
+[PASS] Cache.addAll with string URL arguments
+[PASS] Cache.addAll with Request arguments
+[PASS] Cache.addAll with a mix of succeeding and failing requests
+[FAIL] Cache.addAll called with the same Request object specified twice
+  promise_rejects_dom: Cache.addAll should throw InvalidStateError if the same request is added twice. function "function() { throw e }" threw object "TypeError: Failed to execute 'addAll' on 'Cache': Request failed" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
+[PASS] Cache.addAll should succeed when entries differ by vary header
+[PASS] Cache.addAll should reject when entries are duplicate by vary header
+[PASS] Cache.addAll should reject when one entry has a vary header matching another entry
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any.serviceworker-expected.txt
index 3d82496..b305d3a 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any.serviceworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any.serviceworker-expected.txt
@@ -1,25 +1,26 @@
 This is a testharness.js-based test.
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.addAll with opaque-filtered 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice promise_rejects_dom: Cache.addAll should throw InvalidStateError if the same request is added twice. function "function() { throw e }" threw object "TypeError: Failed to execute 'addAll' on 'Cache': Request failed" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
-PASS Cache.addAll should succeed when entries differ by vary header
-PASS Cache.addAll should reject when entries are duplicate by vary header
-PASS Cache.addAll should reject when one entry has a vary header matching another entry
+[PASS] Cache.add called with no arguments
+[PASS] Cache.add called with relative URL specified as a string
+[PASS] Cache.add called with non-HTTP/HTTPS URL
+[PASS] Cache.add called with Request object
+[PASS] Cache.add called with POST request
+[PASS] Cache.add called twice with the same Request object
+[PASS] Cache.add with request with null body (not consumed)
+[PASS] Cache.add with 206 response
+[PASS] Cache.addAll with 206 response
+[PASS] Cache.addAll with opaque-filtered 206 response
+[PASS] Cache.add with request that results in a status of 404
+[PASS] Cache.add with request that results in a status of 500
+[PASS] Cache.addAll with no arguments
+[PASS] Cache.addAll with a mix of valid and undefined arguments
+[PASS] Cache.addAll with an empty array
+[PASS] Cache.addAll with string URL arguments
+[PASS] Cache.addAll with Request arguments
+[PASS] Cache.addAll with a mix of succeeding and failing requests
+[FAIL] Cache.addAll called with the same Request object specified twice
+  promise_rejects_dom: Cache.addAll should throw InvalidStateError if the same request is added twice. function "function() { throw e }" threw object "TypeError: Failed to execute 'addAll' on 'Cache': Request failed" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
+[PASS] Cache.addAll should succeed when entries differ by vary header
+[PASS] Cache.addAll should reject when entries are duplicate by vary header
+[PASS] Cache.addAll should reject when one entry has a vary header matching another entry
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any.sharedworker-expected.txt
index 3d82496..b305d3a 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any.sharedworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any.sharedworker-expected.txt
@@ -1,25 +1,26 @@
 This is a testharness.js-based test.
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.addAll with opaque-filtered 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice promise_rejects_dom: Cache.addAll should throw InvalidStateError if the same request is added twice. function "function() { throw e }" threw object "TypeError: Failed to execute 'addAll' on 'Cache': Request failed" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
-PASS Cache.addAll should succeed when entries differ by vary header
-PASS Cache.addAll should reject when entries are duplicate by vary header
-PASS Cache.addAll should reject when one entry has a vary header matching another entry
+[PASS] Cache.add called with no arguments
+[PASS] Cache.add called with relative URL specified as a string
+[PASS] Cache.add called with non-HTTP/HTTPS URL
+[PASS] Cache.add called with Request object
+[PASS] Cache.add called with POST request
+[PASS] Cache.add called twice with the same Request object
+[PASS] Cache.add with request with null body (not consumed)
+[PASS] Cache.add with 206 response
+[PASS] Cache.addAll with 206 response
+[PASS] Cache.addAll with opaque-filtered 206 response
+[PASS] Cache.add with request that results in a status of 404
+[PASS] Cache.add with request that results in a status of 500
+[PASS] Cache.addAll with no arguments
+[PASS] Cache.addAll with a mix of valid and undefined arguments
+[PASS] Cache.addAll with an empty array
+[PASS] Cache.addAll with string URL arguments
+[PASS] Cache.addAll with Request arguments
+[PASS] Cache.addAll with a mix of succeeding and failing requests
+[FAIL] Cache.addAll called with the same Request object specified twice
+  promise_rejects_dom: Cache.addAll should throw InvalidStateError if the same request is added twice. function "function() { throw e }" threw object "TypeError: Failed to execute 'addAll' on 'Cache': Request failed" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
+[PASS] Cache.addAll should succeed when entries differ by vary header
+[PASS] Cache.addAll should reject when entries are duplicate by vary header
+[PASS] Cache.addAll should reject when one entry has a vary header matching another entry
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any.worker-expected.txt
index 3d82496..b305d3a 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-add.https.any.worker-expected.txt
@@ -1,25 +1,26 @@
 This is a testharness.js-based test.
-PASS Cache.add called with no arguments
-PASS Cache.add called with relative URL specified as a string
-PASS Cache.add called with non-HTTP/HTTPS URL
-PASS Cache.add called with Request object
-PASS Cache.add called with POST request
-PASS Cache.add called twice with the same Request object
-PASS Cache.add with request with null body (not consumed)
-PASS Cache.add with 206 response
-PASS Cache.addAll with 206 response
-PASS Cache.addAll with opaque-filtered 206 response
-PASS Cache.add with request that results in a status of 404
-PASS Cache.add with request that results in a status of 500
-PASS Cache.addAll with no arguments
-PASS Cache.addAll with a mix of valid and undefined arguments
-PASS Cache.addAll with an empty array
-PASS Cache.addAll with string URL arguments
-PASS Cache.addAll with Request arguments
-PASS Cache.addAll with a mix of succeeding and failing requests
-FAIL Cache.addAll called with the same Request object specified twice promise_rejects_dom: Cache.addAll should throw InvalidStateError if the same request is added twice. function "function() { throw e }" threw object "TypeError: Failed to execute 'addAll' on 'Cache': Request failed" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
-PASS Cache.addAll should succeed when entries differ by vary header
-PASS Cache.addAll should reject when entries are duplicate by vary header
-PASS Cache.addAll should reject when one entry has a vary header matching another entry
+[PASS] Cache.add called with no arguments
+[PASS] Cache.add called with relative URL specified as a string
+[PASS] Cache.add called with non-HTTP/HTTPS URL
+[PASS] Cache.add called with Request object
+[PASS] Cache.add called with POST request
+[PASS] Cache.add called twice with the same Request object
+[PASS] Cache.add with request with null body (not consumed)
+[PASS] Cache.add with 206 response
+[PASS] Cache.addAll with 206 response
+[PASS] Cache.addAll with opaque-filtered 206 response
+[PASS] Cache.add with request that results in a status of 404
+[PASS] Cache.add with request that results in a status of 500
+[PASS] Cache.addAll with no arguments
+[PASS] Cache.addAll with a mix of valid and undefined arguments
+[PASS] Cache.addAll with an empty array
+[PASS] Cache.addAll with string URL arguments
+[PASS] Cache.addAll with Request arguments
+[PASS] Cache.addAll with a mix of succeeding and failing requests
+[FAIL] Cache.addAll called with the same Request object specified twice
+  promise_rejects_dom: Cache.addAll should throw InvalidStateError if the same request is added twice. function "function() { throw e }" threw object "TypeError: Failed to execute 'addAll' on 'Cache': Request failed" that is not a DOMException InvalidStateError: property "code" is equal to undefined, expected 11
+[PASS] Cache.addAll should succeed when entries differ by vary header
+[PASS] Cache.addAll should reject when entries are duplicate by vary header
+[PASS] Cache.addAll should reject when one entry has a vary header matching another entry
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys-attributes-for-service-worker.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys-attributes-for-service-worker.https-expected.txt
index 452fa9f..c0b00dd1 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys-attributes-for-service-worker.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys-attributes-for-service-worker.https-expected.txt
@@ -1,5 +1,7 @@
 This is a testharness.js-based test.
-FAIL Request.IsReloadNavigation should persist. assert_equals: expected "original: false, stored: false" but got "original: undefined, stored: undefined"
-FAIL Request.IsHistoryNavigation should persist. assert_equals: expected "original: true, stored: true" but got "original: true, stored: false"
+[FAIL] Request.IsReloadNavigation should persist.
+  assert_equals: expected "original: false, stored: false" but got "original: undefined, stored: undefined"
+[FAIL] Request.IsHistoryNavigation should persist.
+  assert_equals: expected "original: true, stored: true" but got "original: true, stored: false"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any-expected.txt
index cfd4098..60d3b7b9 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any-expected.txt
@@ -1,19 +1,20 @@
 This is a testharness.js-based test.
-PASS Cache.keys() called on an empty cache
-PASS Cache.keys with no matching entries
-PASS Cache.keys with URL
-PASS Cache.keys with Request
-PASS Cache.keys with new Request
-PASS Cache.keys with ignoreSearch option (request with no search parameters)
-PASS Cache.keys with ignoreSearch option (request with search parameters)
-PASS Cache.keys supports ignoreMethod
-PASS Cache.keys supports ignoreVary
-PASS Cache.keys with URL containing fragment
-PASS Cache.keys with string fragment "http" as query
-PASS Cache.keys without parameters
-PASS Cache.keys with explicitly undefined request
-PASS Cache.keys with explicitly undefined request and empty options
-FAIL Cache.keys without parameters and VARY entries assert_equals: Cache.keys without parameters should match all entries. expected 3 but got 1
-PASS Cache.keys with a HEAD Request
+[PASS] Cache.keys() called on an empty cache
+[PASS] Cache.keys with no matching entries
+[PASS] Cache.keys with URL
+[PASS] Cache.keys with Request
+[PASS] Cache.keys with new Request
+[PASS] Cache.keys with ignoreSearch option (request with no search parameters)
+[PASS] Cache.keys with ignoreSearch option (request with search parameters)
+[PASS] Cache.keys supports ignoreMethod
+[PASS] Cache.keys supports ignoreVary
+[PASS] Cache.keys with URL containing fragment
+[PASS] Cache.keys with string fragment "http" as query
+[PASS] Cache.keys without parameters
+[PASS] Cache.keys with explicitly undefined request
+[PASS] Cache.keys with explicitly undefined request and empty options
+[FAIL] Cache.keys without parameters and VARY entries
+  assert_equals: Cache.keys without parameters should match all entries. expected 3 but got 1
+[PASS] Cache.keys with a HEAD Request
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any.serviceworker-expected.txt
index cfd4098..60d3b7b9 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any.serviceworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any.serviceworker-expected.txt
@@ -1,19 +1,20 @@
 This is a testharness.js-based test.
-PASS Cache.keys() called on an empty cache
-PASS Cache.keys with no matching entries
-PASS Cache.keys with URL
-PASS Cache.keys with Request
-PASS Cache.keys with new Request
-PASS Cache.keys with ignoreSearch option (request with no search parameters)
-PASS Cache.keys with ignoreSearch option (request with search parameters)
-PASS Cache.keys supports ignoreMethod
-PASS Cache.keys supports ignoreVary
-PASS Cache.keys with URL containing fragment
-PASS Cache.keys with string fragment "http" as query
-PASS Cache.keys without parameters
-PASS Cache.keys with explicitly undefined request
-PASS Cache.keys with explicitly undefined request and empty options
-FAIL Cache.keys without parameters and VARY entries assert_equals: Cache.keys without parameters should match all entries. expected 3 but got 1
-PASS Cache.keys with a HEAD Request
+[PASS] Cache.keys() called on an empty cache
+[PASS] Cache.keys with no matching entries
+[PASS] Cache.keys with URL
+[PASS] Cache.keys with Request
+[PASS] Cache.keys with new Request
+[PASS] Cache.keys with ignoreSearch option (request with no search parameters)
+[PASS] Cache.keys with ignoreSearch option (request with search parameters)
+[PASS] Cache.keys supports ignoreMethod
+[PASS] Cache.keys supports ignoreVary
+[PASS] Cache.keys with URL containing fragment
+[PASS] Cache.keys with string fragment "http" as query
+[PASS] Cache.keys without parameters
+[PASS] Cache.keys with explicitly undefined request
+[PASS] Cache.keys with explicitly undefined request and empty options
+[FAIL] Cache.keys without parameters and VARY entries
+  assert_equals: Cache.keys without parameters should match all entries. expected 3 but got 1
+[PASS] Cache.keys with a HEAD Request
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any.sharedworker-expected.txt
index cfd4098..60d3b7b9 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any.sharedworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any.sharedworker-expected.txt
@@ -1,19 +1,20 @@
 This is a testharness.js-based test.
-PASS Cache.keys() called on an empty cache
-PASS Cache.keys with no matching entries
-PASS Cache.keys with URL
-PASS Cache.keys with Request
-PASS Cache.keys with new Request
-PASS Cache.keys with ignoreSearch option (request with no search parameters)
-PASS Cache.keys with ignoreSearch option (request with search parameters)
-PASS Cache.keys supports ignoreMethod
-PASS Cache.keys supports ignoreVary
-PASS Cache.keys with URL containing fragment
-PASS Cache.keys with string fragment "http" as query
-PASS Cache.keys without parameters
-PASS Cache.keys with explicitly undefined request
-PASS Cache.keys with explicitly undefined request and empty options
-FAIL Cache.keys without parameters and VARY entries assert_equals: Cache.keys without parameters should match all entries. expected 3 but got 1
-PASS Cache.keys with a HEAD Request
+[PASS] Cache.keys() called on an empty cache
+[PASS] Cache.keys with no matching entries
+[PASS] Cache.keys with URL
+[PASS] Cache.keys with Request
+[PASS] Cache.keys with new Request
+[PASS] Cache.keys with ignoreSearch option (request with no search parameters)
+[PASS] Cache.keys with ignoreSearch option (request with search parameters)
+[PASS] Cache.keys supports ignoreMethod
+[PASS] Cache.keys supports ignoreVary
+[PASS] Cache.keys with URL containing fragment
+[PASS] Cache.keys with string fragment "http" as query
+[PASS] Cache.keys without parameters
+[PASS] Cache.keys with explicitly undefined request
+[PASS] Cache.keys with explicitly undefined request and empty options
+[FAIL] Cache.keys without parameters and VARY entries
+  assert_equals: Cache.keys without parameters should match all entries. expected 3 but got 1
+[PASS] Cache.keys with a HEAD Request
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any.worker-expected.txt
index cfd4098..60d3b7b9 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-keys.https.any.worker-expected.txt
@@ -1,19 +1,20 @@
 This is a testharness.js-based test.
-PASS Cache.keys() called on an empty cache
-PASS Cache.keys with no matching entries
-PASS Cache.keys with URL
-PASS Cache.keys with Request
-PASS Cache.keys with new Request
-PASS Cache.keys with ignoreSearch option (request with no search parameters)
-PASS Cache.keys with ignoreSearch option (request with search parameters)
-PASS Cache.keys supports ignoreMethod
-PASS Cache.keys supports ignoreVary
-PASS Cache.keys with URL containing fragment
-PASS Cache.keys with string fragment "http" as query
-PASS Cache.keys without parameters
-PASS Cache.keys with explicitly undefined request
-PASS Cache.keys with explicitly undefined request and empty options
-FAIL Cache.keys without parameters and VARY entries assert_equals: Cache.keys without parameters should match all entries. expected 3 but got 1
-PASS Cache.keys with a HEAD Request
+[PASS] Cache.keys() called on an empty cache
+[PASS] Cache.keys with no matching entries
+[PASS] Cache.keys with URL
+[PASS] Cache.keys with Request
+[PASS] Cache.keys with new Request
+[PASS] Cache.keys with ignoreSearch option (request with no search parameters)
+[PASS] Cache.keys with ignoreSearch option (request with search parameters)
+[PASS] Cache.keys supports ignoreMethod
+[PASS] Cache.keys supports ignoreVary
+[PASS] Cache.keys with URL containing fragment
+[PASS] Cache.keys with string fragment "http" as query
+[PASS] Cache.keys without parameters
+[PASS] Cache.keys with explicitly undefined request
+[PASS] Cache.keys with explicitly undefined request and empty options
+[FAIL] Cache.keys without parameters and VARY entries
+  assert_equals: Cache.keys without parameters should match all entries. expected 3 but got 1
+[PASS] Cache.keys with a HEAD Request
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any-expected.txt
index 07557f1..491bb75 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any-expected.txt
@@ -1,28 +1,29 @@
 This is a testharness.js-based test.
-PASS Cache.match with no matching entries
-PASS Cache.match with URL
-PASS Cache.match with Request
-PASS Cache.match with multiple cache hits
-PASS Cache.match with new Request
-PASS Cache.match with HEAD
-PASS Cache.match with ignoreSearch option (request with no search parameters)
-PASS Cache.match with ignoreSearch option (request with search parameter)
-PASS Cache.match supports ignoreMethod
-PASS Cache.match supports ignoreVary
-PASS Cache.match does not support cacheName option
-PASS Cache.match with URL containing fragment
-PASS Cache.match with string fragment "http" as query
-PASS Cache.match with responses containing "Vary" header
-PASS Cache.match with Request and Response objects with different URLs
-PASS Cache.match invoked multiple times for the same Request/Response
-PASS Cache.match blob should be sliceable
-PASS Cache.match with POST Request
-PASS Cache.match with a non-2xx Response
-PASS Cache.match with a network error Response
-PASS Cache produces large Responses that can be cloned and read correctly.
-PASS cors-exposed header should be stored correctly.
-PASS MIME type should be set from content-header correctly.
-FAIL MIME type should reflect Content-Type headers of response. assert_equals: mime type can be overridden expected "text/plain" but got "text/html"
-PASS Cache.match ignores vary headers on opaque response.
+[PASS] Cache.match with no matching entries
+[PASS] Cache.match with URL
+[PASS] Cache.match with Request
+[PASS] Cache.match with multiple cache hits
+[PASS] Cache.match with new Request
+[PASS] Cache.match with HEAD
+[PASS] Cache.match with ignoreSearch option (request with no search parameters)
+[PASS] Cache.match with ignoreSearch option (request with search parameter)
+[PASS] Cache.match supports ignoreMethod
+[PASS] Cache.match supports ignoreVary
+[PASS] Cache.match does not support cacheName option
+[PASS] Cache.match with URL containing fragment
+[PASS] Cache.match with string fragment "http" as query
+[PASS] Cache.match with responses containing "Vary" header
+[PASS] Cache.match with Request and Response objects with different URLs
+[PASS] Cache.match invoked multiple times for the same Request/Response
+[PASS] Cache.match blob should be sliceable
+[PASS] Cache.match with POST Request
+[PASS] Cache.match with a non-2xx Response
+[PASS] Cache.match with a network error Response
+[PASS] Cache produces large Responses that can be cloned and read correctly.
+[PASS] cors-exposed header should be stored correctly.
+[PASS] MIME type should be set from content-header correctly.
+[FAIL] MIME type should reflect Content-Type headers of response.
+  assert_equals: mime type can be overridden expected "text/plain" but got "text/html"
+[PASS] Cache.match ignores vary headers on opaque response.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any.serviceworker-expected.txt
index 07557f1..491bb75 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any.serviceworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any.serviceworker-expected.txt
@@ -1,28 +1,29 @@
 This is a testharness.js-based test.
-PASS Cache.match with no matching entries
-PASS Cache.match with URL
-PASS Cache.match with Request
-PASS Cache.match with multiple cache hits
-PASS Cache.match with new Request
-PASS Cache.match with HEAD
-PASS Cache.match with ignoreSearch option (request with no search parameters)
-PASS Cache.match with ignoreSearch option (request with search parameter)
-PASS Cache.match supports ignoreMethod
-PASS Cache.match supports ignoreVary
-PASS Cache.match does not support cacheName option
-PASS Cache.match with URL containing fragment
-PASS Cache.match with string fragment "http" as query
-PASS Cache.match with responses containing "Vary" header
-PASS Cache.match with Request and Response objects with different URLs
-PASS Cache.match invoked multiple times for the same Request/Response
-PASS Cache.match blob should be sliceable
-PASS Cache.match with POST Request
-PASS Cache.match with a non-2xx Response
-PASS Cache.match with a network error Response
-PASS Cache produces large Responses that can be cloned and read correctly.
-PASS cors-exposed header should be stored correctly.
-PASS MIME type should be set from content-header correctly.
-FAIL MIME type should reflect Content-Type headers of response. assert_equals: mime type can be overridden expected "text/plain" but got "text/html"
-PASS Cache.match ignores vary headers on opaque response.
+[PASS] Cache.match with no matching entries
+[PASS] Cache.match with URL
+[PASS] Cache.match with Request
+[PASS] Cache.match with multiple cache hits
+[PASS] Cache.match with new Request
+[PASS] Cache.match with HEAD
+[PASS] Cache.match with ignoreSearch option (request with no search parameters)
+[PASS] Cache.match with ignoreSearch option (request with search parameter)
+[PASS] Cache.match supports ignoreMethod
+[PASS] Cache.match supports ignoreVary
+[PASS] Cache.match does not support cacheName option
+[PASS] Cache.match with URL containing fragment
+[PASS] Cache.match with string fragment "http" as query
+[PASS] Cache.match with responses containing "Vary" header
+[PASS] Cache.match with Request and Response objects with different URLs
+[PASS] Cache.match invoked multiple times for the same Request/Response
+[PASS] Cache.match blob should be sliceable
+[PASS] Cache.match with POST Request
+[PASS] Cache.match with a non-2xx Response
+[PASS] Cache.match with a network error Response
+[PASS] Cache produces large Responses that can be cloned and read correctly.
+[PASS] cors-exposed header should be stored correctly.
+[PASS] MIME type should be set from content-header correctly.
+[FAIL] MIME type should reflect Content-Type headers of response.
+  assert_equals: mime type can be overridden expected "text/plain" but got "text/html"
+[PASS] Cache.match ignores vary headers on opaque response.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any.sharedworker-expected.txt
index 07557f1..491bb75 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any.sharedworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any.sharedworker-expected.txt
@@ -1,28 +1,29 @@
 This is a testharness.js-based test.
-PASS Cache.match with no matching entries
-PASS Cache.match with URL
-PASS Cache.match with Request
-PASS Cache.match with multiple cache hits
-PASS Cache.match with new Request
-PASS Cache.match with HEAD
-PASS Cache.match with ignoreSearch option (request with no search parameters)
-PASS Cache.match with ignoreSearch option (request with search parameter)
-PASS Cache.match supports ignoreMethod
-PASS Cache.match supports ignoreVary
-PASS Cache.match does not support cacheName option
-PASS Cache.match with URL containing fragment
-PASS Cache.match with string fragment "http" as query
-PASS Cache.match with responses containing "Vary" header
-PASS Cache.match with Request and Response objects with different URLs
-PASS Cache.match invoked multiple times for the same Request/Response
-PASS Cache.match blob should be sliceable
-PASS Cache.match with POST Request
-PASS Cache.match with a non-2xx Response
-PASS Cache.match with a network error Response
-PASS Cache produces large Responses that can be cloned and read correctly.
-PASS cors-exposed header should be stored correctly.
-PASS MIME type should be set from content-header correctly.
-FAIL MIME type should reflect Content-Type headers of response. assert_equals: mime type can be overridden expected "text/plain" but got "text/html"
-PASS Cache.match ignores vary headers on opaque response.
+[PASS] Cache.match with no matching entries
+[PASS] Cache.match with URL
+[PASS] Cache.match with Request
+[PASS] Cache.match with multiple cache hits
+[PASS] Cache.match with new Request
+[PASS] Cache.match with HEAD
+[PASS] Cache.match with ignoreSearch option (request with no search parameters)
+[PASS] Cache.match with ignoreSearch option (request with search parameter)
+[PASS] Cache.match supports ignoreMethod
+[PASS] Cache.match supports ignoreVary
+[PASS] Cache.match does not support cacheName option
+[PASS] Cache.match with URL containing fragment
+[PASS] Cache.match with string fragment "http" as query
+[PASS] Cache.match with responses containing "Vary" header
+[PASS] Cache.match with Request and Response objects with different URLs
+[PASS] Cache.match invoked multiple times for the same Request/Response
+[PASS] Cache.match blob should be sliceable
+[PASS] Cache.match with POST Request
+[PASS] Cache.match with a non-2xx Response
+[PASS] Cache.match with a network error Response
+[PASS] Cache produces large Responses that can be cloned and read correctly.
+[PASS] cors-exposed header should be stored correctly.
+[PASS] MIME type should be set from content-header correctly.
+[FAIL] MIME type should reflect Content-Type headers of response.
+  assert_equals: mime type can be overridden expected "text/plain" but got "text/html"
+[PASS] Cache.match ignores vary headers on opaque response.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any.worker-expected.txt
index 07557f1..491bb75 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-match.https.any.worker-expected.txt
@@ -1,28 +1,29 @@
 This is a testharness.js-based test.
-PASS Cache.match with no matching entries
-PASS Cache.match with URL
-PASS Cache.match with Request
-PASS Cache.match with multiple cache hits
-PASS Cache.match with new Request
-PASS Cache.match with HEAD
-PASS Cache.match with ignoreSearch option (request with no search parameters)
-PASS Cache.match with ignoreSearch option (request with search parameter)
-PASS Cache.match supports ignoreMethod
-PASS Cache.match supports ignoreVary
-PASS Cache.match does not support cacheName option
-PASS Cache.match with URL containing fragment
-PASS Cache.match with string fragment "http" as query
-PASS Cache.match with responses containing "Vary" header
-PASS Cache.match with Request and Response objects with different URLs
-PASS Cache.match invoked multiple times for the same Request/Response
-PASS Cache.match blob should be sliceable
-PASS Cache.match with POST Request
-PASS Cache.match with a non-2xx Response
-PASS Cache.match with a network error Response
-PASS Cache produces large Responses that can be cloned and read correctly.
-PASS cors-exposed header should be stored correctly.
-PASS MIME type should be set from content-header correctly.
-FAIL MIME type should reflect Content-Type headers of response. assert_equals: mime type can be overridden expected "text/plain" but got "text/html"
-PASS Cache.match ignores vary headers on opaque response.
+[PASS] Cache.match with no matching entries
+[PASS] Cache.match with URL
+[PASS] Cache.match with Request
+[PASS] Cache.match with multiple cache hits
+[PASS] Cache.match with new Request
+[PASS] Cache.match with HEAD
+[PASS] Cache.match with ignoreSearch option (request with no search parameters)
+[PASS] Cache.match with ignoreSearch option (request with search parameter)
+[PASS] Cache.match supports ignoreMethod
+[PASS] Cache.match supports ignoreVary
+[PASS] Cache.match does not support cacheName option
+[PASS] Cache.match with URL containing fragment
+[PASS] Cache.match with string fragment "http" as query
+[PASS] Cache.match with responses containing "Vary" header
+[PASS] Cache.match with Request and Response objects with different URLs
+[PASS] Cache.match invoked multiple times for the same Request/Response
+[PASS] Cache.match blob should be sliceable
+[PASS] Cache.match with POST Request
+[PASS] Cache.match with a non-2xx Response
+[PASS] Cache.match with a network error Response
+[PASS] Cache produces large Responses that can be cloned and read correctly.
+[PASS] cors-exposed header should be stored correctly.
+[PASS] MIME type should be set from content-header correctly.
+[FAIL] MIME type should reflect Content-Type headers of response.
+  assert_equals: mime type can be overridden expected "text/plain" but got "text/html"
+[PASS] Cache.match ignores vary headers on opaque response.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any-expected.txt
index 391a706..27d8fdcb 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any-expected.txt
@@ -1,19 +1,21 @@
 This is a testharness.js-based test.
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-PASS Cache.matchAll with explicitly undefined request
-PASS Cache.matchAll with explicitly undefined request and empty options
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
+[PASS] Cache.matchAll with no matching entries
+[PASS] Cache.matchAll with URL
+[PASS] Cache.matchAll with Request
+[PASS] Cache.matchAll with new Request
+[PASS] Cache.matchAll with HEAD
+[PASS] Cache.matchAll with ignoreSearch option (request with no search parameters)
+[PASS] Cache.matchAll with ignoreSearch option (request with search parameters)
+[PASS] Cache.matchAll supports ignoreMethod
+[PASS] Cache.matchAll supports ignoreVary
+[PASS] Cache.matchAll with URL containing fragment
+[PASS] Cache.matchAll with string fragment "http" as query
+[PASS] Cache.matchAll without parameters
+[PASS] Cache.matchAll with explicitly undefined request
+[PASS] Cache.matchAll with explicitly undefined request and empty options
+[FAIL] Cache.matchAll with responses containing "Vary" header
+  assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
+[FAIL] Cache.matchAll with multiple vary pairs
+  assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any.serviceworker-expected.txt
index 391a706..27d8fdcb 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any.serviceworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any.serviceworker-expected.txt
@@ -1,19 +1,21 @@
 This is a testharness.js-based test.
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-PASS Cache.matchAll with explicitly undefined request
-PASS Cache.matchAll with explicitly undefined request and empty options
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
+[PASS] Cache.matchAll with no matching entries
+[PASS] Cache.matchAll with URL
+[PASS] Cache.matchAll with Request
+[PASS] Cache.matchAll with new Request
+[PASS] Cache.matchAll with HEAD
+[PASS] Cache.matchAll with ignoreSearch option (request with no search parameters)
+[PASS] Cache.matchAll with ignoreSearch option (request with search parameters)
+[PASS] Cache.matchAll supports ignoreMethod
+[PASS] Cache.matchAll supports ignoreVary
+[PASS] Cache.matchAll with URL containing fragment
+[PASS] Cache.matchAll with string fragment "http" as query
+[PASS] Cache.matchAll without parameters
+[PASS] Cache.matchAll with explicitly undefined request
+[PASS] Cache.matchAll with explicitly undefined request and empty options
+[FAIL] Cache.matchAll with responses containing "Vary" header
+  assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
+[FAIL] Cache.matchAll with multiple vary pairs
+  assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any.sharedworker-expected.txt
index 391a706..27d8fdcb 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any.sharedworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any.sharedworker-expected.txt
@@ -1,19 +1,21 @@
 This is a testharness.js-based test.
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-PASS Cache.matchAll with explicitly undefined request
-PASS Cache.matchAll with explicitly undefined request and empty options
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
+[PASS] Cache.matchAll with no matching entries
+[PASS] Cache.matchAll with URL
+[PASS] Cache.matchAll with Request
+[PASS] Cache.matchAll with new Request
+[PASS] Cache.matchAll with HEAD
+[PASS] Cache.matchAll with ignoreSearch option (request with no search parameters)
+[PASS] Cache.matchAll with ignoreSearch option (request with search parameters)
+[PASS] Cache.matchAll supports ignoreMethod
+[PASS] Cache.matchAll supports ignoreVary
+[PASS] Cache.matchAll with URL containing fragment
+[PASS] Cache.matchAll with string fragment "http" as query
+[PASS] Cache.matchAll without parameters
+[PASS] Cache.matchAll with explicitly undefined request
+[PASS] Cache.matchAll with explicitly undefined request and empty options
+[FAIL] Cache.matchAll with responses containing "Vary" header
+  assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
+[FAIL] Cache.matchAll with multiple vary pairs
+  assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any.worker-expected.txt
index 391a706..27d8fdcb 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-matchAll.https.any.worker-expected.txt
@@ -1,19 +1,21 @@
 This is a testharness.js-based test.
-PASS Cache.matchAll with no matching entries
-PASS Cache.matchAll with URL
-PASS Cache.matchAll with Request
-PASS Cache.matchAll with new Request
-PASS Cache.matchAll with HEAD
-PASS Cache.matchAll with ignoreSearch option (request with no search parameters)
-PASS Cache.matchAll with ignoreSearch option (request with search parameters)
-PASS Cache.matchAll supports ignoreMethod
-PASS Cache.matchAll supports ignoreVary
-PASS Cache.matchAll with URL containing fragment
-PASS Cache.matchAll with string fragment "http" as query
-PASS Cache.matchAll without parameters
-PASS Cache.matchAll with explicitly undefined request
-PASS Cache.matchAll with explicitly undefined request and empty options
-FAIL Cache.matchAll with responses containing "Vary" header assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
-FAIL Cache.matchAll with multiple vary pairs assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
+[PASS] Cache.matchAll with no matching entries
+[PASS] Cache.matchAll with URL
+[PASS] Cache.matchAll with Request
+[PASS] Cache.matchAll with new Request
+[PASS] Cache.matchAll with HEAD
+[PASS] Cache.matchAll with ignoreSearch option (request with no search parameters)
+[PASS] Cache.matchAll with ignoreSearch option (request with search parameters)
+[PASS] Cache.matchAll supports ignoreMethod
+[PASS] Cache.matchAll supports ignoreVary
+[PASS] Cache.matchAll with URL containing fragment
+[PASS] Cache.matchAll with string fragment "http" as query
+[PASS] Cache.matchAll without parameters
+[PASS] Cache.matchAll with explicitly undefined request
+[PASS] Cache.matchAll with explicitly undefined request and empty options
+[FAIL] Cache.matchAll with responses containing "Vary" header
+  assert_equals: Cache.matchAll should match the entire header if a vary header is present in both the query and cached requests. expected 1 but got 0
+[FAIL] Cache.matchAll with multiple vary pairs
+  assert_equals: Cache.matchAll should support multiple vary request/response pairs. expected 3 but got 1
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any-expected.txt
index d1c62496..9d4852c 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any-expected.txt
@@ -1,13 +1,14 @@
 This is a testharness.js-based test.
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
+[PASS] CacheStorage.open
+[PASS] CacheStorage.delete dooms, but does not delete immediately
+[PASS] CacheStorage.open with an empty name
+[PASS] CacheStorage.open with no arguments
+[PASS] CacheStorage.has with existing cache
+[PASS] CacheStorage.has with nonexistent cache
+[PASS] CacheStorage.open with existing cache
+[PASS] CacheStorage.delete with existing cache
+[PASS] CacheStorage.delete with nonexistent cache
+[FAIL] CacheStorage names are DOMStrings not USVStrings
+  assert_true: keys should include cache with bad name expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any.serviceworker-expected.txt
index d1c62496..9d4852c 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any.serviceworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any.serviceworker-expected.txt
@@ -1,13 +1,14 @@
 This is a testharness.js-based test.
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
+[PASS] CacheStorage.open
+[PASS] CacheStorage.delete dooms, but does not delete immediately
+[PASS] CacheStorage.open with an empty name
+[PASS] CacheStorage.open with no arguments
+[PASS] CacheStorage.has with existing cache
+[PASS] CacheStorage.has with nonexistent cache
+[PASS] CacheStorage.open with existing cache
+[PASS] CacheStorage.delete with existing cache
+[PASS] CacheStorage.delete with nonexistent cache
+[FAIL] CacheStorage names are DOMStrings not USVStrings
+  assert_true: keys should include cache with bad name expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any.sharedworker-expected.txt
index d1c62496..9d4852c 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any.sharedworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any.sharedworker-expected.txt
@@ -1,13 +1,14 @@
 This is a testharness.js-based test.
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
+[PASS] CacheStorage.open
+[PASS] CacheStorage.delete dooms, but does not delete immediately
+[PASS] CacheStorage.open with an empty name
+[PASS] CacheStorage.open with no arguments
+[PASS] CacheStorage.has with existing cache
+[PASS] CacheStorage.has with nonexistent cache
+[PASS] CacheStorage.open with existing cache
+[PASS] CacheStorage.delete with existing cache
+[PASS] CacheStorage.delete with nonexistent cache
+[FAIL] CacheStorage names are DOMStrings not USVStrings
+  assert_true: keys should include cache with bad name expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any.worker-expected.txt
index d1c62496..9d4852c 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/cache-storage.https.any.worker-expected.txt
@@ -1,13 +1,14 @@
 This is a testharness.js-based test.
-PASS CacheStorage.open
-PASS CacheStorage.delete dooms, but does not delete immediately
-PASS CacheStorage.open with an empty name
-PASS CacheStorage.open with no arguments
-PASS CacheStorage.has with existing cache
-PASS CacheStorage.has with nonexistent cache
-PASS CacheStorage.open with existing cache
-PASS CacheStorage.delete with existing cache
-PASS CacheStorage.delete with nonexistent cache
-FAIL CacheStorage names are DOMStrings not USVStrings assert_true: keys should include cache with bad name expected true got false
+[PASS] CacheStorage.open
+[PASS] CacheStorage.delete dooms, but does not delete immediately
+[PASS] CacheStorage.open with an empty name
+[PASS] CacheStorage.open with no arguments
+[PASS] CacheStorage.has with existing cache
+[PASS] CacheStorage.has with nonexistent cache
+[PASS] CacheStorage.open with existing cache
+[PASS] CacheStorage.delete with existing cache
+[PASS] CacheStorage.delete with nonexistent cache
+[FAIL] CacheStorage names are DOMStrings not USVStrings
+  assert_true: keys should include cache with bad name expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/sandboxed-iframes.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/sandboxed-iframes.https-expected.txt
index a0a6460..e2f2f01 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/sandboxed-iframes.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/sandboxed-iframes.https-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
-PASS Sandboxed iframe with allow-same-origin is allowed access
-FAIL Sandboxed iframe without allow-same-origin is denied access assert_equals: Access should be denied if sandbox lacks allow-same-origin expected "denied" but got "unexpecteddenied"
+[PASS] Sandboxed iframe with allow-same-origin is allowed access
+[FAIL] Sandboxed iframe without allow-same-origin is denied access
+  assert_equals: Access should be denied if sandbox lacks allow-same-origin expected "denied" but got "unexpecteddenied"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.serviceworker-expected.txt
index cc464f5..7553bf5 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.serviceworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.serviceworker-expected.txt
@@ -1,299 +1,331 @@
 This is a testharness.js-based test.
 Found 295 tests; 263 PASS, 32 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Partial interface Navigator: original interface defined
-PASS Partial interface Navigator: member names are unique
-PASS Partial interface WorkerNavigator: original interface defined
-PASS Partial interface WorkerNavigator: member names are unique
-PASS Partial interface mixin WindowOrWorkerGlobalScope: original interface mixin defined
-PASS Partial interface mixin WindowOrWorkerGlobalScope: member names are unique
-PASS Partial interface Navigator[2]: member names are unique
-PASS Partial interface mixin NavigatorID: member names are unique
-PASS Partial interface Window: member names are unique
-PASS ServiceWorker includes AbstractWorker: member names are unique
-PASS Window includes GlobalEventHandlers: member names are unique
-PASS Window includes WindowEventHandlers: member names are unique
-PASS Window includes WindowOrWorkerGlobalScope: member names are unique
-PASS WorkerGlobalScope includes WindowOrWorkerGlobalScope: member names are unique
-PASS Navigator includes NavigatorID: member names are unique
-PASS Navigator includes NavigatorLanguage: member names are unique
-PASS Navigator includes NavigatorOnLine: member names are unique
-PASS Navigator includes NavigatorContentUtils: member names are unique
-PASS Navigator includes NavigatorCookies: member names are unique
-PASS Navigator includes NavigatorPlugins: member names are unique
-PASS Navigator includes NavigatorConcurrentHardware: member names are unique
-PASS Window includes AnimationFrameProvider: member names are unique
-PASS WorkerNavigator includes NavigatorID: member names are unique
-PASS WorkerNavigator includes NavigatorLanguage: member names are unique
-PASS WorkerNavigator includes NavigatorOnLine: member names are unique
-PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique
-PASS Window includes WindowSessionStorage: member names are unique
-PASS Window includes WindowLocalStorage: member names are unique
-PASS ServiceWorker interface: existence and properties of interface object
-PASS ServiceWorker interface object length
-PASS ServiceWorker interface object name
-PASS ServiceWorker interface: existence and properties of interface prototype object
-PASS ServiceWorker interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorker interface: existence and properties of interface prototype object's @@unscopables property
-PASS ServiceWorker interface: attribute scriptURL
-PASS ServiceWorker interface: attribute state
-PASS ServiceWorker interface: operation postMessage(any, sequence<object>)
-PASS ServiceWorker interface: operation postMessage(any, optional StructuredSerializeOptions)
-PASS ServiceWorker interface: attribute onstatechange
-PASS ServiceWorker must be primary interface of serviceWorker
-PASS Stringification of serviceWorker
-PASS ServiceWorker interface: serviceWorker must inherit property "scriptURL" with the proper type
-PASS ServiceWorker interface: serviceWorker must inherit property "state" with the proper type
-PASS ServiceWorker interface: serviceWorker must inherit property "postMessage(any, sequence<object>)" with the proper type
-PASS ServiceWorker interface: calling postMessage(any, sequence<object>) on serviceWorker with too few arguments must throw TypeError
-PASS ServiceWorker interface: serviceWorker must inherit property "postMessage(any, optional StructuredSerializeOptions)" with the proper type
-PASS ServiceWorker interface: calling postMessage(any, optional StructuredSerializeOptions) on serviceWorker with too few arguments must throw TypeError
-PASS ServiceWorker interface: serviceWorker must inherit property "onstatechange" with the proper type
-PASS ServiceWorkerRegistration interface: existence and properties of interface object
-PASS ServiceWorkerRegistration interface object length
-PASS ServiceWorkerRegistration interface object name
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's @@unscopables property
-PASS ServiceWorkerRegistration interface: attribute installing
-PASS ServiceWorkerRegistration interface: attribute waiting
-PASS ServiceWorkerRegistration interface: attribute active
-PASS ServiceWorkerRegistration interface: attribute navigationPreload
-PASS ServiceWorkerRegistration interface: attribute scope
-PASS ServiceWorkerRegistration interface: attribute updateViaCache
-PASS ServiceWorkerRegistration interface: operation update()
-PASS ServiceWorkerRegistration interface: operation unregister()
-PASS ServiceWorkerRegistration interface: attribute onupdatefound
-PASS ServiceWorkerRegistration must be primary interface of registration
-PASS Stringification of registration
-PASS ServiceWorkerRegistration interface: registration must inherit property "installing" with the proper type
-PASS ServiceWorkerRegistration interface: registration must inherit property "waiting" with the proper type
-PASS ServiceWorkerRegistration interface: registration must inherit property "active" with the proper type
-PASS ServiceWorkerRegistration interface: registration must inherit property "navigationPreload" with the proper type
-PASS ServiceWorkerRegistration interface: registration must inherit property "scope" with the proper type
-PASS ServiceWorkerRegistration interface: registration must inherit property "updateViaCache" with the proper type
-PASS ServiceWorkerRegistration interface: registration must inherit property "update()" with the proper type
-PASS ServiceWorkerRegistration interface: registration must inherit property "unregister()" with the proper type
-PASS ServiceWorkerRegistration interface: registration must inherit property "onupdatefound" with the proper type
-FAIL ServiceWorkerContainer interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface object length assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface object name assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute controller assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute ready assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: operation register(USVString, optional RegistrationOptions) assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: operation getRegistration(optional USVString) assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: operation getRegistrations() assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: operation startMessages() assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute oncontrollerchange assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute onmessage assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute onmessageerror assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer must be primary interface of navigator.serviceWorker assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL Stringification of navigator.serviceWorker assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "controller" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "ready" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "register(USVString, optional RegistrationOptions)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: calling register(USVString, optional RegistrationOptions) on navigator.serviceWorker with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistration(optional USVString)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: calling getRegistration(optional USVString) on navigator.serviceWorker with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistrations()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "startMessages()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "oncontrollerchange" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessage" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessageerror" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-PASS NavigationPreloadManager interface: existence and properties of interface object
-PASS NavigationPreloadManager interface object length
-PASS NavigationPreloadManager interface object name
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's @@unscopables property
-PASS NavigationPreloadManager interface: operation enable()
-PASS NavigationPreloadManager interface: operation disable()
-PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString)
-PASS NavigationPreloadManager interface: operation getState()
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface object
-PASS ServiceWorkerGlobalScope interface object length
-PASS ServiceWorkerGlobalScope interface object name
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via __proto__ should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Object.setPrototypeOf should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via __proto__ should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object's @@unscopables property
-PASS ServiceWorkerGlobalScope interface: attribute clients
-PASS ServiceWorkerGlobalScope interface: attribute registration
-PASS ServiceWorkerGlobalScope interface: attribute serviceWorker
-PASS ServiceWorkerGlobalScope interface: operation skipWaiting()
-PASS ServiceWorkerGlobalScope interface: attribute oninstall
-PASS ServiceWorkerGlobalScope interface: attribute onactivate
-PASS ServiceWorkerGlobalScope interface: attribute onfetch
-PASS ServiceWorkerGlobalScope interface: attribute onmessage
-PASS ServiceWorkerGlobalScope interface: attribute onmessageerror
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via __proto__ should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Object.setPrototypeOf should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via __proto__ should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS ServiceWorkerGlobalScope must be primary interface of self
-PASS Stringification of self
-PASS ServiceWorkerGlobalScope interface: self must inherit property "clients" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "registration" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "serviceWorker" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "skipWaiting()" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "oninstall" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onactivate" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onfetch" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onmessage" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onmessageerror" with the proper type
-PASS WorkerGlobalScope interface: self must inherit property "caches" with the proper type
-PASS Client interface: existence and properties of interface object
-PASS Client interface object length
-PASS Client interface object name
-PASS Client interface: existence and properties of interface prototype object
-PASS Client interface: existence and properties of interface prototype object's "constructor" property
-PASS Client interface: existence and properties of interface prototype object's @@unscopables property
-PASS Client interface: attribute url
-PASS Client interface: attribute frameType
-PASS Client interface: attribute id
-PASS Client interface: attribute type
-PASS Client interface: operation postMessage(any, sequence<object>)
-PASS Client interface: operation postMessage(any, optional StructuredSerializeOptions)
-PASS WindowClient interface: existence and properties of interface object
-PASS WindowClient interface object length
-PASS WindowClient interface object name
-PASS WindowClient interface: existence and properties of interface prototype object
-PASS WindowClient interface: existence and properties of interface prototype object's "constructor" property
-PASS WindowClient interface: existence and properties of interface prototype object's @@unscopables property
-PASS WindowClient interface: attribute visibilityState
-PASS WindowClient interface: attribute focused
-FAIL WindowClient interface: attribute ancestorOrigins assert_true: The prototype object must have a property "ancestorOrigins" expected true got false
-PASS WindowClient interface: operation focus()
-PASS WindowClient interface: operation navigate(USVString)
-PASS Clients interface: existence and properties of interface object
-PASS Clients interface object length
-PASS Clients interface object name
-PASS Clients interface: existence and properties of interface prototype object
-PASS Clients interface: existence and properties of interface prototype object's "constructor" property
-PASS Clients interface: existence and properties of interface prototype object's @@unscopables property
-PASS Clients interface: operation get(DOMString)
-PASS Clients interface: operation matchAll(optional ClientQueryOptions)
-PASS Clients interface: operation openWindow(USVString)
-PASS Clients interface: operation claim()
-PASS Clients must be primary interface of clients
-PASS Stringification of clients
-PASS Clients interface: clients must inherit property "get(DOMString)" with the proper type
-PASS Clients interface: calling get(DOMString) on clients with too few arguments must throw TypeError
-PASS Clients interface: clients must inherit property "matchAll(optional ClientQueryOptions)" with the proper type
-PASS Clients interface: calling matchAll(optional ClientQueryOptions) on clients with too few arguments must throw TypeError
-PASS Clients interface: clients must inherit property "openWindow(USVString)" with the proper type
-PASS Clients interface: calling openWindow(USVString) on clients with too few arguments must throw TypeError
-PASS Clients interface: clients must inherit property "claim()" with the proper type
-PASS ExtendableEvent interface: existence and properties of interface object
-PASS ExtendableEvent interface object length
-PASS ExtendableEvent interface object name
-PASS ExtendableEvent interface: existence and properties of interface prototype object
-PASS ExtendableEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS ExtendableEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS ExtendableEvent interface: operation waitUntil(Promise<any>)
-PASS ExtendableEvent must be primary interface of new ExtendableEvent("type")
-PASS Stringification of new ExtendableEvent("type")
-PASS ExtendableEvent interface: new ExtendableEvent("type") must inherit property "waitUntil(Promise<any>)" with the proper type
-PASS ExtendableEvent interface: calling waitUntil(Promise<any>) on new ExtendableEvent("type") with too few arguments must throw TypeError
-PASS FetchEvent interface: existence and properties of interface object
-PASS FetchEvent interface object length
-PASS FetchEvent interface object name
-PASS FetchEvent interface: existence and properties of interface prototype object
-PASS FetchEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS FetchEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS FetchEvent interface: attribute request
-PASS FetchEvent interface: attribute preloadResponse
-PASS FetchEvent interface: attribute clientId
-PASS FetchEvent interface: attribute resultingClientId
-FAIL FetchEvent interface: attribute replacesClientId assert_true: The prototype object must have a property "replacesClientId" expected true got false
-PASS FetchEvent interface: attribute handled
-PASS FetchEvent interface: operation respondWith(Promise<Response>)
-PASS FetchEvent must be primary interface of new FetchEvent("type", { request: new Request("") })
-PASS Stringification of new FetchEvent("type", { request: new Request("") })
-PASS FetchEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "request" with the proper type
-PASS FetchEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "preloadResponse" with the proper type
-PASS FetchEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "clientId" with the proper type
-PASS FetchEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "resultingClientId" with the proper type
-FAIL FetchEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "replacesClientId" with the proper type assert_inherits: property "replacesClientId" not found in prototype chain
-PASS FetchEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "handled" with the proper type
-PASS FetchEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "respondWith(Promise<Response>)" with the proper type
-PASS FetchEvent interface: calling respondWith(Promise<Response>) on new FetchEvent("type", { request: new Request("") }) with too few arguments must throw TypeError
-PASS ExtendableEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "waitUntil(Promise<any>)" with the proper type
-PASS ExtendableEvent interface: calling waitUntil(Promise<any>) on new FetchEvent("type", { request: new Request("") }) with too few arguments must throw TypeError
-PASS ExtendableMessageEvent interface: existence and properties of interface object
-PASS ExtendableMessageEvent interface object length
-PASS ExtendableMessageEvent interface object name
-PASS ExtendableMessageEvent interface: existence and properties of interface prototype object
-PASS ExtendableMessageEvent interface: existence and properties of interface prototype object's "constructor" property
-PASS ExtendableMessageEvent interface: existence and properties of interface prototype object's @@unscopables property
-PASS ExtendableMessageEvent interface: attribute data
-PASS ExtendableMessageEvent interface: attribute origin
-PASS ExtendableMessageEvent interface: attribute lastEventId
-PASS ExtendableMessageEvent interface: attribute source
-PASS ExtendableMessageEvent interface: attribute ports
-PASS Cache interface: existence and properties of interface object
-PASS Cache interface object length
-PASS Cache interface object name
-PASS Cache interface: existence and properties of interface prototype object
-PASS Cache interface: existence and properties of interface prototype object's "constructor" property
-PASS Cache interface: existence and properties of interface prototype object's @@unscopables property
-PASS Cache interface: operation match(RequestInfo, optional CacheQueryOptions)
-PASS Cache interface: operation matchAll(optional RequestInfo, optional CacheQueryOptions)
-PASS Cache interface: operation add(RequestInfo)
-PASS Cache interface: operation addAll(sequence<RequestInfo>)
-PASS Cache interface: operation put(RequestInfo, Response)
-PASS Cache interface: operation delete(RequestInfo, optional CacheQueryOptions)
-PASS Cache interface: operation keys(optional RequestInfo, optional CacheQueryOptions)
-PASS Cache must be primary interface of self.cacheInstance
-PASS Stringification of self.cacheInstance
-PASS Cache interface: self.cacheInstance must inherit property "match(RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling match(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "matchAll(optional RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling matchAll(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type
-PASS Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "addAll(sequence<RequestInfo>)" with the proper type
-PASS Cache interface: calling addAll(sequence<RequestInfo>) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type
-PASS Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling delete(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "keys(optional RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling keys(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS CacheStorage interface: existence and properties of interface object
-PASS CacheStorage interface object length
-PASS CacheStorage interface object name
-PASS CacheStorage interface: existence and properties of interface prototype object
-PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property
-PASS CacheStorage interface: existence and properties of interface prototype object's @@unscopables property
-PASS CacheStorage interface: operation match(RequestInfo, optional MultiCacheQueryOptions)
-PASS CacheStorage interface: operation has(DOMString)
-PASS CacheStorage interface: operation open(DOMString)
-PASS CacheStorage interface: operation delete(DOMString)
-PASS CacheStorage interface: operation keys()
-PASS CacheStorage must be primary interface of caches
-PASS Stringification of caches
-PASS CacheStorage interface: caches must inherit property "match(RequestInfo, optional MultiCacheQueryOptions)" with the proper type
-PASS CacheStorage interface: calling match(RequestInfo, optional MultiCacheQueryOptions) on caches with too few arguments must throw TypeError
-PASS CacheStorage interface: caches must inherit property "has(DOMString)" with the proper type
-PASS CacheStorage interface: calling has(DOMString) on caches with too few arguments must throw TypeError
-PASS CacheStorage interface: caches must inherit property "open(DOMString)" with the proper type
-PASS CacheStorage interface: calling open(DOMString) on caches with too few arguments must throw TypeError
-PASS CacheStorage interface: caches must inherit property "delete(DOMString)" with the proper type
-PASS CacheStorage interface: calling delete(DOMString) on caches with too few arguments must throw TypeError
-PASS CacheStorage interface: caches must inherit property "keys()" with the proper type
-PASS WorkerGlobalScope interface: attribute caches
-FAIL WorkerNavigator interface: attribute serviceWorker assert_true: The prototype object must have a property "serviceWorker" expected true got false
+[PASS] idl_test setup
+[PASS] idl_test validation
+[PASS] Partial interface Navigator: original interface defined
+[PASS] Partial interface Navigator: member names are unique
+[PASS] Partial interface WorkerNavigator: original interface defined
+[PASS] Partial interface WorkerNavigator: member names are unique
+[PASS] Partial interface mixin WindowOrWorkerGlobalScope: original interface mixin defined
+[PASS] Partial interface mixin WindowOrWorkerGlobalScope: member names are unique
+[PASS] Partial interface Navigator[2]: member names are unique
+[PASS] Partial interface mixin NavigatorID: member names are unique
+[PASS] Partial interface Window: member names are unique
+[PASS] ServiceWorker includes AbstractWorker: member names are unique
+[PASS] Window includes GlobalEventHandlers: member names are unique
+[PASS] Window includes WindowEventHandlers: member names are unique
+[PASS] Window includes WindowOrWorkerGlobalScope: member names are unique
+[PASS] WorkerGlobalScope includes WindowOrWorkerGlobalScope: member names are unique
+[PASS] Navigator includes NavigatorID: member names are unique
+[PASS] Navigator includes NavigatorLanguage: member names are unique
+[PASS] Navigator includes NavigatorOnLine: member names are unique
+[PASS] Navigator includes NavigatorContentUtils: member names are unique
+[PASS] Navigator includes NavigatorCookies: member names are unique
+[PASS] Navigator includes NavigatorPlugins: member names are unique
+[PASS] Navigator includes NavigatorConcurrentHardware: member names are unique
+[PASS] Window includes AnimationFrameProvider: member names are unique
+[PASS] WorkerNavigator includes NavigatorID: member names are unique
+[PASS] WorkerNavigator includes NavigatorLanguage: member names are unique
+[PASS] WorkerNavigator includes NavigatorOnLine: member names are unique
+[PASS] WorkerNavigator includes NavigatorConcurrentHardware: member names are unique
+[PASS] Window includes WindowSessionStorage: member names are unique
+[PASS] Window includes WindowLocalStorage: member names are unique
+[PASS] ServiceWorker interface: existence and properties of interface object
+[PASS] ServiceWorker interface object length
+[PASS] ServiceWorker interface object name
+[PASS] ServiceWorker interface: existence and properties of interface prototype object
+[PASS] ServiceWorker interface: existence and properties of interface prototype object's "constructor" property
+[PASS] ServiceWorker interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] ServiceWorker interface: attribute scriptURL
+[PASS] ServiceWorker interface: attribute state
+[PASS] ServiceWorker interface: operation postMessage(any, sequence<object>)
+[PASS] ServiceWorker interface: operation postMessage(any, optional StructuredSerializeOptions)
+[PASS] ServiceWorker interface: attribute onstatechange
+[PASS] ServiceWorker must be primary interface of serviceWorker
+[PASS] Stringification of serviceWorker
+[PASS] ServiceWorker interface: serviceWorker must inherit property "scriptURL" with the proper type
+[PASS] ServiceWorker interface: serviceWorker must inherit property "state" with the proper type
+[PASS] ServiceWorker interface: serviceWorker must inherit property "postMessage(any, sequence<object>)" with the proper type
+[PASS] ServiceWorker interface: calling postMessage(any, sequence<object>) on serviceWorker with too few arguments must throw TypeError
+[PASS] ServiceWorker interface: serviceWorker must inherit property "postMessage(any, optional StructuredSerializeOptions)" with the proper type
+[PASS] ServiceWorker interface: calling postMessage(any, optional StructuredSerializeOptions) on serviceWorker with too few arguments must throw TypeError
+[PASS] ServiceWorker interface: serviceWorker must inherit property "onstatechange" with the proper type
+[PASS] ServiceWorkerRegistration interface: existence and properties of interface object
+[PASS] ServiceWorkerRegistration interface object length
+[PASS] ServiceWorkerRegistration interface object name
+[PASS] ServiceWorkerRegistration interface: existence and properties of interface prototype object
+[PASS] ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
+[PASS] ServiceWorkerRegistration interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] ServiceWorkerRegistration interface: attribute installing
+[PASS] ServiceWorkerRegistration interface: attribute waiting
+[PASS] ServiceWorkerRegistration interface: attribute active
+[PASS] ServiceWorkerRegistration interface: attribute navigationPreload
+[PASS] ServiceWorkerRegistration interface: attribute scope
+[PASS] ServiceWorkerRegistration interface: attribute updateViaCache
+[PASS] ServiceWorkerRegistration interface: operation update()
+[PASS] ServiceWorkerRegistration interface: operation unregister()
+[PASS] ServiceWorkerRegistration interface: attribute onupdatefound
+[PASS] ServiceWorkerRegistration must be primary interface of registration
+[PASS] Stringification of registration
+[PASS] ServiceWorkerRegistration interface: registration must inherit property "installing" with the proper type
+[PASS] ServiceWorkerRegistration interface: registration must inherit property "waiting" with the proper type
+[PASS] ServiceWorkerRegistration interface: registration must inherit property "active" with the proper type
+[PASS] ServiceWorkerRegistration interface: registration must inherit property "navigationPreload" with the proper type
+[PASS] ServiceWorkerRegistration interface: registration must inherit property "scope" with the proper type
+[PASS] ServiceWorkerRegistration interface: registration must inherit property "updateViaCache" with the proper type
+[PASS] ServiceWorkerRegistration interface: registration must inherit property "update()" with the proper type
+[PASS] ServiceWorkerRegistration interface: registration must inherit property "unregister()" with the proper type
+[PASS] ServiceWorkerRegistration interface: registration must inherit property "onupdatefound" with the proper type
+[FAIL] ServiceWorkerContainer interface: existence and properties of interface object
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface object length
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface object name
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: existence and properties of interface prototype object
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: existence and properties of interface prototype object's "constructor" property
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: existence and properties of interface prototype object's @@unscopables property
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute controller
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute ready
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: operation register(USVString, optional RegistrationOptions)
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: operation getRegistration(optional USVString)
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: operation getRegistrations()
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: operation startMessages()
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute oncontrollerchange
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute onmessage
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute onmessageerror
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer must be primary interface of navigator.serviceWorker
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] Stringification of navigator.serviceWorker
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "controller" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "ready" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "register(USVString, optional RegistrationOptions)" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: calling register(USVString, optional RegistrationOptions) on navigator.serviceWorker with too few arguments must throw TypeError
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistration(optional USVString)" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: calling getRegistration(optional USVString) on navigator.serviceWorker with too few arguments must throw TypeError
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistrations()" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "startMessages()" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "oncontrollerchange" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessage" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessageerror" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[PASS] NavigationPreloadManager interface: existence and properties of interface object
+[PASS] NavigationPreloadManager interface object length
+[PASS] NavigationPreloadManager interface object name
+[PASS] NavigationPreloadManager interface: existence and properties of interface prototype object
+[PASS] NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
+[PASS] NavigationPreloadManager interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] NavigationPreloadManager interface: operation enable()
+[PASS] NavigationPreloadManager interface: operation disable()
+[PASS] NavigationPreloadManager interface: operation setHeaderValue(ByteString)
+[PASS] NavigationPreloadManager interface: operation getState()
+[PASS] ServiceWorkerGlobalScope interface: existence and properties of interface object
+[PASS] ServiceWorkerGlobalScope interface object length
+[PASS] ServiceWorkerGlobalScope interface object name
+[PASS] ServiceWorkerGlobalScope interface: existence and properties of interface prototype object
+[PASS] ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError
+[PASS] ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via __proto__ should throw a TypeError
+[PASS] ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Reflect.setPrototypeOf should return false
+[PASS] ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Object.setPrototypeOf should not throw
+[PASS] ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via __proto__ should not throw
+[PASS] ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Reflect.setPrototypeOf should return true
+[PASS] ServiceWorkerGlobalScope interface: existence and properties of interface prototype object's "constructor" property
+[PASS] ServiceWorkerGlobalScope interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] ServiceWorkerGlobalScope interface: attribute clients
+[PASS] ServiceWorkerGlobalScope interface: attribute registration
+[PASS] ServiceWorkerGlobalScope interface: attribute serviceWorker
+[PASS] ServiceWorkerGlobalScope interface: operation skipWaiting()
+[PASS] ServiceWorkerGlobalScope interface: attribute oninstall
+[PASS] ServiceWorkerGlobalScope interface: attribute onactivate
+[PASS] ServiceWorkerGlobalScope interface: attribute onfetch
+[PASS] ServiceWorkerGlobalScope interface: attribute onmessage
+[PASS] ServiceWorkerGlobalScope interface: attribute onmessageerror
+[PASS] ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError
+[PASS] ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via __proto__ should throw a TypeError
+[PASS] ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Reflect.setPrototypeOf should return false
+[PASS] ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Object.setPrototypeOf should not throw
+[PASS] ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via __proto__ should not throw
+[PASS] ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Reflect.setPrototypeOf should return true
+[PASS] ServiceWorkerGlobalScope must be primary interface of self
+[PASS] Stringification of self
+[PASS] ServiceWorkerGlobalScope interface: self must inherit property "clients" with the proper type
+[PASS] ServiceWorkerGlobalScope interface: self must inherit property "registration" with the proper type
+[PASS] ServiceWorkerGlobalScope interface: self must inherit property "serviceWorker" with the proper type
+[PASS] ServiceWorkerGlobalScope interface: self must inherit property "skipWaiting()" with the proper type
+[PASS] ServiceWorkerGlobalScope interface: self must inherit property "oninstall" with the proper type
+[PASS] ServiceWorkerGlobalScope interface: self must inherit property "onactivate" with the proper type
+[PASS] ServiceWorkerGlobalScope interface: self must inherit property "onfetch" with the proper type
+[PASS] ServiceWorkerGlobalScope interface: self must inherit property "onmessage" with the proper type
+[PASS] ServiceWorkerGlobalScope interface: self must inherit property "onmessageerror" with the proper type
+[PASS] WorkerGlobalScope interface: self must inherit property "caches" with the proper type
+[PASS] Client interface: existence and properties of interface object
+[PASS] Client interface object length
+[PASS] Client interface object name
+[PASS] Client interface: existence and properties of interface prototype object
+[PASS] Client interface: existence and properties of interface prototype object's "constructor" property
+[PASS] Client interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] Client interface: attribute url
+[PASS] Client interface: attribute frameType
+[PASS] Client interface: attribute id
+[PASS] Client interface: attribute type
+[PASS] Client interface: operation postMessage(any, sequence<object>)
+[PASS] Client interface: operation postMessage(any, optional StructuredSerializeOptions)
+[PASS] WindowClient interface: existence and properties of interface object
+[PASS] WindowClient interface object length
+[PASS] WindowClient interface object name
+[PASS] WindowClient interface: existence and properties of interface prototype object
+[PASS] WindowClient interface: existence and properties of interface prototype object's "constructor" property
+[PASS] WindowClient interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] WindowClient interface: attribute visibilityState
+[PASS] WindowClient interface: attribute focused
+[FAIL] WindowClient interface: attribute ancestorOrigins
+  assert_true: The prototype object must have a property "ancestorOrigins" expected true got false
+[PASS] WindowClient interface: operation focus()
+[PASS] WindowClient interface: operation navigate(USVString)
+[PASS] Clients interface: existence and properties of interface object
+[PASS] Clients interface object length
+[PASS] Clients interface object name
+[PASS] Clients interface: existence and properties of interface prototype object
+[PASS] Clients interface: existence and properties of interface prototype object's "constructor" property
+[PASS] Clients interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] Clients interface: operation get(DOMString)
+[PASS] Clients interface: operation matchAll(optional ClientQueryOptions)
+[PASS] Clients interface: operation openWindow(USVString)
+[PASS] Clients interface: operation claim()
+[PASS] Clients must be primary interface of clients
+[PASS] Stringification of clients
+[PASS] Clients interface: clients must inherit property "get(DOMString)" with the proper type
+[PASS] Clients interface: calling get(DOMString) on clients with too few arguments must throw TypeError
+[PASS] Clients interface: clients must inherit property "matchAll(optional ClientQueryOptions)" with the proper type
+[PASS] Clients interface: calling matchAll(optional ClientQueryOptions) on clients with too few arguments must throw TypeError
+[PASS] Clients interface: clients must inherit property "openWindow(USVString)" with the proper type
+[PASS] Clients interface: calling openWindow(USVString) on clients with too few arguments must throw TypeError
+[PASS] Clients interface: clients must inherit property "claim()" with the proper type
+[PASS] ExtendableEvent interface: existence and properties of interface object
+[PASS] ExtendableEvent interface object length
+[PASS] ExtendableEvent interface object name
+[PASS] ExtendableEvent interface: existence and properties of interface prototype object
+[PASS] ExtendableEvent interface: existence and properties of interface prototype object's "constructor" property
+[PASS] ExtendableEvent interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] ExtendableEvent interface: operation waitUntil(Promise<any>)
+[PASS] ExtendableEvent must be primary interface of new ExtendableEvent("type")
+[PASS] Stringification of new ExtendableEvent("type")
+[PASS] ExtendableEvent interface: new ExtendableEvent("type") must inherit property "waitUntil(Promise<any>)" with the proper type
+[PASS] ExtendableEvent interface: calling waitUntil(Promise<any>) on new ExtendableEvent("type") with too few arguments must throw TypeError
+[PASS] FetchEvent interface: existence and properties of interface object
+[PASS] FetchEvent interface object length
+[PASS] FetchEvent interface object name
+[PASS] FetchEvent interface: existence and properties of interface prototype object
+[PASS] FetchEvent interface: existence and properties of interface prototype object's "constructor" property
+[PASS] FetchEvent interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] FetchEvent interface: attribute request
+[PASS] FetchEvent interface: attribute preloadResponse
+[PASS] FetchEvent interface: attribute clientId
+[PASS] FetchEvent interface: attribute resultingClientId
+[FAIL] FetchEvent interface: attribute replacesClientId
+  assert_true: The prototype object must have a property "replacesClientId" expected true got false
+[PASS] FetchEvent interface: attribute handled
+[PASS] FetchEvent interface: operation respondWith(Promise<Response>)
+[PASS] FetchEvent must be primary interface of new FetchEvent("type", { request: new Request("") })
+[PASS] Stringification of new FetchEvent("type", { request: new Request("") })
+[PASS] FetchEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "request" with the proper type
+[PASS] FetchEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "preloadResponse" with the proper type
+[PASS] FetchEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "clientId" with the proper type
+[PASS] FetchEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "resultingClientId" with the proper type
+[FAIL] FetchEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "replacesClientId" with the proper type
+  assert_inherits: property "replacesClientId" not found in prototype chain
+[PASS] FetchEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "handled" with the proper type
+[PASS] FetchEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "respondWith(Promise<Response>)" with the proper type
+[PASS] FetchEvent interface: calling respondWith(Promise<Response>) on new FetchEvent("type", { request: new Request("") }) with too few arguments must throw TypeError
+[PASS] ExtendableEvent interface: new FetchEvent("type", { request: new Request("") }) must inherit property "waitUntil(Promise<any>)" with the proper type
+[PASS] ExtendableEvent interface: calling waitUntil(Promise<any>) on new FetchEvent("type", { request: new Request("") }) with too few arguments must throw TypeError
+[PASS] ExtendableMessageEvent interface: existence and properties of interface object
+[PASS] ExtendableMessageEvent interface object length
+[PASS] ExtendableMessageEvent interface object name
+[PASS] ExtendableMessageEvent interface: existence and properties of interface prototype object
+[PASS] ExtendableMessageEvent interface: existence and properties of interface prototype object's "constructor" property
+[PASS] ExtendableMessageEvent interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] ExtendableMessageEvent interface: attribute data
+[PASS] ExtendableMessageEvent interface: attribute origin
+[PASS] ExtendableMessageEvent interface: attribute lastEventId
+[PASS] ExtendableMessageEvent interface: attribute source
+[PASS] ExtendableMessageEvent interface: attribute ports
+[PASS] Cache interface: existence and properties of interface object
+[PASS] Cache interface object length
+[PASS] Cache interface object name
+[PASS] Cache interface: existence and properties of interface prototype object
+[PASS] Cache interface: existence and properties of interface prototype object's "constructor" property
+[PASS] Cache interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] Cache interface: operation match(RequestInfo, optional CacheQueryOptions)
+[PASS] Cache interface: operation matchAll(optional RequestInfo, optional CacheQueryOptions)
+[PASS] Cache interface: operation add(RequestInfo)
+[PASS] Cache interface: operation addAll(sequence<RequestInfo>)
+[PASS] Cache interface: operation put(RequestInfo, Response)
+[PASS] Cache interface: operation delete(RequestInfo, optional CacheQueryOptions)
+[PASS] Cache interface: operation keys(optional RequestInfo, optional CacheQueryOptions)
+[PASS] Cache must be primary interface of self.cacheInstance
+[PASS] Stringification of self.cacheInstance
+[PASS] Cache interface: self.cacheInstance must inherit property "match(RequestInfo, optional CacheQueryOptions)" with the proper type
+[PASS] Cache interface: calling match(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "matchAll(optional RequestInfo, optional CacheQueryOptions)" with the proper type
+[PASS] Cache interface: calling matchAll(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type
+[PASS] Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "addAll(sequence<RequestInfo>)" with the proper type
+[PASS] Cache interface: calling addAll(sequence<RequestInfo>) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type
+[PASS] Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, optional CacheQueryOptions)" with the proper type
+[PASS] Cache interface: calling delete(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "keys(optional RequestInfo, optional CacheQueryOptions)" with the proper type
+[PASS] Cache interface: calling keys(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] CacheStorage interface: existence and properties of interface object
+[PASS] CacheStorage interface object length
+[PASS] CacheStorage interface object name
+[PASS] CacheStorage interface: existence and properties of interface prototype object
+[PASS] CacheStorage interface: existence and properties of interface prototype object's "constructor" property
+[PASS] CacheStorage interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] CacheStorage interface: operation match(RequestInfo, optional MultiCacheQueryOptions)
+[PASS] CacheStorage interface: operation has(DOMString)
+[PASS] CacheStorage interface: operation open(DOMString)
+[PASS] CacheStorage interface: operation delete(DOMString)
+[PASS] CacheStorage interface: operation keys()
+[PASS] CacheStorage must be primary interface of caches
+[PASS] Stringification of caches
+[PASS] CacheStorage interface: caches must inherit property "match(RequestInfo, optional MultiCacheQueryOptions)" with the proper type
+[PASS] CacheStorage interface: calling match(RequestInfo, optional MultiCacheQueryOptions) on caches with too few arguments must throw TypeError
+[PASS] CacheStorage interface: caches must inherit property "has(DOMString)" with the proper type
+[PASS] CacheStorage interface: calling has(DOMString) on caches with too few arguments must throw TypeError
+[PASS] CacheStorage interface: caches must inherit property "open(DOMString)" with the proper type
+[PASS] CacheStorage interface: calling open(DOMString) on caches with too few arguments must throw TypeError
+[PASS] CacheStorage interface: caches must inherit property "delete(DOMString)" with the proper type
+[PASS] CacheStorage interface: calling delete(DOMString) on caches with too few arguments must throw TypeError
+[PASS] CacheStorage interface: caches must inherit property "keys()" with the proper type
+[PASS] WorkerGlobalScope interface: attribute caches
+[FAIL] WorkerNavigator interface: attribute serviceWorker
+  assert_true: The prototype object must have a property "serviceWorker" expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.sharedworker-expected.txt
index fbda11715..003a608 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.sharedworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.sharedworker-expected.txt
@@ -1,158 +1,198 @@
 This is a testharness.js-based test.
 Found 154 tests; 114 PASS, 40 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Partial interface Navigator: original interface defined
-PASS Partial interface Navigator: member names are unique
-PASS Partial interface WorkerNavigator: original interface defined
-PASS Partial interface WorkerNavigator: member names are unique
-PASS Partial interface mixin WindowOrWorkerGlobalScope: original interface mixin defined
-PASS Partial interface mixin WindowOrWorkerGlobalScope: member names are unique
-PASS Partial interface Navigator[2]: member names are unique
-PASS Partial interface mixin NavigatorID: member names are unique
-PASS Partial interface Window: member names are unique
-PASS ServiceWorker includes AbstractWorker: member names are unique
-PASS Window includes GlobalEventHandlers: member names are unique
-PASS Window includes WindowEventHandlers: member names are unique
-PASS Window includes WindowOrWorkerGlobalScope: member names are unique
-PASS WorkerGlobalScope includes WindowOrWorkerGlobalScope: member names are unique
-PASS Navigator includes NavigatorID: member names are unique
-PASS Navigator includes NavigatorLanguage: member names are unique
-PASS Navigator includes NavigatorOnLine: member names are unique
-PASS Navigator includes NavigatorContentUtils: member names are unique
-PASS Navigator includes NavigatorCookies: member names are unique
-PASS Navigator includes NavigatorPlugins: member names are unique
-PASS Navigator includes NavigatorConcurrentHardware: member names are unique
-PASS Window includes AnimationFrameProvider: member names are unique
-PASS WorkerNavigator includes NavigatorID: member names are unique
-PASS WorkerNavigator includes NavigatorLanguage: member names are unique
-PASS WorkerNavigator includes NavigatorOnLine: member names are unique
-PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique
-PASS Window includes WindowSessionStorage: member names are unique
-PASS Window includes WindowLocalStorage: member names are unique
-FAIL ServiceWorker interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface object length assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface object name assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute scriptURL assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute state assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: operation postMessage(any, sequence<object>) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: operation postMessage(any, optional StructuredSerializeOptions) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute onstatechange assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-PASS ServiceWorkerRegistration interface: existence and properties of interface object
-PASS ServiceWorkerRegistration interface object length
-PASS ServiceWorkerRegistration interface object name
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's @@unscopables property
-PASS ServiceWorkerRegistration interface: attribute installing
-PASS ServiceWorkerRegistration interface: attribute waiting
-PASS ServiceWorkerRegistration interface: attribute active
-PASS ServiceWorkerRegistration interface: attribute navigationPreload
-PASS ServiceWorkerRegistration interface: attribute scope
-PASS ServiceWorkerRegistration interface: attribute updateViaCache
-PASS ServiceWorkerRegistration interface: operation update()
-PASS ServiceWorkerRegistration interface: operation unregister()
-PASS ServiceWorkerRegistration interface: attribute onupdatefound
-FAIL ServiceWorkerContainer interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface object length assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface object name assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute controller assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute ready assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: operation register(USVString, optional RegistrationOptions) assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: operation getRegistration(optional USVString) assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: operation getRegistrations() assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: operation startMessages() assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute oncontrollerchange assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute onmessage assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute onmessageerror assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer must be primary interface of navigator.serviceWorker assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL Stringification of navigator.serviceWorker assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "controller" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "ready" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "register(USVString, optional RegistrationOptions)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: calling register(USVString, optional RegistrationOptions) on navigator.serviceWorker with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistration(optional USVString)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: calling getRegistration(optional USVString) on navigator.serviceWorker with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistrations()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "startMessages()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "oncontrollerchange" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessage" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessageerror" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-PASS NavigationPreloadManager interface: existence and properties of interface object
-PASS NavigationPreloadManager interface object length
-PASS NavigationPreloadManager interface object name
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's @@unscopables property
-PASS NavigationPreloadManager interface: operation enable()
-PASS NavigationPreloadManager interface: operation disable()
-PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString)
-PASS NavigationPreloadManager interface: operation getState()
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface object
-PASS Client interface: existence and properties of interface object
-PASS WindowClient interface: existence and properties of interface object
-PASS Clients interface: existence and properties of interface object
-PASS ExtendableEvent interface: existence and properties of interface object
-PASS FetchEvent interface: existence and properties of interface object
-PASS ExtendableMessageEvent interface: existence and properties of interface object
-PASS Cache interface: existence and properties of interface object
-PASS Cache interface object length
-PASS Cache interface object name
-PASS Cache interface: existence and properties of interface prototype object
-PASS Cache interface: existence and properties of interface prototype object's "constructor" property
-PASS Cache interface: existence and properties of interface prototype object's @@unscopables property
-PASS Cache interface: operation match(RequestInfo, optional CacheQueryOptions)
-PASS Cache interface: operation matchAll(optional RequestInfo, optional CacheQueryOptions)
-PASS Cache interface: operation add(RequestInfo)
-PASS Cache interface: operation addAll(sequence<RequestInfo>)
-PASS Cache interface: operation put(RequestInfo, Response)
-PASS Cache interface: operation delete(RequestInfo, optional CacheQueryOptions)
-PASS Cache interface: operation keys(optional RequestInfo, optional CacheQueryOptions)
-PASS Cache must be primary interface of self.cacheInstance
-PASS Stringification of self.cacheInstance
-PASS Cache interface: self.cacheInstance must inherit property "match(RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling match(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "matchAll(optional RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling matchAll(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type
-PASS Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "addAll(sequence<RequestInfo>)" with the proper type
-PASS Cache interface: calling addAll(sequence<RequestInfo>) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type
-PASS Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling delete(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "keys(optional RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling keys(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS CacheStorage interface: existence and properties of interface object
-PASS CacheStorage interface object length
-PASS CacheStorage interface object name
-PASS CacheStorage interface: existence and properties of interface prototype object
-PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property
-PASS CacheStorage interface: existence and properties of interface prototype object's @@unscopables property
-PASS CacheStorage interface: operation match(RequestInfo, optional MultiCacheQueryOptions)
-PASS CacheStorage interface: operation has(DOMString)
-PASS CacheStorage interface: operation open(DOMString)
-PASS CacheStorage interface: operation delete(DOMString)
-PASS CacheStorage interface: operation keys()
-PASS CacheStorage must be primary interface of caches
-PASS Stringification of caches
-PASS CacheStorage interface: caches must inherit property "match(RequestInfo, optional MultiCacheQueryOptions)" with the proper type
-PASS CacheStorage interface: calling match(RequestInfo, optional MultiCacheQueryOptions) on caches with too few arguments must throw TypeError
-PASS CacheStorage interface: caches must inherit property "has(DOMString)" with the proper type
-PASS CacheStorage interface: calling has(DOMString) on caches with too few arguments must throw TypeError
-PASS CacheStorage interface: caches must inherit property "open(DOMString)" with the proper type
-PASS CacheStorage interface: calling open(DOMString) on caches with too few arguments must throw TypeError
-PASS CacheStorage interface: caches must inherit property "delete(DOMString)" with the proper type
-PASS CacheStorage interface: calling delete(DOMString) on caches with too few arguments must throw TypeError
-PASS CacheStorage interface: caches must inherit property "keys()" with the proper type
-PASS WorkerGlobalScope interface: attribute caches
-FAIL WorkerNavigator interface: attribute serviceWorker assert_true: The prototype object must have a property "serviceWorker" expected true got false
+[PASS] idl_test setup
+[PASS] idl_test validation
+[PASS] Partial interface Navigator: original interface defined
+[PASS] Partial interface Navigator: member names are unique
+[PASS] Partial interface WorkerNavigator: original interface defined
+[PASS] Partial interface WorkerNavigator: member names are unique
+[PASS] Partial interface mixin WindowOrWorkerGlobalScope: original interface mixin defined
+[PASS] Partial interface mixin WindowOrWorkerGlobalScope: member names are unique
+[PASS] Partial interface Navigator[2]: member names are unique
+[PASS] Partial interface mixin NavigatorID: member names are unique
+[PASS] Partial interface Window: member names are unique
+[PASS] ServiceWorker includes AbstractWorker: member names are unique
+[PASS] Window includes GlobalEventHandlers: member names are unique
+[PASS] Window includes WindowEventHandlers: member names are unique
+[PASS] Window includes WindowOrWorkerGlobalScope: member names are unique
+[PASS] WorkerGlobalScope includes WindowOrWorkerGlobalScope: member names are unique
+[PASS] Navigator includes NavigatorID: member names are unique
+[PASS] Navigator includes NavigatorLanguage: member names are unique
+[PASS] Navigator includes NavigatorOnLine: member names are unique
+[PASS] Navigator includes NavigatorContentUtils: member names are unique
+[PASS] Navigator includes NavigatorCookies: member names are unique
+[PASS] Navigator includes NavigatorPlugins: member names are unique
+[PASS] Navigator includes NavigatorConcurrentHardware: member names are unique
+[PASS] Window includes AnimationFrameProvider: member names are unique
+[PASS] WorkerNavigator includes NavigatorID: member names are unique
+[PASS] WorkerNavigator includes NavigatorLanguage: member names are unique
+[PASS] WorkerNavigator includes NavigatorOnLine: member names are unique
+[PASS] WorkerNavigator includes NavigatorConcurrentHardware: member names are unique
+[PASS] Window includes WindowSessionStorage: member names are unique
+[PASS] Window includes WindowLocalStorage: member names are unique
+[FAIL] ServiceWorker interface: existence and properties of interface object
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface object length
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface object name
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: existence and properties of interface prototype object
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: existence and properties of interface prototype object's "constructor" property
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: existence and properties of interface prototype object's @@unscopables property
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: attribute scriptURL
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: attribute state
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: operation postMessage(any, sequence<object>)
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: operation postMessage(any, optional StructuredSerializeOptions)
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: attribute onstatechange
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[PASS] ServiceWorkerRegistration interface: existence and properties of interface object
+[PASS] ServiceWorkerRegistration interface object length
+[PASS] ServiceWorkerRegistration interface object name
+[PASS] ServiceWorkerRegistration interface: existence and properties of interface prototype object
+[PASS] ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
+[PASS] ServiceWorkerRegistration interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] ServiceWorkerRegistration interface: attribute installing
+[PASS] ServiceWorkerRegistration interface: attribute waiting
+[PASS] ServiceWorkerRegistration interface: attribute active
+[PASS] ServiceWorkerRegistration interface: attribute navigationPreload
+[PASS] ServiceWorkerRegistration interface: attribute scope
+[PASS] ServiceWorkerRegistration interface: attribute updateViaCache
+[PASS] ServiceWorkerRegistration interface: operation update()
+[PASS] ServiceWorkerRegistration interface: operation unregister()
+[PASS] ServiceWorkerRegistration interface: attribute onupdatefound
+[FAIL] ServiceWorkerContainer interface: existence and properties of interface object
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface object length
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface object name
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: existence and properties of interface prototype object
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: existence and properties of interface prototype object's "constructor" property
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: existence and properties of interface prototype object's @@unscopables property
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute controller
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute ready
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: operation register(USVString, optional RegistrationOptions)
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: operation getRegistration(optional USVString)
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: operation getRegistrations()
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: operation startMessages()
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute oncontrollerchange
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute onmessage
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute onmessageerror
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer must be primary interface of navigator.serviceWorker
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] Stringification of navigator.serviceWorker
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "controller" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "ready" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "register(USVString, optional RegistrationOptions)" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: calling register(USVString, optional RegistrationOptions) on navigator.serviceWorker with too few arguments must throw TypeError
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistration(optional USVString)" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: calling getRegistration(optional USVString) on navigator.serviceWorker with too few arguments must throw TypeError
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistrations()" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "startMessages()" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "oncontrollerchange" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessage" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessageerror" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[PASS] NavigationPreloadManager interface: existence and properties of interface object
+[PASS] NavigationPreloadManager interface object length
+[PASS] NavigationPreloadManager interface object name
+[PASS] NavigationPreloadManager interface: existence and properties of interface prototype object
+[PASS] NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
+[PASS] NavigationPreloadManager interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] NavigationPreloadManager interface: operation enable()
+[PASS] NavigationPreloadManager interface: operation disable()
+[PASS] NavigationPreloadManager interface: operation setHeaderValue(ByteString)
+[PASS] NavigationPreloadManager interface: operation getState()
+[PASS] ServiceWorkerGlobalScope interface: existence and properties of interface object
+[PASS] Client interface: existence and properties of interface object
+[PASS] WindowClient interface: existence and properties of interface object
+[PASS] Clients interface: existence and properties of interface object
+[PASS] ExtendableEvent interface: existence and properties of interface object
+[PASS] FetchEvent interface: existence and properties of interface object
+[PASS] ExtendableMessageEvent interface: existence and properties of interface object
+[PASS] Cache interface: existence and properties of interface object
+[PASS] Cache interface object length
+[PASS] Cache interface object name
+[PASS] Cache interface: existence and properties of interface prototype object
+[PASS] Cache interface: existence and properties of interface prototype object's "constructor" property
+[PASS] Cache interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] Cache interface: operation match(RequestInfo, optional CacheQueryOptions)
+[PASS] Cache interface: operation matchAll(optional RequestInfo, optional CacheQueryOptions)
+[PASS] Cache interface: operation add(RequestInfo)
+[PASS] Cache interface: operation addAll(sequence<RequestInfo>)
+[PASS] Cache interface: operation put(RequestInfo, Response)
+[PASS] Cache interface: operation delete(RequestInfo, optional CacheQueryOptions)
+[PASS] Cache interface: operation keys(optional RequestInfo, optional CacheQueryOptions)
+[PASS] Cache must be primary interface of self.cacheInstance
+[PASS] Stringification of self.cacheInstance
+[PASS] Cache interface: self.cacheInstance must inherit property "match(RequestInfo, optional CacheQueryOptions)" with the proper type
+[PASS] Cache interface: calling match(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "matchAll(optional RequestInfo, optional CacheQueryOptions)" with the proper type
+[PASS] Cache interface: calling matchAll(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type
+[PASS] Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "addAll(sequence<RequestInfo>)" with the proper type
+[PASS] Cache interface: calling addAll(sequence<RequestInfo>) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type
+[PASS] Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, optional CacheQueryOptions)" with the proper type
+[PASS] Cache interface: calling delete(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "keys(optional RequestInfo, optional CacheQueryOptions)" with the proper type
+[PASS] Cache interface: calling keys(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] CacheStorage interface: existence and properties of interface object
+[PASS] CacheStorage interface object length
+[PASS] CacheStorage interface object name
+[PASS] CacheStorage interface: existence and properties of interface prototype object
+[PASS] CacheStorage interface: existence and properties of interface prototype object's "constructor" property
+[PASS] CacheStorage interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] CacheStorage interface: operation match(RequestInfo, optional MultiCacheQueryOptions)
+[PASS] CacheStorage interface: operation has(DOMString)
+[PASS] CacheStorage interface: operation open(DOMString)
+[PASS] CacheStorage interface: operation delete(DOMString)
+[PASS] CacheStorage interface: operation keys()
+[PASS] CacheStorage must be primary interface of caches
+[PASS] Stringification of caches
+[PASS] CacheStorage interface: caches must inherit property "match(RequestInfo, optional MultiCacheQueryOptions)" with the proper type
+[PASS] CacheStorage interface: calling match(RequestInfo, optional MultiCacheQueryOptions) on caches with too few arguments must throw TypeError
+[PASS] CacheStorage interface: caches must inherit property "has(DOMString)" with the proper type
+[PASS] CacheStorage interface: calling has(DOMString) on caches with too few arguments must throw TypeError
+[PASS] CacheStorage interface: caches must inherit property "open(DOMString)" with the proper type
+[PASS] CacheStorage interface: calling open(DOMString) on caches with too few arguments must throw TypeError
+[PASS] CacheStorage interface: caches must inherit property "delete(DOMString)" with the proper type
+[PASS] CacheStorage interface: calling delete(DOMString) on caches with too few arguments must throw TypeError
+[PASS] CacheStorage interface: caches must inherit property "keys()" with the proper type
+[PASS] WorkerGlobalScope interface: attribute caches
+[FAIL] WorkerNavigator interface: attribute serviceWorker
+  assert_true: The prototype object must have a property "serviceWorker" expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.worker-expected.txt
index fbda11715..003a608 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.worker-expected.txt
@@ -1,158 +1,198 @@
 This is a testharness.js-based test.
 Found 154 tests; 114 PASS, 40 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS idl_test setup
-PASS idl_test validation
-PASS Partial interface Navigator: original interface defined
-PASS Partial interface Navigator: member names are unique
-PASS Partial interface WorkerNavigator: original interface defined
-PASS Partial interface WorkerNavigator: member names are unique
-PASS Partial interface mixin WindowOrWorkerGlobalScope: original interface mixin defined
-PASS Partial interface mixin WindowOrWorkerGlobalScope: member names are unique
-PASS Partial interface Navigator[2]: member names are unique
-PASS Partial interface mixin NavigatorID: member names are unique
-PASS Partial interface Window: member names are unique
-PASS ServiceWorker includes AbstractWorker: member names are unique
-PASS Window includes GlobalEventHandlers: member names are unique
-PASS Window includes WindowEventHandlers: member names are unique
-PASS Window includes WindowOrWorkerGlobalScope: member names are unique
-PASS WorkerGlobalScope includes WindowOrWorkerGlobalScope: member names are unique
-PASS Navigator includes NavigatorID: member names are unique
-PASS Navigator includes NavigatorLanguage: member names are unique
-PASS Navigator includes NavigatorOnLine: member names are unique
-PASS Navigator includes NavigatorContentUtils: member names are unique
-PASS Navigator includes NavigatorCookies: member names are unique
-PASS Navigator includes NavigatorPlugins: member names are unique
-PASS Navigator includes NavigatorConcurrentHardware: member names are unique
-PASS Window includes AnimationFrameProvider: member names are unique
-PASS WorkerNavigator includes NavigatorID: member names are unique
-PASS WorkerNavigator includes NavigatorLanguage: member names are unique
-PASS WorkerNavigator includes NavigatorOnLine: member names are unique
-PASS WorkerNavigator includes NavigatorConcurrentHardware: member names are unique
-PASS Window includes WindowSessionStorage: member names are unique
-PASS Window includes WindowLocalStorage: member names are unique
-FAIL ServiceWorker interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface object length assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface object name assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute scriptURL assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute state assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: operation postMessage(any, sequence<object>) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: operation postMessage(any, optional StructuredSerializeOptions) assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-FAIL ServiceWorker interface: attribute onstatechange assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
-PASS ServiceWorkerRegistration interface: existence and properties of interface object
-PASS ServiceWorkerRegistration interface object length
-PASS ServiceWorkerRegistration interface object name
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's @@unscopables property
-PASS ServiceWorkerRegistration interface: attribute installing
-PASS ServiceWorkerRegistration interface: attribute waiting
-PASS ServiceWorkerRegistration interface: attribute active
-PASS ServiceWorkerRegistration interface: attribute navigationPreload
-PASS ServiceWorkerRegistration interface: attribute scope
-PASS ServiceWorkerRegistration interface: attribute updateViaCache
-PASS ServiceWorkerRegistration interface: operation update()
-PASS ServiceWorkerRegistration interface: operation unregister()
-PASS ServiceWorkerRegistration interface: attribute onupdatefound
-FAIL ServiceWorkerContainer interface: existence and properties of interface object assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface object length assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface object name assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute controller assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute ready assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: operation register(USVString, optional RegistrationOptions) assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: operation getRegistration(optional USVString) assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: operation getRegistrations() assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: operation startMessages() assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute oncontrollerchange assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute onmessage assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer interface: attribute onmessageerror assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
-FAIL ServiceWorkerContainer must be primary interface of navigator.serviceWorker assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL Stringification of navigator.serviceWorker assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "controller" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "ready" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "register(USVString, optional RegistrationOptions)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: calling register(USVString, optional RegistrationOptions) on navigator.serviceWorker with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistration(optional USVString)" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: calling getRegistration(optional USVString) on navigator.serviceWorker with too few arguments must throw TypeError assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistrations()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "startMessages()" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "oncontrollerchange" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessage" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-FAIL ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessageerror" with the proper type assert_equals: wrong typeof object expected "object" but got "undefined"
-PASS NavigationPreloadManager interface: existence and properties of interface object
-PASS NavigationPreloadManager interface object length
-PASS NavigationPreloadManager interface object name
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's @@unscopables property
-PASS NavigationPreloadManager interface: operation enable()
-PASS NavigationPreloadManager interface: operation disable()
-PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString)
-PASS NavigationPreloadManager interface: operation getState()
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface object
-PASS Client interface: existence and properties of interface object
-PASS WindowClient interface: existence and properties of interface object
-PASS Clients interface: existence and properties of interface object
-PASS ExtendableEvent interface: existence and properties of interface object
-PASS FetchEvent interface: existence and properties of interface object
-PASS ExtendableMessageEvent interface: existence and properties of interface object
-PASS Cache interface: existence and properties of interface object
-PASS Cache interface object length
-PASS Cache interface object name
-PASS Cache interface: existence and properties of interface prototype object
-PASS Cache interface: existence and properties of interface prototype object's "constructor" property
-PASS Cache interface: existence and properties of interface prototype object's @@unscopables property
-PASS Cache interface: operation match(RequestInfo, optional CacheQueryOptions)
-PASS Cache interface: operation matchAll(optional RequestInfo, optional CacheQueryOptions)
-PASS Cache interface: operation add(RequestInfo)
-PASS Cache interface: operation addAll(sequence<RequestInfo>)
-PASS Cache interface: operation put(RequestInfo, Response)
-PASS Cache interface: operation delete(RequestInfo, optional CacheQueryOptions)
-PASS Cache interface: operation keys(optional RequestInfo, optional CacheQueryOptions)
-PASS Cache must be primary interface of self.cacheInstance
-PASS Stringification of self.cacheInstance
-PASS Cache interface: self.cacheInstance must inherit property "match(RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling match(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "matchAll(optional RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling matchAll(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type
-PASS Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "addAll(sequence<RequestInfo>)" with the proper type
-PASS Cache interface: calling addAll(sequence<RequestInfo>) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type
-PASS Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling delete(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "keys(optional RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling keys(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS CacheStorage interface: existence and properties of interface object
-PASS CacheStorage interface object length
-PASS CacheStorage interface object name
-PASS CacheStorage interface: existence and properties of interface prototype object
-PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property
-PASS CacheStorage interface: existence and properties of interface prototype object's @@unscopables property
-PASS CacheStorage interface: operation match(RequestInfo, optional MultiCacheQueryOptions)
-PASS CacheStorage interface: operation has(DOMString)
-PASS CacheStorage interface: operation open(DOMString)
-PASS CacheStorage interface: operation delete(DOMString)
-PASS CacheStorage interface: operation keys()
-PASS CacheStorage must be primary interface of caches
-PASS Stringification of caches
-PASS CacheStorage interface: caches must inherit property "match(RequestInfo, optional MultiCacheQueryOptions)" with the proper type
-PASS CacheStorage interface: calling match(RequestInfo, optional MultiCacheQueryOptions) on caches with too few arguments must throw TypeError
-PASS CacheStorage interface: caches must inherit property "has(DOMString)" with the proper type
-PASS CacheStorage interface: calling has(DOMString) on caches with too few arguments must throw TypeError
-PASS CacheStorage interface: caches must inherit property "open(DOMString)" with the proper type
-PASS CacheStorage interface: calling open(DOMString) on caches with too few arguments must throw TypeError
-PASS CacheStorage interface: caches must inherit property "delete(DOMString)" with the proper type
-PASS CacheStorage interface: calling delete(DOMString) on caches with too few arguments must throw TypeError
-PASS CacheStorage interface: caches must inherit property "keys()" with the proper type
-PASS WorkerGlobalScope interface: attribute caches
-FAIL WorkerNavigator interface: attribute serviceWorker assert_true: The prototype object must have a property "serviceWorker" expected true got false
+[PASS] idl_test setup
+[PASS] idl_test validation
+[PASS] Partial interface Navigator: original interface defined
+[PASS] Partial interface Navigator: member names are unique
+[PASS] Partial interface WorkerNavigator: original interface defined
+[PASS] Partial interface WorkerNavigator: member names are unique
+[PASS] Partial interface mixin WindowOrWorkerGlobalScope: original interface mixin defined
+[PASS] Partial interface mixin WindowOrWorkerGlobalScope: member names are unique
+[PASS] Partial interface Navigator[2]: member names are unique
+[PASS] Partial interface mixin NavigatorID: member names are unique
+[PASS] Partial interface Window: member names are unique
+[PASS] ServiceWorker includes AbstractWorker: member names are unique
+[PASS] Window includes GlobalEventHandlers: member names are unique
+[PASS] Window includes WindowEventHandlers: member names are unique
+[PASS] Window includes WindowOrWorkerGlobalScope: member names are unique
+[PASS] WorkerGlobalScope includes WindowOrWorkerGlobalScope: member names are unique
+[PASS] Navigator includes NavigatorID: member names are unique
+[PASS] Navigator includes NavigatorLanguage: member names are unique
+[PASS] Navigator includes NavigatorOnLine: member names are unique
+[PASS] Navigator includes NavigatorContentUtils: member names are unique
+[PASS] Navigator includes NavigatorCookies: member names are unique
+[PASS] Navigator includes NavigatorPlugins: member names are unique
+[PASS] Navigator includes NavigatorConcurrentHardware: member names are unique
+[PASS] Window includes AnimationFrameProvider: member names are unique
+[PASS] WorkerNavigator includes NavigatorID: member names are unique
+[PASS] WorkerNavigator includes NavigatorLanguage: member names are unique
+[PASS] WorkerNavigator includes NavigatorOnLine: member names are unique
+[PASS] WorkerNavigator includes NavigatorConcurrentHardware: member names are unique
+[PASS] Window includes WindowSessionStorage: member names are unique
+[PASS] Window includes WindowLocalStorage: member names are unique
+[FAIL] ServiceWorker interface: existence and properties of interface object
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface object length
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface object name
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: existence and properties of interface prototype object
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: existence and properties of interface prototype object's "constructor" property
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: existence and properties of interface prototype object's @@unscopables property
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: attribute scriptURL
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: attribute state
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: operation postMessage(any, sequence<object>)
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: operation postMessage(any, optional StructuredSerializeOptions)
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[FAIL] ServiceWorker interface: attribute onstatechange
+  assert_own_property: self does not have own property "ServiceWorker" expected property "ServiceWorker" missing
+[PASS] ServiceWorkerRegistration interface: existence and properties of interface object
+[PASS] ServiceWorkerRegistration interface object length
+[PASS] ServiceWorkerRegistration interface object name
+[PASS] ServiceWorkerRegistration interface: existence and properties of interface prototype object
+[PASS] ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
+[PASS] ServiceWorkerRegistration interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] ServiceWorkerRegistration interface: attribute installing
+[PASS] ServiceWorkerRegistration interface: attribute waiting
+[PASS] ServiceWorkerRegistration interface: attribute active
+[PASS] ServiceWorkerRegistration interface: attribute navigationPreload
+[PASS] ServiceWorkerRegistration interface: attribute scope
+[PASS] ServiceWorkerRegistration interface: attribute updateViaCache
+[PASS] ServiceWorkerRegistration interface: operation update()
+[PASS] ServiceWorkerRegistration interface: operation unregister()
+[PASS] ServiceWorkerRegistration interface: attribute onupdatefound
+[FAIL] ServiceWorkerContainer interface: existence and properties of interface object
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface object length
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface object name
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: existence and properties of interface prototype object
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: existence and properties of interface prototype object's "constructor" property
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: existence and properties of interface prototype object's @@unscopables property
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute controller
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute ready
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: operation register(USVString, optional RegistrationOptions)
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: operation getRegistration(optional USVString)
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: operation getRegistrations()
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: operation startMessages()
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute oncontrollerchange
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute onmessage
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer interface: attribute onmessageerror
+  assert_own_property: self does not have own property "ServiceWorkerContainer" expected property "ServiceWorkerContainer" missing
+[FAIL] ServiceWorkerContainer must be primary interface of navigator.serviceWorker
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] Stringification of navigator.serviceWorker
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "controller" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "ready" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "register(USVString, optional RegistrationOptions)" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: calling register(USVString, optional RegistrationOptions) on navigator.serviceWorker with too few arguments must throw TypeError
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistration(optional USVString)" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: calling getRegistration(optional USVString) on navigator.serviceWorker with too few arguments must throw TypeError
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "getRegistrations()" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "startMessages()" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "oncontrollerchange" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessage" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[FAIL] ServiceWorkerContainer interface: navigator.serviceWorker must inherit property "onmessageerror" with the proper type
+  assert_equals: wrong typeof object expected "object" but got "undefined"
+[PASS] NavigationPreloadManager interface: existence and properties of interface object
+[PASS] NavigationPreloadManager interface object length
+[PASS] NavigationPreloadManager interface object name
+[PASS] NavigationPreloadManager interface: existence and properties of interface prototype object
+[PASS] NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
+[PASS] NavigationPreloadManager interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] NavigationPreloadManager interface: operation enable()
+[PASS] NavigationPreloadManager interface: operation disable()
+[PASS] NavigationPreloadManager interface: operation setHeaderValue(ByteString)
+[PASS] NavigationPreloadManager interface: operation getState()
+[PASS] ServiceWorkerGlobalScope interface: existence and properties of interface object
+[PASS] Client interface: existence and properties of interface object
+[PASS] WindowClient interface: existence and properties of interface object
+[PASS] Clients interface: existence and properties of interface object
+[PASS] ExtendableEvent interface: existence and properties of interface object
+[PASS] FetchEvent interface: existence and properties of interface object
+[PASS] ExtendableMessageEvent interface: existence and properties of interface object
+[PASS] Cache interface: existence and properties of interface object
+[PASS] Cache interface object length
+[PASS] Cache interface object name
+[PASS] Cache interface: existence and properties of interface prototype object
+[PASS] Cache interface: existence and properties of interface prototype object's "constructor" property
+[PASS] Cache interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] Cache interface: operation match(RequestInfo, optional CacheQueryOptions)
+[PASS] Cache interface: operation matchAll(optional RequestInfo, optional CacheQueryOptions)
+[PASS] Cache interface: operation add(RequestInfo)
+[PASS] Cache interface: operation addAll(sequence<RequestInfo>)
+[PASS] Cache interface: operation put(RequestInfo, Response)
+[PASS] Cache interface: operation delete(RequestInfo, optional CacheQueryOptions)
+[PASS] Cache interface: operation keys(optional RequestInfo, optional CacheQueryOptions)
+[PASS] Cache must be primary interface of self.cacheInstance
+[PASS] Stringification of self.cacheInstance
+[PASS] Cache interface: self.cacheInstance must inherit property "match(RequestInfo, optional CacheQueryOptions)" with the proper type
+[PASS] Cache interface: calling match(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "matchAll(optional RequestInfo, optional CacheQueryOptions)" with the proper type
+[PASS] Cache interface: calling matchAll(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type
+[PASS] Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "addAll(sequence<RequestInfo>)" with the proper type
+[PASS] Cache interface: calling addAll(sequence<RequestInfo>) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type
+[PASS] Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, optional CacheQueryOptions)" with the proper type
+[PASS] Cache interface: calling delete(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] Cache interface: self.cacheInstance must inherit property "keys(optional RequestInfo, optional CacheQueryOptions)" with the proper type
+[PASS] Cache interface: calling keys(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
+[PASS] CacheStorage interface: existence and properties of interface object
+[PASS] CacheStorage interface object length
+[PASS] CacheStorage interface object name
+[PASS] CacheStorage interface: existence and properties of interface prototype object
+[PASS] CacheStorage interface: existence and properties of interface prototype object's "constructor" property
+[PASS] CacheStorage interface: existence and properties of interface prototype object's @@unscopables property
+[PASS] CacheStorage interface: operation match(RequestInfo, optional MultiCacheQueryOptions)
+[PASS] CacheStorage interface: operation has(DOMString)
+[PASS] CacheStorage interface: operation open(DOMString)
+[PASS] CacheStorage interface: operation delete(DOMString)
+[PASS] CacheStorage interface: operation keys()
+[PASS] CacheStorage must be primary interface of caches
+[PASS] Stringification of caches
+[PASS] CacheStorage interface: caches must inherit property "match(RequestInfo, optional MultiCacheQueryOptions)" with the proper type
+[PASS] CacheStorage interface: calling match(RequestInfo, optional MultiCacheQueryOptions) on caches with too few arguments must throw TypeError
+[PASS] CacheStorage interface: caches must inherit property "has(DOMString)" with the proper type
+[PASS] CacheStorage interface: calling has(DOMString) on caches with too few arguments must throw TypeError
+[PASS] CacheStorage interface: caches must inherit property "open(DOMString)" with the proper type
+[PASS] CacheStorage interface: calling open(DOMString) on caches with too few arguments must throw TypeError
+[PASS] CacheStorage interface: caches must inherit property "delete(DOMString)" with the proper type
+[PASS] CacheStorage interface: calling delete(DOMString) on caches with too few arguments must throw TypeError
+[PASS] CacheStorage interface: caches must inherit property "keys()" with the proper type
+[PASS] WorkerGlobalScope interface: attribute caches
+[FAIL] WorkerNavigator interface: attribute serviceWorker
+  assert_true: The prototype object must have a property "serviceWorker" expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/about-blank-replacement.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/about-blank-replacement.https-expected.txt
index 9aa4a28..6eb70e3 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/about-blank-replacement.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/about-blank-replacement.https-expected.txt
@@ -1,10 +1,16 @@
 This is a testharness.js-based test.
-FAIL Initial about:blank is controlled, exposed to clients.matchAll(), and matches final Client. assert_false: result: failure: could not find about:blank client expected false got true
-FAIL Initial about:blank modified by parent is controlled, exposed to clients.matchAll(), and matches final Client. assert_false: result: failure: could not find about:blank client expected false got true
-FAIL Popup initial about:blank is controlled, exposed to clients.matchAll(), and matches final Client. assert_false: result: failure: could not find about:blank client expected false got true
-PASS Initial about:blank is controlled, exposed to clients.matchAll(), and final Client is not controlled by a service worker.
-FAIL Simple about:blank is controlled and is exposed to clients.matchAll(). promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of null (reading 'scriptURL')"
-FAIL Nested about:srcdoc is controlled and is exposed to clients.matchAll(). promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of null (reading 'scriptURL')"
-FAIL Dynamic about:blank is controlled and is exposed to clients.matchAll(). promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of null (reading 'scriptURL')"
+[FAIL] Initial about:blank is controlled, exposed to clients.matchAll(), and matches final Client.
+  assert_false: result: failure: could not find about:blank client expected false got true
+[FAIL] Initial about:blank modified by parent is controlled, exposed to clients.matchAll(), and matches final Client.
+  assert_false: result: failure: could not find about:blank client expected false got true
+[FAIL] Popup initial about:blank is controlled, exposed to clients.matchAll(), and matches final Client.
+  assert_false: result: failure: could not find about:blank client expected false got true
+[PASS] Initial about:blank is controlled, exposed to clients.matchAll(), and final Client is not controlled by a service worker.
+[FAIL] Simple about:blank is controlled and is exposed to clients.matchAll().
+  promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of null (reading 'scriptURL')"
+[FAIL] Nested about:srcdoc is controlled and is exposed to clients.matchAll().
+  promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of null (reading 'scriptURL')"
+[FAIL] Dynamic about:blank is controlled and is exposed to clients.matchAll().
+  promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of null (reading 'scriptURL')"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt
index bc07e04..36cb811 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Client.url of a blob URL worker should be a blob URL. assert_not_equals: worker client should exist got disallowed value "one worker client should exist"
+[FAIL] Client.url of a blob URL worker should be a blob URL.
+  assert_not_equals: worker client should exist got disallowed value "one worker client should exist"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
index 58bae30..d594d08 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Test Clients.get() with window and worker clients assert_not_equals: Worker(Started by main frame) client should not be undefined got disallowed value undefined
+[FAIL] Test Clients.get() with window and worker clients
+  assert_not_equals: Worker(Started by main frame) client should not be undefined got disallowed value undefined
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt
index 0065aa4a..3ffdbfe 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt
@@ -1,5 +1,7 @@
 This is a testharness.js-based test.
-FAIL Test Clients.matchAll() with a blob URL worker client. assert_equals: expected 1 but got 0
-FAIL Test Clients.matchAll() with an uncontrolled blob URL worker client. assert_equals: expected 1 but got 0
+[FAIL] Test Clients.matchAll() with a blob URL worker client.
+  assert_equals: expected 1 but got 0
+[FAIL] Test Clients.matchAll() with an uncontrolled blob URL worker client.
+  assert_equals: expected 1 but got 0
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt
index a5702d0..688c093 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-matchall-client-types.https-expected.txt
@@ -1,5 +1,7 @@
 This is a testharness.js-based test.
-FAIL Verify matchAll() with window client type assert_array_equals: expected property 2 to be "https://web-platform.test:8444/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html" but got "https://web-platform.test:8444/service-workers/service-worker/resources/url-modified-via-pushstate.html" (expected array ["visible", true, "https://web-platform.test:8444/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html", "window", "nested"] got ["visible", true, "https://web-platform.test:8444/service-workers/service-worker/resources/url-modified-via-pushstate.html", "window", "nested"])
-FAIL Verify matchAll() with {window, sharedworker, worker} client types assert_array_equals: expected property 2 to be "https://web-platform.test:8444/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html" but got "https://web-platform.test:8444/service-workers/service-worker/resources/url-modified-via-pushstate.html" (expected array ["visible", true, "https://web-platform.test:8444/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html", "window", "nested"] got ["visible", true, "https://web-platform.test:8444/service-workers/service-worker/resources/url-modified-via-pushstate.html", "window", "nested"])
+[FAIL] Verify matchAll() with window client type
+  assert_array_equals: expected property 2 to be "https://web-platform.test:8444/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html" but got "https://web-platform.test:8444/service-workers/service-worker/resources/url-modified-via-pushstate.html" (expected array ["visible", true, "https://web-platform.test:8444/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html", "window", "nested"] got ["visible", true, "https://web-platform.test:8444/service-workers/service-worker/resources/url-modified-via-pushstate.html", "window", "nested"])
+[FAIL] Verify matchAll() with {window, sharedworker, worker} client types
+  assert_array_equals: expected property 2 to be "https://web-platform.test:8444/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html" but got "https://web-platform.test:8444/service-workers/service-worker/resources/url-modified-via-pushstate.html" (expected array ["visible", true, "https://web-platform.test:8444/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html", "window", "nested"] got ["visible", true, "https://web-platform.test:8444/service-workers/service-worker/resources/url-modified-via-pushstate.html", "window", "nested"])
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt
index 78737fe..bc5ecc0e 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/clients-matchall-order.https-expected.txt
@@ -1,10 +1,14 @@
 This is a testharness.js-based test.
-PASS Clients.matchAll() returns non-focused controlled windows in creation order.
-PASS Clients.matchAll() returns controlled windows in focus order.  Case 1.
-PASS Clients.matchAll() returns controlled windows in focus order.  Case 2.
-FAIL Clients.matchAll() returns non-focused uncontrolled windows in creation order. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns uncontrolled windows in focus order.  Case 1. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns uncontrolled windows in focus order.  Case 2. assert_equals: expected 6 but got 5
-FAIL Clients.matchAll() returns controlled windows and frames in focus order. assert_equals: expected URL index 1 expected "https://web-platform.test:8444/service-workers/service-worker/resources/empty.html?name=focus-controlled-nested-windows&q=1" but got "https://web-platform.test:8444/service-workers/service-worker/resources/empty.html?name=focus-controlled-nested-windows&q=1&nested=true"
+[PASS] Clients.matchAll() returns non-focused controlled windows in creation order.
+[PASS] Clients.matchAll() returns controlled windows in focus order.  Case 1.
+[PASS] Clients.matchAll() returns controlled windows in focus order.  Case 2.
+[FAIL] Clients.matchAll() returns non-focused uncontrolled windows in creation order.
+  assert_equals: expected 6 but got 5
+[FAIL] Clients.matchAll() returns uncontrolled windows in focus order.  Case 1.
+  assert_equals: expected 6 but got 5
+[FAIL] Clients.matchAll() returns uncontrolled windows in focus order.  Case 2.
+  assert_equals: expected 6 but got 5
+[FAIL] Clients.matchAll() returns controlled windows and frames in focus order.
+  assert_equals: expected URL index 1 expected "https://web-platform.test:8444/service-workers/service-worker/resources/empty.html?name=focus-controlled-nested-windows&q=1" but got "https://web-platform.test:8444/service-workers/service-worker/resources/empty.html?name=focus-controlled-nested-windows&q=1&nested=true"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt
index e6e6986..f00908f 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt
@@ -1,6 +1,9 @@
 This is a testharness.js-based test.
-FAIL Top-level module loading should be intercepted by a service worker. assert_equals: expected "LOADED_FROM_SERVICE_WORKER" but got "LOADED_FROM_NETWORK"
-FAIL Static import should be intercepted by a service worker. assert_equals: expected "LOADED_FROM_SERVICE_WORKER" but got "LOADED_FROM_NETWORK"
-FAIL Dynamic import should be intercepted by a service worker. assert_equals: expected "LOADED_FROM_SERVICE_WORKER" but got "LOADED_FROM_NETWORK"
+[FAIL] Top-level module loading should be intercepted by a service worker.
+  assert_equals: expected "LOADED_FROM_SERVICE_WORKER" but got "LOADED_FROM_NETWORK"
+[FAIL] Static import should be intercepted by a service worker.
+  assert_equals: expected "LOADED_FROM_SERVICE_WORKER" but got "LOADED_FROM_NETWORK"
+[FAIL] Dynamic import should be intercepted by a service worker.
+  assert_equals: expected "LOADED_FROM_SERVICE_WORKER" but got "LOADED_FROM_NETWORK"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt
index 44bbf24..ca711835 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event-redirect.https-expected.txt
@@ -1,60 +1,65 @@
 This is a testharness.js-based test.
 Found 56 tests; 51 PASS, 5 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS initialize global state
-PASS Non-navigation, manual redirect, cors mode Request redirected to same-origin without credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to no-cors without credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to cors without credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to same-origin without credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to no-cors without credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to cors without credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to same-origin without credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to no-cors without credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to cors without credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to same-origin with credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to no-cors with credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, cors mode Request redirected to cors with credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to same-origin with credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to no-cors with credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, same-origin mode Request redirected to cors with credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to same-origin with credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to no-cors with credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, manual redirect, no-cors mode Request redirected to cors with credentials should succeed opaqueredirect interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to cors without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to no-cors without credentials should succeed interception and response should not be redirected
-PASS Non-navigation, follow redirect, no-cors mode Request redirected to cors without credentials should succeed interception and response should not be redirected
-FAIL Non-navigation, follow redirect, cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-PASS Non-navigation, follow redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, cors mode Request redirected to cors with credentials should fail interception and response should be redirected
-FAIL Non-navigation, follow redirect, same-origin mode Request redirected to same-origin with credentials should succeed interception and response should be redirected promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, follow redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to no-cors with credentials should succeed interception and response should not be redirected promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-FAIL Non-navigation, follow redirect, no-cors mode Request redirected to cors with credentials should succeed interception and response should not be redirected promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
-PASS Non-navigation, error redirect, cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to cors without credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, cors mode Request redirected to cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
-PASS Non-navigation, error redirect, no-cors mode Request redirected to cors with credentials should fail interception and response should not be redirected
-PASS restore global state
+[PASS] initialize global state
+[PASS] Non-navigation, manual redirect, cors mode Request redirected to same-origin without credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, cors mode Request redirected to no-cors without credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, cors mode Request redirected to cors without credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, same-origin mode Request redirected to same-origin without credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, same-origin mode Request redirected to no-cors without credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, same-origin mode Request redirected to cors without credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, no-cors mode Request redirected to same-origin without credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, no-cors mode Request redirected to no-cors without credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, no-cors mode Request redirected to cors without credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, cors mode Request redirected to same-origin with credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, cors mode Request redirected to no-cors with credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, cors mode Request redirected to cors with credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, same-origin mode Request redirected to same-origin with credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, same-origin mode Request redirected to no-cors with credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, same-origin mode Request redirected to cors with credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, no-cors mode Request redirected to same-origin with credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, no-cors mode Request redirected to no-cors with credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, manual redirect, no-cors mode Request redirected to cors with credentials should succeed opaqueredirect interception and response should not be redirected
+[PASS] Non-navigation, follow redirect, cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
+[PASS] Non-navigation, follow redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, follow redirect, cors mode Request redirected to cors without credentials should succeed interception and response should be redirected
+[PASS] Non-navigation, follow redirect, same-origin mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
+[PASS] Non-navigation, follow redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, follow redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, follow redirect, no-cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected
+[PASS] Non-navigation, follow redirect, no-cors mode Request redirected to no-cors without credentials should succeed interception and response should not be redirected
+[PASS] Non-navigation, follow redirect, no-cors mode Request redirected to cors without credentials should succeed interception and response should not be redirected
+[FAIL] Non-navigation, follow redirect, cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected
+  promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+[PASS] Non-navigation, follow redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, follow redirect, cors mode Request redirected to cors with credentials should fail interception and response should be redirected
+[FAIL] Non-navigation, follow redirect, same-origin mode Request redirected to same-origin with credentials should succeed interception and response should be redirected
+  promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+[PASS] Non-navigation, follow redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, follow redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected
+[FAIL] Non-navigation, follow redirect, no-cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected
+  promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+[FAIL] Non-navigation, follow redirect, no-cors mode Request redirected to no-cors with credentials should succeed interception and response should not be redirected
+  promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+[FAIL] Non-navigation, follow redirect, no-cors mode Request redirected to cors with credentials should succeed interception and response should not be redirected
+  promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch"
+[PASS] Non-navigation, error redirect, cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, cors mode Request redirected to cors without credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, same-origin mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, same-origin mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, same-origin mode Request redirected to cors without credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, no-cors mode Request redirected to same-origin without credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, no-cors mode Request redirected to no-cors without credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, no-cors mode Request redirected to cors without credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, cors mode Request redirected to cors with credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, same-origin mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, same-origin mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, same-origin mode Request redirected to cors with credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, no-cors mode Request redirected to same-origin with credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, no-cors mode Request redirected to no-cors with credentials should fail interception and response should not be redirected
+[PASS] Non-navigation, error redirect, no-cors mode Request redirected to cors with credentials should fail interception and response should not be redirected
+[PASS] restore global state
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
index 3967218..f4e62c0f 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
@@ -1,46 +1,51 @@
 This is a testharness.js-based test.
-PASS global setup
-PASS Service Worker headers in the request of a fetch event
-PASS Service Worker responds to fetch event with string
-PASS Service Worker responds to fetch event using request fragment with string
-PASS Service Worker responds to fetch event with blob body
-PASS Service Worker responds to fetch event with the referrer URL
-PASS Service Worker responds to fetch event with an existing client id
-PASS Service Worker responds to fetch event with the correct resulting client id
-PASS Service Worker does not respond to fetch event
-PASS Service Worker responds to fetch event with null response body
-PASS Service Worker fetches other file in fetch event
-PASS Service Worker responds to fetch event with POST form
-PASS Service Worker falls back to network in fetch event with POST form
-PASS Multiple calls of respondWith must throw InvalidStateErrors
-PASS Service Worker event.respondWith must set the used flag
-PASS Service Worker should expose FetchEvent URL fragments.
-PASS Service Worker responds to fetch event with the correct cache types
-PASS Service Worker should intercept EventSource
-FAIL Service Worker responds to fetch event with the correct integrity_metadata assert_equals: integrity expected "gs0nqru8KbsrIt5YToQqS9fYao4GQJXtcId610g7cCU=" but got ""
-PASS FetchEvent#body is a string
-PASS FetchEvent#body is a ReadableStream
-PASS FetchEvent#body is a string and is passed to network fallback
-PASS FetchEvent#body is a none Uint8Array ReadableStream and is passed to a service worker
-PASS FetchEvent#body is a string, used and passed to network fallback
-PASS FetchEvent#body is a string, cloned and passed to network fallback
-PASS FetchEvent#body is a blob
-PASS FetchEvent#body is a blob and is passed to network fallback
-PASS Service Worker responds to fetch event with the correct keepalive value
-FAIL FetchEvent#request.isReloadNavigation is true (location.reload()) assert_equals: expected "method = GET, isReloadNavigation = false" but got "method = GET, isReloadNavigation = undefined"
-FAIL FetchEvent#request.isReloadNavigation is true (history.go(0)) assert_equals: expected "method = GET, isReloadNavigation = false" but got "method = GET, isReloadNavigation = undefined"
-FAIL FetchEvent#request.isReloadNavigation is true (POST + location.reload()) assert_equals: expected "method = GET, isReloadNavigation = false" but got "method = GET, isReloadNavigation = undefined"
-FAIL FetchEvent#request.isReloadNavigation is true (with history traversal) assert_equals: expected "method = GET, isReloadNavigation = false" but got "method = GET, isReloadNavigation = undefined"
-PASS FetchEvent#request.isHistoryNavigation is true (with history.go(-1))
-PASS FetchEvent#request.isHistoryNavigation is true (with history.go(1))
-PASS FetchEvent#request.isHistoryNavigation is false (with history.go(0))
-PASS FetchEvent#request.isHistoryNavigation is false (with location.reload)
-PASS FetchEvent#request.isHistoryNavigation is true (with history.go(-2))
-PASS FetchEvent#request.isHistoryNavigation is true (with history.go(2))
-PASS FetchEvent#request.isHistoryNavigation is true (POST + history.go(-1))
-PASS XHR upload progress events for response coming from SW
-PASS XHR upload progress events for network fallback
-PASS Fetch with POST with text on sw 421 response should not be retried.
-PASS restore global state
+[PASS] global setup
+[PASS] Service Worker headers in the request of a fetch event
+[PASS] Service Worker responds to fetch event with string
+[PASS] Service Worker responds to fetch event using request fragment with string
+[PASS] Service Worker responds to fetch event with blob body
+[PASS] Service Worker responds to fetch event with the referrer URL
+[PASS] Service Worker responds to fetch event with an existing client id
+[PASS] Service Worker responds to fetch event with the correct resulting client id
+[PASS] Service Worker does not respond to fetch event
+[PASS] Service Worker responds to fetch event with null response body
+[PASS] Service Worker fetches other file in fetch event
+[PASS] Service Worker responds to fetch event with POST form
+[PASS] Service Worker falls back to network in fetch event with POST form
+[PASS] Multiple calls of respondWith must throw InvalidStateErrors
+[PASS] Service Worker event.respondWith must set the used flag
+[PASS] Service Worker should expose FetchEvent URL fragments.
+[PASS] Service Worker responds to fetch event with the correct cache types
+[PASS] Service Worker should intercept EventSource
+[FAIL] Service Worker responds to fetch event with the correct integrity_metadata
+  assert_equals: integrity expected "gs0nqru8KbsrIt5YToQqS9fYao4GQJXtcId610g7cCU=" but got ""
+[PASS] FetchEvent#body is a string
+[PASS] FetchEvent#body is a ReadableStream
+[PASS] FetchEvent#body is a string and is passed to network fallback
+[PASS] FetchEvent#body is a none Uint8Array ReadableStream and is passed to a service worker
+[PASS] FetchEvent#body is a string, used and passed to network fallback
+[PASS] FetchEvent#body is a string, cloned and passed to network fallback
+[PASS] FetchEvent#body is a blob
+[PASS] FetchEvent#body is a blob and is passed to network fallback
+[PASS] Service Worker responds to fetch event with the correct keepalive value
+[FAIL] FetchEvent#request.isReloadNavigation is true (location.reload())
+  assert_equals: expected "method = GET, isReloadNavigation = false" but got "method = GET, isReloadNavigation = undefined"
+[FAIL] FetchEvent#request.isReloadNavigation is true (history.go(0))
+  assert_equals: expected "method = GET, isReloadNavigation = false" but got "method = GET, isReloadNavigation = undefined"
+[FAIL] FetchEvent#request.isReloadNavigation is true (POST + location.reload())
+  assert_equals: expected "method = GET, isReloadNavigation = false" but got "method = GET, isReloadNavigation = undefined"
+[FAIL] FetchEvent#request.isReloadNavigation is true (with history traversal)
+  assert_equals: expected "method = GET, isReloadNavigation = false" but got "method = GET, isReloadNavigation = undefined"
+[PASS] FetchEvent#request.isHistoryNavigation is true (with history.go(-1))
+[PASS] FetchEvent#request.isHistoryNavigation is true (with history.go(1))
+[PASS] FetchEvent#request.isHistoryNavigation is false (with history.go(0))
+[PASS] FetchEvent#request.isHistoryNavigation is false (with location.reload)
+[PASS] FetchEvent#request.isHistoryNavigation is true (with history.go(-2))
+[PASS] FetchEvent#request.isHistoryNavigation is true (with history.go(2))
+[PASS] FetchEvent#request.isHistoryNavigation is true (POST + history.go(-1))
+[PASS] XHR upload progress events for response coming from SW
+[PASS] XHR upload progress events for network fallback
+[PASS] Fetch with POST with text on sw 421 response should not be retried.
+[PASS] restore global state
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-xhr-sync-error.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-xhr-sync-error.https.window-expected.txt
index f9ed9ece..9ecce22 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-xhr-sync-error.https.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-xhr-sync-error.https.window-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Verify synchronous XMLHttpRequest always throws a NetworkError for ReadableStream errors assert_throws_dom: function "() => frame.contentWindow.performSyncXHR("non-existent-stream-1.txt")" did not throw
+[FAIL] Verify synchronous XMLHttpRequest always throws a NetworkError for ReadableStream errors
+  assert_throws_dom: function "() => frame.contentWindow.performSyncXHR("non-existent-stream-1.txt")" did not throw
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt
index 724b7d8..14c09fc 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Verify SyncXHR is intercepted assert_equals: HTTP response status code for intercepted request expected 200 but got 404
+[FAIL] Verify SyncXHR is intercepted
+  assert_equals: HTTP response status code for intercepted request expected 200 but got 404
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt
index 71bc4c0a..a4c1cc2 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-request-xhr.https-expected.txt
@@ -1,16 +1,20 @@
 This is a testharness.js-based test.
-PASS initialize global state
-FAIL event.request has the expected headers for same-origin GET. promise_test: Unhandled rejection with value: object "Error: assert_array_equals: event.request has the expected headers for same-origin GET. lengths differ, expected array ["accept"] length 1, got ["accept", "sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform", "user-agent"] length 5"
-FAIL event.request has the expected headers for same-origin POST. promise_test: Unhandled rejection with value: object "Error: assert_array_equals: event.request has the expected headers for same-origin POST. lengths differ, expected array ["accept", "content-type"] length 2, got ["accept", "content-type", "sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform", "user-agent"] length 6"
-FAIL event.request has the expected headers for cross-origin GET. promise_test: Unhandled rejection with value: object "Error: assert_array_equals: event.request has the expected headers for cross-origin GET. lengths differ, expected array ["accept"] length 1, got ["accept", "sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform", "user-agent"] length 5"
-FAIL event.request has the expected headers for cross-origin POST. promise_test: Unhandled rejection with value: object "Error: assert_array_equals: event.request has the expected headers for cross-origin POST. lengths differ, expected array ["accept", "content-type"] length 2, got ["accept", "content-type", "sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform", "user-agent"] length 6"
-PASS FetchEvent#request.body contains XHR request data (string)
-PASS FetchEvent#request.body contains XHR request data (blob)
-PASS FetchEvent#request.method is set to XHR method
-PASS XHR using OPTIONS method
-PASS XHR with form data
-PASS XHR with mode/credentials set
-PASS XHR to data URL
-PASS restore global state
+[PASS] initialize global state
+[FAIL] event.request has the expected headers for same-origin GET.
+  promise_test: Unhandled rejection with value: object "Error: assert_array_equals: event.request has the expected headers for same-origin GET. lengths differ, expected array ["accept"] length 1, got ["accept", "sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform", "user-agent"] length 5"
+[FAIL] event.request has the expected headers for same-origin POST.
+  promise_test: Unhandled rejection with value: object "Error: assert_array_equals: event.request has the expected headers for same-origin POST. lengths differ, expected array ["accept", "content-type"] length 2, got ["accept", "content-type", "sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform", "user-agent"] length 6"
+[FAIL] event.request has the expected headers for cross-origin GET.
+  promise_test: Unhandled rejection with value: object "Error: assert_array_equals: event.request has the expected headers for cross-origin GET. lengths differ, expected array ["accept"] length 1, got ["accept", "sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform", "user-agent"] length 5"
+[FAIL] event.request has the expected headers for cross-origin POST.
+  promise_test: Unhandled rejection with value: object "Error: assert_array_equals: event.request has the expected headers for cross-origin POST. lengths differ, expected array ["accept", "content-type"] length 2, got ["accept", "content-type", "sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform", "user-agent"] length 6"
+[PASS] FetchEvent#request.body contains XHR request data (string)
+[PASS] FetchEvent#request.body contains XHR request data (blob)
+[PASS] FetchEvent#request.method is set to XHR method
+[PASS] XHR using OPTIONS method
+[PASS] XHR with form data
+[PASS] XHR with mode/credentials set
+[PASS] XHR to data URL
+[PASS] restore global state
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-waits-for-activate.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-waits-for-activate.https-expected.txt
index c764406..1904fbd 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-waits-for-activate.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-waits-for-activate.https-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
-PASS Navigation fetch events should wait for the activate event to complete.
-FAIL Subresource fetch events should wait for the activate event to complete. assert_false: fetch()-ing a Service Worker-controlled scope shouldn't have settled yet expected false got true
+[PASS] Navigation fetch events should wait for the activate event to complete.
+[FAIL] Subresource fetch events should wait for the activate event to complete.
+  assert_false: fetch()-ing a Service Worker-controlled scope shouldn't have settled yet expected false got true
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/idlharness-sw.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/idlharness-sw.https-expected.txt
deleted file mode 100644
index f3ad33f..0000000
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/idlharness-sw.https-expected.txt
+++ /dev/null
@@ -1,189 +0,0 @@
-This is a testharness.js-based test.
-Found 185 tests; 183 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Interfaces and attributes in ServiceWorkerGlobalScope
-PASS test setup (cache creation)
-FAIL Event constructors assert_equals: FetchEvent.isReload should not exist expected (undefined) undefined but got (boolean) false
-PASS xhr is not exposed
-PASS URL.createObjectURL is not exposed
-PASS ServiceWorker includes AbstractWorker: member names are unique
-PASS WorkerGlobalScope includes WindowOrWorkerGlobalScope: member names are unique
-PASS ServiceWorker interface: existence and properties of interface object
-PASS ServiceWorker interface object length
-PASS ServiceWorker interface object name
-PASS ServiceWorker interface: existence and properties of interface prototype object
-PASS ServiceWorker interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorker interface: existence and properties of interface prototype object's @@unscopables property
-PASS ServiceWorker interface: attribute scriptURL
-PASS ServiceWorker interface: attribute state
-PASS ServiceWorker interface: operation postMessage(any, sequence<object>)
-PASS ServiceWorker interface: operation postMessage(any, optional PostMessageOptions)
-PASS ServiceWorker interface: attribute onstatechange
-PASS ServiceWorkerRegistration interface: existence and properties of interface object
-PASS ServiceWorkerRegistration interface object length
-PASS ServiceWorkerRegistration interface object name
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerRegistration interface: existence and properties of interface prototype object's @@unscopables property
-PASS ServiceWorkerRegistration interface: attribute installing
-PASS ServiceWorkerRegistration interface: attribute waiting
-PASS ServiceWorkerRegistration interface: attribute active
-PASS ServiceWorkerRegistration interface: attribute navigationPreload
-PASS ServiceWorkerRegistration interface: attribute scope
-PASS ServiceWorkerRegistration interface: attribute updateViaCache
-PASS ServiceWorkerRegistration interface: operation update()
-PASS ServiceWorkerRegistration interface: operation unregister()
-PASS ServiceWorkerRegistration interface: attribute onupdatefound
-PASS ServiceWorkerRegistration must be primary interface of self.registration
-PASS Stringification of self.registration
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "installing" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "waiting" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "active" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "navigationPreload" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "scope" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "updateViaCache" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "update()" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "unregister()" with the proper type
-PASS ServiceWorkerRegistration interface: self.registration must inherit property "onupdatefound" with the proper type
-PASS NavigationPreloadManager interface: existence and properties of interface object
-PASS NavigationPreloadManager interface object length
-PASS NavigationPreloadManager interface object name
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's "constructor" property
-PASS NavigationPreloadManager interface: existence and properties of interface prototype object's @@unscopables property
-PASS NavigationPreloadManager interface: operation enable()
-PASS NavigationPreloadManager interface: operation disable()
-PASS NavigationPreloadManager interface: operation setHeaderValue(ByteString)
-PASS NavigationPreloadManager interface: operation getState()
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface object
-PASS ServiceWorkerGlobalScope interface object length
-PASS ServiceWorkerGlobalScope interface object name
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via __proto__ should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Object.setPrototypeOf should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via __proto__ should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of interface prototype object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object's "constructor" property
-PASS ServiceWorkerGlobalScope interface: existence and properties of interface prototype object's @@unscopables property
-PASS ServiceWorkerGlobalScope interface: attribute clients
-PASS ServiceWorkerGlobalScope interface: attribute registration
-PASS ServiceWorkerGlobalScope interface: attribute serviceWorker
-PASS ServiceWorkerGlobalScope interface: operation skipWaiting()
-PASS ServiceWorkerGlobalScope interface: attribute oninstall
-PASS ServiceWorkerGlobalScope interface: attribute onactivate
-PASS ServiceWorkerGlobalScope interface: attribute onfetch
-PASS ServiceWorkerGlobalScope interface: attribute onmessage
-PASS ServiceWorkerGlobalScope interface: attribute onmessageerror
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Object.setPrototypeOf should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via __proto__ should throw a TypeError
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to a new value via Reflect.setPrototypeOf should return false
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Object.setPrototypeOf should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via __proto__ should not throw
-PASS ServiceWorkerGlobalScope interface: internal [[SetPrototypeOf]] method of global platform object - setting to its original value via Reflect.setPrototypeOf should return true
-PASS ServiceWorkerGlobalScope must be primary interface of self
-PASS Stringification of self
-PASS ServiceWorkerGlobalScope interface: self must inherit property "clients" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "registration" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "serviceWorker" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "skipWaiting()" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "oninstall" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onactivate" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onfetch" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onmessage" with the proper type
-PASS ServiceWorkerGlobalScope interface: self must inherit property "onmessageerror" with the proper type
-PASS Client interface: existence and properties of interface object
-PASS Client interface object length
-PASS Client interface object name
-PASS Client interface: existence and properties of interface prototype object
-PASS Client interface: existence and properties of interface prototype object's "constructor" property
-PASS Client interface: existence and properties of interface prototype object's @@unscopables property
-PASS Client interface: attribute url
-PASS Client interface: attribute frameType
-PASS Client interface: attribute id
-PASS Client interface: attribute type
-PASS Client interface: operation postMessage(any, sequence<object>)
-PASS Client interface: operation postMessage(any, optional PostMessageOptions)
-PASS WindowClient interface: existence and properties of interface object
-PASS WindowClient interface object length
-PASS WindowClient interface object name
-PASS WindowClient interface: existence and properties of interface prototype object
-PASS WindowClient interface: existence and properties of interface prototype object's "constructor" property
-PASS WindowClient interface: existence and properties of interface prototype object's @@unscopables property
-PASS WindowClient interface: attribute visibilityState
-PASS WindowClient interface: attribute focused
-FAIL WindowClient interface: attribute ancestorOrigins assert_true: The prototype object must have a property "ancestorOrigins" expected true got false
-PASS WindowClient interface: operation focus()
-PASS WindowClient interface: operation navigate(USVString)
-PASS Clients interface: existence and properties of interface object
-PASS Clients interface object length
-PASS Clients interface object name
-PASS Clients interface: existence and properties of interface prototype object
-PASS Clients interface: existence and properties of interface prototype object's "constructor" property
-PASS Clients interface: existence and properties of interface prototype object's @@unscopables property
-PASS Clients interface: operation get(DOMString)
-PASS Clients interface: operation matchAll(optional ClientQueryOptions)
-PASS Clients interface: operation openWindow(USVString)
-PASS Clients interface: operation claim()
-PASS Clients must be primary interface of self.clients
-PASS Stringification of self.clients
-PASS Clients interface: self.clients must inherit property "get(DOMString)" with the proper type
-PASS Clients interface: calling get(DOMString) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "matchAll(optional ClientQueryOptions)" with the proper type
-PASS Clients interface: calling matchAll(optional ClientQueryOptions) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "openWindow(USVString)" with the proper type
-PASS Clients interface: calling openWindow(USVString) on self.clients with too few arguments must throw TypeError
-PASS Clients interface: self.clients must inherit property "claim()" with the proper type
-PASS Cache interface: existence and properties of interface object
-PASS Cache interface object length
-PASS Cache interface object name
-PASS Cache interface: existence and properties of interface prototype object
-PASS Cache interface: existence and properties of interface prototype object's "constructor" property
-PASS Cache interface: existence and properties of interface prototype object's @@unscopables property
-PASS Cache interface: operation match(RequestInfo, optional CacheQueryOptions)
-PASS Cache interface: operation matchAll(optional RequestInfo, optional CacheQueryOptions)
-PASS Cache interface: operation add(RequestInfo)
-PASS Cache interface: operation addAll(sequence<RequestInfo>)
-PASS Cache interface: operation put(RequestInfo, Response)
-PASS Cache interface: operation delete(RequestInfo, optional CacheQueryOptions)
-PASS Cache interface: operation keys(optional RequestInfo, optional CacheQueryOptions)
-PASS Cache must be primary interface of self.cacheInstance
-PASS Stringification of self.cacheInstance
-PASS Cache interface: self.cacheInstance must inherit property "match(RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling match(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "matchAll(optional RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling matchAll(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "add(RequestInfo)" with the proper type
-PASS Cache interface: calling add(RequestInfo) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "addAll(sequence<RequestInfo>)" with the proper type
-PASS Cache interface: calling addAll(sequence<RequestInfo>) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "put(RequestInfo, Response)" with the proper type
-PASS Cache interface: calling put(RequestInfo, Response) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "delete(RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling delete(RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS Cache interface: self.cacheInstance must inherit property "keys(optional RequestInfo, optional CacheQueryOptions)" with the proper type
-PASS Cache interface: calling keys(optional RequestInfo, optional CacheQueryOptions) on self.cacheInstance with too few arguments must throw TypeError
-PASS CacheStorage interface: existence and properties of interface object
-PASS CacheStorage interface object length
-PASS CacheStorage interface object name
-PASS CacheStorage interface: existence and properties of interface prototype object
-PASS CacheStorage interface: existence and properties of interface prototype object's "constructor" property
-PASS CacheStorage interface: existence and properties of interface prototype object's @@unscopables property
-PASS CacheStorage interface: operation match(RequestInfo, optional MultiCacheQueryOptions)
-PASS CacheStorage interface: operation has(DOMString)
-PASS CacheStorage interface: operation open(DOMString)
-PASS CacheStorage interface: operation delete(DOMString)
-PASS CacheStorage interface: operation keys()
-PASS CacheStorage must be primary interface of self.caches
-PASS Stringification of self.caches
-PASS CacheStorage interface: self.caches must inherit property "match(RequestInfo, optional MultiCacheQueryOptions)" with the proper type
-PASS CacheStorage interface: calling match(RequestInfo, optional MultiCacheQueryOptions) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "has(DOMString)" with the proper type
-PASS CacheStorage interface: calling has(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "open(DOMString)" with the proper type
-PASS CacheStorage interface: calling open(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "delete(DOMString)" with the proper type
-PASS CacheStorage interface: calling delete(DOMString) on self.caches with too few arguments must throw TypeError
-PASS CacheStorage interface: self.caches must inherit property "keys()" with the proper type
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/import-module-scripts.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/import-module-scripts.https-expected.txt
deleted file mode 100644
index ea80ea9..0000000
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/import-module-scripts.https-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-This is a testharness.js-based test.
-PASS Static import.
-PASS Static import (cross-origin).
-FAIL Static import (redirect). promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker for scope ('https://web-platform.test:8444/workers/modules/resources/static-import-redirect-worker.js') with script ('https://web-platform.test:8444/workers/modules/resources/static-import-redirect-worker.js'): ServiceWorker cannot be started"
-PASS Nested static import.
-FAIL Static import and then dynamic import. assert_array_equals: value is "Failed to do dynamic import: TypeError: Module scripts are not supported on ServiceWorkerGlobalScope yet (see https://crbug.com/824647).", expected array
-FAIL Dynamic import. assert_array_equals: value is "Failed to do dynamic import: TypeError: Module scripts are not supported on ServiceWorkerGlobalScope yet (see https://crbug.com/824647).", expected array
-FAIL Nested dynamic import. assert_array_equals: value is "Failed to do dynamic import: TypeError: Module scripts are not supported on ServiceWorkerGlobalScope yet (see https://crbug.com/824647).", expected array
-FAIL Dynamic import and then static import. assert_array_equals: value is "Failed to do dynamic import: TypeError: Module scripts are not supported on ServiceWorkerGlobalScope yet (see https://crbug.com/824647).", expected array
-FAIL eval(import()). assert_array_equals: value is "Failed to do dynamic import: TypeError: Module scripts are not supported on ServiceWorkerGlobalScope yet (see https://crbug.com/824647).", expected array
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt
deleted file mode 100644
index 54836e4..0000000
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/import-scripts-redirect.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL importScripts() supports redirects promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker: ServiceWorker script evaluation failed"
-FAIL importScripts() supports redirects and can be updated promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker: ServiceWorker script evaluation failed"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/interface-requirements-sw.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/interface-requirements-sw.https-expected.txt
index 42f0b416..4e1cc15 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/interface-requirements-sw.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/interface-requirements-sw.https-expected.txt
@@ -1,7 +1,8 @@
 This is a testharness.js-based test.
-PASS Interfaces and attributes in ServiceWorkerGlobalScope
-FAIL Event constructors assert_equals: FetchEvent.isReload should not exist expected (undefined) undefined but got (boolean) false
-PASS xhr is not exposed
-PASS URL.createObjectURL is not exposed
+[PASS] Interfaces and attributes in ServiceWorkerGlobalScope
+[FAIL] Event constructors
+  assert_equals: FetchEvent.isReload should not exist expected (undefined) undefined but got (boolean) false
+[PASS] xhr is not exposed
+[PASS] URL.createObjectURL is not exposed
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt
index afcb9a7a..8e867339 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt
@@ -1,10 +1,15 @@
 This is a testharness.js-based test.
-FAIL Same-origin blob URL iframe should inherit service worker controller. assert_equals: blob URL iframe should inherit controller expected (string) "https://web-platform.test:8444/service-workers/service-worker/resources/local-url-inherit-controller-worker.js" but got (object) null
-FAIL Same-origin blob URL iframe should intercept fetch(). assert_equals: blob URL iframe should intercept fetch expected "intercepted" but got "var hello = \"world\";\n"
-FAIL Same-origin blob URL worker should inherit service worker controller. promise_test: Unhandled rejection with value: "Uncaught TypeError: Cannot read properties of undefined (reading 'controller')"
-PASS Same-origin blob URL worker should intercept fetch().
-PASS Data URL iframe should not intercept fetch().
-FAIL Data URL worker should not inherit service worker controller. promise_test: Unhandled rejection with value: "Uncaught TypeError: Cannot read properties of undefined (reading 'controller')"
-FAIL Data URL worker should not intercept fetch(). assert_equals: data URL worker should not intercept fetch expected "" but got "intercepted"
+[FAIL] Same-origin blob URL iframe should inherit service worker controller.
+  assert_equals: blob URL iframe should inherit controller expected (string) "https://web-platform.test:8444/service-workers/service-worker/resources/local-url-inherit-controller-worker.js" but got (object) null
+[FAIL] Same-origin blob URL iframe should intercept fetch().
+  assert_equals: blob URL iframe should intercept fetch expected "intercepted" but got "var hello = \"world\";\n"
+[FAIL] Same-origin blob URL worker should inherit service worker controller.
+  promise_test: Unhandled rejection with value: "Uncaught TypeError: Cannot read properties of undefined (reading 'controller')"
+[PASS] Same-origin blob URL worker should intercept fetch().
+[PASS] Data URL iframe should not intercept fetch().
+[FAIL] Data URL worker should not inherit service worker controller.
+  promise_test: Unhandled rejection with value: "Uncaught TypeError: Cannot read properties of undefined (reading 'controller')"
+[FAIL] Data URL worker should not intercept fetch().
+  assert_equals: data URL worker should not intercept fetch expected "" but got "intercepted"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt
index d70dc69..f46e952 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigate-window.https-expected.txt
@@ -1,5 +1,7 @@
 This is a testharness.js-based test.
-FAIL Clients.matchAll() should not show an old window as controlled after it navigates. assert_unreached: unexpected rejection: assert_equals: client should have expected frame type expected "auxiliary" but got "top-level" Reached unreachable code
-FAIL Clients.matchAll() should not show an old window after it navigates. assert_unreached: unexpected rejection: assert_equals: client should have expected frame type expected "auxiliary" but got "top-level" Reached unreachable code
+[FAIL] Clients.matchAll() should not show an old window as controlled after it navigates.
+  assert_unreached: unexpected rejection: assert_equals: client should have expected frame type expected "auxiliary" but got "top-level" Reached unreachable code
+[FAIL] Clients.matchAll() should not show an old window after it navigates.
+  assert_unreached: unexpected rejection: assert_equals: client should have expected frame type expected "auxiliary" but got "top-level" Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-redirect-resolution.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-redirect-resolution.https-expected.txt
index 5f2fb74a..3753e5b2 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-redirect-resolution.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-redirect-resolution.https-expected.txt
@@ -1,6 +1,9 @@
 This is a testharness.js-based test.
-FAIL test relative opaqueredirect assert_equals: expected "https://web-platform.test:8444/service-workers/service-worker/resources/blank.html" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/blank.html"
-FAIL test relative opaqueredirect with CacheStorage assert_equals: expected "https://web-platform.test:8444/service-workers/service-worker/resources/blank.html" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/blank.html"
-FAIL test relative opaqueredirect with clone assert_equals: expected "https://web-platform.test:8444/service-workers/service-worker/resources/blank.html" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/blank.html"
+[FAIL] test relative opaqueredirect
+  assert_equals: expected "https://web-platform.test:8444/service-workers/service-worker/resources/blank.html" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/blank.html"
+[FAIL] test relative opaqueredirect with CacheStorage
+  assert_equals: expected "https://web-platform.test:8444/service-workers/service-worker/resources/blank.html" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/blank.html"
+[FAIL] test relative opaqueredirect with clone
+  assert_equals: expected "https://web-platform.test:8444/service-workers/service-worker/resources/blank.html" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/blank.html"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/next-hop-protocol.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/next-hop-protocol.https-expected.txt
index c6d12e4eb..b44c2b2 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/next-hop-protocol.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/next-hop-protocol.https-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
-PASS nextHopProtocol reports H1 correctly when routed via a service worker.
-FAIL nextHopProtocol reports H2 correctly when routed via a service worker. assert_equals: nextHopProtocol is set on fallback expected "h2" but got "http/1.1"
+[PASS] nextHopProtocol reports H1 correctly when routed via a service worker.
+[FAIL] nextHopProtocol reports H2 correctly when routed via a service worker.
+  assert_equals: nextHopProtocol is set on fallback expected "h2" but got "http/1.1"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/ready.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/ready.https-expected.txt
deleted file mode 100644
index d29a2b4e..0000000
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/ready.https-expected.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-This is a testharness.js-based test.
-PASS ready returns the same Promise object
-PASS ready returns a Promise object in the context of the related document
-PASS ready on a controlled document
-PASS ready on a potential controlled document
-PASS ready on an iframe whose parent registers a new service worker
-PASS ready on an iframe that installs a new service worker
-PASS ready after a longer matched registration registered
-PASS access ready after it has been resolved
-FAIL access ready on uninstalling registration that is resurrected assert_not_equals: ready promise should resolve before timeout got disallowed value null
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/redirected-response.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/redirected-response.https-expected.txt
index 30d7aad..9eb87bc1 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/redirected-response.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/redirected-response.https-expected.txt
@@ -1,29 +1,30 @@
 This is a testharness.js-based test.
-PASS initialize global state (service worker registration and caches)
-PASS mode: "follow", non-intercepted request, no server redirect
-PASS mode: "follow", non-intercepted request
-PASS mode: "manual", non-intercepted request
-PASS mode: "error", non-intercepted request
-PASS mode: "follow", no mode change, no server redirect
-PASS mode: "follow", no mode change
-PASS mode: "error", mode change: "follow"
-PASS mode: "manual", mode change: "follow"
-PASS mode: "follow", mode change: "manual"
-PASS mode: "error", mode change: "manual"
-PASS mode: "manual", no mode change
-PASS mode: "follow", generated redirect response
-PASS mode: "error", generated redirect response
-PASS mode: "manual", generated redirect response
-PASS mode: "follow", manually-generated redirect response
-PASS mode: "error", manually-generated redirect response
-PASS mode: "manual", manually-generated redirect response
-FAIL mode: "follow", generated relative redirect response assert_unreached: Should have rejected: Following the generated redirect response from the service worker should result fail. Reached unreachable code
-PASS mode: "error", generated relative redirect response
-PASS mode: "manual", generated relative redirect response
-PASS Fetch should follow the redirect response 20 times
-PASS Fetch should not follow the redirect response 21 times.
-PASS The URL for the service worker redirected request should be propagated to response.
-PASS restore global state (service worker registration)
-PASS restore global state (caches)
+[PASS] initialize global state (service worker registration and caches)
+[PASS] mode: "follow", non-intercepted request, no server redirect
+[PASS] mode: "follow", non-intercepted request
+[PASS] mode: "manual", non-intercepted request
+[PASS] mode: "error", non-intercepted request
+[PASS] mode: "follow", no mode change, no server redirect
+[PASS] mode: "follow", no mode change
+[PASS] mode: "error", mode change: "follow"
+[PASS] mode: "manual", mode change: "follow"
+[PASS] mode: "follow", mode change: "manual"
+[PASS] mode: "error", mode change: "manual"
+[PASS] mode: "manual", no mode change
+[PASS] mode: "follow", generated redirect response
+[PASS] mode: "error", generated redirect response
+[PASS] mode: "manual", generated redirect response
+[PASS] mode: "follow", manually-generated redirect response
+[PASS] mode: "error", manually-generated redirect response
+[PASS] mode: "manual", manually-generated redirect response
+[FAIL] mode: "follow", generated relative redirect response
+  assert_unreached: Should have rejected: Following the generated redirect response from the service worker should result fail. Reached unreachable code
+[PASS] mode: "error", generated relative redirect response
+[PASS] mode: "manual", generated relative redirect response
+[PASS] Fetch should follow the redirect response 20 times
+[PASS] Fetch should not follow the redirect response 21 times.
+[PASS] The URL for the service worker redirected request should be propagated to response.
+[PASS] restore global state (service worker registration)
+[PASS] restore global state (caches)
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-scope-module-static-import.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-scope-module-static-import.https-expected.txt
index f2c49780..eb7ea1c 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-scope-module-static-import.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-scope-module-static-import.https-expected.txt
@@ -1,6 +1,7 @@
 This is a testharness.js-based test.
-PASS imported-module-script.js works when used as top-level
-PASS static imports to outside path restriction should be allowed
-FAIL static imports redirecting to outside path restriction should be allowed promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker for scope ('https://web-platform.test:8444/service-workers/service-worker/resources/scope1/') with script ('https://web-platform.test:8444/service-workers/service-worker/resources/scope1/module-worker-importing-redirect-to-scope2.js'): ServiceWorker cannot be started"
+[PASS] imported-module-script.js works when used as top-level
+[PASS] static imports to outside path restriction should be allowed
+[FAIL] static imports redirecting to outside path restriction should be allowed
+  promise_test: Unhandled rejection with value: object "TypeError: Failed to register a ServiceWorker for scope ('https://web-platform.test:8444/service-workers/service-worker/resources/scope1/') with script ('https://web-platform.test:8444/service-workers/service-worker/resources/scope1/module-worker-importing-redirect-to-scope2.js'): ServiceWorker cannot be started"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt
index 0024744..98b3094 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/registration-updateviacache.https-expected.txt
@@ -1,28 +1,29 @@
 This is a testharness.js-based test.
-PASS register-with-updateViaCache-undefined
-PASS register-with-updateViaCache-imports
-PASS register-with-updateViaCache-all
-PASS register-with-updateViaCache-none
-PASS register-with-updateViaCache-undefined-then-undefined
-PASS register-with-updateViaCache-undefined-then-imports
-PASS register-with-updateViaCache-undefined-then-all
-PASS register-with-updateViaCache-undefined-then-none
-PASS register-with-updateViaCache-imports-then-undefined
-PASS register-with-updateViaCache-imports-then-imports
-PASS register-with-updateViaCache-imports-then-all
-PASS register-with-updateViaCache-imports-then-none
-PASS register-with-updateViaCache-all-then-undefined
-PASS register-with-updateViaCache-all-then-imports
-PASS register-with-updateViaCache-all-then-all
-PASS register-with-updateViaCache-all-then-none
-PASS register-with-updateViaCache-none-then-undefined
-PASS register-with-updateViaCache-none-then-imports
-PASS register-with-updateViaCache-none-then-all
-PASS register-with-updateViaCache-none-then-none
-PASS access-updateViaCache-after-unregister-undefined
-PASS access-updateViaCache-after-unregister-imports
-PASS access-updateViaCache-after-unregister-all
-PASS access-updateViaCache-after-unregister-none
-FAIL updateViaCache is not updated if register() rejects assert_equals: after update attempt expected "imports" but got "none"
+[PASS] register-with-updateViaCache-undefined
+[PASS] register-with-updateViaCache-imports
+[PASS] register-with-updateViaCache-all
+[PASS] register-with-updateViaCache-none
+[PASS] register-with-updateViaCache-undefined-then-undefined
+[PASS] register-with-updateViaCache-undefined-then-imports
+[PASS] register-with-updateViaCache-undefined-then-all
+[PASS] register-with-updateViaCache-undefined-then-none
+[PASS] register-with-updateViaCache-imports-then-undefined
+[PASS] register-with-updateViaCache-imports-then-imports
+[PASS] register-with-updateViaCache-imports-then-all
+[PASS] register-with-updateViaCache-imports-then-none
+[PASS] register-with-updateViaCache-all-then-undefined
+[PASS] register-with-updateViaCache-all-then-imports
+[PASS] register-with-updateViaCache-all-then-all
+[PASS] register-with-updateViaCache-all-then-none
+[PASS] register-with-updateViaCache-none-then-undefined
+[PASS] register-with-updateViaCache-none-then-imports
+[PASS] register-with-updateViaCache-none-then-all
+[PASS] register-with-updateViaCache-none-then-none
+[PASS] access-updateViaCache-after-unregister-undefined
+[PASS] access-updateViaCache-after-unregister-imports
+[PASS] access-updateViaCache-after-unregister-all
+[PASS] access-updateViaCache-after-unregister-none
+[FAIL] updateViaCache is not updated if register() rejects
+  assert_equals: after update attempt expected "imports" but got "none"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resource-timing-fetch-variants.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resource-timing-fetch-variants.https-expected.txt
deleted file mode 100644
index 9166fc4..0000000
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resource-timing-fetch-variants.https-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS Redirects done from within a service-worker should not be exposed to client ResourceTiming
-PASS Connection info from within a service-worker should not be exposed to client ResourceTiming
-FAIL requestStart should never be before fetchStart assert_not_equals: got disallowed value "back"
-PASS Delay from within service-worker (after internal fetching) should be accessible through `responseStart`
-PASS Delay from within service-worker (before internal fetching) should be measured before responseStart in the client ResourceTiming entry
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/same-site-cookies.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/same-site-cookies.https-expected.txt
index 0535759..eac574e 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/same-site-cookies.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/same-site-cookies.https-expected.txt
@@ -1,70 +1,79 @@
 This is a testharness.js-based test.
 Found 66 tests; 57 PASS, 9 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS Setup service workers
-PASS same-origin, window.open with no service worker
-PASS same-origin, window.open with fallback
-PASS same-origin, window.open with passthrough
-PASS same-origin, window.open with change-request
-PASS same-origin, window.open with navpreload
-PASS same-site, window.open with no service worker
-PASS same-site, window.open with fallback
-PASS same-site, window.open with passthrough
-PASS same-site, window.open with change-request
-PASS same-site, window.open with navpreload
-PASS cross-site, window.open with no service worker
-PASS cross-site, window.open with fallback
-PASS cross-site, window.open with passthrough
-PASS cross-site, window.open with change-request
-PASS cross-site, window.open with navpreload
-PASS same-origin, window.open with no service worker and same-site redirect
-PASS same-origin, window.open with fallback and same-site redirect
-PASS same-origin, window.open with passthrough and same-site redirect
-PASS same-origin, window.open with change-request and same-site redirect
-PASS same-origin, window.open with navpreload and same-site redirect
-PASS same-origin, window.open with no service worker and cross-site redirect
-PASS same-origin, window.open with fallback and cross-site redirect
-PASS same-origin, window.open with passthrough and cross-site redirect
-PASS same-origin, window.open with change-request and cross-site redirect
-PASS same-origin, window.open with navpreload and cross-site redirect
-PASS same-origin, window.open with no service worker, cross-site redirect, and same-origin redirect
-PASS same-origin, window.open with fallback, cross-site redirect, and same-origin redirect
-PASS same-origin, window.open with passthrough, cross-site redirect, and same-origin redirect
-PASS same-origin, window.open with change-request, cross-site redirect, and same-origin redirect
-PASS same-origin, window.open with navpreload, cross-site redirect, and same-origin redirect
-PASS same-origin, nested window.open with cross-site middle frame and no service worker
-PASS same-origin, nested window.open with cross-site middle frame and fallback service worker
-PASS same-origin, nested window.open with cross-site middle frame and passthrough service worker
-PASS same-origin, nested window.open with cross-site middle frame and change-request service worker
-PASS same-origin, nested window.open with cross-site middle frame and navpreload service worker
-PASS same-origin, nested set location with cross-site middle frame and no service worker
-PASS same-origin, nested set location with cross-site middle frame and fallback service worker
-PASS same-origin, nested set location with cross-site middle frame and passthrough service worker
-PASS same-origin, nested set location with cross-site middle frame and change-request service worker
-PASS same-origin, nested set location with cross-site middle frame and navpreload service worker
-PASS same-origin, form post with no service worker
-PASS same-origin, form post with fallback
-PASS same-origin, form post with passthrough
-PASS same-origin, form post with change-request
-PASS same-site, form post with no service worker
-PASS same-site, form post with fallback
-PASS same-site, form post with passthrough
-PASS same-site, form post with change-request
-FAIL cross-site, form post with no service worker assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
-FAIL cross-site, form post with fallback assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
-FAIL cross-site, form post with passthrough assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
-PASS cross-site, form post with change-request
-PASS same-origin, form post with no service worker and same-site redirect
-PASS same-origin, form post with fallback and same-site redirect
-PASS same-origin, form post with passthrough and same-site redirect
-PASS same-origin, form post with change-request and same-site redirect
-FAIL same-origin, form post with no service worker and cross-site redirect assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
-FAIL same-origin, form post with fallback and cross-site redirect assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
-FAIL same-origin, form post with passthrough and cross-site redirect assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
-PASS same-origin, form post with change-request and cross-site redirect
-FAIL same-origin, form post with no service worker, cross-site redirect, and same-origin redirect assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
-FAIL same-origin, form post with fallback, cross-site redirect, and same-origin redirect assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
-FAIL same-origin, form post with passthrough, cross-site redirect, and same-origin redirect assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
-PASS same-origin, form post with change-request, cross-site redirect, and same-origin redirect
-PASS Cleanup service workers
+[PASS] Setup service workers
+[PASS] same-origin, window.open with no service worker
+[PASS] same-origin, window.open with fallback
+[PASS] same-origin, window.open with passthrough
+[PASS] same-origin, window.open with change-request
+[PASS] same-origin, window.open with navpreload
+[PASS] same-site, window.open with no service worker
+[PASS] same-site, window.open with fallback
+[PASS] same-site, window.open with passthrough
+[PASS] same-site, window.open with change-request
+[PASS] same-site, window.open with navpreload
+[PASS] cross-site, window.open with no service worker
+[PASS] cross-site, window.open with fallback
+[PASS] cross-site, window.open with passthrough
+[PASS] cross-site, window.open with change-request
+[PASS] cross-site, window.open with navpreload
+[PASS] same-origin, window.open with no service worker and same-site redirect
+[PASS] same-origin, window.open with fallback and same-site redirect
+[PASS] same-origin, window.open with passthrough and same-site redirect
+[PASS] same-origin, window.open with change-request and same-site redirect
+[PASS] same-origin, window.open with navpreload and same-site redirect
+[PASS] same-origin, window.open with no service worker and cross-site redirect
+[PASS] same-origin, window.open with fallback and cross-site redirect
+[PASS] same-origin, window.open with passthrough and cross-site redirect
+[PASS] same-origin, window.open with change-request and cross-site redirect
+[PASS] same-origin, window.open with navpreload and cross-site redirect
+[PASS] same-origin, window.open with no service worker, cross-site redirect, and same-origin redirect
+[PASS] same-origin, window.open with fallback, cross-site redirect, and same-origin redirect
+[PASS] same-origin, window.open with passthrough, cross-site redirect, and same-origin redirect
+[PASS] same-origin, window.open with change-request, cross-site redirect, and same-origin redirect
+[PASS] same-origin, window.open with navpreload, cross-site redirect, and same-origin redirect
+[PASS] same-origin, nested window.open with cross-site middle frame and no service worker
+[PASS] same-origin, nested window.open with cross-site middle frame and fallback service worker
+[PASS] same-origin, nested window.open with cross-site middle frame and passthrough service worker
+[PASS] same-origin, nested window.open with cross-site middle frame and change-request service worker
+[PASS] same-origin, nested window.open with cross-site middle frame and navpreload service worker
+[PASS] same-origin, nested set location with cross-site middle frame and no service worker
+[PASS] same-origin, nested set location with cross-site middle frame and fallback service worker
+[PASS] same-origin, nested set location with cross-site middle frame and passthrough service worker
+[PASS] same-origin, nested set location with cross-site middle frame and change-request service worker
+[PASS] same-origin, nested set location with cross-site middle frame and navpreload service worker
+[PASS] same-origin, form post with no service worker
+[PASS] same-origin, form post with fallback
+[PASS] same-origin, form post with passthrough
+[PASS] same-origin, form post with change-request
+[PASS] same-site, form post with no service worker
+[PASS] same-site, form post with fallback
+[PASS] same-site, form post with passthrough
+[PASS] same-site, form post with change-request
+[FAIL] cross-site, form post with no service worker
+  assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
+[FAIL] cross-site, form post with fallback
+  assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
+[FAIL] cross-site, form post with passthrough
+  assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
+[PASS] cross-site, form post with change-request
+[PASS] same-origin, form post with no service worker and same-site redirect
+[PASS] same-origin, form post with fallback and same-site redirect
+[PASS] same-origin, form post with passthrough and same-site redirect
+[PASS] same-origin, form post with change-request and same-site redirect
+[FAIL] same-origin, form post with no service worker and cross-site redirect
+  assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
+[FAIL] same-origin, form post with fallback and cross-site redirect
+  assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
+[FAIL] same-origin, form post with passthrough and cross-site redirect
+  assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
+[PASS] same-origin, form post with change-request and cross-site redirect
+[FAIL] same-origin, form post with no service worker, cross-site redirect, and same-origin redirect
+  assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
+[FAIL] same-origin, form post with fallback, cross-site redirect, and same-origin redirect
+  assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
+[FAIL] same-origin, form post with passthrough, cross-site redirect, and same-origin redirect
+  assert_not_equals: Unspecified-SameSite cookies are not sent with cross-site requests. got disallowed value "COOKIE_VALUE"
+[PASS] same-origin, form post with change-request, cross-site redirect, and same-origin redirect
+[PASS] Cleanup service workers
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/unregister-then-register-new-script.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/unregister-then-register-new-script.https-expected.txt
index 20a0fa54..1fabde69 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/unregister-then-register-new-script.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/unregister-then-register-new-script.https-expected.txt
@@ -1,6 +1,8 @@
 This is a testharness.js-based test.
-FAIL Registering a new script URL while an unregistered registration is in use assert_equals: before activated registration.installing expected null but got object "[object ServiceWorker]"
-PASS Registering a new script URL that 404s does not resurrect unregistered registration
-FAIL Registering a new script URL that fails to install does not resurrect unregistered registration assert_not_equals: New registration is different got disallowed value object "[object ServiceWorkerRegistration]"
+[FAIL] Registering a new script URL while an unregistered registration is in use
+  assert_equals: before activated registration.installing expected null but got object "[object ServiceWorker]"
+[PASS] Registering a new script URL that 404s does not resurrect unregistered registration
+[FAIL] Registering a new script URL that fails to install does not resurrect unregistered registration
+  assert_not_equals: New registration is different got disallowed value object "[object ServiceWorkerRegistration]"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/unregister-then-register.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/unregister-then-register.https-expected.txt
index 30d5ef1..8f60e9b 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/unregister-then-register.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/unregister-then-register.https-expected.txt
@@ -1,7 +1,9 @@
 This is a testharness.js-based test.
-PASS Unregister then register resolves to a new value
-FAIL Unregister then register does not resolve to the original value even if the registration is in use. assert_not_equals: Unregister and register should always create a new registration got disallowed value object "[object ServiceWorkerRegistration]"
-PASS Unregister then register does not affect existing controllee
-FAIL Unregister then register does not resurrect the registration assert_equals: Registration is new expected null but got object "[object ServiceWorker]"
+[PASS] Unregister then register resolves to a new value
+[FAIL] Unregister then register does not resolve to the original value even if the registration is in use.
+  assert_not_equals: Unregister and register should always create a new registration got disallowed value object "[object ServiceWorkerRegistration]"
+[PASS] Unregister then register does not affect existing controllee
+[FAIL] Unregister then register does not resurrect the registration
+  assert_equals: Registration is new expected null but got object "[object ServiceWorker]"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/update-after-oneday.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/update-after-oneday.https-expected.txt
deleted file mode 100644
index e4f15c8..0000000
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/update-after-oneday.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Update should be triggered after a functional event when last update time is over 24 hours promise_test: Unhandled rejection with value: object "TypeError: frame.contentWindow.load_image is not a function"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt
index 5d5d770..32c47f9 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/update-recovery.https-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Recover from a bad service worker by updating after a failed navigation. promise_test: Unhandled rejection with value: "expected bad iframe should not fire a load event!"
+[FAIL] Recover from a bad service worker by updating after a failed navigation.
+  promise_test: Unhandled rejection with value: "expected bad iframe should not fire a load event!"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception-redirect.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception-redirect.https-expected.txt
index 6ebfc05..23027580 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception-redirect.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception-redirect.https-expected.txt
@@ -1,58 +1,81 @@
 This is a testharness.js-based test.
 Found 54 tests; 31 PASS, 23 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS initialize global state
-PASS Case #1: network scope1->scope2 (classic DedicatedWorker)
-PASS Case #1: network scope1->scope2 (module DedicatedWorker)
-FAIL Case #1: network scope1->scope2 (classic SharedWorker) assert_equals: expected "the worker script was served from network" but got "sw2 saw the request for the worker script"
-FAIL Case #1: network scope1->scope2 (module SharedWorker) assert_equals: expected "the worker script was served from network" but got "sw2 saw the request for the worker script"
-PASS Case #2: network scope1->out-scope (classic DedicatedWorker)
-PASS Case #2: network scope1->out-scope (module DedicatedWorker)
-PASS Case #2: network scope1->out-scope (classic SharedWorker)
-PASS Case #2: network scope1->out-scope (module SharedWorker)
-FAIL Case #3: sw scope1->scope2 (classic DedicatedWorker) assert_unreached: Worker error Reached unreachable code
-FAIL Case #3: sw scope1->scope2 (module DedicatedWorker) assert_unreached: Worker error Reached unreachable code
-PASS Case #3: sw scope1->scope2 (classic SharedWorker)
-PASS Case #3: sw scope1->scope2 (module SharedWorker)
-FAIL Case #4: sw scope1->out-scope (classic DedicatedWorker) assert_unreached: Worker error Reached unreachable code
-FAIL Case #4: sw scope1->out-scope (module DedicatedWorker) assert_unreached: Worker error Reached unreachable code
-PASS Case #4: sw scope1->out-scope (classic SharedWorker)
-PASS Case #4: sw scope1->out-scope (module SharedWorker)
-PASS cleanup global state
-FAIL Case #1: network scope1->scope2 (classic DedicatedWorker, importScripts()) assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/scope2/import-scripts-echo.py" but got "importScripts: served from network (scope2/)"
-FAIL Case #1: network scope1->scope2 (classic DedicatedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): a simple text file (scope2/)\n"
-PASS Case #1: network scope1->scope2 (classic DedicatedWorker, location.href)
-PASS Case #1: network scope1->scope2 (module DedicatedWorker, importScripts())
-FAIL Case #1: network scope1->scope2 (module DedicatedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): a simple text file (scope2/)\n"
-PASS Case #1: network scope1->scope2 (module DedicatedWorker, location.href)
-FAIL Case #1: network scope1->scope2 (classic SharedWorker, importScripts()) assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/scope2/import-scripts-echo.py" but got "sw2 saw importScripts from the worker: /service-workers/service-worker/resources/subdir/import-scripts-echo.py"
-FAIL Case #1: network scope1->scope2 (classic SharedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): sw2 saw the fetch from the worker: /service-workers/service-worker/resources/subdir/simple.txt"
-FAIL Case #1: network scope1->scope2 (classic SharedWorker, location.href) assert_equals: location.href expected "https://web-platform.test:8444/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py?greeting=sw2%20saw%20the%20request%20for%20the%20worker%20script"
-PASS Case #1: network scope1->scope2 (module SharedWorker, importScripts())
-FAIL Case #1: network scope1->scope2 (module SharedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): sw2 saw the fetch from the worker: /service-workers/service-worker/resources/subdir/simple.txt"
-FAIL Case #1: network scope1->scope2 (module SharedWorker, location.href) assert_equals: location.href expected "https://web-platform.test:8444/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py?greeting=sw2%20saw%20the%20request%20for%20the%20worker%20script"
-FAIL Case #2: network scope1->out-scope (classic DedicatedWorker, importScripts()) assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/import-scripts-echo.py" but got "importScripts: served from network"
-FAIL Case #2: network scope1->out-scope (classic DedicatedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
-PASS Case #2: network scope1->out-scope (classic DedicatedWorker, location.href)
-PASS Case #2: network scope1->out-scope (module DedicatedWorker, importScripts())
-FAIL Case #2: network scope1->out-scope (module DedicatedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
-PASS Case #2: network scope1->out-scope (module DedicatedWorker, location.href)
-FAIL Case #2: network scope1->out-scope (classic SharedWorker, importScripts()) assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/import-scripts-echo.py" but got "importScripts: served from network"
-FAIL Case #2: network scope1->out-scope (classic SharedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
-PASS Case #2: network scope1->out-scope (classic SharedWorker, location.href)
-PASS Case #2: network scope1->out-scope (module SharedWorker, importScripts())
-FAIL Case #2: network scope1->out-scope (module SharedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
-PASS Case #2: network scope1->out-scope (module SharedWorker, location.href)
-PASS Case #3: sw scope1->scope2 (classic SharedWorker, importScripts())
-PASS Case #3: sw scope1->scope2 (classic SharedWorker, fetch())
-PASS Case #3: sw scope1->scope2 (classic SharedWorker, location.href)
-PASS Case #3: sw scope1->scope2 (module SharedWorker, importScripts())
-PASS Case #3: sw scope1->scope2 (module SharedWorker, fetch())
-PASS Case #3: sw scope1->scope2 (module SharedWorker, location.href)
-FAIL Case #4: sw scope1->out-scope (classic SharedWorker, importScripts()) assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/import-scripts-echo.py" but got "importScripts: served from network"
-FAIL Case #4: sw scope1->out-scope (classic SharedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
-PASS Case #4: sw scope1->out-scope (classic SharedWorker, location.href)
-PASS Case #4: sw scope1->out-scope (module SharedWorker, importScripts())
-FAIL Case #4: sw scope1->out-scope (module SharedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
-PASS Case #4: sw scope1->out-scope (module SharedWorker, location.href)
+[PASS] initialize global state
+[PASS] Case #1: network scope1->scope2 (classic DedicatedWorker)
+[PASS] Case #1: network scope1->scope2 (module DedicatedWorker)
+[FAIL] Case #1: network scope1->scope2 (classic SharedWorker)
+  assert_equals: expected "the worker script was served from network" but got "sw2 saw the request for the worker script"
+[FAIL] Case #1: network scope1->scope2 (module SharedWorker)
+  assert_equals: expected "the worker script was served from network" but got "sw2 saw the request for the worker script"
+[PASS] Case #2: network scope1->out-scope (classic DedicatedWorker)
+[PASS] Case #2: network scope1->out-scope (module DedicatedWorker)
+[PASS] Case #2: network scope1->out-scope (classic SharedWorker)
+[PASS] Case #2: network scope1->out-scope (module SharedWorker)
+[FAIL] Case #3: sw scope1->scope2 (classic DedicatedWorker)
+  assert_unreached: Worker error Reached unreachable code
+[FAIL] Case #3: sw scope1->scope2 (module DedicatedWorker)
+  assert_unreached: Worker error Reached unreachable code
+[PASS] Case #3: sw scope1->scope2 (classic SharedWorker)
+[PASS] Case #3: sw scope1->scope2 (module SharedWorker)
+[FAIL] Case #4: sw scope1->out-scope (classic DedicatedWorker)
+  assert_unreached: Worker error Reached unreachable code
+[FAIL] Case #4: sw scope1->out-scope (module DedicatedWorker)
+  assert_unreached: Worker error Reached unreachable code
+[PASS] Case #4: sw scope1->out-scope (classic SharedWorker)
+[PASS] Case #4: sw scope1->out-scope (module SharedWorker)
+[PASS] cleanup global state
+[FAIL] Case #1: network scope1->scope2 (classic DedicatedWorker, importScripts())
+  assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/scope2/import-scripts-echo.py" but got "importScripts: served from network (scope2/)"
+[FAIL] Case #1: network scope1->scope2 (classic DedicatedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): a simple text file (scope2/)\n"
+[PASS] Case #1: network scope1->scope2 (classic DedicatedWorker, location.href)
+[PASS] Case #1: network scope1->scope2 (module DedicatedWorker, importScripts())
+[FAIL] Case #1: network scope1->scope2 (module DedicatedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): a simple text file (scope2/)\n"
+[PASS] Case #1: network scope1->scope2 (module DedicatedWorker, location.href)
+[FAIL] Case #1: network scope1->scope2 (classic SharedWorker, importScripts())
+  assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/scope2/import-scripts-echo.py" but got "sw2 saw importScripts from the worker: /service-workers/service-worker/resources/subdir/import-scripts-echo.py"
+[FAIL] Case #1: network scope1->scope2 (classic SharedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): sw2 saw the fetch from the worker: /service-workers/service-worker/resources/subdir/simple.txt"
+[FAIL] Case #1: network scope1->scope2 (classic SharedWorker, location.href)
+  assert_equals: location.href expected "https://web-platform.test:8444/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py?greeting=sw2%20saw%20the%20request%20for%20the%20worker%20script"
+[PASS] Case #1: network scope1->scope2 (module SharedWorker, importScripts())
+[FAIL] Case #1: network scope1->scope2 (module SharedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): sw2 saw the fetch from the worker: /service-workers/service-worker/resources/subdir/simple.txt"
+[FAIL] Case #1: network scope1->scope2 (module SharedWorker, location.href)
+  assert_equals: location.href expected "https://web-platform.test:8444/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py?greeting=sw2%20saw%20the%20request%20for%20the%20worker%20script"
+[FAIL] Case #2: network scope1->out-scope (classic DedicatedWorker, importScripts())
+  assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/import-scripts-echo.py" but got "importScripts: served from network"
+[FAIL] Case #2: network scope1->out-scope (classic DedicatedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
+[PASS] Case #2: network scope1->out-scope (classic DedicatedWorker, location.href)
+[PASS] Case #2: network scope1->out-scope (module DedicatedWorker, importScripts())
+[FAIL] Case #2: network scope1->out-scope (module DedicatedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
+[PASS] Case #2: network scope1->out-scope (module DedicatedWorker, location.href)
+[FAIL] Case #2: network scope1->out-scope (classic SharedWorker, importScripts())
+  assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/import-scripts-echo.py" but got "importScripts: served from network"
+[FAIL] Case #2: network scope1->out-scope (classic SharedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
+[PASS] Case #2: network scope1->out-scope (classic SharedWorker, location.href)
+[PASS] Case #2: network scope1->out-scope (module SharedWorker, importScripts())
+[FAIL] Case #2: network scope1->out-scope (module SharedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
+[PASS] Case #2: network scope1->out-scope (module SharedWorker, location.href)
+[PASS] Case #3: sw scope1->scope2 (classic SharedWorker, importScripts())
+[PASS] Case #3: sw scope1->scope2 (classic SharedWorker, fetch())
+[PASS] Case #3: sw scope1->scope2 (classic SharedWorker, location.href)
+[PASS] Case #3: sw scope1->scope2 (module SharedWorker, importScripts())
+[PASS] Case #3: sw scope1->scope2 (module SharedWorker, fetch())
+[PASS] Case #3: sw scope1->scope2 (module SharedWorker, location.href)
+[FAIL] Case #4: sw scope1->out-scope (classic SharedWorker, importScripts())
+  assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/import-scripts-echo.py" but got "importScripts: served from network"
+[FAIL] Case #4: sw scope1->out-scope (classic SharedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
+[PASS] Case #4: sw scope1->out-scope (classic SharedWorker, location.href)
+[PASS] Case #4: sw scope1->out-scope (module SharedWorker, importScripts())
+[FAIL] Case #4: sw scope1->out-scope (module SharedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
+[PASS] Case #4: sw scope1->out-scope (module SharedWorker, location.href)
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
deleted file mode 100644
index dba3694a..0000000
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify a dedicated worker script request issued from a uncontrolled document is intercepted by worker's own service worker. promise_test: Unhandled rejection with value: undefined
-FAIL Verify an out-of-scope dedicated worker script request issued from a controlled document should not be intercepted by document's service worker. assert_equals: expected "worker loading was not intercepted by service worker" but got "worker loading intercepted by service worker"
-PASS Verify a shared worker script request issued from a uncontrolled document is intercepted by worker's own service worker.
-FAIL Verify a same-origin worker script served by a service worker succeeds in starting a dedicated worker. promise_test: Unhandled rejection with value: undefined
-PASS Verify a same-origin worker script served by a service worker succeeds in starting a shared worker.
-PASS Verify a cors worker script served by a service worker fails dedicated worker start.
-PASS Verify a cors worker script served by a service worker fails shared worker start.
-PASS Verify a no-cors cross-origin worker script served by a service worker fails dedicated worker start.
-PASS Verify a no-cors cross-origin worker script served by a service worker fails shared worker start.
-PASS Register a service worker for worker subresource interception tests.
-FAIL Requests on a dedicated worker controlled by a service worker. assert_equals: expected "This load was successfully intercepted." but got "{\"error\": {\"code\": 404, \"message\": \"\"}}"
-PASS Requests on a shared worker controlled by a service worker.
-FAIL Requests on a dedicated worker nested in a dedicated worker and controlled by a service worker assert_equals: expected "This load was successfully intercepted." but got "{\"error\": {\"code\": 404, \"message\": \"\"}}"
-FAIL Requests on a dedicated worker nested in a shared worker and controlled by a service worker assert_equals: expected "This load was successfully intercepted." but got "Unexpected error! Worker is not defined"
-PASS Unregister a service worker for subresource interception tests.
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/xhr-content-length.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/xhr-content-length.https.window-expected.txt
index 7222d7db..a83de08 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/xhr-content-length.https.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/xhr-content-length.https.window-expected.txt
@@ -1,8 +1,9 @@
 This is a testharness.js-based test.
-PASS Setup
-PASS Synthetic response without Content-Length header
-PASS Synthetic response with Content-Length header with value larger than response body length
-FAIL Synthetic response with two Content-Length headers value larger than response body length assert_equals: expected "10000, 10000" but got "10000"
-PASS Synthetic response with bogus Content-Length header
+[PASS] Setup
+[PASS] Synthetic response without Content-Length header
+[PASS] Synthetic response with Content-Length header with value larger than response body length
+[FAIL] Synthetic response with two Content-Length headers value larger than response body length
+  assert_equals: expected "10000, 10000" but got "10000"
+[PASS] Synthetic response with bogus Content-Length header
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/xhr-content-length.window-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/xhr-content-length.window-expected.txt
deleted file mode 100644
index 52c2f67..0000000
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/xhr-content-length.window-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL Setup promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'getRegistration' of undefined"
-FAIL Synthetic response without Content-Length header promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'contentWindow' of undefined"
-FAIL Synthetic response with Content-Length header with value larger than response body length promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'contentWindow' of undefined"
-FAIL Synthetic response with two Content-Length headers value larger than response body length promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'contentWindow' of undefined"
-FAIL Synthetic response with bogus Content-Length header promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'contentWindow' of undefined"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/video-encoder-content-hint.https.any.js b/third_party/blink/web_tests/external/wpt/webcodecs/video-encoder-content-hint.https.any.js
new file mode 100644
index 0000000..cdc32fe
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webcodecs/video-encoder-content-hint.https.any.js
@@ -0,0 +1,21 @@
+// META: global=window,dedicatedworker
+
+promise_test(async t => {
+  const config = {
+    codec: 'vp8',
+    width: 1280,
+    height: 720,
+    bitrate: 5000000,
+    bitrateMode: 'constant',
+    framerate: 25,
+    latencyMode: 'realtime',
+    contentHint: 'text',
+  };
+
+  let support = await VideoEncoder.isConfigSupported(config);
+  assert_equals(support.supported, true);
+
+  let new_config = support.config;
+  assert_equals(new_config.codec, config.codec);
+  assert_equals(new_config.contentHint, 'text');
+}, 'Test that contentHint is recognized by VideoEncoder');
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/network/__init__.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/network/__init__.py
index cab997d..7ec80ac3 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/network/__init__.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/network/__init__.py
@@ -203,6 +203,11 @@
         # in assert_request_data
         del expected_response["headers"]
 
+    if response_data["status"] in [401, 407]:
+        assert isinstance(response_data["authChallenges"], list)
+    else:
+        assert "authChallenges" not in response_data
+
     recursive_compare(expected_response, response_data)
 
 
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/network/response_completed/response_completed.py.ini b/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/network/response_completed/response_completed.py.ini
index 4f5b5477..f39d03be 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/network/response_completed/response_completed.py.ini
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/network/response_completed/response_completed.py.ini
@@ -1,7 +1,13 @@
 [response_completed.py]
   expected: [TIMEOUT, OK]
-  [test_response_status[101-Switching Protocols\]]
+  [test_redirect_document[http\]]
+    expected: [PASS, FAIL]
+
+  [test_redirect_document[https coop\]]
     expected: FAIL
 
-  [test_response_status[407-Proxy Authentication Required\]]
+  [test_redirect_document[https\]]
+    expected: [FAIL, PASS]
+
+  [test_response_status[401-Unauthorized\]]
     expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/network/response_started/response_started.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/network/response_started/response_started.py
index d3a84fd6..2af2697 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/network/response_started/response_started.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/network/response_started/response_started.py
@@ -33,9 +33,7 @@
     async def on_event(_, data):
         events.append(data)
 
-    remove_listener = bidi_session.add_event_listener(
-        RESPONSE_STARTED_EVENT, on_event
-    )
+    remove_listener = bidi_session.add_event_listener(RESPONSE_STARTED_EVENT, on_event)
 
     text_url = url(PAGE_EMPTY_TEXT)
     on_response_started = wait_for_event(RESPONSE_STARTED_EVENT)
@@ -113,7 +111,9 @@
 async def test_response_status(
     wait_for_event, url, fetch, setup_network_test, status, status_text
 ):
-    status_url = url(f"/webdriver/tests/support/http_handlers/status.py?status={status}&nocache={RESPONSE_STARTED_EVENT}")
+    status_url = url(
+        f"/webdriver/tests/support/http_handlers/status.py?status={status}&nocache={RESPONSE_STARTED_EVENT}"
+    )
 
     network_events = await setup_network_test(events=[RESPONSE_STARTED_EVENT])
     events = network_events[RESPONSE_STARTED_EVENT]
@@ -140,9 +140,7 @@
 
 
 @pytest.mark.asyncio
-async def test_response_headers(
-    wait_for_event, url, fetch, setup_network_test
-):
+async def test_response_headers(wait_for_event, url, fetch, setup_network_test):
     headers_url = url(
         "/webdriver/tests/support/http_handlers/headers.py?header=foo:bar&header=baz:biz"
     )
@@ -210,9 +208,48 @@
 
 
 @pytest.mark.asyncio
+async def test_www_authenticate(
+    bidi_session, new_tab, url, wait_for_event, setup_network_test
+):
+    auth_url = url(
+        f"/webdriver/tests/support/http_handlers/authentication.py?realm=testrealm"
+    )
+
+    network_events = await setup_network_test(events=[RESPONSE_STARTED_EVENT])
+    events = network_events[RESPONSE_STARTED_EVENT]
+
+    on_response_started = wait_for_event(RESPONSE_STARTED_EVENT)
+    await bidi_session.browsing_context.navigate(
+        context=new_tab["context"],
+        url=auth_url,
+        wait="none",
+    )
+
+    await on_response_started
+
+    assert len(events) == 1
+
+    expected_request = {"method": "GET", "url": auth_url}
+    expected_response = {
+        "url": auth_url,
+        "authChallenges": [
+            ({"scheme": "Basic", "realm": "testrealm"}),
+        ],
+    }
+    assert_response_event(
+        events[0],
+        expected_request=expected_request,
+        expected_response=expected_response,
+        redirect_count=0,
+    )
+
+
+@pytest.mark.asyncio
 async def test_redirect(bidi_session, url, fetch, setup_network_test):
     text_url = url(PAGE_EMPTY_TEXT)
-    redirect_url = url(f"/webdriver/tests/support/http_handlers/redirect.py?location={text_url}")
+    redirect_url = url(
+        f"/webdriver/tests/support/http_handlers/redirect.py?location={text_url}"
+    )
 
     network_events = await setup_network_test(events=[RESPONSE_STARTED_EVENT])
     events = network_events[RESPONSE_STARTED_EVENT]
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/conv2d.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/conv2d.https.any-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/webnn/conv2d.https.any-expected.txt
rename to third_party/blink/web_tests/external/wpt/webnn/conv2d.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/conv_transpose2d.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/conv_transpose2d.https.any-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/webnn/conv_transpose2d.https.any-expected.txt
rename to third_party/blink/web_tests/external/wpt/webnn/conv_transpose2d.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/elementwise_binary.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/elementwise_binary.https.any-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/webnn/elementwise_binary.https.any-expected.txt
rename to third_party/blink/web_tests/external/wpt/webnn/elementwise_binary.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/elementwise_unary.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/elementwise_unary.https.any-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/webnn/elementwise_unary.https.any-expected.txt
rename to third_party/blink/web_tests/external/wpt/webnn/elementwise_unary.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/elu.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/elu.https.any-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/webnn/elu.https.any-expected.txt
rename to third_party/blink/web_tests/external/wpt/webnn/elu.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/gemm.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/gemm.https.any-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/webnn/gemm.https.any-expected.txt
rename to third_party/blink/web_tests/external/wpt/webnn/gemm.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/idlharness.https.any-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any-expected.txt
rename to third_party/blink/web_tests/external/wpt/webnn/idlharness.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/pad.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/pad.https.any-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/webnn/pad.https.any-expected.txt
rename to third_party/blink/web_tests/external/wpt/webnn/pad.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/pooling.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/pooling.https.any-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/webnn/pooling.https.any-expected.txt
rename to third_party/blink/web_tests/external/wpt/webnn/pooling.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/prelu.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/prelu.https.any-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/webnn/prelu.https.any-expected.txt
rename to third_party/blink/web_tests/external/wpt/webnn/prelu.https.any-expected.txt
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/reduction.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/reduction.https.any-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/webnn/reduction.https.any-expected.txt
rename to third_party/blink/web_tests/external/wpt/webnn/reduction.https.any-expected.txt
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Close-1000-reason.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Close-1000-reason.any.worker_wpt_flags=h2-expected.txt
index dc3fa03..59016ecc 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Close-1000-reason.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Close-1000-reason.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Close the Connection - close(1000, reason) - readyState should be in CLOSED state and wasClean is TRUE - Connection should be closed assert_true: WebSocket connection should be opened expected true got false
+[FAIL] Create WebSocket - Close the Connection - close(1000, reason) - readyState should be in CLOSED state and wasClean is TRUE - Connection should be closed
+  assert_true: WebSocket connection should be opened expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Close-1000-reason.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Close-1000-reason.any_wpt_flags=h2-expected.txt
index dc3fa03..59016ecc 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Close-1000-reason.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Close-1000-reason.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Close the Connection - close(1000, reason) - readyState should be in CLOSED state and wasClean is TRUE - Connection should be closed assert_true: WebSocket connection should be opened expected true got false
+[FAIL] Create WebSocket - Close the Connection - close(1000, reason) - readyState should be in CLOSED state and wasClean is TRUE - Connection should be closed
+  assert_true: WebSocket connection should be opened expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Close-2999-reason.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Close-2999-reason.any_wpt_flags=h2-expected.txt
index f1e9dc8..847cc821 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Close-2999-reason.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Close-2999-reason.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Close the Connection - close(2999, reason) - INVALID_ACCESS_ERR is thrown assert_unreached: close event should not fire Reached unreachable code
+[FAIL] Create WebSocket - Close the Connection - close(2999, reason) - INVALID_ACCESS_ERR is thrown
+  assert_unreached: close event should not fire Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Close-delayed.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Close-delayed.any.worker_wpt_flags=h2-expected.txt
index 302107b..0cc474c 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Close-delayed.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Close-delayed.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Close the Connection - close should not emit until handshake completes - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Create WebSocket - Close the Connection - close should not emit until handshake completes - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Close-delayed.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Close-delayed.any_wpt_flags=h2-expected.txt
index 302107b..0cc474c 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Close-delayed.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Close-delayed.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Close the Connection - close should not emit until handshake completes - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Create WebSocket - Close the Connection - close should not emit until handshake completes - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Close-server-initiated-close.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Close-server-initiated-close.any.worker_wpt_flags=h2-expected.txt
index 1711963..68ef88d 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Close-server-initiated-close.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Close-server-initiated-close.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Server initiated Close - Client sends back a CLOSE - readyState should be in CLOSED state and wasClean is TRUE - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Create WebSocket - Server initiated Close - Client sends back a CLOSE - readyState should be in CLOSED state and wasClean is TRUE - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-Secure-url-with-space.any-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-Secure-url-with-space.any-expected.txt
deleted file mode 100644
index 6e14133..0000000
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-Secure-url-with-space.any-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a testharness.js-based test.
-FAIL Create Secure WebSocket - Pass a URL with a space - SYNTAX_ERR should be thrown assert_throws_dom: function "function() {
-    wsocket = CreateWebSocketWithSpaceInUrl(spaceUrl)
-  }" did not throw
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-Secure-url-with-space.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-Secure-url-with-space.any.worker-expected.txt
deleted file mode 100644
index 6e14133..0000000
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-Secure-url-with-space.any.worker-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a testharness.js-based test.
-FAIL Create Secure WebSocket - Pass a URL with a space - SYNTAX_ERR should be thrown assert_throws_dom: function "function() {
-    wsocket = CreateWebSocketWithSpaceInUrl(spaceUrl)
-  }" did not throw
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-http-urls.any-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-http-urls.any-expected.txt
index 9412ba1..4ade8bbf 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-http-urls.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-http-urls.any-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSocket: ensure both HTTP schemes are supported Failed to construct 'WebSocket': The URL's scheme must be either 'ws' or 'wss'. 'http' is not allowed.
+[FAIL] WebSocket: ensure both HTTP schemes are supported
+  Failed to construct 'WebSocket': The URL's scheme must be either 'ws' or 'wss'. 'http' is not allowed.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-http-urls.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-http-urls.any.worker-expected.txt
index 9412ba1..4ade8bbf 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-http-urls.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-http-urls.any.worker-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSocket: ensure both HTTP schemes are supported Failed to construct 'WebSocket': The URL's scheme must be either 'ws' or 'wss'. 'http' is not allowed.
+[FAIL] WebSocket: ensure both HTTP schemes are supported
+  Failed to construct 'WebSocket': The URL's scheme must be either 'ws' or 'wss'. 'http' is not allowed.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-invalid-urls.any-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-invalid-urls.any-expected.txt
index 851aded5..5ff3f4e 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-invalid-urls.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-invalid-urls.any-expected.txt
@@ -1,11 +1,13 @@
 This is a testharness.js-based test.
-FAIL new WebSocket("ws://foo bar.com/") should throw a "SyntaxError" DOMException assert_throws_dom: function "() => new WebSocket(input)" did not throw
-FAIL new WebSocket("wss://foo bar.com/") should throw a "SyntaxError" DOMException assert_throws_dom: function "() => new WebSocket(input)" did not throw
-PASS new WebSocket("ftp://web-platform.test:8001/") should throw a "SyntaxError" DOMException
-PASS new WebSocket("mailto:example@example.org") should throw a "SyntaxError" DOMException
-PASS new WebSocket("about:blank") should throw a "SyntaxError" DOMException
-PASS new WebSocket("http://web-platform.test:8001/#") should throw a "SyntaxError" DOMException
-PASS new WebSocket("http://web-platform.test:8001/#test") should throw a "SyntaxError" DOMException
-PASS new WebSocket("#test") should throw a "SyntaxError" DOMException
+[FAIL] new WebSocket("ws://foo bar.com/") should throw a "SyntaxError" DOMException
+  assert_throws_dom: function "() => new WebSocket(input)" did not throw
+[FAIL] new WebSocket("wss://foo bar.com/") should throw a "SyntaxError" DOMException
+  assert_throws_dom: function "() => new WebSocket(input)" did not throw
+[PASS] new WebSocket("ftp://web-platform.test:8001/") should throw a "SyntaxError" DOMException
+[PASS] new WebSocket("mailto:example@example.org") should throw a "SyntaxError" DOMException
+[PASS] new WebSocket("about:blank") should throw a "SyntaxError" DOMException
+[PASS] new WebSocket("http://web-platform.test:8001/#") should throw a "SyntaxError" DOMException
+[PASS] new WebSocket("http://web-platform.test:8001/#test") should throw a "SyntaxError" DOMException
+[PASS] new WebSocket("#test") should throw a "SyntaxError" DOMException
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-invalid-urls.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-invalid-urls.any.worker-expected.txt
index 851aded5..5ff3f4e 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-invalid-urls.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-invalid-urls.any.worker-expected.txt
@@ -1,11 +1,13 @@
 This is a testharness.js-based test.
-FAIL new WebSocket("ws://foo bar.com/") should throw a "SyntaxError" DOMException assert_throws_dom: function "() => new WebSocket(input)" did not throw
-FAIL new WebSocket("wss://foo bar.com/") should throw a "SyntaxError" DOMException assert_throws_dom: function "() => new WebSocket(input)" did not throw
-PASS new WebSocket("ftp://web-platform.test:8001/") should throw a "SyntaxError" DOMException
-PASS new WebSocket("mailto:example@example.org") should throw a "SyntaxError" DOMException
-PASS new WebSocket("about:blank") should throw a "SyntaxError" DOMException
-PASS new WebSocket("http://web-platform.test:8001/#") should throw a "SyntaxError" DOMException
-PASS new WebSocket("http://web-platform.test:8001/#test") should throw a "SyntaxError" DOMException
-PASS new WebSocket("#test") should throw a "SyntaxError" DOMException
+[FAIL] new WebSocket("ws://foo bar.com/") should throw a "SyntaxError" DOMException
+  assert_throws_dom: function "() => new WebSocket(input)" did not throw
+[FAIL] new WebSocket("wss://foo bar.com/") should throw a "SyntaxError" DOMException
+  assert_throws_dom: function "() => new WebSocket(input)" did not throw
+[PASS] new WebSocket("ftp://web-platform.test:8001/") should throw a "SyntaxError" DOMException
+[PASS] new WebSocket("mailto:example@example.org") should throw a "SyntaxError" DOMException
+[PASS] new WebSocket("about:blank") should throw a "SyntaxError" DOMException
+[PASS] new WebSocket("http://web-platform.test:8001/#") should throw a "SyntaxError" DOMException
+[PASS] new WebSocket("http://web-platform.test:8001/#test") should throw a "SyntaxError" DOMException
+[PASS] new WebSocket("#test") should throw a "SyntaxError" DOMException
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-non-absolute-url.any-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-non-absolute-url.any-expected.txt
index cd6dc87..d8bc89cf 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-non-absolute-url.any-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-non-absolute-url.any-expected.txt
@@ -1,7 +1,11 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a non absolute URL: test Failed to construct 'WebSocket': The URL 'test' is invalid.
-FAIL Create WebSocket - Pass a non absolute URL: ? Failed to construct 'WebSocket': The URL '?' is invalid.
-FAIL Create WebSocket - Pass a non absolute URL: null Failed to construct 'WebSocket': The URL 'null' is invalid.
-FAIL Create WebSocket - Pass a non absolute URL: 123 Failed to construct 'WebSocket': The URL '123' is invalid.
+[FAIL] Create WebSocket - Pass a non absolute URL: test
+  Failed to construct 'WebSocket': The URL 'test' is invalid.
+[FAIL] Create WebSocket - Pass a non absolute URL: ?
+  Failed to construct 'WebSocket': The URL '?' is invalid.
+[FAIL] Create WebSocket - Pass a non absolute URL: null
+  Failed to construct 'WebSocket': The URL 'null' is invalid.
+[FAIL] Create WebSocket - Pass a non absolute URL: 123
+  Failed to construct 'WebSocket': The URL '123' is invalid.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-non-absolute-url.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-non-absolute-url.any.worker-expected.txt
index cd6dc87..d8bc89cf 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-non-absolute-url.any.worker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-non-absolute-url.any.worker-expected.txt
@@ -1,7 +1,11 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a non absolute URL: test Failed to construct 'WebSocket': The URL 'test' is invalid.
-FAIL Create WebSocket - Pass a non absolute URL: ? Failed to construct 'WebSocket': The URL '?' is invalid.
-FAIL Create WebSocket - Pass a non absolute URL: null Failed to construct 'WebSocket': The URL 'null' is invalid.
-FAIL Create WebSocket - Pass a non absolute URL: 123 Failed to construct 'WebSocket': The URL '123' is invalid.
+[FAIL] Create WebSocket - Pass a non absolute URL: test
+  Failed to construct 'WebSocket': The URL 'test' is invalid.
+[FAIL] Create WebSocket - Pass a non absolute URL: ?
+  Failed to construct 'WebSocket': The URL '?' is invalid.
+[FAIL] Create WebSocket - Pass a non absolute URL: null
+  Failed to construct 'WebSocket': The URL 'null' is invalid.
+[FAIL] Create WebSocket - Pass a non absolute URL: 123
+  Failed to construct 'WebSocket': The URL '123' is invalid.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any.worker_default-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any.worker_default-expected.txt
index 27b7a39..91b1b29 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any.worker_default-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any.worker_default-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a valid URL and an array of protocol strings with repeated values but different case - SYNTAX_ERR is thrown assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithRepeatedProtocolsCaseInsensitive()\n  }" did not throw
+[FAIL] Create WebSocket - Pass a valid URL and an array of protocol strings with repeated values but different case - SYNTAX_ERR is thrown
+  assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithRepeatedProtocolsCaseInsensitive()\n  }" did not throw
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any.worker_wpt_flags=h2-expected.txt
index 27b7a39..91b1b29 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a valid URL and an array of protocol strings with repeated values but different case - SYNTAX_ERR is thrown assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithRepeatedProtocolsCaseInsensitive()\n  }" did not throw
+[FAIL] Create WebSocket - Pass a valid URL and an array of protocol strings with repeated values but different case - SYNTAX_ERR is thrown
+  assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithRepeatedProtocolsCaseInsensitive()\n  }" did not throw
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any.worker_wss-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any.worker_wss-expected.txt
index 27b7a39..91b1b29 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any.worker_wss-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any.worker_wss-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a valid URL and an array of protocol strings with repeated values but different case - SYNTAX_ERR is thrown assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithRepeatedProtocolsCaseInsensitive()\n  }" did not throw
+[FAIL] Create WebSocket - Pass a valid URL and an array of protocol strings with repeated values but different case - SYNTAX_ERR is thrown
+  assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithRepeatedProtocolsCaseInsensitive()\n  }" did not throw
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_default-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_default-expected.txt
index 27b7a39..91b1b29 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_default-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_default-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a valid URL and an array of protocol strings with repeated values but different case - SYNTAX_ERR is thrown assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithRepeatedProtocolsCaseInsensitive()\n  }" did not throw
+[FAIL] Create WebSocket - Pass a valid URL and an array of protocol strings with repeated values but different case - SYNTAX_ERR is thrown
+  assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithRepeatedProtocolsCaseInsensitive()\n  }" did not throw
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wpt_flags=h2-expected.txt
index 27b7a39..91b1b29 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a valid URL and an array of protocol strings with repeated values but different case - SYNTAX_ERR is thrown assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithRepeatedProtocolsCaseInsensitive()\n  }" did not throw
+[FAIL] Create WebSocket - Pass a valid URL and an array of protocol strings with repeated values but different case - SYNTAX_ERR is thrown
+  assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithRepeatedProtocolsCaseInsensitive()\n  }" did not throw
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wss-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wss-expected.txt
index 27b7a39..91b1b29 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wss-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wss-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a valid URL and an array of protocol strings with repeated values but different case - SYNTAX_ERR is thrown assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithRepeatedProtocolsCaseInsensitive()\n  }" did not throw
+[FAIL] Create WebSocket - Pass a valid URL and an array of protocol strings with repeated values but different case - SYNTAX_ERR is thrown
+  assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithRepeatedProtocolsCaseInsensitive()\n  }" did not throw
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any.worker_default-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any.worker_default-expected.txt
index d3d8e9b..e7dfa97c 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any.worker_default-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any.worker_default-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a URL with a space - SYNTAX_ERR should be thrown assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithSpaceInUrl(spaceUrl)\n  }" did not throw
+[FAIL] Create WebSocket - Pass a URL with a space - SYNTAX_ERR should be thrown
+  assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithSpaceInUrl(spaceUrl)\n  }" did not throw
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any.worker_wpt_flags=h2-expected.txt
index d3d8e9b..e7dfa97c 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a URL with a space - SYNTAX_ERR should be thrown assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithSpaceInUrl(spaceUrl)\n  }" did not throw
+[FAIL] Create WebSocket - Pass a URL with a space - SYNTAX_ERR should be thrown
+  assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithSpaceInUrl(spaceUrl)\n  }" did not throw
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any.worker_wss-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any.worker_wss-expected.txt
index d3d8e9b..e7dfa97c 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any.worker_wss-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any.worker_wss-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a URL with a space - SYNTAX_ERR should be thrown assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithSpaceInUrl(spaceUrl)\n  }" did not throw
+[FAIL] Create WebSocket - Pass a URL with a space - SYNTAX_ERR should be thrown
+  assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithSpaceInUrl(spaceUrl)\n  }" did not throw
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any_default-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any_default-expected.txt
index d3d8e9b..e7dfa97c 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any_default-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any_default-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a URL with a space - SYNTAX_ERR should be thrown assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithSpaceInUrl(spaceUrl)\n  }" did not throw
+[FAIL] Create WebSocket - Pass a URL with a space - SYNTAX_ERR should be thrown
+  assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithSpaceInUrl(spaceUrl)\n  }" did not throw
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any_wpt_flags=h2-expected.txt
index d3d8e9b..e7dfa97c 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a URL with a space - SYNTAX_ERR should be thrown assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithSpaceInUrl(spaceUrl)\n  }" did not throw
+[FAIL] Create WebSocket - Pass a URL with a space - SYNTAX_ERR should be thrown
+  assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithSpaceInUrl(spaceUrl)\n  }" did not throw
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any_wss-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any_wss-expected.txt
index d3d8e9b..e7dfa97c 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any_wss-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-space.any_wss-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a URL with a space - SYNTAX_ERR should be thrown assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithSpaceInUrl(spaceUrl)\n  }" did not throw
+[FAIL] Create WebSocket - Pass a URL with a space - SYNTAX_ERR should be thrown
+  assert_throws_dom: function "function() {\n    wsocket = CreateWebSocketWithSpaceInUrl(spaceUrl)\n  }" did not throw
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-windows-1252-encoding-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-windows-1252-encoding-expected.txt
index e1df1c2..076d3a7 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-windows-1252-encoding-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-url-with-windows-1252-encoding-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL URL's percent-encoding is always in UTF-8 for WebSocket Failed to construct 'WebSocket': The URL '/?€' is invalid.
+[FAIL] URL's percent-encoding is always in UTF-8 for WebSocket
+  Failed to construct 'WebSocket': The URL '/?€' is invalid.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-valid-url-array-protocols.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-valid-url-array-protocols.any.worker_wpt_flags=h2-expected.txt
index f7aa3bd..1faa9cf 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-valid-url-array-protocols.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-valid-url-array-protocols.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a valid URL and array of protocol strings - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Create WebSocket - Pass a valid URL and array of protocol strings - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-valid-url-protocol-string.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-valid-url-protocol-string.any.worker_wpt_flags=h2-expected.txt
index eab04c0..8582ca1 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-valid-url-protocol-string.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Create-valid-url-protocol-string.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a valid URL and protocol string - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Create WebSocket - Pass a valid URL and protocol string - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Create-valid-url-protocol.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-valid-url-protocol.any.worker_wpt_flags=h2-expected.txt
deleted file mode 100644
index d46b601..0000000
--- a/third_party/blink/web_tests/external/wpt/websockets/Create-valid-url-protocol.any.worker_wpt_flags=h2-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a valid URL and a protocol string - Connection should be closed assert_true: WebSocket connection should be open expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Send-0byte-data.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Send-0byte-data.any.worker_wpt_flags=h2-expected.txt
index 13ac904..15e25a4 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Send-0byte-data.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Send-0byte-data.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Send 0 byte data on a WebSocket - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Send 0 byte data on a WebSocket - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-float64.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-float64.any_wpt_flags=h2-expected.txt
index 51f63a3b..7aefdc0 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-float64.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-float64.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Send binary data on a WebSocket - ArrayBufferView - Float64Array - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Send binary data on a WebSocket - ArrayBufferView - Float64Array - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-int16-offset.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-int16-offset.any.worker_wpt_flags=h2-expected.txt
index 5cf6c45..6778f1a 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-int16-offset.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-int16-offset.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Send binary data on a WebSocket - ArrayBufferView - Int16Array with offset - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Send binary data on a WebSocket - ArrayBufferView - Int16Array with offset - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-int16-offset.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-int16-offset.any_wpt_flags=h2-expected.txt
index 5cf6c45..6778f1a 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-int16-offset.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-int16-offset.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Send binary data on a WebSocket - ArrayBufferView - Int16Array with offset - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Send binary data on a WebSocket - ArrayBufferView - Int16Array with offset - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-uint32-offset.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-uint32-offset.any_wpt_flags=h2-expected.txt
index 29a3626c1..f6158906 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-uint32-offset.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Send-binary-arraybufferview-uint32-offset.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Send binary data on a WebSocket - ArrayBufferView - Uint32Array with offset - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Send binary data on a WebSocket - ArrayBufferView - Uint32Array with offset - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Send-unpaired-surrogates.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Send-unpaired-surrogates.any.worker_wpt_flags=h2-expected.txt
index 69f784d..6558a55f 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/Send-unpaired-surrogates.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/Send-unpaired-surrogates.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Send unpaired surrogates on a WebSocket - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Send unpaired surrogates on a WebSocket - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/Send-unpaired-surrogates.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Send-unpaired-surrogates.any_wpt_flags=h2-expected.txt
deleted file mode 100644
index 69f784d..0000000
--- a/third_party/blink/web_tests/external/wpt/websockets/Send-unpaired-surrogates.any_wpt_flags=h2-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Send unpaired surrogates on a WebSocket - Connection should be closed assert_true: WebSocket connection should be open expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/websockets/back-forward-cache-with-closed-websocket-connection-ccns.tentative.window-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/back-forward-cache-with-closed-websocket-connection-ccns.tentative.window-expected.txt
index 444dc8a..5636f8f 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/back-forward-cache-with-closed-websocket-connection-ccns.tentative.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/back-forward-cache-with-closed-websocket-connection-ccns.tentative.window-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-PRECONDITION_FAILED Testing BFCache support for page with closed WebSocket connection and "Cache-Control: no-store" header. BFCache not supported.
+[PRECONDITION_FAILED] Testing BFCache support for page with closed WebSocket connection and "Cache-Control: no-store" header.
+  BFCache not supported.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/back-forward-cache-with-open-websocket-connection-ccns.tentative.window-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/back-forward-cache-with-open-websocket-connection-ccns.tentative.window-expected.txt
index d8c0770..e35106d 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/back-forward-cache-with-open-websocket-connection-ccns.tentative.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/back-forward-cache-with-open-websocket-connection-ccns.tentative.window-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-PRECONDITION_FAILED Testing BFCache support for page with open WebSocket connection and "Cache-Control: no-store" header. BFCache not supported.
+[PRECONDITION_FAILED] Testing BFCache support for page with open WebSocket connection and "Cache-Control: no-store" header.
+  BFCache not supported.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.serviceworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.serviceworker_wpt_flags=h2-expected.txt
index 97ce540..406a7ff7 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.serviceworker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.serviceworker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL HTTP basic authentication should work with WebSockets assert_unreached: open should succeed Reached unreachable code
+[FAIL] HTTP basic authentication should work with WebSockets
+  assert_unreached: open should succeed Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.sharedworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.sharedworker_wpt_flags=h2-expected.txt
index 97ce540..406a7ff7 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.sharedworker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.sharedworker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL HTTP basic authentication should work with WebSockets assert_unreached: open should succeed Reached unreachable code
+[FAIL] HTTP basic authentication should work with WebSockets
+  assert_unreached: open should succeed Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.worker_wpt_flags=h2-expected.txt
index 97ce540..406a7ff7 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL HTTP basic authentication should work with WebSockets assert_unreached: open should succeed Reached unreachable code
+[FAIL] HTTP basic authentication should work with WebSockets
+  assert_unreached: open should succeed Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any_wpt_flags=h2-expected.txt
index 97ce540..406a7ff7 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL HTTP basic authentication should work with WebSockets assert_unreached: open should succeed Reached unreachable code
+[FAIL] HTTP basic authentication should work with WebSockets
+  assert_unreached: open should succeed Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/bufferedAmount-unchanged-by-sync-xhr.any.sharedworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/bufferedAmount-unchanged-by-sync-xhr.any.sharedworker_wpt_flags=h2-expected.txt
index 638bdf45..bdefc8a 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/bufferedAmount-unchanged-by-sync-xhr.any.sharedworker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/bufferedAmount-unchanged-by-sync-xhr.any.sharedworker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL bufferedAmount should not be updated during a sync XHR assert_unreached: open should succeed Reached unreachable code
+[FAIL] bufferedAmount should not be updated during a sync XHR
+  assert_unreached: open should succeed Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/bufferedAmount-unchanged-by-sync-xhr.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/bufferedAmount-unchanged-by-sync-xhr.any.worker_wpt_flags=h2-expected.txt
index 638bdf45..bdefc8a 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/bufferedAmount-unchanged-by-sync-xhr.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/bufferedAmount-unchanged-by-sync-xhr.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL bufferedAmount should not be updated during a sync XHR assert_unreached: open should succeed Reached unreachable code
+[FAIL] bufferedAmount should not be updated during a sync XHR
+  assert_unreached: open should succeed Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/bufferedAmount-unchanged-by-sync-xhr.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/bufferedAmount-unchanged-by-sync-xhr.any_wpt_flags=h2-expected.txt
index 638bdf45..bdefc8a 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/bufferedAmount-unchanged-by-sync-xhr.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/bufferedAmount-unchanged-by-sync-xhr.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL bufferedAmount should not be updated during a sync XHR assert_unreached: open should succeed Reached unreachable code
+[FAIL] bufferedAmount should not be updated during a sync XHR
+  assert_unreached: open should succeed Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/closing-handshake/002_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/closing-handshake/002_wpt_flags=h2-expected.txt
index ccb3a2e..d7b469e 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/closing-handshake/002_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/closing-handshake/002_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: server sends closing handshake assert_unreached: Reached unreachable code
+[FAIL] WebSockets: server sends closing handshake
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/closing-handshake/003_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/closing-handshake/003_wpt_flags=h2-expected.txt
index 9fd9e49..a2a65a9 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/closing-handshake/003_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/closing-handshake/003_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: client sends closing handshake assert_unreached: Reached unreachable code
+[FAIL] WebSockets: client sends closing handshake
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/closing-handshake/004_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/closing-handshake/004_wpt_flags=h2-expected.txt
index c9026b54..6187d5f 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/closing-handshake/004_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/closing-handshake/004_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: data after closing handshake assert_unreached: Reached unreachable code
+[FAIL] WebSockets: data after closing handshake
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/constructor/002-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/constructor/002-expected.txt
deleted file mode 100644
index 283195c..0000000
--- a/third_party/blink/web_tests/external/wpt/websockets/constructor/002-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS WebSockets: new WebSocket(invalid url)
-FAIL WebSockets: new WebSocket(invalid url) 1 assert_throws_dom: function "function(){new WebSocket("ws://foo bar.com/")}" did not throw
-FAIL WebSockets: new WebSocket(invalid url) 2 assert_throws_dom: function "function(){new WebSocket("wss://foo bar.com/")}" did not throw
-PASS WebSockets: new WebSocket(invalid url) 3
-PASS WebSockets: new WebSocket(invalid url) 4
-PASS WebSockets: new WebSocket(invalid url) 5
-PASS WebSockets: new WebSocket(invalid url) 6
-PASS WebSockets: new WebSocket(invalid url) 7
-PASS WebSockets: new WebSocket(invalid url) 8
-PASS WebSockets: new WebSocket(invalid url) 9
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/websockets/constructor/002_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/constructor/002_wpt_flags=h2-expected.txt
deleted file mode 100644
index 283195c..0000000
--- a/third_party/blink/web_tests/external/wpt/websockets/constructor/002_wpt_flags=h2-expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-This is a testharness.js-based test.
-PASS WebSockets: new WebSocket(invalid url)
-FAIL WebSockets: new WebSocket(invalid url) 1 assert_throws_dom: function "function(){new WebSocket("ws://foo bar.com/")}" did not throw
-FAIL WebSockets: new WebSocket(invalid url) 2 assert_throws_dom: function "function(){new WebSocket("wss://foo bar.com/")}" did not throw
-PASS WebSockets: new WebSocket(invalid url) 3
-PASS WebSockets: new WebSocket(invalid url) 4
-PASS WebSockets: new WebSocket(invalid url) 5
-PASS WebSockets: new WebSocket(invalid url) 6
-PASS WebSockets: new WebSocket(invalid url) 7
-PASS WebSockets: new WebSocket(invalid url) 8
-PASS WebSockets: new WebSocket(invalid url) 9
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/websockets/constructor/006_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/constructor/006_wpt_flags=h2-expected.txt
index 0ad976a4..700b4a31 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/constructor/006_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/constructor/006_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: converting first arguments assert_unreached: Reached unreachable code
+[FAIL] WebSockets: converting first arguments
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/constructor/009_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/constructor/009_wpt_flags=h2-expected.txt
index 31ce2c6..02d6bc5 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/constructor/009_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/constructor/009_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: protocol assert_unreached: Reached unreachable code
+[FAIL] WebSockets: protocol
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/constructor/013_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/constructor/013_wpt_flags=h2-expected.txt
index f78e8dd..fde1f32 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/constructor/013_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/constructor/013_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: multiple WebSocket objects assert_unreached: Reached unreachable code
+[FAIL] WebSockets: multiple WebSocket objects
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/constructor/016_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/constructor/016_wpt_flags=h2-expected.txt
index fc4a33f..8d310634 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/constructor/016_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/constructor/016_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: non-ascii URL in query, document encoding windows-1252 assert_unreached: Reached unreachable code
+[FAIL] WebSockets: non-ascii URL in query, document encoding windows-1252
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/constructor/018_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/constructor/018_wpt_flags=h2-expected.txt
index 4b45235..6516b7f 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/constructor/018_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/constructor/018_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: NULL char in url assert_unreached: error Reached unreachable code
+[FAIL] WebSockets: NULL char in url
+  assert_unreached: error Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/constructor/019_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/constructor/019_wpt_flags=h2-expected.txt
index 887475f..9d14ea73 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/constructor/019_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/constructor/019_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: uppercase 'WS:' assert_unreached: Reached unreachable code
+[FAIL] WebSockets: uppercase 'WS:'
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/constructor/020_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/constructor/020_wpt_flags=h2-expected.txt
index 0fc1ac2f..fe914fbd 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/constructor/020_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/constructor/020_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: uppercase host assert_unreached: Reached unreachable code
+[FAIL] WebSockets: uppercase host
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/constructor/022_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/constructor/022_wpt_flags=h2-expected.txt
index f9ebad13..e449b751 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/constructor/022_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/constructor/022_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: protocol array assert_unreached: Reached unreachable code
+[FAIL] WebSockets: protocol array
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/cookies/001_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/cookies/001_wpt_flags=h2-expected.txt
index 5c10cb5..642c826 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/cookies/001_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/cookies/001_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: Cookie in request assert_unreached: error Reached unreachable code
+[FAIL] WebSockets: Cookie in request
+  assert_unreached: error Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/cookies/002_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/cookies/002_wpt_flags=h2-expected.txt
index ae76b8d..b993c25 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/cookies/002_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/cookies/002_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: Set-Cookie in response assert_unreached: error Reached unreachable code
+[FAIL] WebSockets: Set-Cookie in response
+  assert_unreached: error Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/cookies/003_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/cookies/003_wpt_flags=h2-expected.txt
index 45c8430..2b19e10 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/cookies/003_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/cookies/003_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: sending HttpOnly cookies in ws request assert_unreached: error Reached unreachable code
+[FAIL] WebSockets: sending HttpOnly cookies in ws request
+  assert_unreached: error Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/cookies/006_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/cookies/006_wpt_flags=h2-expected.txt
index 43826ac..c60b34a5 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/cookies/006_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/cookies/006_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: setting Secure cookie with document.cookie, checking ws request assert_unreached: error Reached unreachable code
+[FAIL] WebSockets: setting Secure cookie with document.cookie, checking ws request
+  assert_unreached: error Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/cookies/006_wss_wpt_flags=https-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/cookies/006_wss_wpt_flags=https-expected.txt
index 5cd37f41..07c06008 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/cookies/006_wss_wpt_flags=https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/cookies/006_wss_wpt_flags=https-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: setting Secure cookie with document.cookie, checking ws request assert_true: cookie should have been visible to wss expected true got false
+[FAIL] WebSockets: setting Secure cookie with document.cookie, checking ws request
+  assert_true: cookie should have been visible to wss expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/cookies/007_default-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/cookies/007_default-expected.txt
index 31f81ab..2c57697 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/cookies/007_default-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/cookies/007_default-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: when to process set-cookie fields in ws response assert_unreached: cookie was set during script execution Reached unreachable code
+[FAIL] WebSockets: when to process set-cookie fields in ws response
+  assert_unreached: cookie was set during script execution Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/cookies/007_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/cookies/007_wpt_flags=h2-expected.txt
index 292e013..b89fbc3 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/cookies/007_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/cookies/007_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: when to process set-cookie fields in ws response assert_unreached: Reached unreachable code
+[FAIL] WebSockets: when to process set-cookie fields in ws response
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/cookies/007_wss-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/cookies/007_wss-expected.txt
deleted file mode 100644
index 31f81ab..0000000
--- a/third_party/blink/web_tests/external/wpt/websockets/cookies/007_wss-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL WebSockets: when to process set-cookie fields in ws response assert_unreached: cookie was set during script execution Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/websockets/interfaces/CloseEvent/clean-close_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/interfaces/CloseEvent/clean-close_wpt_flags=h2-expected.txt
index 828cd2f..fdce3d1 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/interfaces/CloseEvent/clean-close_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/interfaces/CloseEvent/clean-close_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: wasClean, true assert_equals: expected true but got false
+[FAIL] WebSockets: wasClean, true
+  assert_equals: expected true but got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-getting_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-getting_wpt_flags=h2-expected.txt
index 0eef06727..6a40c7a 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-getting_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-getting_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: bufferedAmount after send()ing assert_unreached: Reached unreachable code
+[FAIL] WebSockets: bufferedAmount after send()ing
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-unicode_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-unicode_wpt_flags=h2-expected.txt
index 5defd884..66d2aa61 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-unicode_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-unicode_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: bufferedAmount for unicode data assert_unreached: close event should not fire Reached unreachable code
+[FAIL] WebSockets: bufferedAmount for unicode data
+  assert_unreached: close event should not fire Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/events/016_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/events/016_wpt_flags=h2-expected.txt
index d7808b6..69578b9 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/events/016_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/events/016_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: addEventListener assert_equals: expected 7 but got 1
+[FAIL] WebSockets: addEventListener
+  assert_equals: expected 7 but got 1
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/events/018_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/events/018_wpt_flags=h2-expected.txt
index bb4458e..2a0e7953 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/events/018_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/events/018_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL open, message, error and close events assert_true: open event should fire expected true got false
+[FAIL] open, message, error and close events
+  assert_true: open event should fire expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/007_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/007_wpt_flags=h2-expected.txt
index 00923e854..9f254bc 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/007_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/007_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: close() followed by send() assert_unreached: Reached unreachable code
+[FAIL] WebSockets: close() followed by send()
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/009_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/009_wpt_flags=h2-expected.txt
index 1b093bb..7c04a7f 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/009_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/009_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: send('') assert_unreached: Reached unreachable code
+[FAIL] WebSockets: send('')
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/011_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/011_wpt_flags=h2-expected.txt
index bf6f468..9f5433b 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/011_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/011_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: sending non-ascii, combining chars and non-BMP assert_unreached: Reached unreachable code
+[FAIL] WebSockets: sending non-ascii, combining chars and non-BMP
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/012_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/012_wpt_flags=h2-expected.txt
index 13975df1..87f71c2a 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/012_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/interfaces/WebSocket/send/012_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: sending null assert_unreached: Reached unreachable code
+[FAIL] WebSockets: sending null
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/keeping-connection-open/001_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/keeping-connection-open/001_wpt_flags=h2-expected.txt
index 52f298c1..cf854c4 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/keeping-connection-open/001_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/keeping-connection-open/001_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: 20s inactivity after handshake assert_unreached: Reached unreachable code
+[FAIL] WebSockets: 20s inactivity after handshake
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/mixed-content.https.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/mixed-content.https.any.sharedworker-expected.txt
index bfe2474..5c182f772 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/mixed-content.https.any.sharedworker-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/mixed-content.https.any.sharedworker-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL constructing an insecure WebSocket in a secure context should throw assert_throws_dom: constructor should throw function "() => CreateInsecureWebSocket()" did not throw
+[FAIL] constructing an insecure WebSocket in a secure context should throw
+  assert_throws_dom: constructor should throw function "() => CreateInsecureWebSocket()" did not throw
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/multi-globals/url-parsing/url-parsing-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/multi-globals/url-parsing/url-parsing-expected.txt
index 4b8e0fb..101896de 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/multi-globals/url-parsing/url-parsing-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/multi-globals/url-parsing/url-parsing-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Multiple globals for base URL in WebSocket constructor Failed to construct 'WebSocket': The URL 'foo' is invalid.
+[FAIL] Multiple globals for base URL in WebSocket constructor
+  Failed to construct 'WebSocket': The URL 'foo' is invalid.
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/opening-handshake/002_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/opening-handshake/002_wpt_flags=h2-expected.txt
index fbd87785..664b724 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/opening-handshake/002_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/opening-handshake/002_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: valid handshake assert_unreached: Reached unreachable code
+[FAIL] WebSockets: valid handshake
+  assert_unreached: Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any.serviceworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any.serviceworker_wpt_flags=h2-expected.txt
index f589fdd4..349eb1a0 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any.serviceworker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any.serviceworker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL sending 50 messages of size 65536 with backpressure applied should not hang assert_true: connection should have been opened expected true got false
+[FAIL] sending 50 messages of size 65536 with backpressure applied should not hang
+  assert_true: connection should have been opened expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any.sharedworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any.sharedworker_wpt_flags=h2-expected.txt
index f589fdd4..349eb1a0 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any.sharedworker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any.sharedworker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL sending 50 messages of size 65536 with backpressure applied should not hang assert_true: connection should have been opened expected true got false
+[FAIL] sending 50 messages of size 65536 with backpressure applied should not hang
+  assert_true: connection should have been opened expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any.worker_wpt_flags=h2-expected.txt
index f589fdd4..349eb1a0 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL sending 50 messages of size 65536 with backpressure applied should not hang assert_true: connection should have been opened expected true got false
+[FAIL] sending 50 messages of size 65536 with backpressure applied should not hang
+  assert_true: connection should have been opened expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any_wpt_flags=h2-expected.txt
index f589fdd4..349eb1a0 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/send-many-64K-messages-with-backpressure.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL sending 50 messages of size 65536 with backpressure applied should not hang assert_true: connection should have been opened expected true got false
+[FAIL] sending 50 messages of size 65536 with backpressure applied should not hang
+  assert_true: connection should have been opened expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any.serviceworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any.serviceworker_wpt_flags=h2-expected.txt
index dc14c81..c272749 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any.serviceworker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any.serviceworker_wpt_flags=h2-expected.txt
@@ -1,6 +1,7 @@
 This is a testharness.js-based test.
-PASS abort before constructing should prevent connection
-PASS abort during handshake should work
-FAIL abort after connect should do nothing promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] abort before constructing should prevent connection
+[PASS] abort during handshake should work
+[FAIL] abort after connect should do nothing
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any.sharedworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any.sharedworker_wpt_flags=h2-expected.txt
index dc14c81..c272749 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any.sharedworker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any.sharedworker_wpt_flags=h2-expected.txt
@@ -1,6 +1,7 @@
 This is a testharness.js-based test.
-PASS abort before constructing should prevent connection
-PASS abort during handshake should work
-FAIL abort after connect should do nothing promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] abort before constructing should prevent connection
+[PASS] abort during handshake should work
+[FAIL] abort after connect should do nothing
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any.worker_wpt_flags=h2-expected.txt
index dc14c81..c272749 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any.worker_wpt_flags=h2-expected.txt
@@ -1,6 +1,7 @@
 This is a testharness.js-based test.
-PASS abort before constructing should prevent connection
-PASS abort during handshake should work
-FAIL abort after connect should do nothing promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] abort before constructing should prevent connection
+[PASS] abort during handshake should work
+[FAIL] abort after connect should do nothing
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any_wpt_flags=h2-expected.txt
index dc14c81..c272749 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/abort.any_wpt_flags=h2-expected.txt
@@ -1,6 +1,7 @@
 This is a testharness.js-based test.
-PASS abort before constructing should prevent connection
-PASS abort during handshake should work
-FAIL abort after connect should do nothing promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] abort before constructing should prevent connection
+[PASS] abort during handshake should work
+[FAIL] abort after connect should do nothing
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any.serviceworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any.serviceworker_wpt_flags=h2-expected.txt
deleted file mode 100644
index f6919e9..0000000
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any.serviceworker_wpt_flags=h2-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL backpressure should be applied to received messages promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any.sharedworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any.sharedworker_wpt_flags=h2-expected.txt
index f6919e9..9db766c0 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any.sharedworker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any.sharedworker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL backpressure should be applied to received messages promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[FAIL] backpressure should be applied to received messages
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any.worker_wpt_flags=h2-expected.txt
index f6919e9..9db766c0 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL backpressure should be applied to received messages promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[FAIL] backpressure should be applied to received messages
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any_wpt_flags=h2-expected.txt
index f6919e9..9db766c0 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-receive.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL backpressure should be applied to received messages promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[FAIL] backpressure should be applied to received messages
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-send.any.sharedworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-send.any.sharedworker_wpt_flags=h2-expected.txt
index f453bf19e..3e27615 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-send.any.sharedworker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-send.any.sharedworker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL backpressure should be applied to sent messages promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[FAIL] backpressure should be applied to sent messages
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-send.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-send.any.worker_wpt_flags=h2-expected.txt
index f453bf19e..3e27615 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-send.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-send.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL backpressure should be applied to sent messages promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[FAIL] backpressure should be applied to sent messages
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-send.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-send.any_wpt_flags=h2-expected.txt
index f453bf19e..3e27615 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-send.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-send.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL backpressure should be applied to sent messages promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[FAIL] backpressure should be applied to sent messages
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any.serviceworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any.serviceworker_wpt_flags=h2-expected.txt
index 1841a3de..32c34ab 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any.serviceworker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any.serviceworker_wpt_flags=h2-expected.txt
@@ -1,12 +1,15 @@
 This is a testharness.js-based test.
 Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: A network error occurred
-PASS constructing with no URL should throw
-PASS constructing with an invalid URL should throw
-PASS constructing with invalid options should throw
-PASS protocols should be required to be a list
-FAIL constructing with a valid URL should work promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
-FAIL setting a protocol in the constructor should work promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
-PASS connection failure should reject the promises
-FAIL wss.opened should resolve to the right types promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] constructing with no URL should throw
+[PASS] constructing with an invalid URL should throw
+[PASS] constructing with invalid options should throw
+[PASS] protocols should be required to be a list
+[FAIL] constructing with a valid URL should work
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[FAIL] setting a protocol in the constructor should work
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] connection failure should reject the promises
+[FAIL] wss.opened should resolve to the right types
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any.sharedworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any.sharedworker_wpt_flags=h2-expected.txt
index 1841a3de..32c34ab 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any.sharedworker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any.sharedworker_wpt_flags=h2-expected.txt
@@ -1,12 +1,15 @@
 This is a testharness.js-based test.
 Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: A network error occurred
-PASS constructing with no URL should throw
-PASS constructing with an invalid URL should throw
-PASS constructing with invalid options should throw
-PASS protocols should be required to be a list
-FAIL constructing with a valid URL should work promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
-FAIL setting a protocol in the constructor should work promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
-PASS connection failure should reject the promises
-FAIL wss.opened should resolve to the right types promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] constructing with no URL should throw
+[PASS] constructing with an invalid URL should throw
+[PASS] constructing with invalid options should throw
+[PASS] protocols should be required to be a list
+[FAIL] constructing with a valid URL should work
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[FAIL] setting a protocol in the constructor should work
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] connection failure should reject the promises
+[FAIL] wss.opened should resolve to the right types
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any.worker_wpt_flags=h2-expected.txt
index 1841a3de..32c34ab 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any.worker_wpt_flags=h2-expected.txt
@@ -1,12 +1,15 @@
 This is a testharness.js-based test.
 Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: A network error occurred
-PASS constructing with no URL should throw
-PASS constructing with an invalid URL should throw
-PASS constructing with invalid options should throw
-PASS protocols should be required to be a list
-FAIL constructing with a valid URL should work promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
-FAIL setting a protocol in the constructor should work promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
-PASS connection failure should reject the promises
-FAIL wss.opened should resolve to the right types promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] constructing with no URL should throw
+[PASS] constructing with an invalid URL should throw
+[PASS] constructing with invalid options should throw
+[PASS] protocols should be required to be a list
+[FAIL] constructing with a valid URL should work
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[FAIL] setting a protocol in the constructor should work
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] connection failure should reject the promises
+[FAIL] wss.opened should resolve to the right types
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any_wpt_flags=h2-expected.txt
index 1841a3de..32c34ab 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/constructor.any_wpt_flags=h2-expected.txt
@@ -1,12 +1,15 @@
 This is a testharness.js-based test.
 Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: A network error occurred
-PASS constructing with no URL should throw
-PASS constructing with an invalid URL should throw
-PASS constructing with invalid options should throw
-PASS protocols should be required to be a list
-FAIL constructing with a valid URL should work promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
-FAIL setting a protocol in the constructor should work promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
-PASS connection failure should reject the promises
-FAIL wss.opened should resolve to the right types promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] constructing with no URL should throw
+[PASS] constructing with an invalid URL should throw
+[PASS] constructing with invalid options should throw
+[PASS] protocols should be required to be a list
+[FAIL] constructing with a valid URL should work
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[FAIL] setting a protocol in the constructor should work
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] connection failure should reject the promises
+[FAIL] wss.opened should resolve to the right types
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/001_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/001_wpt_flags=h2-expected.txt
index aa0c1e5..9a20095a 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/001_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/001_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: navigating top-level browsing context assert_unreached: Got unexpected event error Reached unreachable code
+[FAIL] WebSockets: navigating top-level browsing context
+  assert_unreached: Got unexpected event error Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/002_default-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/002_default-expected.txt
index 1da3d918..c69e6b0 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/002_default-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/002_default-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: navigating top-level browsing context with closed websocket assert_unreached: document was discarded Reached unreachable code
+[FAIL] WebSockets: navigating top-level browsing context with closed websocket
+  assert_unreached: document was discarded Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/002_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/002_wpt_flags=h2-expected.txt
index 186cb19..0d29f4b 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/002_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/002_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: navigating top-level browsing context with closed websocket assert_unreached: Got unexpected event error Reached unreachable code
+[FAIL] WebSockets: navigating top-level browsing context with closed websocket
+  assert_unreached: Got unexpected event error Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/002_wss-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/002_wss-expected.txt
deleted file mode 100644
index 99bc355..0000000
--- a/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/002_wss-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL WebSockets: navigating top-level browsing context with closed websocket SCHEME_DOMAIN_PORT is not defined
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/004-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/004-expected.txt
index 108c294c..acbbbc4a 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/004-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/004-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: navigating nested browsing context with closed websocket assert_unreached: document was discarded Reached unreachable code
+[FAIL] WebSockets: navigating nested browsing context with closed websocket
+  assert_unreached: document was discarded Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/005_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/005_wpt_flags=h2-expected.txt
index 3092338..34118a8b 100644
--- a/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/005_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/websockets/unload-a-document/005_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: navigating nested browsing context with a websocket in top-level assert_unreached: Got unexpected event error Reached unreachable code
+[FAIL] WebSockets: navigating nested browsing context with a websocket in top-level
+  assert_unreached: Got unexpected event error Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/fast/css/fontfaceset-check-platform-fonts.html b/third_party/blink/web_tests/fast/css/fontfaceset-check-platform-fonts.html
index 81473a4..393178f 100644
--- a/third_party/blink/web_tests/fast/css/fontfaceset-check-platform-fonts.html
+++ b/third_party/blink/web_tests/fast/css/fontfaceset-check-platform-fonts.html
@@ -5,10 +5,10 @@
 
 test(() => {
   assert_true(document.fonts.check('10px Arial'), 'Arial');
-  assert_false(document.fonts.check('10px Nonexistent'), 'Nonexistent');
+  assert_true(document.fonts.check('10px Nonexistent'), 'Nonexistent');
   assert_true(document.fonts.check('10px sans-serif'), 'sans-serif');
   assert_true(document.fonts.check('10px Nonexistent, monospace'), 'Nonexistent, monospace');
-  assert_false(document.fonts.check('10px Nonexistent1, Nonexistent2'), 'Nonexistent1, Nonexistent2');
+  assert_true(document.fonts.check('10px Nonexistent1, Nonexistent2'), 'Nonexistent1, Nonexistent2');
 }, 'Tests FontFaceSet#check() returns true for platform fonts');
 
 </script>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/cross-site-redirect-chain-exclusion-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/cross-site-redirect-chain-exclusion-expected.txt
new file mode 100644
index 0000000..6fa818e
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/cross-site-redirect-chain-exclusion-expected.txt
@@ -0,0 +1,30 @@
+Verifies that after a cross-site redirect SameSite cookies file an Issue
+
+{
+    issue : {
+        code : CookieIssue
+        details : {
+            cookieIssueDetails : {
+                cookie : {
+                    domain : firstparty.test
+                    name : fooStrict
+                    path : /
+                }
+                cookieExclusionReasons : [
+                    [0] : ExcludeSameSiteStrict
+                ]
+                cookieUrl : https://firstparty.test:8443/inspector-protocol/resources/redirect-chain.html?end
+                cookieWarningReasons : [
+                    [0] : WarnCrossSiteRedirectDowngradeChangesInclusion
+                ]
+                operation : ReadCookie
+                request : {
+                    requestId : <string>
+                    url : https://firstparty.test:8443/inspector-protocol/resources/redirect-chain.html?end
+                }
+                siteForCookies : https://firstparty.test/
+            }
+        }
+    }
+}
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/cross-site-redirect-chain-exclusion.js b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/cross-site-redirect-chain-exclusion.js
new file mode 100644
index 0000000..90cb983
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/cross-site-redirect-chain-exclusion.js
@@ -0,0 +1,48 @@
+(async testRunner => {
+  // This test requires kCookieSameSiteConsidersRedirectChain to be enabled in order to pass.
+  const {page, session, dp} = await testRunner.startBlank(
+      `Verifies that after a cross-site redirect SameSite cookies file an Issue\n`);
+
+  await dp.Network.enable();
+  await dp.Audits.enable();
+
+  // Set the cookie.
+  const response = await dp.Network.setCookie({
+    url: 'https://firstparty.test:8443',
+    secure: true,
+    name: 'fooStrict',
+    value: 'bar',
+    sameSite: 'Strict',
+  });
+
+  if (response.error)
+    testRunner.log(`setCookie failed: ${response.error.message}`);
+
+  // Push events to arrays to prevent async races from causing flakes.
+  const requestWillBeSentExtraInfos = [];
+  let issueAdded;
+
+  const expectedRequests =
+      new Promise(resolve => dp.Network.onRequestWillBeSentExtraInfo(event => {
+        requestWillBeSentExtraInfos.push(event.params);
+        // There will be the first navigation -> redirect -> final navigation == 3
+        if (requestWillBeSentExtraInfos.length === 3) {
+          resolve();
+        }
+      }));
+
+  const expectedIssue = dp.Audits.onceIssueAdded(event => {
+    // Safely ignore irrelevant issue...
+    return event.params.issue.code !== 'QuirksModeIssue';
+  });
+
+  page.navigate(
+      'https://firstparty.test:8443/inspector-protocol/resources/redirect-chain.html?start');
+
+  await expectedRequests;
+
+  issueAdded = await expectedIssue;
+  testRunner.log(issueAdded.params);
+
+  testRunner.completeTest();
+});
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/back-from-prerender-crash-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/back-from-prerender-crash-expected.txt
new file mode 100644
index 0000000..b3269f8
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/back-from-prerender-crash-expected.txt
@@ -0,0 +1,19 @@
+Tests that we don't crash when navigating from pre-rendered page to BF-cached original page.
+{
+    sessionId : <string>
+    targetInfo : {
+        attached : true
+        browserContextId : <string>
+        canAccessOpener : false
+        subtype : prerender
+        targetId : <string>
+        title : 
+        type : page
+        url : 
+    }
+    waitingForDebugger : true
+}
+Navigation: http://devtools.oopif-a.test:8000/inspector-protocol/prerender/resources/empty.html
+Navigated to http://devtools.oopif-a.test:8000/inspector-protocol/prerender/resources/empty.html
+Now back to http://devtools.oopif-a.test:8000/inspector-protocol/prerender/resources/simple-prerender.html
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/back-from-prerender-crash.js b/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/back-from-prerender-crash.js
new file mode 100644
index 0000000..bf96147
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/prerender/back-from-prerender-crash.js
@@ -0,0 +1,55 @@
+(async function(testRunner) {
+  testRunner.log(`Tests that we don't crash when navigating from pre-rendered page to BF-cached original page.`);
+
+  const pageUrl = 'http://devtools.oopif-a.test:8000/inspector-protocol/prerender/resources/simple-prerender.html';
+
+  const bp = testRunner.browserP();
+
+  const params = {url: 'about:blank', forTab: true};
+  const tabTargetId = (await bp.Target.createTarget(params)).result.targetId;
+  const tabTargetSessionId =
+      (await bp.Target.attachToTarget({targetId: tabTargetId, flatten: true}))
+          .result.sessionId;
+  const tabTargetSession =
+      new TestRunner.Session(testRunner, tabTargetSessionId);
+  const tp = tabTargetSession.protocol;
+
+  const events = [];
+  tp.Target.onAttachedToTarget(event => {
+    events.push(event);
+  });
+  await tp.Target.setAutoAttach(
+      {autoAttach: true, waitForDebuggerOnStart: true, flatten: true});
+
+  const session = tabTargetSession.createChild(events[0].params.sessionId);
+
+  session.protocol.Page.enable();
+  session.protocol.Preload.enable();
+
+  const prerenderReady = session.protocol.Preload.oncePrerenderStatusUpdated(
+      e => e.params.status == 'Ready');
+  session.navigate(pageUrl);
+
+  const attached = (await tp.Target.onceAttachedToTarget()).params;
+  testRunner.log(attached);
+
+  // Attach to prerender target and make sure it navigates where it should.
+  const prerenderSession = testRunner.browserSession().createChild(attached.sessionId);
+  prerenderSession.protocol.Page.enable();
+  prerenderSession.protocol.Runtime.runIfWaitingForDebugger();
+  const navigated = (await prerenderSession.protocol.Page.onceFrameNavigated()).params;
+  testRunner.log(`${navigated.type}: ${navigated.frame.url}`);
+
+  await prerenderReady;
+
+  // Now activate prerender and make sure old target detaches.
+  session.evaluate(`document.getElementById('link').click()`);
+  await tp.Target.onceDetachedFromTarget();
+
+  testRunner.log(`Navigated to ${await prerenderSession.evaluate('location.href')}`);
+  prerenderSession.evaluate(`history.go(-1)`);
+  await prerenderSession.protocol.Page.onceFrameNavigated();
+  testRunner.log(`Now back to ${await prerenderSession.evaluate('location.href')}`);
+
+  testRunner.completeTest();
+});
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/resources/cross-site-redirect.php b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/cross-site-redirect.php
new file mode 100644
index 0000000..2aeaed55
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/cross-site-redirect.php
@@ -0,0 +1,8 @@
+<?php
+// Redirects back to the first party site.
+header('HTTP/1.1 307 Temporary Redirect');
+header('Expires: Thu, 01 Dec 2003 16:00:00 GMT');
+header('Cache-Control: no-cache, must-revalidate');
+header('Pragma: no-cache');
+header('Location: https://firstparty.test:8443/inspector-protocol/resources/redirect-chain.html?end');
+?>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/resources/redirect-chain.html b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/redirect-chain.html
new file mode 100644
index 0000000..2eb6305
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/redirect-chain.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <script>
+      const urlParams = new URLSearchParams(window.location.search);
+      if(urlParams.has("start")) {
+        window.location = "https://example.test:8443/inspector-protocol/resources/cross-site-redirect.php"
+      }
+    </script>
+  </body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
deleted file mode 100644
index d8073bf..0000000
--- a/third_party/blink/web_tests/platform/linux/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service worker controlled navigation timing assert_greater_than: workerStart marking should not wait for worker activation to finish expected a number greater than 1634042632175.5 but got 1634042632172.9001
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/websockets/Create-blocked-port.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/websockets/Create-blocked-port.any.worker_wpt_flags=h2-expected.txt
index 09e47e3..6757dcf8 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/websockets/Create-blocked-port.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/websockets/Create-blocked-port.any.worker_wpt_flags=h2-expected.txt
@@ -1,82 +1,83 @@
 This is a testharness.js-based test.
 Found 78 tests; 77 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
-FAIL Basic check assert_unreached: Reached unreachable code
-PASS WebSocket blocked port test 1
-PASS WebSocket blocked port test 7
-PASS WebSocket blocked port test 9
-PASS WebSocket blocked port test 11
-PASS WebSocket blocked port test 13
-PASS WebSocket blocked port test 15
-PASS WebSocket blocked port test 17
-PASS WebSocket blocked port test 19
-PASS WebSocket blocked port test 20
-PASS WebSocket blocked port test 21
-PASS WebSocket blocked port test 22
-PASS WebSocket blocked port test 23
-PASS WebSocket blocked port test 25
-PASS WebSocket blocked port test 37
-PASS WebSocket blocked port test 42
-PASS WebSocket blocked port test 43
-PASS WebSocket blocked port test 53
-PASS WebSocket blocked port test 69
-PASS WebSocket blocked port test 77
-PASS WebSocket blocked port test 79
-PASS WebSocket blocked port test 87
-PASS WebSocket blocked port test 95
-PASS WebSocket blocked port test 101
-PASS WebSocket blocked port test 102
-PASS WebSocket blocked port test 103
-PASS WebSocket blocked port test 104
-PASS WebSocket blocked port test 109
-PASS WebSocket blocked port test 110
-PASS WebSocket blocked port test 111
-PASS WebSocket blocked port test 113
-PASS WebSocket blocked port test 115
-PASS WebSocket blocked port test 117
-PASS WebSocket blocked port test 119
-PASS WebSocket blocked port test 123
-PASS WebSocket blocked port test 135
-PASS WebSocket blocked port test 137
-PASS WebSocket blocked port test 139
-PASS WebSocket blocked port test 143
-PASS WebSocket blocked port test 179
-PASS WebSocket blocked port test 389
-PASS WebSocket blocked port test 427
-PASS WebSocket blocked port test 465
-PASS WebSocket blocked port test 512
-PASS WebSocket blocked port test 513
-PASS WebSocket blocked port test 514
-PASS WebSocket blocked port test 515
-PASS WebSocket blocked port test 526
-PASS WebSocket blocked port test 530
-PASS WebSocket blocked port test 531
-PASS WebSocket blocked port test 532
-PASS WebSocket blocked port test 540
-PASS WebSocket blocked port test 548
-PASS WebSocket blocked port test 554
-PASS WebSocket blocked port test 556
-PASS WebSocket blocked port test 563
-PASS WebSocket blocked port test 587
-PASS WebSocket blocked port test 601
-PASS WebSocket blocked port test 636
-PASS WebSocket blocked port test 989
-PASS WebSocket blocked port test 990
-PASS WebSocket blocked port test 993
-PASS WebSocket blocked port test 995
-PASS WebSocket blocked port test 1719
-PASS WebSocket blocked port test 1720
-PASS WebSocket blocked port test 1723
-PASS WebSocket blocked port test 2049
-PASS WebSocket blocked port test 3659
-PASS WebSocket blocked port test 4045
-PASS WebSocket blocked port test 6000
-PASS WebSocket blocked port test 6566
-PASS WebSocket blocked port test 6665
-PASS WebSocket blocked port test 6666
-PASS WebSocket blocked port test 6667
-PASS WebSocket blocked port test 6668
-PASS WebSocket blocked port test 6669
-PASS WebSocket blocked port test 6697
-PASS WebSocket blocked port test 10080
+[FAIL] Basic check
+  assert_unreached: Reached unreachable code
+[PASS] WebSocket blocked port test 1
+[PASS] WebSocket blocked port test 7
+[PASS] WebSocket blocked port test 9
+[PASS] WebSocket blocked port test 11
+[PASS] WebSocket blocked port test 13
+[PASS] WebSocket blocked port test 15
+[PASS] WebSocket blocked port test 17
+[PASS] WebSocket blocked port test 19
+[PASS] WebSocket blocked port test 20
+[PASS] WebSocket blocked port test 21
+[PASS] WebSocket blocked port test 22
+[PASS] WebSocket blocked port test 23
+[PASS] WebSocket blocked port test 25
+[PASS] WebSocket blocked port test 37
+[PASS] WebSocket blocked port test 42
+[PASS] WebSocket blocked port test 43
+[PASS] WebSocket blocked port test 53
+[PASS] WebSocket blocked port test 69
+[PASS] WebSocket blocked port test 77
+[PASS] WebSocket blocked port test 79
+[PASS] WebSocket blocked port test 87
+[PASS] WebSocket blocked port test 95
+[PASS] WebSocket blocked port test 101
+[PASS] WebSocket blocked port test 102
+[PASS] WebSocket blocked port test 103
+[PASS] WebSocket blocked port test 104
+[PASS] WebSocket blocked port test 109
+[PASS] WebSocket blocked port test 110
+[PASS] WebSocket blocked port test 111
+[PASS] WebSocket blocked port test 113
+[PASS] WebSocket blocked port test 115
+[PASS] WebSocket blocked port test 117
+[PASS] WebSocket blocked port test 119
+[PASS] WebSocket blocked port test 123
+[PASS] WebSocket blocked port test 135
+[PASS] WebSocket blocked port test 137
+[PASS] WebSocket blocked port test 139
+[PASS] WebSocket blocked port test 143
+[PASS] WebSocket blocked port test 179
+[PASS] WebSocket blocked port test 389
+[PASS] WebSocket blocked port test 427
+[PASS] WebSocket blocked port test 465
+[PASS] WebSocket blocked port test 512
+[PASS] WebSocket blocked port test 513
+[PASS] WebSocket blocked port test 514
+[PASS] WebSocket blocked port test 515
+[PASS] WebSocket blocked port test 526
+[PASS] WebSocket blocked port test 530
+[PASS] WebSocket blocked port test 531
+[PASS] WebSocket blocked port test 532
+[PASS] WebSocket blocked port test 540
+[PASS] WebSocket blocked port test 548
+[PASS] WebSocket blocked port test 554
+[PASS] WebSocket blocked port test 556
+[PASS] WebSocket blocked port test 563
+[PASS] WebSocket blocked port test 587
+[PASS] WebSocket blocked port test 601
+[PASS] WebSocket blocked port test 636
+[PASS] WebSocket blocked port test 989
+[PASS] WebSocket blocked port test 990
+[PASS] WebSocket blocked port test 993
+[PASS] WebSocket blocked port test 995
+[PASS] WebSocket blocked port test 1719
+[PASS] WebSocket blocked port test 1720
+[PASS] WebSocket blocked port test 1723
+[PASS] WebSocket blocked port test 2049
+[PASS] WebSocket blocked port test 3659
+[PASS] WebSocket blocked port test 4045
+[PASS] WebSocket blocked port test 6000
+[PASS] WebSocket blocked port test 6566
+[PASS] WebSocket blocked port test 6665
+[PASS] WebSocket blocked port test 6666
+[PASS] WebSocket blocked port test 6667
+[PASS] WebSocket blocked port test 6668
+[PASS] WebSocket blocked port test 6669
+[PASS] WebSocket blocked port test 6697
+[PASS] WebSocket blocked port test 10080
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/websockets/Create-blocked-port.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/websockets/Create-blocked-port.any_wpt_flags=h2-expected.txt
index 09e47e3..6757dcf8 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/websockets/Create-blocked-port.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/websockets/Create-blocked-port.any_wpt_flags=h2-expected.txt
@@ -1,82 +1,83 @@
 This is a testharness.js-based test.
 Found 78 tests; 77 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
-FAIL Basic check assert_unreached: Reached unreachable code
-PASS WebSocket blocked port test 1
-PASS WebSocket blocked port test 7
-PASS WebSocket blocked port test 9
-PASS WebSocket blocked port test 11
-PASS WebSocket blocked port test 13
-PASS WebSocket blocked port test 15
-PASS WebSocket blocked port test 17
-PASS WebSocket blocked port test 19
-PASS WebSocket blocked port test 20
-PASS WebSocket blocked port test 21
-PASS WebSocket blocked port test 22
-PASS WebSocket blocked port test 23
-PASS WebSocket blocked port test 25
-PASS WebSocket blocked port test 37
-PASS WebSocket blocked port test 42
-PASS WebSocket blocked port test 43
-PASS WebSocket blocked port test 53
-PASS WebSocket blocked port test 69
-PASS WebSocket blocked port test 77
-PASS WebSocket blocked port test 79
-PASS WebSocket blocked port test 87
-PASS WebSocket blocked port test 95
-PASS WebSocket blocked port test 101
-PASS WebSocket blocked port test 102
-PASS WebSocket blocked port test 103
-PASS WebSocket blocked port test 104
-PASS WebSocket blocked port test 109
-PASS WebSocket blocked port test 110
-PASS WebSocket blocked port test 111
-PASS WebSocket blocked port test 113
-PASS WebSocket blocked port test 115
-PASS WebSocket blocked port test 117
-PASS WebSocket blocked port test 119
-PASS WebSocket blocked port test 123
-PASS WebSocket blocked port test 135
-PASS WebSocket blocked port test 137
-PASS WebSocket blocked port test 139
-PASS WebSocket blocked port test 143
-PASS WebSocket blocked port test 179
-PASS WebSocket blocked port test 389
-PASS WebSocket blocked port test 427
-PASS WebSocket blocked port test 465
-PASS WebSocket blocked port test 512
-PASS WebSocket blocked port test 513
-PASS WebSocket blocked port test 514
-PASS WebSocket blocked port test 515
-PASS WebSocket blocked port test 526
-PASS WebSocket blocked port test 530
-PASS WebSocket blocked port test 531
-PASS WebSocket blocked port test 532
-PASS WebSocket blocked port test 540
-PASS WebSocket blocked port test 548
-PASS WebSocket blocked port test 554
-PASS WebSocket blocked port test 556
-PASS WebSocket blocked port test 563
-PASS WebSocket blocked port test 587
-PASS WebSocket blocked port test 601
-PASS WebSocket blocked port test 636
-PASS WebSocket blocked port test 989
-PASS WebSocket blocked port test 990
-PASS WebSocket blocked port test 993
-PASS WebSocket blocked port test 995
-PASS WebSocket blocked port test 1719
-PASS WebSocket blocked port test 1720
-PASS WebSocket blocked port test 1723
-PASS WebSocket blocked port test 2049
-PASS WebSocket blocked port test 3659
-PASS WebSocket blocked port test 4045
-PASS WebSocket blocked port test 6000
-PASS WebSocket blocked port test 6566
-PASS WebSocket blocked port test 6665
-PASS WebSocket blocked port test 6666
-PASS WebSocket blocked port test 6667
-PASS WebSocket blocked port test 6668
-PASS WebSocket blocked port test 6669
-PASS WebSocket blocked port test 6697
-PASS WebSocket blocked port test 10080
+[FAIL] Basic check
+  assert_unreached: Reached unreachable code
+[PASS] WebSocket blocked port test 1
+[PASS] WebSocket blocked port test 7
+[PASS] WebSocket blocked port test 9
+[PASS] WebSocket blocked port test 11
+[PASS] WebSocket blocked port test 13
+[PASS] WebSocket blocked port test 15
+[PASS] WebSocket blocked port test 17
+[PASS] WebSocket blocked port test 19
+[PASS] WebSocket blocked port test 20
+[PASS] WebSocket blocked port test 21
+[PASS] WebSocket blocked port test 22
+[PASS] WebSocket blocked port test 23
+[PASS] WebSocket blocked port test 25
+[PASS] WebSocket blocked port test 37
+[PASS] WebSocket blocked port test 42
+[PASS] WebSocket blocked port test 43
+[PASS] WebSocket blocked port test 53
+[PASS] WebSocket blocked port test 69
+[PASS] WebSocket blocked port test 77
+[PASS] WebSocket blocked port test 79
+[PASS] WebSocket blocked port test 87
+[PASS] WebSocket blocked port test 95
+[PASS] WebSocket blocked port test 101
+[PASS] WebSocket blocked port test 102
+[PASS] WebSocket blocked port test 103
+[PASS] WebSocket blocked port test 104
+[PASS] WebSocket blocked port test 109
+[PASS] WebSocket blocked port test 110
+[PASS] WebSocket blocked port test 111
+[PASS] WebSocket blocked port test 113
+[PASS] WebSocket blocked port test 115
+[PASS] WebSocket blocked port test 117
+[PASS] WebSocket blocked port test 119
+[PASS] WebSocket blocked port test 123
+[PASS] WebSocket blocked port test 135
+[PASS] WebSocket blocked port test 137
+[PASS] WebSocket blocked port test 139
+[PASS] WebSocket blocked port test 143
+[PASS] WebSocket blocked port test 179
+[PASS] WebSocket blocked port test 389
+[PASS] WebSocket blocked port test 427
+[PASS] WebSocket blocked port test 465
+[PASS] WebSocket blocked port test 512
+[PASS] WebSocket blocked port test 513
+[PASS] WebSocket blocked port test 514
+[PASS] WebSocket blocked port test 515
+[PASS] WebSocket blocked port test 526
+[PASS] WebSocket blocked port test 530
+[PASS] WebSocket blocked port test 531
+[PASS] WebSocket blocked port test 532
+[PASS] WebSocket blocked port test 540
+[PASS] WebSocket blocked port test 548
+[PASS] WebSocket blocked port test 554
+[PASS] WebSocket blocked port test 556
+[PASS] WebSocket blocked port test 563
+[PASS] WebSocket blocked port test 587
+[PASS] WebSocket blocked port test 601
+[PASS] WebSocket blocked port test 636
+[PASS] WebSocket blocked port test 989
+[PASS] WebSocket blocked port test 990
+[PASS] WebSocket blocked port test 993
+[PASS] WebSocket blocked port test 995
+[PASS] WebSocket blocked port test 1719
+[PASS] WebSocket blocked port test 1720
+[PASS] WebSocket blocked port test 1723
+[PASS] WebSocket blocked port test 2049
+[PASS] WebSocket blocked port test 3659
+[PASS] WebSocket blocked port test 4045
+[PASS] WebSocket blocked port test 6000
+[PASS] WebSocket blocked port test 6566
+[PASS] WebSocket blocked port test 6665
+[PASS] WebSocket blocked port test 6666
+[PASS] WebSocket blocked port test 6667
+[PASS] WebSocket blocked port test 6668
+[PASS] WebSocket blocked port test 6669
+[PASS] WebSocket blocked port test 6697
+[PASS] WebSocket blocked port test 10080
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/websockets/Create-valid-url-protocol.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/websockets/Create-valid-url-protocol.any.worker_wpt_flags=h2-expected.txt
new file mode 100644
index 0000000..9c03591
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/websockets/Create-valid-url-protocol.any.worker_wpt_flags=h2-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Create WebSocket - Pass a valid URL and a protocol string - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/websockets/Send-unpaired-surrogates.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/websockets/Send-unpaired-surrogates.any_wpt_flags=h2-expected.txt
new file mode 100644
index 0000000..6558a55f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/websockets/Send-unpaired-surrogates.any_wpt_flags=h2-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Send unpaired surrogates on a WebSocket - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/linux/fast/hidpi/scrollbar-appearance-increase-device-scale-factor-expected.png b/third_party/blink/web_tests/platform/linux/fast/hidpi/scrollbar-appearance-increase-device-scale-factor-expected.png
index 8e10298..3bb10599 100644
--- a/third_party/blink/web_tests/platform/linux/fast/hidpi/scrollbar-appearance-increase-device-scale-factor-expected.png
+++ b/third_party/blink/web_tests/platform/linux/fast/hidpi/scrollbar-appearance-increase-device-scale-factor-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-mask-with-percentages-expected.png b/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-mask-with-percentages-expected.png
index f8ce3cc..d479ab8a 100644
--- a/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-mask-with-percentages-expected.png
+++ b/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-mask-with-percentages-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt
new file mode 100644
index 0000000..316a018
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+[PASS] Client.url of a blob URL worker should be a blob URL.
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
new file mode 100644
index 0000000..f4bff73a
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+[PASS] Test Clients.get() with window and worker clients
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt
new file mode 100644
index 0000000..5f913401
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[PASS] Test Clients.matchAll() with a blob URL worker client.
+[PASS] Test Clients.matchAll() with an uncontrolled blob URL worker client.
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt
new file mode 100644
index 0000000..6b4d04f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt
@@ -0,0 +1,6 @@
+This is a testharness.js-based test.
+[PASS] Top-level module loading should be intercepted by a service worker.
+[PASS] Static import should be intercepted by a service worker.
+[PASS] Dynamic import should be intercepted by a service worker.
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt
index 03b0f79..5139d49 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt
@@ -1,10 +1,14 @@
 This is a testharness.js-based test.
-FAIL Same-origin blob URL iframe should inherit service worker controller. assert_equals: blob URL iframe should inherit controller expected (string) "https://web-platform.test:8444/service-workers/service-worker/resources/local-url-inherit-controller-worker.js" but got (object) null
-FAIL Same-origin blob URL iframe should intercept fetch(). assert_equals: blob URL iframe should intercept fetch expected "intercepted" but got "var hello = \"world\";\n"
-FAIL Same-origin blob URL worker should inherit service worker controller. promise_test: Unhandled rejection with value: "Uncaught TypeError: Cannot read properties of undefined (reading 'controller')"
-PASS Same-origin blob URL worker should intercept fetch().
-PASS Data URL iframe should not intercept fetch().
-FAIL Data URL worker should not inherit service worker controller. promise_test: Unhandled rejection with value: "Uncaught TypeError: Cannot read properties of undefined (reading 'controller')"
-PASS Data URL worker should not intercept fetch().
+[FAIL] Same-origin blob URL iframe should inherit service worker controller.
+  assert_equals: blob URL iframe should inherit controller expected (string) "https://web-platform.test:8444/service-workers/service-worker/resources/local-url-inherit-controller-worker.js" but got (object) null
+[FAIL] Same-origin blob URL iframe should intercept fetch().
+  assert_equals: blob URL iframe should intercept fetch expected "intercepted" but got "var hello = \"world\";\n"
+[FAIL] Same-origin blob URL worker should inherit service worker controller.
+  promise_test: Unhandled rejection with value: "Uncaught TypeError: Cannot read properties of undefined (reading 'controller')"
+[PASS] Same-origin blob URL worker should intercept fetch().
+[PASS] Data URL iframe should not intercept fetch().
+[FAIL] Data URL worker should not inherit service worker controller.
+  promise_test: Unhandled rejection with value: "Uncaught TypeError: Cannot read properties of undefined (reading 'controller')"
+[PASS] Data URL worker should not intercept fetch().
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
deleted file mode 100644
index f1572277..0000000
--- a/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service worker controlled navigation timing assert_greater_than: workerStart marking should not wait for worker activation to finish expected a number greater than 1634041957803.2998 but got 1634041957802
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception-redirect.https-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception-redirect.https-expected.txt
new file mode 100644
index 0000000..30f217571
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception-redirect.https-expected.txt
@@ -0,0 +1,96 @@
+This is a testharness.js-based test.
+Found 66 tests; 40 PASS, 26 FAIL, 0 TIMEOUT, 0 NOTRUN.
+[PASS] initialize global state
+[FAIL] Case #1: network scope1->scope2 (classic DedicatedWorker)
+  assert_equals: expected "the worker script was served from network" but got "sw2 saw the request for the worker script"
+[FAIL] Case #1: network scope1->scope2 (module DedicatedWorker)
+  assert_equals: expected "the worker script was served from network" but got "sw2 saw the request for the worker script"
+[FAIL] Case #1: network scope1->scope2 (classic SharedWorker)
+  assert_equals: expected "the worker script was served from network" but got "sw2 saw the request for the worker script"
+[FAIL] Case #1: network scope1->scope2 (module SharedWorker)
+  assert_equals: expected "the worker script was served from network" but got "sw2 saw the request for the worker script"
+[PASS] Case #2: network scope1->out-scope (classic DedicatedWorker)
+[PASS] Case #2: network scope1->out-scope (module DedicatedWorker)
+[PASS] Case #2: network scope1->out-scope (classic SharedWorker)
+[PASS] Case #2: network scope1->out-scope (module SharedWorker)
+[PASS] Case #3: sw scope1->scope2 (classic DedicatedWorker)
+[PASS] Case #3: sw scope1->scope2 (module DedicatedWorker)
+[PASS] Case #3: sw scope1->scope2 (classic SharedWorker)
+[PASS] Case #3: sw scope1->scope2 (module SharedWorker)
+[PASS] Case #4: sw scope1->out-scope (classic DedicatedWorker)
+[PASS] Case #4: sw scope1->out-scope (module DedicatedWorker)
+[PASS] Case #4: sw scope1->out-scope (classic SharedWorker)
+[PASS] Case #4: sw scope1->out-scope (module SharedWorker)
+[PASS] cleanup global state
+[FAIL] Case #1: network scope1->scope2 (classic DedicatedWorker, importScripts())
+  assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/scope2/import-scripts-echo.py" but got "sw2 saw importScripts from the worker: /service-workers/service-worker/resources/subdir/import-scripts-echo.py"
+[FAIL] Case #1: network scope1->scope2 (classic DedicatedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): sw2 saw the fetch from the worker: /service-workers/service-worker/resources/subdir/simple.txt"
+[FAIL] Case #1: network scope1->scope2 (classic DedicatedWorker, location.href)
+  assert_equals: location.href expected "https://web-platform.test:8444/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py?greeting=sw2%20saw%20the%20request%20for%20the%20worker%20script"
+[PASS] Case #1: network scope1->scope2 (module DedicatedWorker, importScripts())
+[FAIL] Case #1: network scope1->scope2 (module DedicatedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): sw2 saw the fetch from the worker: /service-workers/service-worker/resources/subdir/simple.txt"
+[FAIL] Case #1: network scope1->scope2 (module DedicatedWorker, location.href)
+  assert_equals: location.href expected "https://web-platform.test:8444/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py?greeting=sw2%20saw%20the%20request%20for%20the%20worker%20script"
+[FAIL] Case #1: network scope1->scope2 (classic SharedWorker, importScripts())
+  assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/scope2/import-scripts-echo.py" but got "sw2 saw importScripts from the worker: /service-workers/service-worker/resources/subdir/import-scripts-echo.py"
+[FAIL] Case #1: network scope1->scope2 (classic SharedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): sw2 saw the fetch from the worker: /service-workers/service-worker/resources/subdir/simple.txt"
+[FAIL] Case #1: network scope1->scope2 (classic SharedWorker, location.href)
+  assert_equals: location.href expected "https://web-platform.test:8444/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py?greeting=sw2%20saw%20the%20request%20for%20the%20worker%20script"
+[PASS] Case #1: network scope1->scope2 (module SharedWorker, importScripts())
+[FAIL] Case #1: network scope1->scope2 (module SharedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): sw2 saw the fetch from the worker: /service-workers/service-worker/resources/subdir/simple.txt"
+[FAIL] Case #1: network scope1->scope2 (module SharedWorker, location.href)
+  assert_equals: location.href expected "https://web-platform.test:8444/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py?greeting=sw2%20saw%20the%20request%20for%20the%20worker%20script"
+[FAIL] Case #2: network scope1->out-scope (classic DedicatedWorker, importScripts())
+  assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/import-scripts-echo.py" but got "importScripts: served from network"
+[FAIL] Case #2: network scope1->out-scope (classic DedicatedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
+[PASS] Case #2: network scope1->out-scope (classic DedicatedWorker, location.href)
+[PASS] Case #2: network scope1->out-scope (module DedicatedWorker, importScripts())
+[FAIL] Case #2: network scope1->out-scope (module DedicatedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
+[PASS] Case #2: network scope1->out-scope (module DedicatedWorker, location.href)
+[FAIL] Case #2: network scope1->out-scope (classic SharedWorker, importScripts())
+  assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/import-scripts-echo.py" but got "importScripts: served from network"
+[FAIL] Case #2: network scope1->out-scope (classic SharedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
+[PASS] Case #2: network scope1->out-scope (classic SharedWorker, location.href)
+[PASS] Case #2: network scope1->out-scope (module SharedWorker, importScripts())
+[FAIL] Case #2: network scope1->out-scope (module SharedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
+[PASS] Case #2: network scope1->out-scope (module SharedWorker, location.href)
+[PASS] Case #3: sw scope1->scope2 (classic DedicatedWorker, importScripts())
+[PASS] Case #3: sw scope1->scope2 (classic DedicatedWorker, fetch())
+[PASS] Case #3: sw scope1->scope2 (classic DedicatedWorker, location.href)
+[PASS] Case #3: sw scope1->scope2 (module DedicatedWorker, importScripts())
+[PASS] Case #3: sw scope1->scope2 (module DedicatedWorker, fetch())
+[PASS] Case #3: sw scope1->scope2 (module DedicatedWorker, location.href)
+[PASS] Case #3: sw scope1->scope2 (classic SharedWorker, importScripts())
+[PASS] Case #3: sw scope1->scope2 (classic SharedWorker, fetch())
+[PASS] Case #3: sw scope1->scope2 (classic SharedWorker, location.href)
+[PASS] Case #3: sw scope1->scope2 (module SharedWorker, importScripts())
+[PASS] Case #3: sw scope1->scope2 (module SharedWorker, fetch())
+[PASS] Case #3: sw scope1->scope2 (module SharedWorker, location.href)
+[FAIL] Case #4: sw scope1->out-scope (classic DedicatedWorker, importScripts())
+  assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/import-scripts-echo.py" but got "importScripts: served from network"
+[FAIL] Case #4: sw scope1->out-scope (classic DedicatedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
+[PASS] Case #4: sw scope1->out-scope (classic DedicatedWorker, location.href)
+[PASS] Case #4: sw scope1->out-scope (module DedicatedWorker, importScripts())
+[FAIL] Case #4: sw scope1->out-scope (module DedicatedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
+[PASS] Case #4: sw scope1->out-scope (module DedicatedWorker, location.href)
+[FAIL] Case #4: sw scope1->out-scope (classic SharedWorker, importScripts())
+  assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/import-scripts-echo.py" but got "importScripts: served from network"
+[FAIL] Case #4: sw scope1->out-scope (classic SharedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
+[PASS] Case #4: sw scope1->out-scope (classic SharedWorker, location.href)
+[PASS] Case #4: sw scope1->out-scope (module SharedWorker, importScripts())
+[FAIL] Case #4: sw scope1->out-scope (module SharedWorker, fetch())
+  assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
+[PASS] Case #4: sw scope1->out-scope (module SharedWorker, location.href)
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
deleted file mode 100644
index a544e1f7..0000000
--- a/third_party/blink/web_tests/platform/linux/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-This is a testharness.js-based test.
-FAIL Verify a dedicated worker script request gets correct client Ids assert_equals: expected "feb345a6-8782-432c-9b65-4620c60d2a94" but got ""
-FAIL Verify a dedicated worker script request issued from a uncontrolled document is intercepted by worker's own service worker. promise_test: Unhandled rejection with value: object "Error: wait_for_state needs a ServiceWorker object to be passed."
-PASS Verify an out-of-scope dedicated worker script request issued from a controlled document should not be intercepted by document's service worker.
-PASS Verify a shared worker script request issued from a uncontrolled document is intercepted by worker's own service worker.
-PASS Verify a same-origin worker script served by a service worker succeeds in starting a dedicated worker.
-PASS Verify a same-origin worker script served by a service worker succeeds in starting a shared worker.
-PASS Verify a cors worker script served by a service worker fails dedicated worker start.
-PASS Verify a cors worker script served by a service worker fails shared worker start.
-PASS Verify a no-cors cross-origin worker script served by a service worker fails dedicated worker start.
-PASS Verify a no-cors cross-origin worker script served by a service worker fails shared worker start.
-PASS Register a service worker for worker subresource interception tests.
-PASS Requests on a dedicated worker controlled by a service worker.
-PASS Requests on a shared worker controlled by a service worker.
-PASS Requests on a dedicated worker nested in a dedicated worker and controlled by a service worker
-FAIL Requests on a dedicated worker nested in a shared worker and controlled by a service worker assert_equals: expected "This load was successfully intercepted." but got "Unexpected error! Worker is not defined"
-PASS Unregister a service worker for subresource interception tests.
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/linux/virtual/scalefactor200/css3/filters/backdrop-filter-plus-mask-large-expected.png b/third_party/blink/web_tests/platform/linux/virtual/scalefactor200/css3/filters/backdrop-filter-plus-mask-large-expected.png
index d7b99e77..9376163 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/scalefactor200/css3/filters/backdrop-filter-plus-mask-large-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/scalefactor200/css3/filters/backdrop-filter-plus-mask-large-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/platform/linux/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png
index caf265b..caadf43 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
deleted file mode 100644
index d6b1510..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service worker controlled navigation timing assert_greater_than: workerStart marking should not wait for worker activation to finish expected a number greater than 1634043667232.9 but got 1634043667232.2
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/stream/tentative/backpressure-receive.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/stream/tentative/backpressure-receive.any_wpt_flags=h2-expected.txt
deleted file mode 100644
index 07389ab..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/stream/tentative/backpressure-receive.any_wpt_flags=h2-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-PASS backpressure should be applied to received messages
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker_wpt_flags=h2-expected.txt
deleted file mode 100644
index f453bf19e..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker_wpt_flags=h2-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL backpressure should be applied to sent messages promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.15/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
deleted file mode 100644
index d5246e9..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.15/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service worker controlled navigation timing assert_greater_than: workerStart marking should not wait for worker activation to finish expected a number greater than 1634043281629.2 but got 1634043281628.7002
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
deleted file mode 100644
index e4ff24ec..0000000
--- a/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service worker controlled navigation timing assert_greater_than: workerStart marking should not wait for worker activation to finish expected a number greater than 1634043925788.1 but got 1634043925788
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/service-workers/service-worker/resource-timing-fetch-variants.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/service-workers/service-worker/resource-timing-fetch-variants.https-expected.txt
deleted file mode 100644
index ed296ab9..0000000
--- a/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/service-workers/service-worker/resource-timing-fetch-variants.https-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS Redirects done from within a service-worker should not be exposed to client ResourceTiming
-PASS Connection info from within a service-worker should not be exposed to client ResourceTiming
-PASS requestStart should never be before fetchStart
-PASS Delay from within service-worker (after internal fetching) should be accessible through `responseStart`
-PASS Delay from within service-worker (before internal fetching) should be measured before responseStart in the client ResourceTiming entry
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/websockets/cookies/007_default-expected.txt b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/websockets/cookies/007_default-expected.txt
new file mode 100644
index 0000000..2c57697
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/websockets/cookies/007_default-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] WebSockets: when to process set-cookie fields in ws response
+  assert_unreached: cookie was set during script execution Reached unreachable code
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker_wpt_flags=h2-expected.txt
deleted file mode 100644
index f453bf19e..0000000
--- a/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker_wpt_flags=h2-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL backpressure should be applied to sent messages promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/websockets/stream/tentative/constructor.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/websockets/stream/tentative/constructor.any.worker_wpt_flags=h2-expected.txt
new file mode 100644
index 0000000..32c34ab
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/websockets/stream/tentative/constructor.any.worker_wpt_flags=h2-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: A network error occurred
+[PASS] constructing with no URL should throw
+[PASS] constructing with an invalid URL should throw
+[PASS] constructing with invalid options should throw
+[PASS] protocols should be required to be a list
+[FAIL] constructing with a valid URL should work
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[FAIL] setting a protocol in the constructor should work
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] connection failure should reject the promises
+[FAIL] wss.opened should resolve to the right types
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
deleted file mode 100644
index f169810..0000000
--- a/third_party/blink/web_tests/platform/mac-mac11-arm64/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service worker controlled navigation timing assert_greater_than: workerStart marking should not wait for worker activation to finish expected a number greater than 1634043763019.1 but got 1634043763018.9
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac11/external/wpt/websockets/stream/tentative/abort.any.serviceworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac-mac11/external/wpt/websockets/stream/tentative/abort.any.serviceworker_wpt_flags=h2-expected.txt
new file mode 100644
index 0000000..c272749
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11/external/wpt/websockets/stream/tentative/abort.any.serviceworker_wpt_flags=h2-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[PASS] abort before constructing should prevent connection
+[PASS] abort during handshake should work
+[FAIL] abort after connect should do nothing
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac11/external/wpt/websockets/stream/tentative/constructor.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac-mac11/external/wpt/websockets/stream/tentative/constructor.any_wpt_flags=h2-expected.txt
new file mode 100644
index 0000000..32c34ab
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11/external/wpt/websockets/stream/tentative/constructor.any_wpt_flags=h2-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: A network error occurred
+[PASS] constructing with no URL should throw
+[PASS] constructing with an invalid URL should throw
+[PASS] constructing with invalid options should throw
+[PASS] protocols should be required to be a list
+[FAIL] constructing with a valid URL should work
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[FAIL] setting a protocol in the constructor should work
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] connection failure should reject the promises
+[FAIL] wss.opened should resolve to the right types
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/external/wpt/websockets/cookies/007_default-expected.txt b/third_party/blink/web_tests/platform/mac-mac12-arm64/external/wpt/websockets/cookies/007_default-expected.txt
new file mode 100644
index 0000000..2c57697
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/external/wpt/websockets/cookies/007_default-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] WebSockets: when to process set-cookie fields in ws response
+  assert_unreached: cookie was set during script execution Reached unreachable code
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/external/wpt/websockets/stream/tentative/abort.any.serviceworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac-mac12-arm64/external/wpt/websockets/stream/tentative/abort.any.serviceworker_wpt_flags=h2-expected.txt
new file mode 100644
index 0000000..c272749
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/external/wpt/websockets/stream/tentative/abort.any.serviceworker_wpt_flags=h2-expected.txt
@@ -0,0 +1,7 @@
+This is a testharness.js-based test.
+[PASS] abort before constructing should prevent connection
+[PASS] abort during handshake should work
+[FAIL] abort after connect should do nothing
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac12-arm64/external/wpt/websockets/stream/tentative/constructor.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac-mac12-arm64/external/wpt/websockets/stream/tentative/constructor.any_wpt_flags=h2-expected.txt
new file mode 100644
index 0000000..32c34ab
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac12-arm64/external/wpt/websockets/stream/tentative/constructor.any_wpt_flags=h2-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: A network error occurred
+[PASS] constructing with no URL should throw
+[PASS] constructing with an invalid URL should throw
+[PASS] constructing with invalid options should throw
+[PASS] protocols should be required to be a list
+[FAIL] constructing with a valid URL should work
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[FAIL] setting a protocol in the constructor should work
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+[PASS] connection failure should reject the promises
+[FAIL] wss.opened should resolve to the right types
+  promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
deleted file mode 100644
index fcd4d8b..0000000
--- a/third_party/blink/web_tests/platform/mac/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service worker controlled navigation timing assert_greater_than: workerStart marking should not wait for worker activation to finish expected a number greater than 1634043789619.9001 but got 1634043789618.7002
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-1000.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-1000.any_wpt_flags=h2-expected.txt
index 867b80f..ebd5498 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-1000.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-1000.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Close the Connection - close(1000) - readyState should be in CLOSED state and wasClean is TRUE - Connection should be closed assert_true: WebSocket connection should be opened expected true got false
+[FAIL] Create WebSocket - Close the Connection - close(1000) - readyState should be in CLOSED state and wasClean is TRUE - Connection should be closed
+  assert_true: WebSocket connection should be opened expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-1005.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-1005.any.worker_wpt_flags=h2-expected.txt
index 8c61fe14..ada4592 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-1005.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-1005.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Close the Connection - close(1005) - see '7.1.5.  The WebSocket Connection Close Code' in http://www.ietf.org/rfc/rfc6455.txt assert_unreached: close event should not fire Reached unreachable code
+[FAIL] Create WebSocket - Close the Connection - close(1005) - see '7.1.5.  The WebSocket Connection Close Code' in http://www.ietf.org/rfc/rfc6455.txt
+  assert_unreached: close event should not fire Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-1005.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-1005.any_wpt_flags=h2-expected.txt
index 8c61fe14..ada4592 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-1005.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-1005.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Close the Connection - close(1005) - see '7.1.5.  The WebSocket Connection Close Code' in http://www.ietf.org/rfc/rfc6455.txt assert_unreached: close event should not fire Reached unreachable code
+[FAIL] Create WebSocket - Close the Connection - close(1005) - see '7.1.5.  The WebSocket Connection Close Code' in http://www.ietf.org/rfc/rfc6455.txt
+  assert_unreached: close event should not fire Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-3000-reason.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-3000-reason.any.worker_wpt_flags=h2-expected.txt
index 11c898e..4223afc 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-3000-reason.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-3000-reason.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Close the Connection - close(3000, reason) - readyState should be in CLOSED state and wasClean is TRUE - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Create WebSocket - Close the Connection - close(3000, reason) - readyState should be in CLOSED state and wasClean is TRUE - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-3000-verify-code.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-3000-verify-code.any.worker_wpt_flags=h2-expected.txt
index 651e4a7..6cd815d 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-3000-verify-code.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Close-3000-verify-code.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Close the Connection - close(3000, reason) - verify return code is 3000 - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Create WebSocket - Close the Connection - close(3000, reason) - verify return code is 3000 - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-blocked-port.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-blocked-port.any.worker_wpt_flags=h2-expected.txt
index 09e47e3..6757dcf8 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-blocked-port.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-blocked-port.any.worker_wpt_flags=h2-expected.txt
@@ -1,82 +1,83 @@
 This is a testharness.js-based test.
 Found 78 tests; 77 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
-FAIL Basic check assert_unreached: Reached unreachable code
-PASS WebSocket blocked port test 1
-PASS WebSocket blocked port test 7
-PASS WebSocket blocked port test 9
-PASS WebSocket blocked port test 11
-PASS WebSocket blocked port test 13
-PASS WebSocket blocked port test 15
-PASS WebSocket blocked port test 17
-PASS WebSocket blocked port test 19
-PASS WebSocket blocked port test 20
-PASS WebSocket blocked port test 21
-PASS WebSocket blocked port test 22
-PASS WebSocket blocked port test 23
-PASS WebSocket blocked port test 25
-PASS WebSocket blocked port test 37
-PASS WebSocket blocked port test 42
-PASS WebSocket blocked port test 43
-PASS WebSocket blocked port test 53
-PASS WebSocket blocked port test 69
-PASS WebSocket blocked port test 77
-PASS WebSocket blocked port test 79
-PASS WebSocket blocked port test 87
-PASS WebSocket blocked port test 95
-PASS WebSocket blocked port test 101
-PASS WebSocket blocked port test 102
-PASS WebSocket blocked port test 103
-PASS WebSocket blocked port test 104
-PASS WebSocket blocked port test 109
-PASS WebSocket blocked port test 110
-PASS WebSocket blocked port test 111
-PASS WebSocket blocked port test 113
-PASS WebSocket blocked port test 115
-PASS WebSocket blocked port test 117
-PASS WebSocket blocked port test 119
-PASS WebSocket blocked port test 123
-PASS WebSocket blocked port test 135
-PASS WebSocket blocked port test 137
-PASS WebSocket blocked port test 139
-PASS WebSocket blocked port test 143
-PASS WebSocket blocked port test 179
-PASS WebSocket blocked port test 389
-PASS WebSocket blocked port test 427
-PASS WebSocket blocked port test 465
-PASS WebSocket blocked port test 512
-PASS WebSocket blocked port test 513
-PASS WebSocket blocked port test 514
-PASS WebSocket blocked port test 515
-PASS WebSocket blocked port test 526
-PASS WebSocket blocked port test 530
-PASS WebSocket blocked port test 531
-PASS WebSocket blocked port test 532
-PASS WebSocket blocked port test 540
-PASS WebSocket blocked port test 548
-PASS WebSocket blocked port test 554
-PASS WebSocket blocked port test 556
-PASS WebSocket blocked port test 563
-PASS WebSocket blocked port test 587
-PASS WebSocket blocked port test 601
-PASS WebSocket blocked port test 636
-PASS WebSocket blocked port test 989
-PASS WebSocket blocked port test 990
-PASS WebSocket blocked port test 993
-PASS WebSocket blocked port test 995
-PASS WebSocket blocked port test 1719
-PASS WebSocket blocked port test 1720
-PASS WebSocket blocked port test 1723
-PASS WebSocket blocked port test 2049
-PASS WebSocket blocked port test 3659
-PASS WebSocket blocked port test 4045
-PASS WebSocket blocked port test 6000
-PASS WebSocket blocked port test 6566
-PASS WebSocket blocked port test 6665
-PASS WebSocket blocked port test 6666
-PASS WebSocket blocked port test 6667
-PASS WebSocket blocked port test 6668
-PASS WebSocket blocked port test 6669
-PASS WebSocket blocked port test 6697
-PASS WebSocket blocked port test 10080
+[FAIL] Basic check
+  assert_unreached: Reached unreachable code
+[PASS] WebSocket blocked port test 1
+[PASS] WebSocket blocked port test 7
+[PASS] WebSocket blocked port test 9
+[PASS] WebSocket blocked port test 11
+[PASS] WebSocket blocked port test 13
+[PASS] WebSocket blocked port test 15
+[PASS] WebSocket blocked port test 17
+[PASS] WebSocket blocked port test 19
+[PASS] WebSocket blocked port test 20
+[PASS] WebSocket blocked port test 21
+[PASS] WebSocket blocked port test 22
+[PASS] WebSocket blocked port test 23
+[PASS] WebSocket blocked port test 25
+[PASS] WebSocket blocked port test 37
+[PASS] WebSocket blocked port test 42
+[PASS] WebSocket blocked port test 43
+[PASS] WebSocket blocked port test 53
+[PASS] WebSocket blocked port test 69
+[PASS] WebSocket blocked port test 77
+[PASS] WebSocket blocked port test 79
+[PASS] WebSocket blocked port test 87
+[PASS] WebSocket blocked port test 95
+[PASS] WebSocket blocked port test 101
+[PASS] WebSocket blocked port test 102
+[PASS] WebSocket blocked port test 103
+[PASS] WebSocket blocked port test 104
+[PASS] WebSocket blocked port test 109
+[PASS] WebSocket blocked port test 110
+[PASS] WebSocket blocked port test 111
+[PASS] WebSocket blocked port test 113
+[PASS] WebSocket blocked port test 115
+[PASS] WebSocket blocked port test 117
+[PASS] WebSocket blocked port test 119
+[PASS] WebSocket blocked port test 123
+[PASS] WebSocket blocked port test 135
+[PASS] WebSocket blocked port test 137
+[PASS] WebSocket blocked port test 139
+[PASS] WebSocket blocked port test 143
+[PASS] WebSocket blocked port test 179
+[PASS] WebSocket blocked port test 389
+[PASS] WebSocket blocked port test 427
+[PASS] WebSocket blocked port test 465
+[PASS] WebSocket blocked port test 512
+[PASS] WebSocket blocked port test 513
+[PASS] WebSocket blocked port test 514
+[PASS] WebSocket blocked port test 515
+[PASS] WebSocket blocked port test 526
+[PASS] WebSocket blocked port test 530
+[PASS] WebSocket blocked port test 531
+[PASS] WebSocket blocked port test 532
+[PASS] WebSocket blocked port test 540
+[PASS] WebSocket blocked port test 548
+[PASS] WebSocket blocked port test 554
+[PASS] WebSocket blocked port test 556
+[PASS] WebSocket blocked port test 563
+[PASS] WebSocket blocked port test 587
+[PASS] WebSocket blocked port test 601
+[PASS] WebSocket blocked port test 636
+[PASS] WebSocket blocked port test 989
+[PASS] WebSocket blocked port test 990
+[PASS] WebSocket blocked port test 993
+[PASS] WebSocket blocked port test 995
+[PASS] WebSocket blocked port test 1719
+[PASS] WebSocket blocked port test 1720
+[PASS] WebSocket blocked port test 1723
+[PASS] WebSocket blocked port test 2049
+[PASS] WebSocket blocked port test 3659
+[PASS] WebSocket blocked port test 4045
+[PASS] WebSocket blocked port test 6000
+[PASS] WebSocket blocked port test 6566
+[PASS] WebSocket blocked port test 6665
+[PASS] WebSocket blocked port test 6666
+[PASS] WebSocket blocked port test 6667
+[PASS] WebSocket blocked port test 6668
+[PASS] WebSocket blocked port test 6669
+[PASS] WebSocket blocked port test 6697
+[PASS] WebSocket blocked port test 10080
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-blocked-port.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-blocked-port.any_wpt_flags=h2-expected.txt
index 09e47e3..6757dcf8 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-blocked-port.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-blocked-port.any_wpt_flags=h2-expected.txt
@@ -1,82 +1,83 @@
 This is a testharness.js-based test.
 Found 78 tests; 77 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
-FAIL Basic check assert_unreached: Reached unreachable code
-PASS WebSocket blocked port test 1
-PASS WebSocket blocked port test 7
-PASS WebSocket blocked port test 9
-PASS WebSocket blocked port test 11
-PASS WebSocket blocked port test 13
-PASS WebSocket blocked port test 15
-PASS WebSocket blocked port test 17
-PASS WebSocket blocked port test 19
-PASS WebSocket blocked port test 20
-PASS WebSocket blocked port test 21
-PASS WebSocket blocked port test 22
-PASS WebSocket blocked port test 23
-PASS WebSocket blocked port test 25
-PASS WebSocket blocked port test 37
-PASS WebSocket blocked port test 42
-PASS WebSocket blocked port test 43
-PASS WebSocket blocked port test 53
-PASS WebSocket blocked port test 69
-PASS WebSocket blocked port test 77
-PASS WebSocket blocked port test 79
-PASS WebSocket blocked port test 87
-PASS WebSocket blocked port test 95
-PASS WebSocket blocked port test 101
-PASS WebSocket blocked port test 102
-PASS WebSocket blocked port test 103
-PASS WebSocket blocked port test 104
-PASS WebSocket blocked port test 109
-PASS WebSocket blocked port test 110
-PASS WebSocket blocked port test 111
-PASS WebSocket blocked port test 113
-PASS WebSocket blocked port test 115
-PASS WebSocket blocked port test 117
-PASS WebSocket blocked port test 119
-PASS WebSocket blocked port test 123
-PASS WebSocket blocked port test 135
-PASS WebSocket blocked port test 137
-PASS WebSocket blocked port test 139
-PASS WebSocket blocked port test 143
-PASS WebSocket blocked port test 179
-PASS WebSocket blocked port test 389
-PASS WebSocket blocked port test 427
-PASS WebSocket blocked port test 465
-PASS WebSocket blocked port test 512
-PASS WebSocket blocked port test 513
-PASS WebSocket blocked port test 514
-PASS WebSocket blocked port test 515
-PASS WebSocket blocked port test 526
-PASS WebSocket blocked port test 530
-PASS WebSocket blocked port test 531
-PASS WebSocket blocked port test 532
-PASS WebSocket blocked port test 540
-PASS WebSocket blocked port test 548
-PASS WebSocket blocked port test 554
-PASS WebSocket blocked port test 556
-PASS WebSocket blocked port test 563
-PASS WebSocket blocked port test 587
-PASS WebSocket blocked port test 601
-PASS WebSocket blocked port test 636
-PASS WebSocket blocked port test 989
-PASS WebSocket blocked port test 990
-PASS WebSocket blocked port test 993
-PASS WebSocket blocked port test 995
-PASS WebSocket blocked port test 1719
-PASS WebSocket blocked port test 1720
-PASS WebSocket blocked port test 1723
-PASS WebSocket blocked port test 2049
-PASS WebSocket blocked port test 3659
-PASS WebSocket blocked port test 4045
-PASS WebSocket blocked port test 6000
-PASS WebSocket blocked port test 6566
-PASS WebSocket blocked port test 6665
-PASS WebSocket blocked port test 6666
-PASS WebSocket blocked port test 6667
-PASS WebSocket blocked port test 6668
-PASS WebSocket blocked port test 6669
-PASS WebSocket blocked port test 6697
-PASS WebSocket blocked port test 10080
+[FAIL] Basic check
+  assert_unreached: Reached unreachable code
+[PASS] WebSocket blocked port test 1
+[PASS] WebSocket blocked port test 7
+[PASS] WebSocket blocked port test 9
+[PASS] WebSocket blocked port test 11
+[PASS] WebSocket blocked port test 13
+[PASS] WebSocket blocked port test 15
+[PASS] WebSocket blocked port test 17
+[PASS] WebSocket blocked port test 19
+[PASS] WebSocket blocked port test 20
+[PASS] WebSocket blocked port test 21
+[PASS] WebSocket blocked port test 22
+[PASS] WebSocket blocked port test 23
+[PASS] WebSocket blocked port test 25
+[PASS] WebSocket blocked port test 37
+[PASS] WebSocket blocked port test 42
+[PASS] WebSocket blocked port test 43
+[PASS] WebSocket blocked port test 53
+[PASS] WebSocket blocked port test 69
+[PASS] WebSocket blocked port test 77
+[PASS] WebSocket blocked port test 79
+[PASS] WebSocket blocked port test 87
+[PASS] WebSocket blocked port test 95
+[PASS] WebSocket blocked port test 101
+[PASS] WebSocket blocked port test 102
+[PASS] WebSocket blocked port test 103
+[PASS] WebSocket blocked port test 104
+[PASS] WebSocket blocked port test 109
+[PASS] WebSocket blocked port test 110
+[PASS] WebSocket blocked port test 111
+[PASS] WebSocket blocked port test 113
+[PASS] WebSocket blocked port test 115
+[PASS] WebSocket blocked port test 117
+[PASS] WebSocket blocked port test 119
+[PASS] WebSocket blocked port test 123
+[PASS] WebSocket blocked port test 135
+[PASS] WebSocket blocked port test 137
+[PASS] WebSocket blocked port test 139
+[PASS] WebSocket blocked port test 143
+[PASS] WebSocket blocked port test 179
+[PASS] WebSocket blocked port test 389
+[PASS] WebSocket blocked port test 427
+[PASS] WebSocket blocked port test 465
+[PASS] WebSocket blocked port test 512
+[PASS] WebSocket blocked port test 513
+[PASS] WebSocket blocked port test 514
+[PASS] WebSocket blocked port test 515
+[PASS] WebSocket blocked port test 526
+[PASS] WebSocket blocked port test 530
+[PASS] WebSocket blocked port test 531
+[PASS] WebSocket blocked port test 532
+[PASS] WebSocket blocked port test 540
+[PASS] WebSocket blocked port test 548
+[PASS] WebSocket blocked port test 554
+[PASS] WebSocket blocked port test 556
+[PASS] WebSocket blocked port test 563
+[PASS] WebSocket blocked port test 587
+[PASS] WebSocket blocked port test 601
+[PASS] WebSocket blocked port test 636
+[PASS] WebSocket blocked port test 989
+[PASS] WebSocket blocked port test 990
+[PASS] WebSocket blocked port test 993
+[PASS] WebSocket blocked port test 995
+[PASS] WebSocket blocked port test 1719
+[PASS] WebSocket blocked port test 1720
+[PASS] WebSocket blocked port test 1723
+[PASS] WebSocket blocked port test 2049
+[PASS] WebSocket blocked port test 3659
+[PASS] WebSocket blocked port test 4045
+[PASS] WebSocket blocked port test 6000
+[PASS] WebSocket blocked port test 6566
+[PASS] WebSocket blocked port test 6665
+[PASS] WebSocket blocked port test 6666
+[PASS] WebSocket blocked port test 6667
+[PASS] WebSocket blocked port test 6668
+[PASS] WebSocket blocked port test 6669
+[PASS] WebSocket blocked port test 6697
+[PASS] WebSocket blocked port test 10080
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-extensions-empty.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-extensions-empty.any_wpt_flags=h2-expected.txt
index 668ef1f..e45b2f9 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-extensions-empty.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-extensions-empty.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - wsocket.extensions should be set to '' after connection is established - Connection should be closed assert_true: WebSocket connection should be closed expected true got false
+[FAIL] Create WebSocket - wsocket.extensions should be set to '' after connection is established - Connection should be closed
+  assert_true: WebSocket connection should be closed expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-valid-url-array-protocols.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-valid-url-array-protocols.any_wpt_flags=h2-expected.txt
index f7aa3bd..1faa9cf 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-valid-url-array-protocols.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-valid-url-array-protocols.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a valid URL and array of protocol strings - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Create WebSocket - Pass a valid URL and array of protocol strings - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-valid-url-protocol.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-valid-url-protocol.any.worker_wpt_flags=h2-expected.txt
new file mode 100644
index 0000000..9c03591
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-valid-url-protocol.any.worker_wpt_flags=h2-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Create WebSocket - Pass a valid URL and a protocol string - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-valid-url.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-valid-url.any.worker_wpt_flags=h2-expected.txt
index f2056d7..5e00789 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-valid-url.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Create-valid-url.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a valid URL - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Create WebSocket - Pass a valid URL - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-0byte-data.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-0byte-data.any_wpt_flags=h2-expected.txt
index 13ac904..15e25a4 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-0byte-data.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-0byte-data.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Send 0 byte data on a WebSocket - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Send 0 byte data on a WebSocket - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-65K-data.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-65K-data.any_wpt_flags=h2-expected.txt
index 9261cf3c..54bb74a 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-65K-data.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-65K-data.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Send 65K data on a WebSocket - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Send 65K data on a WebSocket - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-65K-arraybuffer.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-65K-arraybuffer.any.worker_wpt_flags=h2-expected.txt
index bc3206eb..0dd56cfc 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-65K-arraybuffer.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-65K-arraybuffer.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Send 65K binary data on a WebSocket - ArrayBuffer - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Send 65K binary data on a WebSocket - ArrayBuffer - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-arraybufferview-int8.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-arraybufferview-int8.any.worker_wpt_flags=h2-expected.txt
index f138353c..c26c7b9e 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-arraybufferview-int8.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-arraybufferview-int8.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Send binary data on a WebSocket - ArrayBufferView - Int8Array - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Send binary data on a WebSocket - ArrayBufferView - Int8Array - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-arraybufferview-int8.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-arraybufferview-int8.any_wpt_flags=h2-expected.txt
index f138353c..c26c7b9e 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-arraybufferview-int8.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-arraybufferview-int8.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Send binary data on a WebSocket - ArrayBufferView - Int8Array - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Send binary data on a WebSocket - ArrayBufferView - Int8Array - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-arraybufferview-uint8-offset.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-arraybufferview-uint8-offset.any_wpt_flags=h2-expected.txt
index 91449cc..201818c05b 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-arraybufferview-uint8-offset.any_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-binary-arraybufferview-uint8-offset.any_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Send binary data on a WebSocket - ArrayBufferView - Uint8Array with offset - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Send binary data on a WebSocket - ArrayBufferView - Uint8Array with offset - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-unicode-data.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-unicode-data.any.worker_wpt_flags=h2-expected.txt
index 48d4875a..ec3eb84 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-unicode-data.any.worker_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-unicode-data.any.worker_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL Send unicode data on a WebSocket - Connection should be closed assert_true: WebSocket connection should be open expected true got false
+[FAIL] Send unicode data on a WebSocket - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-unpaired-surrogates.any_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-unpaired-surrogates.any_wpt_flags=h2-expected.txt
new file mode 100644
index 0000000..6558a55f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/Send-unpaired-surrogates.any_wpt_flags=h2-expected.txt
@@ -0,0 +1,5 @@
+This is a testharness.js-based test.
+[FAIL] Send unpaired surrogates on a WebSocket - Connection should be closed
+  assert_true: WebSocket connection should be open expected true got false
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/binary/004_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/binary/004_wpt_flags=h2-expected.txt
index 07040c1e..d19e6d7 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/binary/004_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/binary/004_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: Send/Receive ArrayBuffer, size greater than network array buffer assert_unreached: close event should not fire Reached unreachable code
+[FAIL] WebSockets: Send/Receive ArrayBuffer, size greater than network array buffer
+  assert_unreached: close event should not fire Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-arraybuffer_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-arraybuffer_wpt_flags=h2-expected.txt
index 15b6668c..446309c 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-arraybuffer_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-arraybuffer_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: bufferedAmount for ArrayBuffer assert_unreached: close event should not fire Reached unreachable code
+[FAIL] WebSockets: bufferedAmount for ArrayBuffer
+  assert_unreached: close event should not fire Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/interfaces/WebSocket/send/006_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/interfaces/WebSocket/send/006_wpt_flags=h2-expected.txt
index 3c12a885..5eb6f74 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/websockets/interfaces/WebSocket/send/006_wpt_flags=h2-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/websockets/interfaces/WebSocket/send/006_wpt_flags=h2-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL WebSockets: send() with unpaired surrogate when readyState is OPEN assert_unreached: close event should not fire before message event Reached unreachable code
+[FAIL] WebSockets: send() with unpaired surrogate when readyState is OPEN
+  assert_unreached: close event should not fire before message event Reached unreachable code
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
deleted file mode 100644
index 56be6f9..0000000
--- a/third_party/blink/web_tests/platform/mac/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service worker controlled navigation timing assert_greater_than: workerStart marking should not wait for worker activation to finish expected a number greater than 1634043753605.8 but got 1634043753605.0999
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
deleted file mode 100644
index 669bb6e0..0000000
--- a/third_party/blink/web_tests/platform/win/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service worker controlled navigation timing assert_greater_than: workerStart marking should not wait for worker activation to finish expected a number greater than 1634044893684.5999 but got 1634044893683.9001
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker_wpt_flags=h2-expected.txt
deleted file mode 100644
index f453bf19e..0000000
--- a/third_party/blink/web_tests/platform/win/external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker_wpt_flags=h2-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL backpressure should be applied to sent messages promise_test: Unhandled rejection with value: object "NetworkError: A network error occurred"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win/fast/hidpi/scrollbar-appearance-increase-device-scale-factor-expected.png b/third_party/blink/web_tests/platform/win/fast/hidpi/scrollbar-appearance-increase-device-scale-factor-expected.png
index 1d4ea36..fba3c3b 100644
--- a/third_party/blink/web_tests/platform/win/fast/hidpi/scrollbar-appearance-increase-device-scale-factor-expected.png
+++ b/third_party/blink/web_tests/platform/win/fast/hidpi/scrollbar-appearance-increase-device-scale-factor-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-mask-with-percentages-expected.png b/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-mask-with-percentages-expected.png
index dc9f639c..f494ab60 100644
--- a/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-mask-with-percentages-expected.png
+++ b/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-mask-with-percentages-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/backdrop-filter-plus-mask-large-expected.png b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/backdrop-filter-plus-mask-large-expected.png
index 9a47f58c2..03b3136e 100644
--- a/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/backdrop-filter-plus-mask-large-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/backdrop-filter-plus-mask-large-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/blur-filter-page-scroll-expected.png b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/blur-filter-page-scroll-expected.png
index 609e30e..cfc2d50 100644
--- a/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/blur-filter-page-scroll-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/blur-filter-page-scroll-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/blur-filter-page-scroll-parents-expected.png b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/blur-filter-page-scroll-parents-expected.png
index 3c43d75e..db79b596 100644
--- a/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/blur-filter-page-scroll-parents-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/blur-filter-page-scroll-parents-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/blur-filter-page-scroll-self-expected.png b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/blur-filter-page-scroll-self-expected.png
index 7b30a6a0..ff8a954 100644
--- a/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/blur-filter-page-scroll-self-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/css3/filters/blur-filter-page-scroll-self-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png
index a7d3eb1..6b127b59 100644
--- a/third_party/blink/web_tests/platform/win/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png
+++ b/third_party/blink/web_tests/platform/win/virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/printing/page-format-data-expected.txt b/third_party/blink/web_tests/printing/page-format-data-expected.txt
index 7d45c2b..c553db3b 100644
--- a/third_party/blink/web_tests/printing/page-format-data-expected.txt
+++ b/third_party/blink/web_tests/printing/page-format-data-expected.txt
@@ -71,17 +71,17 @@
 Test non-zero margins
 PASS internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4) is '(10000, 20000)' + pxMargins(10, 20, 40, 80)
 Test percentage margin
-PASS internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4) is '(10000, 20000)' + pxMargins(800, 400, 200, 100)
+PASS internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4) is '(10000, 20000)' + pxMargins(1600, 400, 400, 100)
 Test margin: auto 4% 2% 1%
-PASS internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4) is '(10000, 20000)' + pxMargins(1, 400, 200, 100)
+PASS internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4) is '(10000, 20000)' + pxMargins(1, 400, 400, 100)
 Test margin: 8% auto 2% 1%
-PASS internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4) is '(10000, 20000)' + pxMargins(800, 2, 200, 100)
+PASS internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4) is '(10000, 20000)' + pxMargins(1600, 2, 400, 100)
 Test margin: 8% 4% auto 1%
-PASS internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4) is '(10000, 20000)' + pxMargins(800, 400, 3, 100)
+PASS internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4) is '(10000, 20000)' + pxMargins(1600, 400, 3, 100)
 Test margin: 8% 4% 2% auto
-PASS internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4) is '(10000, 20000)' + pxMargins(800, 400, 200, 4)
+PASS internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4) is '(10000, 20000)' + pxMargins(1600, 400, 400, 4)
 Test visibility: hidden
-PASS internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4) is '(10000, 20000)' + pxMargins(800, 400, 200, 4)
+PASS internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4) is '(10000, 20000)' + pxMargins(1600, 400, 400, 4)
 
 
 PASS successfullyParsed is true
diff --git a/third_party/blink/web_tests/printing/page-format-data.html b/third_party/blink/web_tests/printing/page-format-data.html
index 9cf5175..d92e96a 100644
--- a/third_party/blink/web_tests/printing/page-format-data.html
+++ b/third_party/blink/web_tests/printing/page-format-data.html
@@ -172,27 +172,27 @@
 
         debug("Test percentage margin");
         appendStyle("@page {margin: 8% 4% 2% 1%;}");
-        shouldBe("internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4)", "'(10000, 20000)' + pxMargins(800, 400, 200, 100)");
+        shouldBe("internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4)", "'(10000, 20000)' + pxMargins(1600, 400, 400, 100)");
 
         debug("Test margin: auto 4% 2% 1%");
         appendStyle("@page {margin: auto 4% 2% 1%;}");
-        shouldBe("internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4)", "'(10000, 20000)' + pxMargins(1, 400, 200, 100)");
+        shouldBe("internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4)", "'(10000, 20000)' + pxMargins(1, 400, 400, 100)");
 
         debug("Test margin: 8% auto 2% 1%");
         appendStyle("@page {margin: 8% auto 2% 1%;}");
-        shouldBe("internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4)", "'(10000, 20000)' + pxMargins(800, 2, 200, 100)");
+        shouldBe("internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4)", "'(10000, 20000)' + pxMargins(1600, 2, 400, 100)");
 
         debug("Test margin: 8% 4% auto 1%");
         appendStyle("@page {margin: 8% 4% auto 1%;}");
-        shouldBe("internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4)", "'(10000, 20000)' + pxMargins(800, 400, 3, 100)");
+        shouldBe("internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4)", "'(10000, 20000)' + pxMargins(1600, 400, 3, 100)");
 
         debug("Test margin: 8% 4% 2% auto");
         appendStyle("@page {margin: 8% 4% 2% auto;}");
-        shouldBe("internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4)", "'(10000, 20000)' + pxMargins(800, 400, 200, 4)");
+        shouldBe("internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4)", "'(10000, 20000)' + pxMargins(1600, 400, 400, 4)");
 
         debug("Test visibility: hidden");
         appendStyle("@page {visibility:hidden}");
-        shouldBe("internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4)", "'(10000, 20000)' + pxMargins(800, 400, 200, 4)");
+        shouldBe("internals.pageSizeAndMarginsInPixels(0, 100, 200, 1, 2, 3, 4)", "'(10000, 20000)' + pxMargins(1600, 400, 400, 4)");
 
         debug("");
 
diff --git a/third_party/blink/web_tests/resources/testharnessreport.js b/third_party/blink/web_tests/resources/testharnessreport.js
index a51f78f..0f8157cd 100644
--- a/third_party/blink/web_tests/resources/testharnessreport.js
+++ b/third_party/blink/web_tests/resources/testharnessreport.js
@@ -278,7 +278,9 @@
             location.pathname.startsWith('/html/') ||
             location.pathname.startsWith('/css/css-') ||
             location.pathname.startsWith('/editing/') ||
-            location.pathname.startsWith('/fetch/')) {
+            location.pathname.startsWith('/fetch/') ||
+            location.pathname.startsWith('/service-workers/') ||
+            location.pathname.startsWith('/websockets/')) {
             return true;
         }
         return false;
diff --git a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt b/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt
deleted file mode 100644
index 0edc52a..0000000
--- a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/client-url-of-blob-url-worker.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-PASS Client.url of a blob URL worker should be a blob URL.
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt b/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
deleted file mode 100644
index 37470a43..0000000
--- a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-get-client-types.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-PASS Test Clients.get() with window and worker clients
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt b/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt
deleted file mode 100644
index 4b89cc4..0000000
--- a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-matchall-blob-url-worker.https-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS Test Clients.matchAll() with a blob URL worker client.
-PASS Test Clients.matchAll() with an uncontrolled blob URL worker client.
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-matchall-frozen.https-expected.txt b/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-matchall-frozen.https-expected.txt
deleted file mode 100644
index 1cb1906..0000000
--- a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/clients-matchall-frozen.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Test Clients.matchAll() assert_object_equals: property "url" expected "https://web-platform.test:8444/service-workers/service-worker/resources/clients-frame-freeze.html#1" got "https://web-platform.test:8444/service-workers/service-worker/resources/clients-frame-freeze.html#2"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt b/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt
deleted file mode 100644
index f92bf6cb..0000000
--- a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a testharness.js-based test.
-PASS Top-level module loading should be intercepted by a service worker.
-PASS Static import should be intercepted by a service worker.
-PASS Dynamic import should be intercepted by a service worker.
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt b/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt
deleted file mode 100644
index b3b4691..0000000
--- a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/local-url-inherit-controller.https-expected.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-This is a testharness.js-based test.
-FAIL Same-origin blob URL iframe should inherit service worker controller. assert_equals: blob URL iframe should inherit controller expected (string) "https://web-platform.test:8444/service-workers/service-worker/resources/local-url-inherit-controller-worker.js" but got (object) null
-FAIL Same-origin blob URL iframe should intercept fetch(). assert_equals: blob URL iframe should intercept fetch expected "intercepted" but got "Hello world\n"
-FAIL Same-origin blob URL worker should inherit service worker controller. promise_test: Unhandled rejection with value: "Uncaught TypeError: Cannot read properties of undefined (reading 'controller')"
-PASS Same-origin blob URL worker should intercept fetch().
-PASS Data URL iframe should not intercept fetch().
-FAIL Data URL worker should not inherit service worker controller. promise_test: Unhandled rejection with value: "Uncaught TypeError: Cannot read properties of undefined (reading 'controller')"
-PASS Data URL worker should not intercept fetch().
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt b/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
deleted file mode 100644
index 2cd089c..0000000
--- a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL Service worker controlled navigation timing assert_greater_than: workerStart marking should not wait for worker activation to finish expected a number greater than 1634044522887.2998 but got 1634044522886.8
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception-redirect.https-expected.txt b/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception-redirect.https-expected.txt
deleted file mode 100644
index 06706c05..0000000
--- a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception-redirect.https-expected.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-This is a testharness.js-based test.
-Found 66 tests; 40 PASS, 26 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS initialize global state
-FAIL Case #1: network scope1->scope2 (classic DedicatedWorker) assert_equals: expected "the worker script was served from network" but got "sw2 saw the request for the worker script"
-FAIL Case #1: network scope1->scope2 (module DedicatedWorker) assert_equals: expected "the worker script was served from network" but got "sw2 saw the request for the worker script"
-FAIL Case #1: network scope1->scope2 (classic SharedWorker) assert_equals: expected "the worker script was served from network" but got "sw2 saw the request for the worker script"
-FAIL Case #1: network scope1->scope2 (module SharedWorker) assert_equals: expected "the worker script was served from network" but got "sw2 saw the request for the worker script"
-PASS Case #2: network scope1->out-scope (classic DedicatedWorker)
-PASS Case #2: network scope1->out-scope (module DedicatedWorker)
-PASS Case #2: network scope1->out-scope (classic SharedWorker)
-PASS Case #2: network scope1->out-scope (module SharedWorker)
-PASS Case #3: sw scope1->scope2 (classic DedicatedWorker)
-PASS Case #3: sw scope1->scope2 (module DedicatedWorker)
-PASS Case #3: sw scope1->scope2 (classic SharedWorker)
-PASS Case #3: sw scope1->scope2 (module SharedWorker)
-PASS Case #4: sw scope1->out-scope (classic DedicatedWorker)
-PASS Case #4: sw scope1->out-scope (module DedicatedWorker)
-PASS Case #4: sw scope1->out-scope (classic SharedWorker)
-PASS Case #4: sw scope1->out-scope (module SharedWorker)
-PASS cleanup global state
-FAIL Case #1: network scope1->scope2 (classic DedicatedWorker, importScripts()) assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/scope2/import-scripts-echo.py" but got "sw2 saw importScripts from the worker: /service-workers/service-worker/resources/subdir/import-scripts-echo.py"
-FAIL Case #1: network scope1->scope2 (classic DedicatedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): sw2 saw the fetch from the worker: /service-workers/service-worker/resources/subdir/simple.txt"
-FAIL Case #1: network scope1->scope2 (classic DedicatedWorker, location.href) assert_equals: location.href expected "https://web-platform.test:8444/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py?greeting=sw2%20saw%20the%20request%20for%20the%20worker%20script"
-PASS Case #1: network scope1->scope2 (module DedicatedWorker, importScripts())
-FAIL Case #1: network scope1->scope2 (module DedicatedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): sw2 saw the fetch from the worker: /service-workers/service-worker/resources/subdir/simple.txt"
-FAIL Case #1: network scope1->scope2 (module DedicatedWorker, location.href) assert_equals: location.href expected "https://web-platform.test:8444/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py?greeting=sw2%20saw%20the%20request%20for%20the%20worker%20script"
-FAIL Case #1: network scope1->scope2 (classic SharedWorker, importScripts()) assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/scope2/import-scripts-echo.py" but got "sw2 saw importScripts from the worker: /service-workers/service-worker/resources/subdir/import-scripts-echo.py"
-FAIL Case #1: network scope1->scope2 (classic SharedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): sw2 saw the fetch from the worker: /service-workers/service-worker/resources/subdir/simple.txt"
-FAIL Case #1: network scope1->scope2 (classic SharedWorker, location.href) assert_equals: location.href expected "https://web-platform.test:8444/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py?greeting=sw2%20saw%20the%20request%20for%20the%20worker%20script"
-PASS Case #1: network scope1->scope2 (module SharedWorker, importScripts())
-FAIL Case #1: network scope1->scope2 (module SharedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/scope2/simple.txt" but got "fetch(): sw2 saw the fetch from the worker: /service-workers/service-worker/resources/subdir/simple.txt"
-FAIL Case #1: network scope1->scope2 (module SharedWorker, location.href) assert_equals: location.href expected "https://web-platform.test:8444/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py" but got "https://web-platform.test:8444/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py?greeting=sw2%20saw%20the%20request%20for%20the%20worker%20script"
-FAIL Case #2: network scope1->out-scope (classic DedicatedWorker, importScripts()) assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/import-scripts-echo.py" but got "importScripts: served from network"
-FAIL Case #2: network scope1->out-scope (classic DedicatedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
-PASS Case #2: network scope1->out-scope (classic DedicatedWorker, location.href)
-PASS Case #2: network scope1->out-scope (module DedicatedWorker, importScripts())
-FAIL Case #2: network scope1->out-scope (module DedicatedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
-PASS Case #2: network scope1->out-scope (module DedicatedWorker, location.href)
-FAIL Case #2: network scope1->out-scope (classic SharedWorker, importScripts()) assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/import-scripts-echo.py" but got "importScripts: served from network"
-FAIL Case #2: network scope1->out-scope (classic SharedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
-PASS Case #2: network scope1->out-scope (classic SharedWorker, location.href)
-PASS Case #2: network scope1->out-scope (module SharedWorker, importScripts())
-FAIL Case #2: network scope1->out-scope (module SharedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
-PASS Case #2: network scope1->out-scope (module SharedWorker, location.href)
-PASS Case #3: sw scope1->scope2 (classic DedicatedWorker, importScripts())
-PASS Case #3: sw scope1->scope2 (classic DedicatedWorker, fetch())
-PASS Case #3: sw scope1->scope2 (classic DedicatedWorker, location.href)
-PASS Case #3: sw scope1->scope2 (module DedicatedWorker, importScripts())
-PASS Case #3: sw scope1->scope2 (module DedicatedWorker, fetch())
-PASS Case #3: sw scope1->scope2 (module DedicatedWorker, location.href)
-PASS Case #3: sw scope1->scope2 (classic SharedWorker, importScripts())
-PASS Case #3: sw scope1->scope2 (classic SharedWorker, fetch())
-PASS Case #3: sw scope1->scope2 (classic SharedWorker, location.href)
-PASS Case #3: sw scope1->scope2 (module SharedWorker, importScripts())
-PASS Case #3: sw scope1->scope2 (module SharedWorker, fetch())
-PASS Case #3: sw scope1->scope2 (module SharedWorker, location.href)
-FAIL Case #4: sw scope1->out-scope (classic DedicatedWorker, importScripts()) assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/import-scripts-echo.py" but got "importScripts: served from network"
-FAIL Case #4: sw scope1->out-scope (classic DedicatedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
-PASS Case #4: sw scope1->out-scope (classic DedicatedWorker, location.href)
-PASS Case #4: sw scope1->out-scope (module DedicatedWorker, importScripts())
-FAIL Case #4: sw scope1->out-scope (module DedicatedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
-PASS Case #4: sw scope1->out-scope (module DedicatedWorker, location.href)
-FAIL Case #4: sw scope1->out-scope (classic SharedWorker, importScripts()) assert_equals: expected "sw1 saw importScripts from the worker: /service-workers/service-worker/resources/import-scripts-echo.py" but got "importScripts: served from network"
-FAIL Case #4: sw scope1->out-scope (classic SharedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
-PASS Case #4: sw scope1->out-scope (classic SharedWorker, location.href)
-PASS Case #4: sw scope1->out-scope (module SharedWorker, importScripts())
-FAIL Case #4: sw scope1->out-scope (module SharedWorker, fetch()) assert_equals: expected "fetch(): sw1 saw the fetch from the worker: /service-workers/service-worker/resources/simple.txt" but got "fetch(): a simple text file\n"
-PASS Case #4: sw scope1->out-scope (module SharedWorker, location.href)
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt b/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
deleted file mode 100644
index 41d45df..0000000
--- a/third_party/blink/web_tests/virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception.https-expected.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-This is a testharness.js-based test.
-PASS Verify a dedicated worker script request issued from a uncontrolled document is intercepted by worker's own service worker.
-PASS Verify an out-of-scope dedicated worker script request issued from a controlled document should not be intercepted by document's service worker.
-PASS Verify a shared worker script request issued from a uncontrolled document is intercepted by worker's own service worker.
-PASS Verify a same-origin worker script served by a service worker succeeds in starting a dedicated worker.
-PASS Verify a same-origin worker script served by a service worker succeeds in starting a shared worker.
-PASS Verify a cors worker script served by a service worker fails dedicated worker start.
-PASS Verify a cors worker script served by a service worker fails shared worker start.
-PASS Verify a no-cors cross-origin worker script served by a service worker fails dedicated worker start.
-PASS Verify a no-cors cross-origin worker script served by a service worker fails shared worker start.
-PASS Register a service worker for worker subresource interception tests.
-PASS Requests on a dedicated worker controlled by a service worker.
-PASS Requests on a shared worker controlled by a service worker.
-PASS Requests on a dedicated worker nested in a dedicated worker and controlled by a service worker
-FAIL Requests on a dedicated worker nested in a shared worker and controlled by a service worker assert_equals: expected "This load was successfully intercepted." but got "Unexpected error! Worker is not defined"
-PASS Unregister a service worker for subresource interception tests.
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/initiators-a-element.sub.https_cross-site-expected.txt b/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/initiators-a-element.sub.https_cross-site-expected.txt
deleted file mode 100644
index 0202947..0000000
--- a/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/initiators-a-element.sub.https_cross-site-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS <a>
-FAIL <a target="blank"> assert_in_array: value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/initiators-a-element.sub.https_same-site-expected.txt b/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/initiators-a-element.sub.https_same-site-expected.txt
deleted file mode 100644
index 0202947..0000000
--- a/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/initiators-a-element.sub.https_same-site-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS <a>
-FAIL <a target="blank"> assert_in_array: value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/initiators-window-open.sub.https_cross-site-expected.txt b/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/initiators-window-open.sub.https_cross-site-expected.txt
deleted file mode 100644
index f1c3364e..0000000
--- a/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/initiators-window-open.sub.https_cross-site-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL window.open() assert_in_array: value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
-FAIL window.open(noopener) assert_in_array: value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/initiators-window-open.sub.https_same-site-expected.txt b/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/initiators-window-open.sub.https_same-site-expected.txt
deleted file mode 100644
index f1c3364e..0000000
--- a/third_party/blink/web_tests/virtual/prefetch-reusable/external/wpt/speculation-rules/prefetch/initiators-window-open.sub.https_same-site-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL window.open() assert_in_array: value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
-FAIL window.open(noopener) assert_in_array: value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/initiators-a-element.sub.https_cross-site-expected.txt b/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/initiators-a-element.sub.https_cross-site-expected.txt
deleted file mode 100644
index 0202947..0000000
--- a/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/initiators-a-element.sub.https_cross-site-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS <a>
-FAIL <a target="blank"> assert_in_array: value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/initiators-a-element.sub.https_same-site-expected.txt b/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/initiators-a-element.sub.https_same-site-expected.txt
deleted file mode 100644
index 0202947..0000000
--- a/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/initiators-a-element.sub.https_same-site-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-PASS <a>
-FAIL <a target="blank"> assert_in_array: value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/initiators-window-open.sub.https_cross-site-expected.txt b/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/initiators-window-open.sub.https_cross-site-expected.txt
deleted file mode 100644
index f1c3364e..0000000
--- a/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/initiators-window-open.sub.https_cross-site-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL window.open() assert_in_array: value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
-FAIL window.open(noopener) assert_in_array: value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/initiators-window-open.sub.https_same-site-expected.txt b/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/initiators-window-open.sub.https_same-site-expected.txt
deleted file mode 100644
index f1c3364e..0000000
--- a/third_party/blink/web_tests/virtual/prefetch/external/wpt/speculation-rules/prefetch/initiators-window-open.sub.https_same-site-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL window.open() assert_in_array: value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
-FAIL window.open(noopener) assert_in_array: value "" not in array ["prefetch", "prefetch;anonymous-client-ip"]
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/third-party-cookie-phaseout-enabled/external/wpt/service-workers/service-worker/partitioned-cookies.tentative.https-expected.txt b/third_party/blink/web_tests/virtual/third-party-cookie-phaseout-enabled/external/wpt/service-workers/service-worker/partitioned-cookies.tentative.https-expected.txt
index d4a1375..781e3a2 100644
--- a/third_party/blink/web_tests/virtual/third-party-cookie-phaseout-enabled/external/wpt/service-workers/service-worker/partitioned-cookies.tentative.https-expected.txt
+++ b/third_party/blink/web_tests/virtual/third-party-cookie-phaseout-enabled/external/wpt/service-workers/service-worker/partitioned-cookies.tentative.https-expected.txt
@@ -1,7 +1,8 @@
 This is a testharness.js-based test.
-PASS Service Worker: Partitioned Cookies
-PASS Service Worker: Partitioned Cookies 3P Window
-FAIL Service Worker: Partitioned Cookies 3P Iframe assert_true: Worker can access unpartitioned cookie via HTTP expected true got false
-PASS Service Worker: Partitioned Cookies 3P Credentialless Iframe
+[PASS] Service Worker: Partitioned Cookies
+[PASS] Service Worker: Partitioned Cookies 3P Window
+[FAIL] Service Worker: Partitioned Cookies 3P Iframe
+  assert_true: Worker can access unpartitioned cookie via HTTP expected true got false
+[PASS] Service Worker: Partitioned Cookies 3P Credentialless Iframe
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/cache-storage/cross-partition.https.tentative-expected.txt b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/cache-storage/cross-partition.https.tentative-expected.txt
deleted file mode 100644
index e32cd46..0000000
--- a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/cache-storage/cross-partition.https.tentative-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL CacheStorage caches shouldn't be shared with a cross-partition iframe promise_test: Unhandled rejection with value: "Cache visible in not-same-top-level-site iframe"
-FAIL CacheStorage caches shouldn't be shared with a cross-partition dedicated worker promise_test: Unhandled rejection with value: "Cache visible in not-same-top-level-site worker"
-FAIL CacheStorage caches shouldn't be shared with a cross-partition shared worker promise_test: Unhandled rejection with value: "Cache visible in not-same-top-level-site worker"
-FAIL CacheStorage caches shouldn't be shared with a cross-partition service worker promise_test: Unhandled rejection with value: "Cache visible in not-same-top-level-site worker"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-claim.tentative.https-expected.txt b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-claim.tentative.https-expected.txt
index ed2f192..dedb9fc37 100644
--- a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-claim.tentative.https-expected.txt
+++ b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-claim.tentative.https-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL ServiceWorker's clients.claim() is partitioned assert_equals: 3p iframe was successfully claimed expected "success" but got "failure"
+[FAIL] ServiceWorker's clients.claim() is partitioned
+  assert_equals: 3p iframe was successfully claimed expected "success" but got "failure"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-cookies.tentative.https-expected.txt b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-cookies.tentative.https-expected.txt
index 9b8f646..f02725a 100644
--- a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-cookies.tentative.https-expected.txt
+++ b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-cookies.tentative.https-expected.txt
@@ -1,7 +1,8 @@
 This is a testharness.js-based test.
-PASS Service Worker: Partitioned Cookies
-PASS Service Worker: Partitioned Cookies 3P Window
-FAIL Service Worker: Partitioned Cookies 3P Iframe assert_false: Worker cannot access partitioned cookie via HTTP expected false got true
-PASS Service Worker: Partitioned Cookies 3P Credentialless Iframe
+[PASS] Service Worker: Partitioned Cookies
+[PASS] Service Worker: Partitioned Cookies 3P Window
+[FAIL] Service Worker: Partitioned Cookies 3P Iframe
+  assert_false: Worker cannot access partitioned cookie via HTTP expected false got true
+[PASS] Service Worker: Partitioned Cookies 3P Credentialless Iframe
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-getRegistrations.tentative.https-expected.txt b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-getRegistrations.tentative.https-expected.txt
index ccc4e1b..b560b5a 100644
--- a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-getRegistrations.tentative.https-expected.txt
+++ b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-getRegistrations.tentative.https-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL ServiceWorker's getRegistrations() is partitioned assert_false: 1p SW ID matches 3p SW ID expected false got true
+[FAIL] ServiceWorker's getRegistrations() is partitioned
+  assert_false: 1p SW ID matches 3p SW ID expected false got true
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-matchAll.tentative.https-expected.txt b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-matchAll.tentative.https-expected.txt
index 8b302909..5a2b625 100644
--- a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-matchAll.tentative.https-expected.txt
+++ b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned-matchAll.tentative.https-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
-FAIL ServiceWorker's matchAll() is partitioned assert_equals: expected 1 but got 2
+[FAIL] ServiceWorker's matchAll() is partitioned
+  assert_equals: expected 1 but got 2
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned.tentative.https-expected.txt b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned.tentative.https-expected.txt
index e88643c..0a69c9e 100644
--- a/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned.tentative.https-expected.txt
+++ b/third_party/blink/web_tests/virtual/third-party-storage-partitioning/external/wpt/service-workers/service-worker/partitioned.tentative.https-expected.txt
@@ -1,5 +1,7 @@
 This is a testharness.js-based test.
-FAIL Services workers under different top-level sites are partitioned. assert_true: The 1p iframe saw a pending promise in the service worker. expected true got false
-FAIL Services workers with cross-site ancestors are partitioned. assert_true: The 1p iframe saw a pending promise in the service worker. expected true got false
+[FAIL] Services workers under different top-level sites are partitioned.
+  assert_true: The 1p iframe saw a pending promise in the service worker. expected true got false
+[FAIL] Services workers with cross-site ancestors are partitioned.
+  assert_true: The 1p iframe saw a pending promise in the service worker. expected true got false
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-cssom.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-cssom.html
index 0ede6be..5b1617e 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-cssom.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-cssom.html
@@ -89,4 +89,31 @@
     assert_equals(rule.cssText, "@view-transitions { }");
   });
 }, "navigation-trigger with !important flag should fail to parse.");
+
+test(function () {
+  resetStateAndTest(() => {
+    document.styleSheets[0].insertRule(`
+      @view-transitions {
+        navigation-trigger: none;
+      }
+    `);
+    let rule = document.styleSheets[0].cssRules[0];
+    rule.navigationTrigger = "cross-document-same-origin";
+    assert_equals(rule.navigationTrigger, "cross-document-same-origin");
+  });
+}, "navigation-trigger attribute can be set.");
+
+test(function () {
+  resetStateAndTest(() => {
+    document.styleSheets[0].insertRule(`
+      @view-transitions {
+        navigation-trigger: none;
+      }
+    `);
+    let rule = document.styleSheets[0].cssRules[0];
+    rule.navigationTrigger = "foo";
+    assert_equals(rule.navigationTrigger, "none");
+  });
+}, "navigation-trigger doesn't set invalid token.");
+
 </script>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-via-cssom.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-via-cssom.html
new file mode 100644
index 0000000..86faf4cb
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-via-cssom.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>View Transitions: @view-transitions opt-in programmatically.</title>
+<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/">
+<link rel="author" href="mailto:bokan@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+@view-transitions {
+    navigation-trigger: none;
+}
+</style>
+<script>
+function optIn() {
+    document.styleSheets[0].cssRules[0].navigationTrigger = 'cross-document-same-origin';
+}
+const params = new URLSearchParams(location.search);
+const is_new_page = params.has('new');
+
+if (!is_new_page) {
+  onload = () => requestAnimationFrame(() => requestAnimationFrame(() => {
+      optIn();
+      location.replace(location.href + '?new');
+  }));
+} else {
+  promise_test(() => {
+    optIn();
+    return new Promise((resolve) => {
+        addEventListener('pagereveal', resolve);
+    }).then(event => {
+        assert_not_equals(event.viewTransition, null,
+            "ViewTransition must be triggered.");
+    });
+  });
+}
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-out-via-cssom.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-out-via-cssom.html
new file mode 100644
index 0000000..9d3e384
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-out-via-cssom.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<title>View Transitions: @view-transitions opt-out programmatically.</title>
+<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/">
+<link rel="author" href="mailto:bokan@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+@view-transitions {
+    navigation-trigger: cross-document-same-origin;
+}
+</style>
+<script>
+const params = new URLSearchParams(location.search);
+const is_new_page = params.has('new');
+
+if (!is_new_page) {
+  onload = () => requestAnimationFrame(() => requestAnimationFrame(() => {
+      document.styleSheets[0].rules[0].navigationTrigger = 'none';
+      location.replace(location.href + '?new');
+  }));
+} else {
+  promise_test(() => {
+    return new Promise((resolve) => {
+        addEventListener('pagereveal', resolve);
+    }).then(event => {
+        assert_equals(event.viewTransition, null,
+            "ViewTransition must not be triggered.");
+    });
+  });
+}
+</script>
\ No newline at end of file
diff --git a/third_party/bspatch/README.chromium b/third_party/bspatch/README.chromium
index aba55587..cc08d660 100644
--- a/third_party/bspatch/README.chromium
+++ b/third_party/bspatch/README.chromium
@@ -1,5 +1,5 @@
 Name: bspatch
-URL: http://lxr.mozilla.org/mozilla/source/toolkit/mozapps/update/src/updater/
+URL: https://github.com/mozilla-services/services-central-legacy/tree/master/toolkit/mozapps/update/updater
 Version: unknown
 License: BSD 2-Clause License
 License File: LICENSE
diff --git a/third_party/catapult b/third_party/catapult
index b9ebadd..f496845 160000
--- a/third_party/catapult
+++ b/third_party/catapult
@@ -1 +1 @@
-Subproject commit b9ebaddcd0d4298e8e65641a5f454f7603e90b40
+Subproject commit f496845cb9f8db416fc711747fe8594364109465
diff --git a/third_party/chromium-variations b/third_party/chromium-variations
index ccdc1ba..6d4720a 160000
--- a/third_party/chromium-variations
+++ b/third_party/chromium-variations
@@ -1 +1 @@
-Subproject commit ccdc1ba5ff762128cd9add94b211d53261227297
+Subproject commit 6d4720af28ceb0c0ff855c0e7223e1d8f532c19e
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium
index 98939c2..39968ad0 100644
--- a/third_party/crashpad/README.chromium
+++ b/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@
 Short Name: crashpad
 URL: https://crashpad.chromium.org/
 Version: N/A
-Revision: ce4e3d6ee0bd0407d755584fdcd33135096ec352
+Revision: 376e8c0e699490bdaba5c1661abc98926f5c4231
 License: Apache 2.0
 License File: crashpad/LICENSE
 Security Critical: yes
diff --git a/third_party/crashpad/crashpad/DEPS b/third_party/crashpad/crashpad/DEPS
index bf1910ff..c23ad82 100644
--- a/third_party/crashpad/crashpad/DEPS
+++ b/third_party/crashpad/crashpad/DEPS
@@ -47,7 +47,7 @@
       '9719c1e1e676814c456b55f5f070eabad6709d31',
   'crashpad/third_party/mini_chromium/mini_chromium':
       Var('chromium_git') + '/chromium/mini_chromium@' +
-      '42f1fddfec57b255a3c0fdc804ca75226b493dc8',
+      'bc8dca83bd2f755bc91a2fd55ae229d5a1f13dc2',
   'crashpad/third_party/libfuzzer/src':
       Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git@' +
       'fda403cf93ecb8792cb1d061564d89a6553ca020',
diff --git a/third_party/crashpad/crashpad/client/crash_report_database_generic.cc b/third_party/crashpad/crashpad/client/crash_report_database_generic.cc
index 28a393d..617a074 100644
--- a/third_party/crashpad/crashpad/client/crash_report_database_generic.cc
+++ b/third_party/crashpad/crashpad/client/crash_report_database_generic.cc
@@ -22,6 +22,7 @@
 #include <tuple>
 #include <utility>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "build/build_config.h"
 #include "client/settings.h"
diff --git a/third_party/crashpad/crashpad/client/crash_report_database_mac.mm b/third_party/crashpad/crashpad/client/crash_report_database_mac.mm
index c852262..5d72b17e 100644
--- a/third_party/crashpad/crashpad/client/crash_report_database_mac.mm
+++ b/third_party/crashpad/crashpad/client/crash_report_database_mac.mm
@@ -34,8 +34,8 @@
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/scoped_generic.h"
+#include "base/strings/strcat.h"
 #include "base/strings/string_piece.h"
-#include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
 #include "client/settings.h"
 #include "util/file/directory_reader.h"
@@ -116,9 +116,9 @@
 // have changed, and new_name determines whether the returned xattr name will be
 // the old name or its new equivalent.
 std::string XattrNameInternal(const base::StringPiece& name, bool new_name) {
-  return base::StringPrintf(new_name ? "org.chromium.crashpad.database.%s"
-                                     : "com.googlecode.crashpad.%s",
-                            name.data());
+  return base::StrCat({new_name ? "org.chromium.crashpad.database."
+                                : "com.googlecode.crashpad.",
+                       name});
 }
 
 }  // namespace
diff --git a/third_party/crashpad/crashpad/client/crash_report_database_win.cc b/third_party/crashpad/crashpad/client/crash_report_database_win.cc
index b0c5229e..e925cf9f9 100644
--- a/third_party/crashpad/crashpad/client/crash_report_database_win.cc
+++ b/third_party/crashpad/crashpad/client/crash_report_database_win.cc
@@ -25,6 +25,7 @@
 #include <tuple>
 #include <utility>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/numerics/safe_math.h"
 #include "base/strings/utf_string_conversions.h"
diff --git a/third_party/crashpad/crashpad/client/crashpad_client_fuchsia.cc b/third_party/crashpad/crashpad/client/crashpad_client_fuchsia.cc
index e6addb1..9b09ad1 100644
--- a/third_party/crashpad/crashpad/client/crashpad_client_fuchsia.cc
+++ b/third_party/crashpad/crashpad/client/crashpad_client_fuchsia.cc
@@ -20,6 +20,7 @@
 #include <lib/zx/process.h>
 #include <zircon/processargs.h>
 
+#include "base/check_op.h"
 #include "base/fuchsia/fuchsia_logging.h"
 #include "base/logging.h"
 #include "client/client_argv_handling.h"
diff --git a/third_party/crashpad/crashpad/client/crashpad_client_linux.cc b/third_party/crashpad/crashpad/client/crashpad_client_linux.cc
index f805ff1..1d79be7a 100644
--- a/third_party/crashpad/crashpad/client/crashpad_client_linux.cc
+++ b/third_party/crashpad/crashpad/client/crashpad_client_linux.cc
@@ -30,6 +30,7 @@
 
 #include <atomic>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
 #include "build/build_config.h"
diff --git a/third_party/crashpad/crashpad/client/crashpad_client_mac.cc b/third_party/crashpad/crashpad/client/crashpad_client_mac.cc
index 09ea088..7ee4c50 100644
--- a/third_party/crashpad/crashpad/client/crashpad_client_mac.cc
+++ b/third_party/crashpad/crashpad/client/crashpad_client_mac.cc
@@ -25,6 +25,7 @@
 #include <utility>
 
 #include "base/apple/mach_logging.h"
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
 #include "util/mac/mac_util.h"
diff --git a/third_party/crashpad/crashpad/client/crashpad_client_win.cc b/third_party/crashpad/crashpad/client/crashpad_client_win.cc
index a1da1df..b444bbc 100644
--- a/third_party/crashpad/crashpad/client/crashpad_client_win.cc
+++ b/third_party/crashpad/crashpad/client/crashpad_client_win.cc
@@ -27,6 +27,7 @@
 #include <memory>
 
 #include "base/atomicops.h"
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/scoped_generic.h"
 #include "base/strings/stringprintf.h"
diff --git a/third_party/crashpad/crashpad/client/ios_handler/in_process_intermediate_dump_handler.cc b/third_party/crashpad/crashpad/client/ios_handler/in_process_intermediate_dump_handler.cc
index 06eacce..a7ac5da 100644
--- a/third_party/crashpad/crashpad/client/ios_handler/in_process_intermediate_dump_handler.cc
+++ b/third_party/crashpad/crashpad/client/ios_handler/in_process_intermediate_dump_handler.cc
@@ -24,6 +24,7 @@
 #include <iterator>
 #include <optional>
 
+#include "base/check_op.h"
 #include "build/build_config.h"
 #include "snapshot/snapshot_constants.h"
 #include "util/ios/ios_intermediate_dump_writer.h"
diff --git a/third_party/crashpad/crashpad/handler/linux/exception_handler_server.cc b/third_party/crashpad/crashpad/handler/linux/exception_handler_server.cc
index b13a9e3d..64c77aa3 100644
--- a/third_party/crashpad/crashpad/handler/linux/exception_handler_server.cc
+++ b/third_party/crashpad/crashpad/handler/linux/exception_handler_server.cc
@@ -25,6 +25,7 @@
 
 #include <utility>
 
+#include "base/check_op.h"
 #include "base/compiler_specific.h"
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_annotation_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_annotation_writer.cc
index 1d6a492..751dd013 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_annotation_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_annotation_writer.cc
@@ -16,6 +16,7 @@
 
 #include <memory>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "util/file/file_writer.h"
 #include "util/numeric/safe_assignment.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_byte_array_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_byte_array_writer.cc
index 38ce1c7..b3c8aa9d 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_byte_array_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_byte_array_writer.cc
@@ -14,6 +14,7 @@
 
 #include "minidump/minidump_byte_array_writer.h"
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "util/file/file_writer.h"
 #include "util/numeric/safe_assignment.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_context_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_context_writer.cc
index 84c01482..326b51f 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_context_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_context_writer.cc
@@ -19,6 +19,7 @@
 #include <stdint.h>
 #include <string.h>
 
+#include "base/check_op.h"
 #include "base/compiler_specific.h"
 #include "base/logging.h"
 #include "build/build_config.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_file_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_file_writer.cc
index 6c9b5cc..021b187 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_file_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_file_writer.cc
@@ -16,6 +16,7 @@
 
 #include <utility>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "minidump/minidump_crashpad_info_writer.h"
 #include "minidump/minidump_exception_writer.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_handle_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_handle_writer.cc
index bed4f10..72f1b19 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_handle_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_handle_writer.cc
@@ -16,6 +16,7 @@
 
 #include <string>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "minidump/minidump_extensions.h"
 #include "util/file/file_writer.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_memory_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_memory_writer.cc
index f52e6a4..dd6c91a 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_memory_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_memory_writer.cc
@@ -19,6 +19,7 @@
 #include <utility>
 
 #include "base/auto_reset.h"
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "util/file/file_writer.h"
 #include "util/numeric/safe_assignment.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_module_crashpad_info_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_module_crashpad_info_writer.cc
index 456f4bd4..7f3dcda 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_module_crashpad_info_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_module_crashpad_info_writer.cc
@@ -16,6 +16,7 @@
 
 #include <utility>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "minidump/minidump_annotation_writer.h"
 #include "minidump/minidump_simple_string_dictionary_writer.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_module_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_module_writer.cc
index 237fee0..1287a6d 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_module_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_module_writer.cc
@@ -19,6 +19,7 @@
 #include <limits>
 #include <utility>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
 #include "minidump/minidump_string_writer.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_rva_list_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_rva_list_writer.cc
index 77e10d47..3a1ee8e 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_rva_list_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_rva_list_writer.cc
@@ -16,6 +16,7 @@
 
 #include <utility>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "util/file/file_writer.h"
 #include "util/numeric/safe_assignment.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_simple_string_dictionary_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_simple_string_dictionary_writer.cc
index f4c9011c..cb25098 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_simple_string_dictionary_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_simple_string_dictionary_writer.cc
@@ -16,6 +16,7 @@
 
 #include <utility>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "util/file/file_writer.h"
 #include "util/numeric/safe_assignment.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_string_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_string_writer.cc
index ea7856ab..0b0a3e8 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_string_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_string_writer.cc
@@ -16,6 +16,7 @@
 
 #include <utility>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "minidump/minidump_writer_util.h"
 #include "util/file/file_writer.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_thread_name_list_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_thread_name_list_writer.cc
index 5679b81..aba496a 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_thread_name_list_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_thread_name_list_writer.cc
@@ -16,6 +16,7 @@
 
 #include <utility>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "minidump/minidump_thread_id_map.h"
 #include "snapshot/thread_snapshot.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_thread_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_thread_writer.cc
index 02870f6e..b7aa889 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_thread_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_thread_writer.cc
@@ -16,6 +16,7 @@
 
 #include <utility>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "minidump/minidump_context_writer.h"
 #include "minidump/minidump_memory_writer.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_unloaded_module_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_unloaded_module_writer.cc
index 3f1c8e5d..c7bf3452 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_unloaded_module_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_unloaded_module_writer.cc
@@ -17,6 +17,7 @@
 #include <limits>
 #include <utility>
 
+#include "base/check_op.h"
 #include "minidump/minidump_writer_util.h"
 #include "util/file/file_writer.h"
 #include "util/numeric/in_range_cast.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_writable.cc b/third_party/crashpad/crashpad/minidump/minidump_writable.cc
index cb23b3f..c0badd7 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_writable.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_writable.cc
@@ -18,6 +18,7 @@
 
 #include <iterator>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "util/file/file_writer.h"
 #include "util/numeric/safe_assignment.h"
diff --git a/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader.cc b/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader.cc
index dcab025..b0340e5f 100644
--- a/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader.cc
+++ b/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader.cc
@@ -21,6 +21,7 @@
 #include <utility>
 #include <vector>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/numerics/safe_math.h"
 #include "build/build_config.h"
diff --git a/third_party/crashpad/crashpad/snapshot/fuchsia/process_reader_fuchsia.cc b/third_party/crashpad/crashpad/snapshot/fuchsia/process_reader_fuchsia.cc
index 89aa74d..5bf2acf 100644
--- a/third_party/crashpad/crashpad/snapshot/fuchsia/process_reader_fuchsia.cc
+++ b/third_party/crashpad/crashpad/snapshot/fuchsia/process_reader_fuchsia.cc
@@ -18,6 +18,7 @@
 #include <link.h>
 #include <zircon/syscalls.h>
 
+#include "base/check_op.h"
 #include "base/fuchsia/fuchsia_logging.h"
 #include "base/logging.h"
 #include "util/fuchsia/koid_utilities.h"
diff --git a/third_party/crashpad/crashpad/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc b/third_party/crashpad/crashpad/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc
index cee9c8a..e347845 100644
--- a/third_party/crashpad/crashpad/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc
+++ b/third_party/crashpad/crashpad/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc
@@ -15,6 +15,7 @@
 #include "snapshot/ios/exception_snapshot_ios_intermediate_dump.h"
 
 #include "base/apple/mach_logging.h"
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "snapshot/cpu_context.h"
 #include "snapshot/ios/intermediate_dump_reader_util.h"
diff --git a/third_party/crashpad/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.cc b/third_party/crashpad/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.cc
index a3c7a13..b272eb65 100644
--- a/third_party/crashpad/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.cc
+++ b/third_party/crashpad/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.cc
@@ -14,6 +14,8 @@
 
 #include "snapshot/ios/memory_snapshot_ios_intermediate_dump.h"
 
+#include "base/check_op.h"
+
 namespace crashpad {
 namespace internal {
 
diff --git a/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.cc
index 20b95fb..b32f22d7 100644
--- a/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.cc
+++ b/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.cc
@@ -20,6 +20,7 @@
 
 #include <algorithm>
 
+#include "base/check_op.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/notreached.h"
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader.cc b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader.cc
index 7282552..b648f7f 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader.cc
@@ -22,6 +22,7 @@
 #include <limits>
 #include <utility>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
 #include "client/crashpad_info.h"
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc
index 75f229e..17b7bd33 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc
@@ -20,6 +20,7 @@
 
 #include <utility>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
 #include "build/build_config.h"
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_reader_mac.cc b/third_party/crashpad/crashpad/snapshot/mac/process_reader_mac.cc
index 53dae07..c77c0d3 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/process_reader_mac.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/process_reader_mac.cc
@@ -24,6 +24,7 @@
 #include "base/apple/mach_logging.h"
 #include "base/apple/scoped_mach_port.h"
 #include "base/apple/scoped_mach_vm.h"
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
 #include "snapshot/mac/mach_o_image_reader.h"
diff --git a/third_party/crashpad/crashpad/snapshot/minidump/module_snapshot_minidump.cc b/third_party/crashpad/crashpad/snapshot/minidump/module_snapshot_minidump.cc
index 43229e7..50e5ea85 100644
--- a/third_party/crashpad/crashpad/snapshot/minidump/module_snapshot_minidump.cc
+++ b/third_party/crashpad/crashpad/snapshot/minidump/module_snapshot_minidump.cc
@@ -17,6 +17,7 @@
 #include <stddef.h>
 #include <string.h>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/notreached.h"
 #include "minidump/minidump_extensions.h"
diff --git a/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc b/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc
index 0c4ca0c6..469d789 100644
--- a/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc
+++ b/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc
@@ -19,6 +19,7 @@
 
 #include <memory>
 
+#include "base/check_op.h"
 #include "base/notreached.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/utf_string_conversions.h"
diff --git a/third_party/crashpad/crashpad/test/ios/host/handler_forbidden_allocators.cc b/third_party/crashpad/crashpad/test/ios/host/handler_forbidden_allocators.cc
index 6635257..a14361c 100644
--- a/third_party/crashpad/crashpad/test/ios/host/handler_forbidden_allocators.cc
+++ b/third_party/crashpad/crashpad/test/ios/host/handler_forbidden_allocators.cc
@@ -17,9 +17,11 @@
 #include <CoreFoundation/CoreFoundation.h>
 #include <malloc/malloc.h>
 #include <pthread.h>
+
 #include <limits>
 
 #include "base/apple/mach_logging.h"
+#include "base/check_op.h"
 #include "client/crashpad_client.h"
 #include "util/ios/raw_logging.h"
 
diff --git a/third_party/crashpad/crashpad/util/file/file_io_posix.cc b/third_party/crashpad/crashpad/util/file/file_io_posix.cc
index 07c24c3..6d02462b 100644
--- a/third_party/crashpad/crashpad/util/file/file_io_posix.cc
+++ b/third_party/crashpad/crashpad/util/file/file_io_posix.cc
@@ -24,6 +24,7 @@
 #include <algorithm>
 #include <limits>
 
+#include "base/check_op.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/notreached.h"
diff --git a/third_party/crashpad/crashpad/util/file/file_io_win.cc b/third_party/crashpad/crashpad/util/file/file_io_win.cc
index 595e357..cb9ea14 100644
--- a/third_party/crashpad/crashpad/util/file/file_io_win.cc
+++ b/third_party/crashpad/crashpad/util/file/file_io_win.cc
@@ -17,6 +17,7 @@
 #include <algorithm>
 #include <limits>
 
+#include "base/check_op.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/notreached.h"
diff --git a/third_party/crashpad/crashpad/util/file/file_reader.cc b/third_party/crashpad/crashpad/util/file/file_reader.cc
index b4e8956..f8fcf81 100644
--- a/third_party/crashpad/crashpad/util/file/file_reader.cc
+++ b/third_party/crashpad/crashpad/util/file/file_reader.cc
@@ -14,6 +14,7 @@
 
 #include "util/file/file_reader.h"
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
 #include "build/build_config.h"
diff --git a/third_party/crashpad/crashpad/util/file/file_writer.cc b/third_party/crashpad/crashpad/util/file/file_writer.cc
index 74c55d6..a5bfa081 100644
--- a/third_party/crashpad/crashpad/util/file/file_writer.cc
+++ b/third_party/crashpad/crashpad/util/file/file_writer.cc
@@ -20,6 +20,7 @@
 
 #include <algorithm>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
 #include "build/build_config.h"
diff --git a/third_party/crashpad/crashpad/util/file/string_file.cc b/third_party/crashpad/crashpad/util/file/string_file.cc
index 56f65cd..7ff966e 100644
--- a/third_party/crashpad/crashpad/util/file/string_file.cc
+++ b/third_party/crashpad/crashpad/util/file/string_file.cc
@@ -19,6 +19,7 @@
 #include <algorithm>
 #include <limits>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/numerics/ostream_operators.h"
 #include "base/numerics/safe_math.h"
diff --git a/third_party/crashpad/crashpad/util/fuchsia/scoped_task_suspend.cc b/third_party/crashpad/crashpad/util/fuchsia/scoped_task_suspend.cc
index 0dd5425..ef057ae 100644
--- a/third_party/crashpad/crashpad/util/fuchsia/scoped_task_suspend.cc
+++ b/third_party/crashpad/crashpad/util/fuchsia/scoped_task_suspend.cc
@@ -21,6 +21,7 @@
 
 #include <vector>
 
+#include "base/check_op.h"
 #include "base/fuchsia/fuchsia_logging.h"
 #include "base/logging.h"
 #include "util/fuchsia/koid_utilities.h"
diff --git a/third_party/crashpad/crashpad/util/ios/ios_intermediate_dump_writer.cc b/third_party/crashpad/crashpad/util/ios/ios_intermediate_dump_writer.cc
index c180fc0..67d804b3 100644
--- a/third_party/crashpad/crashpad/util/ios/ios_intermediate_dump_writer.cc
+++ b/third_party/crashpad/crashpad/util/ios/ios_intermediate_dump_writer.cc
@@ -23,6 +23,7 @@
 #include <ostream>
 
 #include "base/check.h"
+#include "base/check_op.h"
 #include "base/posix/eintr_wrapper.h"
 #include "build/build_config.h"
 #include "util/ios/raw_logging.h"
diff --git a/third_party/crashpad/crashpad/util/linux/exception_handler_client.cc b/third_party/crashpad/crashpad/util/linux/exception_handler_client.cc
index cef493df..68dc67ef 100644
--- a/third_party/crashpad/crashpad/util/linux/exception_handler_client.cc
+++ b/third_party/crashpad/crashpad/util/linux/exception_handler_client.cc
@@ -20,6 +20,7 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
 #include "build/build_config.h"
diff --git a/third_party/crashpad/crashpad/util/linux/memory_map.cc b/third_party/crashpad/crashpad/util/linux/memory_map.cc
index 2c18f30..58de835e 100644
--- a/third_party/crashpad/crashpad/util/linux/memory_map.cc
+++ b/third_party/crashpad/crashpad/util/linux/memory_map.cc
@@ -19,6 +19,7 @@
 #include <sys/sysmacros.h>
 
 #include "base/bit_cast.h"
+#include "base/check_op.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "build/build_config.h"
diff --git a/third_party/crashpad/crashpad/util/linux/proc_task_reader.cc b/third_party/crashpad/crashpad/util/linux/proc_task_reader.cc
index ba1f032..2dd7dd7 100644
--- a/third_party/crashpad/crashpad/util/linux/proc_task_reader.cc
+++ b/third_party/crashpad/crashpad/util/linux/proc_task_reader.cc
@@ -18,6 +18,7 @@
 
 #include <iterator>
 
+#include "base/check_op.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
diff --git a/third_party/crashpad/crashpad/util/linux/ptrace_client.cc b/third_party/crashpad/crashpad/util/linux/ptrace_client.cc
index c04ca5b4..56bc555 100644
--- a/third_party/crashpad/crashpad/util/linux/ptrace_client.cc
+++ b/third_party/crashpad/crashpad/util/linux/ptrace_client.cc
@@ -21,6 +21,7 @@
 #include <iterator>
 #include <string>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
 #include "util/file/file_io.h"
diff --git a/third_party/crashpad/crashpad/util/linux/ptracer.cc b/third_party/crashpad/crashpad/util/linux/ptracer.cc
index d8129ad..a985cb1d 100644
--- a/third_party/crashpad/crashpad/util/linux/ptracer.cc
+++ b/third_party/crashpad/crashpad/util/linux/ptracer.cc
@@ -20,6 +20,7 @@
 #include <sys/ptrace.h>
 #include <sys/uio.h>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "build/build_config.h"
 #include "util/misc/from_pointer_cast.h"
diff --git a/third_party/crashpad/crashpad/util/mac/xattr.cc b/third_party/crashpad/crashpad/util/mac/xattr.cc
index ae3555d7..6c12e913 100644
--- a/third_party/crashpad/crashpad/util/mac/xattr.cc
+++ b/third_party/crashpad/crashpad/util/mac/xattr.cc
@@ -19,6 +19,7 @@
 #include <sys/types.h>
 #include <sys/xattr.h>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
diff --git a/third_party/crashpad/crashpad/util/mach/mach_message_server.cc b/third_party/crashpad/crashpad/util/mach/mach_message_server.cc
index bfe8a8c..b4509a9a 100644
--- a/third_party/crashpad/crashpad/util/mach/mach_message_server.cc
+++ b/third_party/crashpad/crashpad/util/mach/mach_message_server.cc
@@ -20,6 +20,7 @@
 
 #include "base/apple/mach_logging.h"
 #include "base/apple/scoped_mach_vm.h"
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "util/mach/mach_message.h"
 
diff --git a/third_party/crashpad/crashpad/util/net/http_body_gzip.cc b/third_party/crashpad/crashpad/util/net/http_body_gzip.cc
index bd0ec5f8..a7882ea 100644
--- a/third_party/crashpad/crashpad/util/net/http_body_gzip.cc
+++ b/third_party/crashpad/crashpad/util/net/http_body_gzip.cc
@@ -16,6 +16,7 @@
 
 #include <utility>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
 #include "third_party/zlib/zlib_crashpad.h"
diff --git a/third_party/crashpad/crashpad/util/net/http_transport_socket.cc b/third_party/crashpad/crashpad/util/net/http_transport_socket.cc
index 3aec8c0..0d7fc0d 100644
--- a/third_party/crashpad/crashpad/util/net/http_transport_socket.cc
+++ b/third_party/crashpad/crashpad/util/net/http_transport_socket.cc
@@ -20,6 +20,7 @@
 
 #include <iterator>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/posix/eintr_wrapper.h"
diff --git a/third_party/crashpad/crashpad/util/net/http_transport_win.cc b/third_party/crashpad/crashpad/util/net/http_transport_win.cc
index 6bc2481..df444d8 100644
--- a/third_party/crashpad/crashpad/util/net/http_transport_win.cc
+++ b/third_party/crashpad/crashpad/util/net/http_transport_win.cc
@@ -24,6 +24,7 @@
 
 #include <iterator>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/scoped_generic.h"
diff --git a/third_party/crashpad/crashpad/util/posix/close_multiple.cc b/third_party/crashpad/crashpad/util/posix/close_multiple.cc
index 528d7cf..f5d7b00 100644
--- a/third_party/crashpad/crashpad/util/posix/close_multiple.cc
+++ b/third_party/crashpad/crashpad/util/posix/close_multiple.cc
@@ -23,6 +23,7 @@
 #include <algorithm>
 #include <iterator>
 
+#include "base/check_op.h"
 #include "base/files/scoped_file.h"
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
diff --git a/third_party/crashpad/crashpad/util/posix/process_info_mac.cc b/third_party/crashpad/crashpad/util/posix/process_info_mac.cc
index 07a93a5..cf61519 100644
--- a/third_party/crashpad/crashpad/util/posix/process_info_mac.cc
+++ b/third_party/crashpad/crashpad/util/posix/process_info_mac.cc
@@ -19,6 +19,7 @@
 #include <iterator>
 
 #include "base/apple/mach_logging.h"
+#include "base/check_op.h"
 #include "base/logging.h"
 
 namespace crashpad {
diff --git a/third_party/crashpad/crashpad/util/process/process_memory_fuchsia.cc b/third_party/crashpad/crashpad/util/process/process_memory_fuchsia.cc
index 7129f8a..a14c2ac6 100644
--- a/third_party/crashpad/crashpad/util/process/process_memory_fuchsia.cc
+++ b/third_party/crashpad/crashpad/util/process/process_memory_fuchsia.cc
@@ -16,8 +16,9 @@
 
 #include <limits>
 
-#include "base/logging.h"
+#include "base/check_op.h"
 #include "base/fuchsia/fuchsia_logging.h"
+#include "base/logging.h"
 
 namespace crashpad {
 
diff --git a/third_party/crashpad/crashpad/util/process/process_memory_linux.cc b/third_party/crashpad/crashpad/util/process/process_memory_linux.cc
index 1e9002d..9c2edea 100644
--- a/third_party/crashpad/crashpad/util/process/process_memory_linux.cc
+++ b/third_party/crashpad/crashpad/util/process/process_memory_linux.cc
@@ -22,6 +22,7 @@
 #include <algorithm>
 #include <limits>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
 #include "build/build_config.h"
diff --git a/third_party/crashpad/crashpad/util/process/process_memory_mac.cc b/third_party/crashpad/crashpad/util/process/process_memory_mac.cc
index a3cb669..a972401 100644
--- a/third_party/crashpad/crashpad/util/process/process_memory_mac.cc
+++ b/third_party/crashpad/crashpad/util/process/process_memory_mac.cc
@@ -20,6 +20,7 @@
 #include <algorithm>
 
 #include "base/apple/mach_logging.h"
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
 #include "util/stdlib/strnlen.h"
diff --git a/third_party/crashpad/crashpad/util/process/process_memory_win.cc b/third_party/crashpad/crashpad/util/process/process_memory_win.cc
index 8c5a167..c120827 100644
--- a/third_party/crashpad/crashpad/util/process/process_memory_win.cc
+++ b/third_party/crashpad/crashpad/util/process/process_memory_win.cc
@@ -19,6 +19,7 @@
 #include <algorithm>
 #include <limits>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/memory/page_size.h"
 #include "base/numerics/safe_conversions.h"
diff --git a/third_party/crashpad/crashpad/util/win/process_info.cc b/third_party/crashpad/crashpad/util/win/process_info.cc
index c5d4138..888b9ea 100644
--- a/third_party/crashpad/crashpad/util/win/process_info.cc
+++ b/third_party/crashpad/crashpad/util/win/process_info.cc
@@ -23,6 +23,7 @@
 #include <new>
 #include <type_traits>
 
+#include "base/check_op.h"
 #include "base/logging.h"
 #include "base/memory/free_deleter.h"
 #include "base/process/memory.h"
diff --git a/third_party/dawn b/third_party/dawn
index c324517..3d86265 160000
--- a/third_party/dawn
+++ b/third_party/dawn
@@ -1 +1 @@
-Subproject commit c3245174b4f2bf8d8bb5d74a343397d568e5ca9a
+Subproject commit 3d86265f5114096248c400539e3bc4da9d4bc834
diff --git a/third_party/depot_tools b/third_party/depot_tools
index 406be82..8f761f5 160000
--- a/third_party/depot_tools
+++ b/third_party/depot_tools
@@ -1 +1 @@
-Subproject commit 406be8281e32743a86df7c855ba608739e812dea
+Subproject commit 8f761f57958a1affcc2752f48ba5e5edf8dc1042
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal
index 4cbcaa0..afa14b3 160000
--- a/third_party/devtools-frontend-internal
+++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@
-Subproject commit 4cbcaa06310577799ba02946d89a4f8b4218a0b9
+Subproject commit afa14b392c2fddb74fbf11018f8dad67d5c42f95
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src
index 31efe53..44e8b42 160000
--- a/third_party/devtools-frontend/src
+++ b/third_party/devtools-frontend/src
@@ -1 +1 @@
-Subproject commit 31efe53d04bae3442cb0bf323586848a6893a490
+Subproject commit 44e8b4234dadbbf5d67d4b82cf8e26e3ce525395
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index 55ba41e..c466bfa 100644
--- a/third_party/freetype/README.chromium
+++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@
 Name: FreeType
 URL: http://www.freetype.org/
-Version: VER-2-13-2-41-g3fa5c8456
-Revision: 3fa5c84565f2431a13247f055623508137dc5739
+Version: VER-2-13-2-42-ga35da2c09
+Revision: a35da2c09312e222e5728e849988f1acf998df9a
 CPEPrefix: cpe:/a:freetype:freetype:2.13.2
 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
          JPEG Group) licenses"
diff --git a/third_party/freetype/src b/third_party/freetype/src
index 3fa5c84..a35da2c 160000
--- a/third_party/freetype/src
+++ b/third_party/freetype/src
@@ -1 +1 @@
-Subproject commit 3fa5c84565f2431a13247f055623508137dc5739
+Subproject commit a35da2c09312e222e5728e849988f1acf998df9a
diff --git a/third_party/libc++/src b/third_party/libc++/src
index 2f6750b..8d4b8a6 160000
--- a/third_party/libc++/src
+++ b/third_party/libc++/src
@@ -1 +1 @@
-Subproject commit 2f6750b44bbad5726de61f2b4e2021fedba63666
+Subproject commit 8d4b8a60c23515932186285479fe1e9c073cc513
diff --git a/third_party/libc++abi/src b/third_party/libc++abi/src
index db9800c..cbc5f2b 160000
--- a/third_party/libc++abi/src
+++ b/third_party/libc++abi/src
@@ -1 +1 @@
-Subproject commit db9800c042df3ee2691031a58b5e37e89a7356a3
+Subproject commit cbc5f2b0cdd7de12e105368fe4d5bb4109278998
diff --git a/third_party/mediapipe/BUILD.gn b/third_party/mediapipe/BUILD.gn
index 33f1e98..9fcde15 100644
--- a/third_party/mediapipe/BUILD.gn
+++ b/third_party/mediapipe/BUILD.gn
@@ -124,6 +124,7 @@
     "src/mediapipe/framework/tool/field_data.proto",
     "src/mediapipe/framework/tool/packet_generator_wrapper_calculator.proto",
     "src/mediapipe/gpu/gl_context_options.proto",
+    "src/mediapipe/gpu/gpu_origin.proto",
     "src/mediapipe/tasks/cc/components/calculators/classification_aggregation_calculator.proto",
     "src/mediapipe/tasks/cc/components/calculators/score_calibration_calculator.proto",
     "src/mediapipe/tasks/cc/components/containers/proto/classifications.proto",
diff --git a/third_party/mediapipe/README.chromium b/third_party/mediapipe/README.chromium
index ca575db..49fe6f7 100644
--- a/third_party/mediapipe/README.chromium
+++ b/third_party/mediapipe/README.chromium
@@ -1,8 +1,8 @@
 Name: MediaPipe
 Short Name: mediapipe
 URL: https://github.com/google/mediapipe
-Version: 6915a79e288afec408edc4bc3f851613200efb8f
-Date: 2023-09-29
+Version: 06cc6d1546788fbdedd0babe41a51d3fa8947d6e
+Date: 2023-10-18
 License: Apache 2.0
 License File: LICENSE
 Security Critical: Yes
diff --git a/third_party/mediapipe/src/WORKSPACE b/third_party/mediapipe/src/WORKSPACE
index 4f7bb3b..df2c4f93 100644
--- a/third_party/mediapipe/src/WORKSPACE
+++ b/third_party/mediapipe/src/WORKSPACE
@@ -244,16 +244,14 @@
 # sentencepiece
 http_archive(
     name = "com_google_sentencepiece",
-    strip_prefix = "sentencepiece-1.0.0",
-    sha256 = "c05901f30a1d0ed64cbcf40eba08e48894e1b0e985777217b7c9036cac631346",
+    strip_prefix = "sentencepiece-0.1.96",
+    sha256 = "8409b0126ebd62b256c685d5757150cf7fcb2b92a2f2b98efb3f38fc36719754",
     urls = [
-        "https://github.com/google/sentencepiece/archive/1.0.0.zip",
+        "https://github.com/google/sentencepiece/archive/refs/tags/v0.1.96.zip"
     ],
-    patches = [
-        "@//third_party:com_google_sentencepiece_no_gflag_no_gtest.diff",
-    ],
+    build_file = "@//third_party:sentencepiece.BUILD",
+    patches = ["@//third_party:com_google_sentencepiece.diff"],
     patch_args = ["-p1"],
-    repo_mapping = {"@com_google_glog" : "@com_github_glog_glog_no_gflags"},
 )
 
 http_archive(
diff --git a/third_party/mediapipe/src/mediapipe/calculators/core/bypass_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/core/bypass_calculator.cc
index 4e00732..3392d8f 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/core/bypass_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/core/bypass_calculator.cc
@@ -92,7 +92,7 @@
     auto options = cc->Options<BypassCalculatorOptions>();
     RET_CHECK_EQ(options.pass_input_stream().size(),
                  options.pass_output_stream().size());
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         auto pass_streams,
         GetPassMap(options, *cc->Inputs().TagMap(), *cc->Outputs().TagMap()));
     std::set<CollectionItemId> pass_out;
@@ -121,8 +121,9 @@
   // Saves the map of passthrough input and output stream ids.
   absl::Status Open(CalculatorContext* cc) override {
     auto options = cc->Options<BypassCalculatorOptions>();
-    ASSIGN_OR_RETURN(pass_streams_, GetPassMap(options, *cc->Inputs().TagMap(),
-                                               *cc->Outputs().TagMap()));
+    MP_ASSIGN_OR_RETURN(
+        pass_streams_,
+        GetPassMap(options, *cc->Inputs().TagMap(), *cc->Outputs().TagMap()));
     return absl::OkStatus();
   }
 
diff --git a/third_party/mediapipe/src/mediapipe/calculators/core/value_or_default_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/core/value_or_default_calculator.cc
new file mode 100644
index 0000000..2ce68187
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/core/value_or_default_calculator.cc
@@ -0,0 +1,90 @@
+#include "mediapipe/framework/calculator_framework.h"
+#include "mediapipe/framework/port/status.h"
+
+namespace mediapipe {
+namespace {
+
+constexpr char kInputValueTag[] = "IN";
+constexpr char kTickerTag[] = "TICK";
+constexpr char kOutputTag[] = "OUT";
+constexpr char kIndicationTag[] = "FLAG";
+
+}  // namespace
+// For every packet received on the TICK stream, if the IN stream is not
+// empty - emit its value as is as OUT. Otherwise output a default packet.
+// FLAG outputs true every time the default value has been used. It does not
+//   output anything when IN has a value.
+//
+// Example config:
+// node {
+//   calculator: "ValueOrDefaultCalculator"
+//   input_stream: "IN:sometimes_missing_value"
+//   input_stream: "TICK:clock"
+//   output_stream: "OUT:value_or_default"
+//   output_stream: "FLAG:used_default"
+//   input_side_packet: "default"
+// }
+//
+// TODO: Consider adding an option for a default value as a input-stream
+// instead of a side-packet, so it will enable using standard calculators
+// instead of creating a new packet-generators. It will also allow a dynamic
+// default value.
+class ValueOrDefaultCalculator : public mediapipe::CalculatorBase {
+ public:
+  ValueOrDefaultCalculator() {}
+
+  ValueOrDefaultCalculator(const ValueOrDefaultCalculator&) = delete;
+  ValueOrDefaultCalculator& operator=(const ValueOrDefaultCalculator&) = delete;
+
+  static mediapipe::Status GetContract(mediapipe::CalculatorContract* cc) {
+    cc->Inputs().Tag(kInputValueTag).SetAny();
+    cc->Inputs().Tag(kTickerTag).SetAny();
+    cc->Outputs().Tag(kOutputTag).SetSameAs(&cc->Inputs().Tag(kInputValueTag));
+    cc->Outputs().Tag(kIndicationTag).Set<bool>();
+    cc->InputSidePackets().Index(0).SetSameAs(
+        &cc->Inputs().Tag(kInputValueTag));
+
+    return mediapipe::OkStatus();
+  }
+
+  mediapipe::Status Open(mediapipe::CalculatorContext* cc) override {
+    if (!cc->Inputs().Tag(kInputValueTag).Header().IsEmpty()) {
+      cc->Outputs()
+          .Tag(kOutputTag)
+          .SetHeader(cc->Inputs().Tag(kInputValueTag).Header());
+    }
+    default_ = cc->InputSidePackets().Index(0);
+    cc->SetOffset(mediapipe::TimestampDiff(0));
+    return mediapipe::OkStatus();
+  }
+
+  mediapipe::Status Process(mediapipe::CalculatorContext* cc) override {
+    // Output according to the TICK signal.
+    if (cc->Inputs().Tag(kTickerTag).IsEmpty()) {
+      return mediapipe::OkStatus();
+    }
+    if (!cc->Inputs().Tag(kInputValueTag).IsEmpty()) {
+      // Output the input as is:
+      cc->Outputs()
+          .Tag(kOutputTag)
+          .AddPacket(cc->Inputs().Tag(kInputValueTag).Value());
+    } else {
+      // Output default:
+      cc->Outputs()
+          .Tag(kOutputTag)
+          .AddPacket(default_.At(cc->InputTimestamp()));
+      cc->Outputs()
+          .Tag(kIndicationTag)
+          .Add(new bool(true), cc->InputTimestamp());
+    }
+    return mediapipe::OkStatus();
+  }
+
+ private:
+  // The default value to replicate every time there is no new value.
+  mediapipe::Packet default_;
+};
+
+REGISTER_CALCULATOR(ValueOrDefaultCalculator);
+
+}  // namespace mediapipe
diff --git a/third_party/mediapipe/src/mediapipe/calculators/image/BUILD b/third_party/mediapipe/src/mediapipe/calculators/image/BUILD
index 259012d..e32e716 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/image/BUILD
+++ b/third_party/mediapipe/src/mediapipe/calculators/image/BUILD
@@ -786,6 +786,7 @@
             ":affine_transformation_runner_gl",
             "//mediapipe/gpu:gl_calculator_helper",
             "//mediapipe/gpu:gpu_buffer",
+            "//mediapipe/gpu:gpu_service",
         ],
     }) + select({
         "//mediapipe/framework/port:disable_opencv": [],
diff --git a/third_party/mediapipe/src/mediapipe/calculators/image/affine_transformation_runner_gl.cc b/third_party/mediapipe/src/mediapipe/calculators/image/affine_transformation_runner_gl.cc
index 0fe2d274..6d4a9a1 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/image/affine_transformation_runner_gl.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/image/affine_transformation_runner_gl.cc
@@ -223,7 +223,7 @@
           absl::StrCat(mediapipe::kMediaPipeFragmentShaderPreamble,
                        interpolation_def, kFragShader);
 
-      ASSIGN_OR_RETURN(program_, create_fn(vert_src, frag_src));
+      MP_ASSIGN_OR_RETURN(program_, create_fn(vert_src, frag_src));
 
       auto create_custom_zero_fn = [&]() -> absl::StatusOr<Program> {
         std::string custom_zero_border_mode_def = R"(
@@ -236,10 +236,10 @@
       };
 #if GL_CLAMP_TO_BORDER_MAY_BE_SUPPORTED
       if (!IsGlClampToBorderSupported(gl_helper_->GetGlContext())) {
-        ASSIGN_OR_RETURN(program_custom_zero_, create_custom_zero_fn());
+        MP_ASSIGN_OR_RETURN(program_custom_zero_, create_custom_zero_fn());
       }
 #else
-      ASSIGN_OR_RETURN(program_custom_zero_, create_custom_zero_fn());
+      MP_ASSIGN_OR_RETURN(program_custom_zero_, create_custom_zero_fn());
 #endif  // GL_CLAMP_TO_BORDER_MAY_BE_SUPPORTED
 
       glGenFramebuffers(1, &framebuffer_);
diff --git a/third_party/mediapipe/src/mediapipe/calculators/image/image_clone_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/image/image_clone_calculator.cc
index 6660d55b..563b4a4 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/image/image_clone_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/image/image_clone_calculator.cc
@@ -64,7 +64,8 @@
           "GPU processing is disabled in build flags");
     }
 #else
-    MP_RETURN_IF_ERROR(mediapipe::GlCalculatorHelper::UpdateContract(cc));
+    MP_RETURN_IF_ERROR(mediapipe::GlCalculatorHelper::UpdateContract(
+        cc, /*requesst_gpu_as_optional=*/true));
 #endif  // MEDIAPIPE_DISABLE_GPU
     return absl::OkStatus();
   }
@@ -72,9 +73,6 @@
   absl::Status Open(CalculatorContext* cc) override {
     const auto& options = cc->Options<mediapipe::ImageCloneCalculatorOptions>();
     output_on_gpu_ = options.output_on_gpu();
-#if !MEDIAPIPE_DISABLE_GPU
-    MP_RETURN_IF_ERROR(gpu_helper_.Open(cc));
-#endif  // !MEDIAPIPE_DISABLE_GPU
     return absl::OkStatus();
   }
 
@@ -104,6 +102,10 @@
 
     if (output_on_gpu_ && !input_on_gpu) {
 #if !MEDIAPIPE_DISABLE_GPU
+      if (!gpu_initialized_) {
+        MP_RETURN_IF_ERROR(gpu_helper_.Open(cc));
+        gpu_initialized_ = true;
+      }
       gpu_helper_.RunInGlContext([&output]() { output->ConvertToGpu(); });
 #endif  // !MEDIAPIPE_DISABLE_GPU
     } else if (!output_on_gpu_ && input_on_gpu) {
@@ -118,6 +120,7 @@
   bool output_on_gpu_;
 #if !MEDIAPIPE_DISABLE_GPU
   mediapipe::GlCalculatorHelper gpu_helper_;
+  bool gpu_initialized_ = false;
 #endif  // !MEDIAPIPE_DISABLE_GPU
 };
 MEDIAPIPE_REGISTER_NODE(ImageCloneCalculator);
diff --git a/third_party/mediapipe/src/mediapipe/calculators/image/image_file_properties_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/image/image_file_properties_calculator.cc
index 97478f9f..db01400 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/image/image_file_properties_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/image/image_file_properties_calculator.cc
@@ -92,11 +92,11 @@
   properties.set_focal_length_mm(result.FocalLength);
   properties.set_focal_length_35mm(result.FocalLengthIn35mm);
 
-  ASSIGN_OR_RETURN(auto focal_length_pixels,
-                   ComputeFocalLengthInPixels(properties.image_width(),
-                                              properties.image_height(),
-                                              properties.focal_length_35mm(),
-                                              properties.focal_length_mm()));
+  MP_ASSIGN_OR_RETURN(auto focal_length_pixels,
+                      ComputeFocalLengthInPixels(properties.image_width(),
+                                                 properties.image_height(),
+                                                 properties.focal_length_35mm(),
+                                                 properties.focal_length_mm()));
   properties.set_focal_length_pixels(focal_length_pixels);
 
   return properties;
@@ -151,7 +151,7 @@
     if (cc->InputSidePackets().NumEntries() == 1) {
       const std::string& image_bytes =
           cc->InputSidePackets().Index(0).Get<std::string>();
-      ASSIGN_OR_RETURN(properties_, GetImageFileProperites(image_bytes));
+      MP_ASSIGN_OR_RETURN(properties_, GetImageFileProperites(image_bytes));
       read_properties_ = true;
     }
 
@@ -169,7 +169,7 @@
         return absl::OkStatus();
       }
       const std::string& image_bytes = cc->Inputs().Index(0).Get<std::string>();
-      ASSIGN_OR_RETURN(properties_, GetImageFileProperites(image_bytes));
+      MP_ASSIGN_OR_RETURN(properties_, GetImageFileProperites(image_bytes));
       read_properties_ = true;
     }
     if (read_properties_) {
diff --git a/third_party/mediapipe/src/mediapipe/calculators/image/segmentation_smoothing_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/image/segmentation_smoothing_calculator.cc
index 1194412..d238975 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/image/segmentation_smoothing_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/image/segmentation_smoothing_calculator.cc
@@ -117,7 +117,8 @@
   cc->Outputs().Tag(kOutputMaskTag).Set<Image>();
 
 #if !MEDIAPIPE_DISABLE_GPU
-  MP_RETURN_IF_ERROR(mediapipe::GlCalculatorHelper::UpdateContract(cc));
+  MP_RETURN_IF_ERROR(mediapipe::GlCalculatorHelper::UpdateContract(
+      cc, /*requesst_gpu_as_optional=*/true));
 #endif  // !MEDIAPIPE_DISABLE_GPU
 
   return absl::OkStatus();
@@ -130,10 +131,6 @@
       cc->Options<mediapipe::SegmentationSmoothingCalculatorOptions>();
   combine_with_previous_ratio_ = options.combine_with_previous_ratio();
 
-#if !MEDIAPIPE_DISABLE_GPU
-  MP_RETURN_IF_ERROR(gpu_helper_.Open(cc));
-#endif  //  !MEDIAPIPE_DISABLE_GPU
-
   return absl::OkStatus();
 }
 
@@ -154,6 +151,9 @@
 
   if (use_gpu) {
 #if !MEDIAPIPE_DISABLE_GPU
+    if (!gpu_initialized_) {
+      MP_RETURN_IF_ERROR(gpu_helper_.Open(cc));
+    }
     MP_RETURN_IF_ERROR(gpu_helper_.RunInGlContext([this, cc]() -> absl::Status {
       if (!gpu_initialized_) {
         MP_RETURN_IF_ERROR(GlSetup(cc));
@@ -178,10 +178,12 @@
 
 absl::Status SegmentationSmoothingCalculator::Close(CalculatorContext* cc) {
 #if !MEDIAPIPE_DISABLE_GPU
-  gpu_helper_.RunInGlContext([this] {
-    if (program_) glDeleteProgram(program_);
-    program_ = 0;
-  });
+  if (gpu_initialized_) {
+    gpu_helper_.RunInGlContext([this] {
+      if (program_) glDeleteProgram(program_);
+      program_ = 0;
+    });
+  }
 #endif  // !MEDIAPIPE_DISABLE_GPU
 
   return absl::OkStatus();
diff --git a/third_party/mediapipe/src/mediapipe/calculators/image/warp_affine_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/image/warp_affine_calculator.cc
index dcc3710..dba500d 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/image/warp_affine_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/image/warp_affine_calculator.cc
@@ -36,6 +36,7 @@
 #if !MEDIAPIPE_DISABLE_GPU
 #include "mediapipe/gpu/gl_calculator_helper.h"
 #include "mediapipe/gpu/gpu_buffer.h"
+#include "mediapipe/gpu/gpu_service.h"
 #endif  // !MEDIAPIPE_DISABLE_GPU
 
 namespace mediapipe {
@@ -79,8 +80,8 @@
   }
   absl::StatusOr<RunnerType*> GetRunner() {
     if (!runner_) {
-      ASSIGN_OR_RETURN(runner_,
-                       CreateAffineTransformationOpenCvRunner(interpolation_));
+      MP_ASSIGN_OR_RETURN(
+          runner_, CreateAffineTransformationOpenCvRunner(interpolation_));
     }
     return runner_.get();
   }
@@ -106,10 +107,12 @@
         cc->Options<mediapipe::WarpAffineCalculatorOptions>().interpolation());
     return gl_helper_->Open(cc);
   }
+
   absl::StatusOr<RunnerType*> GetRunner() {
     if (!runner_) {
-      ASSIGN_OR_RETURN(runner_, CreateAffineTransformationGlRunner(
-                                    gl_helper_, gpu_origin_, interpolation_));
+      MP_ASSIGN_OR_RETURN(
+          runner_, CreateAffineTransformationGlRunner(gl_helper_, gpu_origin_,
+                                                      interpolation_));
     }
     return runner_.get();
   }
@@ -141,7 +144,10 @@
       MP_RETURN_IF_ERROR(cpu_holder_.Open(cc));
 #endif  // !MEDIAPIPE_DISABLE_OPENCV
 #if !MEDIAPIPE_DISABLE_GPU
-      MP_RETURN_IF_ERROR(gpu_holder_.Open(cc));
+      if (cc->Service(kGpuService).IsAvailable()) {
+        MP_RETURN_IF_ERROR(gpu_holder_.Open(cc));
+        gpu_holder_initialized_ = true;
+      }
 #endif  // !MEDIAPIPE_DISABLE_GPU
       return absl::OkStatus();
     }
@@ -151,24 +157,28 @@
         AffineTransformation::BorderMode border_mode) override {
       if (input.UsesGpu()) {
 #if !MEDIAPIPE_DISABLE_GPU
-        ASSIGN_OR_RETURN(auto* runner, gpu_holder_.GetRunner());
-        ASSIGN_OR_RETURN(auto result, runner->Run(input.GetGpuBuffer(), matrix,
-                                                  size, border_mode));
+        if (!gpu_holder_initialized_) {
+          return absl::UnavailableError("GPU support is not available");
+        }
+        MP_ASSIGN_OR_RETURN(auto* runner, gpu_holder_.GetRunner());
+        MP_ASSIGN_OR_RETURN(
+            auto result,
+            runner->Run(input.GetGpuBuffer(), matrix, size, border_mode));
         return mediapipe::Image(*result);
 #else
         return absl::UnavailableError("GPU support is disabled");
 #endif  // !MEDIAPIPE_DISABLE_GPU
       }
 #if !MEDIAPIPE_DISABLE_OPENCV
-      ASSIGN_OR_RETURN(auto* runner, cpu_holder_.GetRunner());
+      MP_ASSIGN_OR_RETURN(auto* runner, cpu_holder_.GetRunner());
       const auto& frame_ptr = input.GetImageFrameSharedPtr();
       // Wrap image into image frame.
       const ImageFrame image_frame(frame_ptr->Format(), frame_ptr->Width(),
                                    frame_ptr->Height(), frame_ptr->WidthStep(),
                                    const_cast<uint8_t*>(frame_ptr->PixelData()),
                                    [](uint8_t* data){});
-      ASSIGN_OR_RETURN(auto result,
-                       runner->Run(image_frame, matrix, size, border_mode));
+      MP_ASSIGN_OR_RETURN(auto result,
+                          runner->Run(image_frame, matrix, size, border_mode));
       return mediapipe::Image(std::make_shared<ImageFrame>(std::move(result)));
 #else
       return absl::UnavailableError("OpenCV support is disabled");
@@ -181,6 +191,7 @@
 #endif  // !MEDIAPIPE_DISABLE_OPENCV
 #if !MEDIAPIPE_DISABLE_GPU
     WarpAffineRunnerHolder<mediapipe::GpuBuffer> gpu_holder_;
+    bool gpu_holder_initialized_ = false;
 #endif  // !MEDIAPIPE_DISABLE_GPU
   };
 
@@ -194,27 +205,31 @@
   static absl::Status UpdateContract(CalculatorContract* cc) {
     if constexpr (std::is_same_v<InterfaceT, WarpAffineCalculatorGpu> ||
                   std::is_same_v<InterfaceT, WarpAffineCalculator>) {
-      MP_RETURN_IF_ERROR(mediapipe::GlCalculatorHelper::UpdateContract(cc));
+      MP_RETURN_IF_ERROR(mediapipe::GlCalculatorHelper::UpdateContract(
+          cc, /*requesst_gpu_as_optional=*/true));
     }
     return absl::OkStatus();
   }
 #endif  // !MEDIAPIPE_DISABLE_GPU
-
-  absl::Status Open(CalculatorContext* cc) override { return holder_.Open(cc); }
-
   absl::Status Process(CalculatorContext* cc) override {
     if (InterfaceT::kInImage(cc).IsEmpty() ||
         InterfaceT::kMatrix(cc).IsEmpty() ||
         InterfaceT::kOutputSize(cc).IsEmpty()) {
       return absl::OkStatus();
     }
+
+    if (!holder_initialized_) {
+      MP_RETURN_IF_ERROR(holder_.Open(cc));
+      holder_initialized_ = true;
+    }
+
     const std::array<float, 16>& transform = *InterfaceT::kMatrix(cc);
     auto [out_width, out_height] = *InterfaceT::kOutputSize(cc);
     AffineTransformation::Size output_size;
     output_size.width = out_width;
     output_size.height = out_height;
-    ASSIGN_OR_RETURN(auto* runner, holder_.GetRunner());
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(auto* runner, holder_.GetRunner());
+    MP_ASSIGN_OR_RETURN(
         auto result,
         runner->Run(
             *InterfaceT::kInImage(cc), transform, output_size,
@@ -228,6 +243,7 @@
  private:
   WarpAffineRunnerHolder<typename decltype(InterfaceT::kInImage)::PayloadT>
       holder_;
+  bool holder_initialized_ = false;
 };
 
 }  // namespace
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/BUILD b/third_party/mediapipe/src/mediapipe/calculators/tensor/BUILD
index d7e2313..d6d050e6 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/BUILD
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/BUILD
@@ -13,16 +13,16 @@
 # limitations under the License.
 #
 
-load("@bazel_skylib//lib:selects.bzl", "selects")
-load("//mediapipe/framework/port:build_config.bzl", "mediapipe_proto_library")
 load(
     "//mediapipe/framework/tool:mediapipe_graph.bzl",
     "mediapipe_binary_graph",
 )
-load("//mediapipe/framework:mediapipe_cc_test.bzl", "mediapipe_cc_test")
+load("@bazel_skylib//lib:selects.bzl", "selects")
 load("//mediapipe/framework:encode_binary_proto.bzl", "encode_binary_proto")
-load("@org_tensorflow//tensorflow/lite/core/shims:cc_library_with_tflite.bzl", "cc_library_with_tflite")
+load("//mediapipe/framework:mediapipe_cc_test.bzl", "mediapipe_cc_test")
 load("//mediapipe/framework:more_selects.bzl", "more_selects")
+load("//mediapipe/framework/port:build_config.bzl", "mediapipe_proto_library")
+load("@org_tensorflow//tensorflow/lite/core/shims:cc_library_with_tflite.bzl", "cc_library_with_tflite")
 
 licenses(["notice"])
 
@@ -254,7 +254,7 @@
         "@com_google_absl//absl/status",
         "@com_google_absl//absl/status:statusor",
         "@com_google_absl//absl/strings",
-        "@com_google_sentencepiece//src:sentencepiece_processor",  # fixdeps: keep
+        "@com_google_sentencepiece//:sentencepiece_processor",  # fixdeps: keep
     ],
 )
 
@@ -303,7 +303,7 @@
         "@com_google_absl//absl/status",
         "@com_google_absl//absl/status:statusor",
         "@com_google_absl//absl/strings",
-        "@com_google_sentencepiece//src:sentencepiece_processor",  # fixdeps: keep
+        "@com_google_sentencepiece//:sentencepiece_processor",  # fixdeps: keep
     ],
 )
 
@@ -1450,6 +1450,30 @@
     alwayslink = 1,
 )
 
+cc_test(
+    name = "tensors_to_segmentation_calculator_test",
+    srcs = ["tensors_to_segmentation_calculator_test.cc"],
+    deps = [
+        ":tensors_to_segmentation_calculator",
+        ":tensors_to_segmentation_calculator_cc_proto",
+        "//mediapipe/framework:calculator_framework",
+        "//mediapipe/framework:calculator_runner",
+        "//mediapipe/framework:packet",
+        "//mediapipe/framework:timestamp",
+        "//mediapipe/framework/formats:image",
+        "//mediapipe/framework/formats:image_format_cc_proto",
+        "//mediapipe/framework/formats:image_opencv",
+        "//mediapipe/framework/formats:rect_cc_proto",
+        "//mediapipe/framework/formats:tensor",
+        "//mediapipe/framework/port:gtest_main",
+        "//mediapipe/framework/port:parse_text_proto",
+        "@com_google_absl//absl/log",
+        "@com_google_absl//absl/log:absl_log",
+        "@com_google_absl//absl/strings",
+        "@com_google_googletest//:gtest_main",
+    ],
+)
+
 cc_library(
     name = "tensors_dequantization_calculator",
     srcs = ["tensors_dequantization_calculator.cc"],
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/audio_to_tensor_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/audio_to_tensor_calculator.cc
index eaf593a..c8d38a6 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/audio_to_tensor_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/audio_to_tensor_calculator.cc
@@ -517,8 +517,8 @@
         // The last two elements are Nyquist component.
         fft_output_matrix(fft_size_ - 2) = fft_output_[1];  // Nyquist real part
         fft_output_matrix(fft_size_ - 1) = 0.0f;  // Nyquist imagery part
-        ASSIGN_OR_RETURN(output_tensor, ConvertToTensor(fft_output_matrix,
-                                                        {2, fft_size_ / 2}));
+        MP_ASSIGN_OR_RETURN(output_tensor, ConvertToTensor(fft_output_matrix,
+                                                           {2, fft_size_ / 2}));
         break;
       }
       case Options::WITH_DC_AND_NYQUIST: {
@@ -529,7 +529,7 @@
         // The last two elements are  Nyquist component.
         fft_output_matrix(fft_size_) = fft_output_[1];  // Nyquist real part
         fft_output_matrix(fft_size_ + 1) = 0.0f;        // Nyquist imagery part
-        ASSIGN_OR_RETURN(
+        MP_ASSIGN_OR_RETURN(
             output_tensor,
             ConvertToTensor(fft_output_matrix, {2, (fft_size_ + 2) / 2}));
         break;
@@ -537,7 +537,7 @@
       case Options::WITHOUT_DC_AND_NYQUIST: {
         Matrix fft_output_matrix =
             Eigen::Map<const Matrix>(fft_output_.data() + 2, 1, fft_size_ - 2);
-        ASSIGN_OR_RETURN(
+        MP_ASSIGN_OR_RETURN(
             output_tensor,
             ConvertToTensor(fft_output_matrix, {2, (fft_size_ - 2) / 2}));
         break;
@@ -547,8 +547,8 @@
     }
 
   } else {
-    ASSIGN_OR_RETURN(output_tensor,
-                     ConvertToTensor(block, {num_channels_, num_samples_}));
+    MP_ASSIGN_OR_RETURN(output_tensor,
+                        ConvertToTensor(block, {num_channels_, num_samples_}));
   }
   kTensorsOut(cc).Send(std::move(output_tensor), timestamp);
   return absl::OkStatus();
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/bert_preprocessor_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/bert_preprocessor_calculator.cc
index 12db149..aaaee4f 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/bert_preprocessor_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/bert_preprocessor_calculator.cc
@@ -68,7 +68,6 @@
 //
 // This calculator is currently configured for the TextClassifier Task but it
 // will eventually be generalized for other Text Tasks.
-// TODO: Handle preprocessing for other Text Tasks too.
 //
 // Inputs:
 //   TEXT - std::string
@@ -161,9 +160,9 @@
       &kMetadataExtractorSideIn(cc).Get();
   const tflite::ProcessUnit* tokenizer_metadata =
       metadata_extractor->GetInputProcessUnit(kTokenizerProcessUnitIndex);
-  ASSIGN_OR_RETURN(tokenizer_,
-                   tasks::text::tokenizers::CreateTokenizerFromProcessUnit(
-                       tokenizer_metadata, metadata_extractor));
+  MP_ASSIGN_OR_RETURN(tokenizer_,
+                      tasks::text::tokenizers::CreateTokenizerFromProcessUnit(
+                          tokenizer_metadata, metadata_extractor));
 
   auto* input_tensors_metadata = metadata_extractor->GetInputTensorMetadata();
   input_ids_tensor_index_ = FindTensorIndexByMetadataName(
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_calculator.cc
index 26fb1d8..171b28eb 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_calculator.cc
@@ -192,18 +192,19 @@
     }
 
 #if MEDIAPIPE_DISABLE_GPU
-    ASSIGN_OR_RETURN(auto image, GetInputImage(kIn(cc)));
+    MP_ASSIGN_OR_RETURN(auto image, GetInputImage(kIn(cc)));
 #else
     const bool is_input_gpu = kInGpu(cc).IsConnected();
-    ASSIGN_OR_RETURN(auto image, is_input_gpu ? GetInputImage(kInGpu(cc))
-                                              : GetInputImage(kIn(cc)));
+    MP_ASSIGN_OR_RETURN(auto image, is_input_gpu ? GetInputImage(kInGpu(cc))
+                                                 : GetInputImage(kIn(cc)));
 #endif  // MEDIAPIPE_DISABLE_GPU
 
     RotatedRect roi = GetRoi(image->width(), image->height(), norm_rect);
     const int tensor_width = params_.output_width.value_or(image->width());
     const int tensor_height = params_.output_height.value_or(image->height());
-    ASSIGN_OR_RETURN(auto padding, PadRoi(tensor_width, tensor_height,
-                                          options_.keep_aspect_ratio(), &roi));
+    MP_ASSIGN_OR_RETURN(auto padding,
+                        PadRoi(tensor_width, tensor_height,
+                               options_.keep_aspect_ratio(), &roi));
     if (kOutLetterboxPadding(cc).IsConnected()) {
       kOutLetterboxPadding(cc).Send(padding);
     }
@@ -247,20 +248,20 @@
       if (!gpu_converter_) {
 #if !MEDIAPIPE_DISABLE_GPU
 #if MEDIAPIPE_METAL_ENABLED
-        ASSIGN_OR_RETURN(
+        MP_ASSIGN_OR_RETURN(
             gpu_converter_,
             CreateMetalConverter(cc, GetBorderMode(options_.border_mode())));
 #elif MEDIAPIPE_OPENGL_ES_VERSION >= MEDIAPIPE_OPENGL_ES_31
-        ASSIGN_OR_RETURN(gpu_converter_,
-                         CreateImageToGlBufferTensorConverter(
-                             cc, DoesGpuInputStartAtBottom(options_),
-                             GetBorderMode(options_.border_mode())));
+        MP_ASSIGN_OR_RETURN(gpu_converter_,
+                            CreateImageToGlBufferTensorConverter(
+                                cc, DoesGpuInputStartAtBottom(options_),
+                                GetBorderMode(options_.border_mode())));
 #else
         if (!gpu_converter_) {
-          ASSIGN_OR_RETURN(gpu_converter_,
-                           CreateImageToGlTextureTensorConverter(
-                               cc, DoesGpuInputStartAtBottom(options_),
-                               GetBorderMode(options_.border_mode())));
+          MP_ASSIGN_OR_RETURN(gpu_converter_,
+                              CreateImageToGlTextureTensorConverter(
+                                  cc, DoesGpuInputStartAtBottom(options_),
+                                  GetBorderMode(options_.border_mode())));
         }
         if (!gpu_converter_) {
           return absl::UnimplementedError(
@@ -272,18 +273,20 @@
     } else {
       if (!cpu_converter_) {
 #if !MEDIAPIPE_DISABLE_OPENCV
-        ASSIGN_OR_RETURN(cpu_converter_,
-                         CreateOpenCvConverter(
-                             cc, GetBorderMode(options_.border_mode()),
-                             GetOutputTensorType(/*uses_gpu=*/false, params_)));
+        MP_ASSIGN_OR_RETURN(
+            cpu_converter_,
+            CreateOpenCvConverter(
+                cc, GetBorderMode(options_.border_mode()),
+                GetOutputTensorType(/*uses_gpu=*/false, params_)));
 // TODO: FrameBuffer-based converter needs to call GetGpuBuffer()
 // to get access to a FrameBuffer view. Investigate if GetGpuBuffer() can be
 // made available even with MEDIAPIPE_DISABLE_GPU set.
 #elif MEDIAPIPE_ENABLE_HALIDE
-        ASSIGN_OR_RETURN(cpu_converter_,
-                         CreateFrameBufferConverter(
-                             cc, GetBorderMode(options_.border_mode()),
-                             GetOutputTensorType(/*uses_gpu=*/false, params_)));
+        MP_ASSIGN_OR_RETURN(
+            cpu_converter_,
+            CreateFrameBufferConverter(
+                cc, GetBorderMode(options_.border_mode()),
+                GetOutputTensorType(/*uses_gpu=*/false, params_)));
 #else
         ABSL_LOG(FATAL) << "Cannot create image to tensor CPU converter since "
                            "MEDIAPIPE_DISABLE_OPENCV is defined and "
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_frame_buffer.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_frame_buffer.cc
index 6f6f6f11..c77575d9 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_frame_buffer.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_frame_buffer.cc
@@ -175,9 +175,9 @@
       cropped_buffer_ = std::make_unique<uint8_t[]>(cropped_buffer_size);
       cropped_buffer_size_ = cropped_buffer_size;
     }
-    ASSIGN_OR_RETURN(cropped,
-                     frame_buffer::CreateFromRawBuffer(
-                         cropped_buffer_.get(), cropped_dims, input->format()));
+    MP_ASSIGN_OR_RETURN(
+        cropped, frame_buffer::CreateFromRawBuffer(
+                     cropped_buffer_.get(), cropped_dims, input->format()));
   }
   MP_RETURN_IF_ERROR(
       frame_buffer::Crop(*input, left, top, right, bottom, cropped.get()));
@@ -194,9 +194,9 @@
         rotated_buffer_ = std::make_unique<uint8_t[]>(rotated_buffer_size);
         rotated_buffer_size_ = rotated_buffer_size;
       }
-      ASSIGN_OR_RETURN(auto rotated, frame_buffer::CreateFromRawBuffer(
-                                         rotated_buffer_.get(), rotated_dims,
-                                         cropped->format()));
+      MP_ASSIGN_OR_RETURN(auto rotated, frame_buffer::CreateFromRawBuffer(
+                                            rotated_buffer_.get(), rotated_dims,
+                                            cropped->format()));
     }
     MP_RETURN_IF_ERROR(
         frame_buffer::Rotate(*cropped, rotation_degrees, rotated.get()));
@@ -217,9 +217,10 @@
   RET_CHECK(output_tensor.element_type() == Tensor::ElementType::kFloat32);
   constexpr float kInputImageRangeMin = 0.0f;
   constexpr float kInputImageRangeMax = 255.0f;
-  ASSIGN_OR_RETURN(auto transform, GetValueRangeTransformation(
-                                       kInputImageRangeMin, kInputImageRangeMax,
-                                       range_min, range_max));
+  MP_ASSIGN_OR_RETURN(
+      auto transform,
+      GetValueRangeTransformation(kInputImageRangeMin, kInputImageRangeMax,
+                                  range_min, range_max));
   return frame_buffer::ToFloatTensor(*input_frame, transform.scale,
                                      transform.offset, output_tensor);
 }
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_gl_buffer.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_gl_buffer.cc
index eb1726a..b32b678 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_gl_buffer.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_gl_buffer.cc
@@ -255,7 +255,7 @@
           << "OpenGL ES 3.1 is required.";
       command_queue_ = tflite::gpu::gl::NewCommandQueue(gpu_info);
 
-      ASSIGN_OR_RETURN(
+      MP_ASSIGN_OR_RETURN(
           auto extractor,
           SubRectExtractorGl::Create(gl_helper_.GetGlContext(),
                                      input_starts_at_bottom, border_mode));
@@ -293,10 +293,10 @@
 
           constexpr float kInputImageRangeMin = 0.0f;
           constexpr float kInputImageRangeMax = 1.0f;
-          ASSIGN_OR_RETURN(auto transform,
-                           GetValueRangeTransformation(kInputImageRangeMin,
-                                                       kInputImageRangeMax,
-                                                       range_min, range_max));
+          MP_ASSIGN_OR_RETURN(auto transform,
+                              GetValueRangeTransformation(
+                                  kInputImageRangeMin, kInputImageRangeMax,
+                                  range_min, range_max));
 
           const int output_size = output_tensor.bytes() / output_shape.dims[0];
           auto buffer_view = output_tensor.GetOpenGlBufferWriteView();
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_gl_texture.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_gl_texture.cc
index 5604aea..2522cae8 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_gl_texture.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_gl_texture.cc
@@ -193,10 +193,10 @@
 
           constexpr float kInputImageRangeMin = 0.0f;
           constexpr float kInputImageRangeMax = 1.0f;
-          ASSIGN_OR_RETURN(auto transform,
-                           GetValueRangeTransformation(kInputImageRangeMin,
-                                                       kInputImageRangeMax,
-                                                       range_min, range_max));
+          MP_ASSIGN_OR_RETURN(auto transform,
+                              GetValueRangeTransformation(
+                                  kInputImageRangeMin, kInputImageRangeMax,
+                                  range_min, range_max));
           auto tensor_view = output_tensor.GetOpenGlTexture2dWriteView();
           MP_RETURN_IF_ERROR(ExtractSubRect(input_texture, roi,
                                             /*flip_horizontaly=*/false,
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_metal.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_metal.cc
index 3545470..cef2abcd 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_metal.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_metal.cc
@@ -345,9 +345,9 @@
   absl::Status Init(CalculatorContext* cc, BorderMode border_mode) {
     metal_helper_ = [[MPPMetalHelper alloc] initWithCalculatorContext:cc];
     RET_CHECK(metal_helper_);
-    ASSIGN_OR_RETURN(extractor_, SubRectExtractorMetal::Make(
-                                     metal_helper_.mtlDevice,
-                                     OutputFormat::kF32C4, border_mode));
+    MP_ASSIGN_OR_RETURN(extractor_, SubRectExtractorMetal::Make(
+                                        metal_helper_.mtlDevice,
+                                        OutputFormat::kF32C4, border_mode));
     return absl::OkStatus();
   }
 
@@ -373,7 +373,7 @@
 
       constexpr float kInputImageRangeMin = 0.0f;
       constexpr float kInputImageRangeMax = 1.0f;
-      ASSIGN_OR_RETURN(
+      MP_ASSIGN_OR_RETURN(
           auto transform,
           GetValueRangeTransformation(kInputImageRangeMin, kInputImageRangeMax,
                                       range_min, range_max));
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_opencv.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_opencv.cc
index bb4c6de..75a29c2e 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_opencv.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/image_to_tensor_converter_opencv.cc
@@ -159,7 +159,7 @@
 
     constexpr float kInputImageRangeMin = 0.0f;
     constexpr float kInputImageRangeMax = 255.0f;
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         auto transform,
         GetValueRangeTransformation(kInputImageRangeMin, kInputImageRangeMax,
                                     range_min, range_max));
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_cpu.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_cpu.cc
index 366e7e8..8cf0006d 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_cpu.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_cpu.cc
@@ -59,7 +59,7 @@
 }
 
 absl::Status InferenceCalculatorCpuImpl::Open(CalculatorContext* cc) {
-  ASSIGN_OR_RETURN(inference_runner_, CreateInferenceRunner(cc));
+  MP_ASSIGN_OR_RETURN(inference_runner_, CreateInferenceRunner(cc));
   return absl::OkStatus();
 }
 
@@ -70,8 +70,8 @@
   const auto& input_tensors = *kInTensors(cc);
   RET_CHECK(!input_tensors.empty());
 
-  ASSIGN_OR_RETURN(std::vector<Tensor> output_tensors,
-                   inference_runner_->Run(cc, input_tensors));
+  MP_ASSIGN_OR_RETURN(std::vector<Tensor> output_tensors,
+                      inference_runner_->Run(cc, input_tensors));
   kOutTensors(cc).Send(std::move(output_tensors));
   return absl::OkStatus();
 }
@@ -83,11 +83,11 @@
 
 absl::StatusOr<std::unique_ptr<InferenceRunner>>
 InferenceCalculatorCpuImpl::CreateInferenceRunner(CalculatorContext* cc) {
-  ASSIGN_OR_RETURN(auto model_packet, GetModelAsPacket(cc));
-  ASSIGN_OR_RETURN(auto op_resolver_packet, GetOpResolverAsPacket(cc));
+  MP_ASSIGN_OR_RETURN(auto model_packet, GetModelAsPacket(cc));
+  MP_ASSIGN_OR_RETURN(auto op_resolver_packet, GetOpResolverAsPacket(cc));
   const int interpreter_num_threads =
       cc->Options<mediapipe::InferenceCalculatorOptions>().cpu_num_thread();
-  ASSIGN_OR_RETURN(TfLiteDelegatePtr delegate, MaybeCreateDelegate(cc));
+  MP_ASSIGN_OR_RETURN(TfLiteDelegatePtr delegate, MaybeCreateDelegate(cc));
   return CreateInferenceInterpreterDelegateRunner(
       std::move(model_packet), std::move(op_resolver_packet),
       std::move(delegate), interpreter_num_threads);
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_gl.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_gl.cc
index 27b8bc2..9ae16e2 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_gl.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_gl.cc
@@ -100,7 +100,7 @@
 
 absl::Status InferenceCalculatorGlImpl::GpuInferenceRunner::LoadModel(
     CalculatorContext* cc) {
-  ASSIGN_OR_RETURN(model_packet_, GetModelAsPacket(cc));
+  MP_ASSIGN_OR_RETURN(model_packet_, GetModelAsPacket(cc));
   const auto& model = *model_packet_.Get();
   if (kSideInOpResolver(cc).IsConnected()) {
     const tflite::OpResolver& op_resolver = kSideInOpResolver(cc).Get();
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_gl_advanced.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_gl_advanced.cc
index 28ea45d..f22def2 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_gl_advanced.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_gl_advanced.cc
@@ -170,7 +170,7 @@
 InferenceCalculatorGlAdvancedImpl::GpuInferenceRunner::InitTFLiteGPURunner(
     CalculatorContext* cc,
     const mediapipe::InferenceCalculatorOptions::Delegate& delegate) {
-  ASSIGN_OR_RETURN(model_packet_, GetModelAsPacket(cc));
+  MP_ASSIGN_OR_RETURN(model_packet_, GetModelAsPacket(cc));
   const auto& model = *model_packet_.Get();
 
   bool allow_precision_loss = delegate.gpu().allow_precision_loss();
@@ -306,16 +306,16 @@
     tflite::gpu::TFLiteGPURunner* gpu_runner) const {
   if (use_kernel_caching_) {
     // Save kernel file.
-    ASSIGN_OR_RETURN(std::vector<uint8_t> kernel_cache,
-                     gpu_runner->GetSerializedBinaryCache());
+    MP_ASSIGN_OR_RETURN(std::vector<uint8_t> kernel_cache,
+                        gpu_runner->GetSerializedBinaryCache());
     std::string cache_str(kernel_cache.begin(), kernel_cache.end());
     MP_RETURN_IF_ERROR(
         mediapipe::file::SetContents(cached_kernel_filename_, cache_str));
   }
   if (use_serialized_model_) {
     // Save serialized model file.
-    ASSIGN_OR_RETURN(std::vector<uint8_t> serialized_model_vec,
-                     gpu_runner->GetSerializedModel());
+    MP_ASSIGN_OR_RETURN(std::vector<uint8_t> serialized_model_vec,
+                        gpu_runner->GetSerializedModel());
     absl::string_view serialized_model(
         reinterpret_cast<char*>(serialized_model_vec.data()),
         serialized_model_vec.size());
@@ -412,8 +412,8 @@
   RET_CHECK(!input_tensors.empty());
   auto output_tensors = absl::make_unique<std::vector<Tensor>>();
 
-  ASSIGN_OR_RETURN(*output_tensors,
-                   gpu_inference_runner_->Process(cc, input_tensors));
+  MP_ASSIGN_OR_RETURN(*output_tensors,
+                      gpu_inference_runner_->Process(cc, input_tensors));
 
   kOutTensors(cc).Send(std::move(output_tensors));
   return absl::OkStatus();
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_metal.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_metal.cc
index 253091a..591f0a7 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_metal.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_metal.cc
@@ -191,6 +191,11 @@
     [output_encoder endEncoding];
   }
   [command_buffer commit];
+  // The below call is found (manual testing) to resolve flickering issues for
+  // some use cases where multiple Metal calculators are involved.
+  // TODO: investigate and ensure proper synchronization
+  // (e.g. fences/barriers/events).
+  [command_buffer waitUntilScheduled];
 
   kOutTensors(cc).Send(std::move(output_tensors));
   return absl::OkStatus();
@@ -208,9 +213,9 @@
 
 absl::Status InferenceCalculatorMetalImpl::InitInterpreter(
     CalculatorContext* cc) {
-  ASSIGN_OR_RETURN(model_packet_, GetModelAsPacket(cc));
+  MP_ASSIGN_OR_RETURN(model_packet_, GetModelAsPacket(cc));
   const auto& model = *model_packet_.Get();
-  ASSIGN_OR_RETURN(auto op_resolver_packet, GetOpResolverAsPacket(cc));
+  MP_ASSIGN_OR_RETURN(auto op_resolver_packet, GetOpResolverAsPacket(cc));
   const auto& op_resolver = op_resolver_packet.Get();
   tflite::InterpreterBuilder interpreter_builder(model, op_resolver);
   AddDelegate(cc, &interpreter_builder);
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_xnnpack.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_xnnpack.cc
index a9417d5..59ec726d 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_xnnpack.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/inference_calculator_xnnpack.cc
@@ -58,7 +58,7 @@
 }
 
 absl::Status InferenceCalculatorXnnpackImpl::Open(CalculatorContext* cc) {
-  ASSIGN_OR_RETURN(inference_runner_, CreateInferenceRunner(cc));
+  MP_ASSIGN_OR_RETURN(inference_runner_, CreateInferenceRunner(cc));
   return absl::OkStatus();
 }
 
@@ -69,8 +69,8 @@
   const auto& input_tensors = *kInTensors(cc);
   RET_CHECK(!input_tensors.empty());
 
-  ASSIGN_OR_RETURN(std::vector<Tensor> output_tensors,
-                   inference_runner_->Run(cc, input_tensors));
+  MP_ASSIGN_OR_RETURN(std::vector<Tensor> output_tensors,
+                      inference_runner_->Run(cc, input_tensors));
   kOutTensors(cc).Send(std::move(output_tensors));
   return absl::OkStatus();
 }
@@ -82,11 +82,11 @@
 
 absl::StatusOr<std::unique_ptr<InferenceRunner>>
 InferenceCalculatorXnnpackImpl::CreateInferenceRunner(CalculatorContext* cc) {
-  ASSIGN_OR_RETURN(auto model_packet, GetModelAsPacket(cc));
-  ASSIGN_OR_RETURN(auto op_resolver_packet, GetOpResolverAsPacket(cc));
+  MP_ASSIGN_OR_RETURN(auto model_packet, GetModelAsPacket(cc));
+  MP_ASSIGN_OR_RETURN(auto op_resolver_packet, GetOpResolverAsPacket(cc));
   const int interpreter_num_threads =
       cc->Options<mediapipe::InferenceCalculatorOptions>().cpu_num_thread();
-  ASSIGN_OR_RETURN(TfLiteDelegatePtr delegate, CreateDelegate(cc));
+  MP_ASSIGN_OR_RETURN(TfLiteDelegatePtr delegate, CreateDelegate(cc));
   return CreateInferenceInterpreterDelegateRunner(
       std::move(model_packet), std::move(op_resolver_packet),
       std::move(delegate), interpreter_num_threads);
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/regex_preprocessor_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/regex_preprocessor_calculator.cc
index 8276462f..723c3a45 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/regex_preprocessor_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/regex_preprocessor_calculator.cc
@@ -106,7 +106,7 @@
     return absl::InvalidArgumentError("No tensor metadata found");
   }
 
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       const auto* tokenizer_metadata,
       metadata_extractor->FindFirstProcessUnit(
           *tensor_metadata, tflite::ProcessUnitOptions_RegexTokenizerOptions));
@@ -115,9 +115,9 @@
   }
   const tflite::RegexTokenizerOptions* regex_tokenizer_options =
       tokenizer_metadata->options_as<tflite::RegexTokenizerOptions>();
-  ASSIGN_OR_RETURN(tokenizer_,
-                   tasks::text::tokenizers::CreateRegexTokenizerFromOptions(
-                       regex_tokenizer_options, metadata_extractor));
+  MP_ASSIGN_OR_RETURN(tokenizer_,
+                      tasks::text::tokenizers::CreateRegexTokenizerFromOptions(
+                          regex_tokenizer_options, metadata_extractor));
 
   const auto& options =
       cc->Options<mediapipe::RegexPreprocessorCalculatorOptions>();
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/tensor_converter_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/tensor_converter_calculator.cc
index e8643658..b42cb0b 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/tensor_converter_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/tensor_converter_calculator.cc
@@ -656,7 +656,7 @@
   }
 
   // Get y-flip mode.
-  ASSIGN_OR_RETURN(flip_vertically_, ShouldFlipVertically(options, use_gpu));
+  MP_ASSIGN_OR_RETURN(flip_vertically_, ShouldFlipVertically(options, use_gpu));
 
   // Get row_major_matrix mode.
   row_major_matrix_ = options.row_major_matrix();
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/tensor_to_joints_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/tensor_to_joints_calculator.cc
new file mode 100644
index 0000000..07b919a
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/tensor_to_joints_calculator.cc
@@ -0,0 +1,84 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "mediapipe/calculators/tensor/tensor_to_joints_calculator.h"
+
+#include <utility>
+
+#include "mediapipe/calculators/tensor/tensor_to_joints_calculator.pb.h"
+#include "mediapipe/framework/calculator_framework.h"
+#include "mediapipe/framework/formats/body_rig.pb.h"
+#include "mediapipe/framework/formats/tensor.h"
+#include "mediapipe/framework/port/ret_check.h"
+
+namespace mediapipe {
+namespace api2 {
+namespace {
+
+// Number of values in 6D representation of rotation.
+constexpr int kRotation6dSize = 6;
+
+}  // namespace
+
+class TensorToJointsCalculatorImpl
+    : public mediapipe::api2::NodeImpl<TensorToJointsCalculator> {
+ public:
+  absl::Status Open(CalculatorContext* cc) override {
+    const auto& options = cc->Options<TensorToJointsCalculatorOptions>();
+
+    // Get number of joints.
+    RET_CHECK_GE(options.num_joints(), 0);
+    num_joints_ = options.num_joints();
+
+    // Get start index.
+    start_index_ = options.start_index();
+
+    return absl::OkStatus();
+  }
+
+  absl::Status Process(CalculatorContext* cc) override {
+    // Skip if Tensor is empty.
+    if (kInTensor(cc).IsEmpty()) {
+      return absl::OkStatus();
+    }
+
+    // Get raw floats from the Tensor.
+    const Tensor& tensor = kInTensor(cc).Get();
+    RET_CHECK_EQ(tensor.shape().num_elements(),
+                 num_joints_ * kRotation6dSize + start_index_)
+        << "Unexpected number of values in Tensor";
+    const float* raw_floats = tensor.GetCpuReadView().buffer<float>();
+
+    // Convert raw floats into Joint rotations.
+    JointList joints;
+    for (int joint_idx = 0; joint_idx < num_joints_; ++joint_idx) {
+      Joint* joint = joints.add_joint();
+      for (int idx_6d = 0; idx_6d < kRotation6dSize; ++idx_6d) {
+        joint->add_rotation_6d(
+            raw_floats[start_index_ + joint_idx * kRotation6dSize + idx_6d]);
+      }
+    }
+
+    kOutJoints(cc).Send(std::move(joints));
+    return absl::OkStatus();
+  }
+
+ private:
+  int num_joints_ = 0;
+  int start_index_ = 0;
+};
+MEDIAPIPE_NODE_IMPLEMENTATION(TensorToJointsCalculatorImpl);
+
+}  // namespace api2
+}  // namespace mediapipe
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/tensor_to_joints_calculator.h b/third_party/mediapipe/src/mediapipe/calculators/tensor/tensor_to_joints_calculator.h
new file mode 100644
index 0000000..c2798526
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/tensor_to_joints_calculator.h
@@ -0,0 +1,64 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef MEDIAPIPE_CALCULATORS_TENSOR_TENSOR_TO_JOINTS_CALCULATOR_H_
+#define MEDIAPIPE_CALCULATORS_TENSOR_TENSOR_TO_JOINTS_CALCULATOR_H_
+
+#include <memory>
+
+#include "mediapipe/framework/api2/node.h"
+#include "mediapipe/framework/calculator_framework.h"
+#include "mediapipe/framework/formats/body_rig.pb.h"
+#include "mediapipe/framework/formats/tensor.h"
+
+namespace mediapipe {
+namespace api2 {
+
+// A calculator to convert Tensors to JointList.
+//
+// Calculator fills in only rotation of the joints leaving visibility undefined.
+//
+// Input:
+//   TENSOR - std::vector<Tensor> with kFloat32 values
+//     Vector of tensors to be converted to joints. Only the first tensor will
+//     be used. Number of values is expected to be multiple of six.
+//
+// Output:
+//   JOINTS - JointList
+//     List of joints with rotations extracted from given tensor and undefined
+//     visibility.
+//
+// Example:
+//   node {
+//     calculator: "TensorToJointsCalculator"
+//     input_stream: "TENSOR:tensor"
+//     output_stream: "JOINTS:joints"
+//     options: {
+//       [mediapipe.TensorToJointsCalculatorOptions.ext] {
+//         num_joints: 56
+//         start_index: 3
+//       }
+//     }
+//   }
+class TensorToJointsCalculator : public NodeIntf {
+ public:
+  static constexpr Input<mediapipe::Tensor> kInTensor{"TENSOR"};
+  static constexpr Output<mediapipe::JointList> kOutJoints{"JOINTS"};
+  MEDIAPIPE_NODE_INTERFACE(TensorToJointsCalculator, kInTensor, kOutJoints);
+};
+
+}  // namespace api2
+}  // namespace mediapipe
+
+#endif  // MEDIAPIPE_CALCULATORS_TENSOR_TENSOR_TO_JOINTS_CALCULATOR_H_
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/tensor_to_joints_calculator.proto b/third_party/mediapipe/src/mediapipe/calculators/tensor/tensor_to_joints_calculator.proto
new file mode 100644
index 0000000..3534e35
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/tensor_to_joints_calculator.proto
@@ -0,0 +1,32 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto2";
+
+package mediapipe;
+
+import "mediapipe/framework/calculator.proto";
+
+message TensorToJointsCalculatorOptions {
+  extend CalculatorOptions {
+    optional TensorToJointsCalculatorOptions ext = 406440177;
+  }
+
+  // Number of joints from the output of the model. Calculator will expect the
+  // tensor to contain `6 * num_joints + start_index` values.
+  optional int32 num_joints = 1;
+
+  // Index to start reading 6 value blocks from.
+  optional int32 start_index = 2 [default = 0];
+}
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/tensors_to_classification_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/tensors_to_classification_calculator.cc
index 7041c02..dc1f101 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/tensors_to_classification_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/tensors_to_classification_calculator.cc
@@ -110,8 +110,8 @@
   sort_by_descending_score_ = options.sort_by_descending_score();
   if (options.has_label_map_path()) {
     std::string string_path;
-    ASSIGN_OR_RETURN(string_path,
-                     PathToResourceAsFile(options.label_map_path()));
+    MP_ASSIGN_OR_RETURN(string_path,
+                        PathToResourceAsFile(options.label_map_path()));
     std::string label_map_string;
     MP_RETURN_IF_ERROR(
         mediapipe::GetResourceContents(string_path, &label_map_string));
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/tensors_to_detections_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/tensors_to_detections_calculator.cc
index 6d42226..8e649c0 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/tensors_to_detections_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/tensors_to_detections_calculator.cc
@@ -266,7 +266,8 @@
     CalculatorContract* cc) {
   if (CanUseGpu()) {
 #ifndef MEDIAPIPE_DISABLE_GL_COMPUTE
-    MP_RETURN_IF_ERROR(mediapipe::GlCalculatorHelper::UpdateContract(cc));
+    MP_RETURN_IF_ERROR(mediapipe::GlCalculatorHelper::UpdateContract(
+        cc, /*requesst_gpu_as_optional=*/true));
 #elif MEDIAPIPE_METAL_ENABLED
     MP_RETURN_IF_ERROR([MPPMetalHelper updateContract:cc]);
 #endif  // !defined(MEDIAPIPE_DISABLE_GL_COMPUTE)
@@ -280,7 +281,6 @@
 
   if (CanUseGpu()) {
 #ifndef MEDIAPIPE_DISABLE_GL_COMPUTE
-    MP_RETURN_IF_ERROR(gpu_helper_.Open(cc));
 #elif MEDIAPIPE_METAL_ENABLED
     gpu_helper_ = [[MPPMetalHelper alloc] initWithCalculatorContext:cc];
     RET_CHECK(gpu_helper_);
@@ -676,13 +676,15 @@
 
 absl::Status TensorsToDetectionsCalculator::Close(CalculatorContext* cc) {
 #ifndef MEDIAPIPE_DISABLE_GL_COMPUTE
-  gpu_helper_.RunInGlContext([this] {
-    decoded_boxes_buffer_ = nullptr;
-    scored_boxes_buffer_ = nullptr;
-    raw_anchors_buffer_ = nullptr;
-    glDeleteProgram(decode_program_);
-    glDeleteProgram(score_program_);
-  });
+  if (gpu_inited_) {
+    gpu_helper_.RunInGlContext([this] {
+      decoded_boxes_buffer_ = nullptr;
+      scored_boxes_buffer_ = nullptr;
+      raw_anchors_buffer_ = nullptr;
+      glDeleteProgram(decode_program_);
+      glDeleteProgram(score_program_);
+    });
+  }
 #elif MEDIAPIPE_METAL_ENABLED
   decoded_boxes_buffer_ = nullptr;
   scored_boxes_buffer_ = nullptr;
@@ -942,6 +944,7 @@
       break;
   }
 #ifndef MEDIAPIPE_DISABLE_GL_COMPUTE
+  MP_RETURN_IF_ERROR(gpu_helper_.Open(cc));
   MP_RETURN_IF_ERROR(gpu_helper_.RunInGlContext([this, output_format_flag]()
                                                     -> absl::Status {
     // A shader to decode detection boxes.
@@ -1420,7 +1423,6 @@
           num_classes_, max_wg_size));
     }
   }
-
 #endif  // !defined(MEDIAPIPE_DISABLE_GL_COMPUTE)
 
   return absl::OkStatus();
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensor/tensors_to_segmentation_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/tensor/tensors_to_segmentation_calculator.cc
index bfe1260..6456126a 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensor/tensors_to_segmentation_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensor/tensors_to_segmentation_calculator.cc
@@ -173,6 +173,7 @@
 #if !MEDIAPIPE_DISABLE_GPU
   mediapipe::GlCalculatorHelper gpu_helper_;
   GLuint upsample_program_;
+  bool gpu_initialized_ = false;
 #if MEDIAPIPE_OPENGL_ES_VERSION >= MEDIAPIPE_OPENGL_ES_31
   int cached_width_ = 0;
   int cached_height_ = 0;
@@ -206,7 +207,8 @@
 
   if (CanUseGpu()) {
 #if !MEDIAPIPE_DISABLE_GPU
-    MP_RETURN_IF_ERROR(mediapipe::GlCalculatorHelper::UpdateContract(cc));
+    MP_RETURN_IF_ERROR(mediapipe::GlCalculatorHelper::UpdateContract(
+        cc, /*requesst_gpu_as_optional=*/true));
 #if MEDIAPIPE_METAL_ENABLED
     MP_RETURN_IF_ERROR([MPPMetalHelper updateContract:cc]);
 #endif  // MEDIAPIPE_METAL_ENABLED
@@ -218,12 +220,9 @@
 
 absl::Status TensorsToSegmentationCalculator::Open(CalculatorContext* cc) {
   cc->SetOffset(TimestampDiff(0));
-  bool use_gpu = false;
 
   if (CanUseGpu()) {
 #if !MEDIAPIPE_DISABLE_GPU
-    use_gpu = true;
-    MP_RETURN_IF_ERROR(gpu_helper_.Open(cc));
 #if MEDIAPIPE_METAL_ENABLED
     metal_helper_ = [[MPPMetalHelper alloc] initWithCalculatorContext:cc];
     RET_CHECK(metal_helper_);
@@ -233,14 +232,6 @@
 
   MP_RETURN_IF_ERROR(LoadOptions(cc));
 
-  if (use_gpu) {
-#if !MEDIAPIPE_DISABLE_GPU
-    MP_RETURN_IF_ERROR(InitGpu(cc));
-#else
-    RET_CHECK_FAIL() << "GPU processing disabled.";
-#endif  // !MEDIAPIPE_DISABLE_GPU
-  }
-
   return absl::OkStatus();
 }
 
@@ -267,7 +258,8 @@
   {
     RET_CHECK(!input_tensors.empty());
     RET_CHECK(input_tensors[0].element_type() == Tensor::ElementType::kFloat32);
-    ASSIGN_OR_RETURN(auto hwc, GetHwcFromDims(input_tensors[0].shape().dims));
+    MP_ASSIGN_OR_RETURN(auto hwc,
+                        GetHwcFromDims(input_tensors[0].shape().dims));
     int tensor_channels = std::get<2>(hwc);
     typedef mediapipe::TensorsToSegmentationCalculatorOptions Options;
     switch (options_.activation()) {
@@ -285,6 +277,15 @@
 
   if (use_gpu) {
 #if !MEDIAPIPE_DISABLE_GPU
+    if (!gpu_initialized_) {
+      MP_RETURN_IF_ERROR(InitGpu(cc));
+      gpu_initialized_ = true;
+    }
+#else
+    RET_CHECK_FAIL() << "GPU processing disabled.";
+#endif  // !MEDIAPIPE_DISABLE_GPU
+
+#if !MEDIAPIPE_DISABLE_GPU
     MP_RETURN_IF_ERROR(gpu_helper_.RunInGlContext([this, cc]() -> absl::Status {
       MP_RETURN_IF_ERROR(ProcessGpu(cc));
       return absl::OkStatus();
@@ -305,6 +306,10 @@
 
 absl::Status TensorsToSegmentationCalculator::Close(CalculatorContext* cc) {
 #if !MEDIAPIPE_DISABLE_GPU
+  if (!gpu_initialized_) {
+    return absl::OkStatus();
+  }
+
   gpu_helper_.RunInGlContext([this] {
     if (upsample_program_) glDeleteProgram(upsample_program_);
     upsample_program_ = 0;
@@ -330,7 +335,7 @@
   // Get input streams, and dimensions.
   const auto& input_tensors =
       cc->Inputs().Tag(kTensorsTag).Get<std::vector<Tensor>>();
-  ASSIGN_OR_RETURN(auto hwc, GetHwcFromDims(input_tensors[0].shape().dims));
+  MP_ASSIGN_OR_RETURN(auto hwc, GetHwcFromDims(input_tensors[0].shape().dims));
   auto [tensor_height, tensor_width, tensor_channels] = hwc;
   int output_width = tensor_width, output_height = tensor_height;
   if (cc->Inputs().HasTag(kOutputSizeTag)) {
@@ -441,7 +446,7 @@
   // Get input streams, and dimensions.
   const auto& input_tensors =
       cc->Inputs().Tag(kTensorsTag).Get<std::vector<Tensor>>();
-  ASSIGN_OR_RETURN(auto hwc, GetHwcFromDims(input_tensors[0].shape().dims));
+  MP_ASSIGN_OR_RETURN(auto hwc, GetHwcFromDims(input_tensors[0].shape().dims));
   auto [tensor_height, tensor_width, tensor_channels] = hwc;
   int output_width = tensor_width, output_height = tensor_height;
   if (cc->Inputs().HasTag(kOutputSizeTag)) {
@@ -634,6 +639,7 @@
 
 absl::Status TensorsToSegmentationCalculator::InitGpu(CalculatorContext* cc) {
 #if !MEDIAPIPE_DISABLE_GPU
+  MP_RETURN_IF_ERROR(gpu_helper_.Open(cc));
   MP_RETURN_IF_ERROR(gpu_helper_.RunInGlContext([this]() -> absl::Status {
   // A shader to process a segmentation tensor into an output mask.
   // Currently uses 4 channels for output, and sets R+A channels as mask value.
@@ -898,6 +904,8 @@
 
     return absl::OkStatus();
   }));
+
+  gpu_initialized_ = true;
 #endif  // !MEDIAPIPE_DISABLE_GPU
 
   return absl::OkStatus();
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tensorflow/object_detection_tensors_to_detections_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/tensorflow/object_detection_tensors_to_detections_calculator.cc
index f85c7bb..95a00a1 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tensorflow/object_detection_tensors_to_detections_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tensorflow/object_detection_tensors_to_detections_calculator.cc
@@ -151,7 +151,7 @@
     tf::Tensor input_num_detections_tensor =
         tf::Tensor(tf::DT_FLOAT, tf::TensorShape({0}));
     if (cc->Inputs().HasTag(kClasses)) {
-      ASSIGN_OR_RETURN(
+      MP_ASSIGN_OR_RETURN(
           input_num_detections_tensor,
           MaybeSqueezeDims(kNumDetections,
                            cc->Inputs().Tag(kNumDetections).Get<tf::Tensor>()));
@@ -160,12 +160,12 @@
       RET_CHECK_EQ(input_num_detections_tensor.dtype(), tf::DT_FLOAT);
     }
 
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         auto input_boxes_tensor,
         MaybeSqueezeDims(kBoxes, cc->Inputs().Tag(kBoxes).Get<tf::Tensor>()));
     RET_CHECK_EQ(input_boxes_tensor.dtype(), tf::DT_FLOAT);
 
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         auto input_scores_tensor,
         MaybeSqueezeDims(kScores, cc->Inputs().Tag(kScores).Get<tf::Tensor>()));
     RET_CHECK_EQ(input_scores_tensor.dtype(), tf::DT_FLOAT);
@@ -173,7 +173,7 @@
     tf::Tensor input_classes_tensor =
         tf::Tensor(tf::DT_FLOAT, tf::TensorShape({0}));
     if (cc->Inputs().HasTag(kClasses)) {
-      ASSIGN_OR_RETURN(
+      MP_ASSIGN_OR_RETURN(
           input_classes_tensor,
           MaybeSqueezeDims(kClasses,
                            cc->Inputs().Tag(kClasses).Get<tf::Tensor>()));
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tflite/tflite_inference_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/tflite/tflite_inference_calculator.cc
index d875b69..18066b7 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tflite/tflite_inference_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tflite/tflite_inference_calculator.cc
@@ -489,8 +489,8 @@
 #if MEDIAPIPE_TFLITE_GL_INFERENCE && defined(MEDIAPIPE_ANDROID)
   if (use_kernel_caching_) {
     // Save kernel file.
-    ASSIGN_OR_RETURN(std::vector<uint8_t> kernel_cache,
-                     tflite_gpu_runner_->GetSerializedBinaryCache());
+    MP_ASSIGN_OR_RETURN(std::vector<uint8_t> kernel_cache,
+                        tflite_gpu_runner_->GetSerializedBinaryCache());
     std::string cache_str(kernel_cache.begin(), kernel_cache.end());
     MP_RETURN_IF_ERROR(
         mediapipe::file::SetContents(cached_kernel_filename_, cache_str));
@@ -733,7 +733,7 @@
 absl::Status TfLiteInferenceCalculator::InitTFLiteGPURunner(
     CalculatorContext* cc) {
 #if MEDIAPIPE_TFLITE_GL_INFERENCE
-  ASSIGN_OR_RETURN(model_packet_, GetModelAsPacket(*cc));
+  MP_ASSIGN_OR_RETURN(model_packet_, GetModelAsPacket(*cc));
   const auto& model = *model_packet_.Get<TfLiteModelPtr>();
 
   tflite::ops::builtin::BuiltinOpResolverWithoutDefaultDelegates
@@ -817,8 +817,8 @@
   gpu_data_out_.resize(tflite_gpu_runner_->outputs_size());
   for (int i = 0; i < tflite_gpu_runner_->outputs_size(); ++i) {
     gpu_data_out_[i] = absl::make_unique<GPUData>();
-    ASSIGN_OR_RETURN(gpu_data_out_[i]->elements,
-                     tflite_gpu_runner_->GetOutputElements(i));
+    MP_ASSIGN_OR_RETURN(gpu_data_out_[i]->elements,
+                        tflite_gpu_runner_->GetOutputElements(i));
     // Create and bind input buffer.
     MP_RETURN_IF_ERROR(
         ::tflite::gpu::gl::CreateReadWriteShaderStorageBuffer<float>(
@@ -839,7 +839,7 @@
     return absl::OkStatus();
   }
 
-  ASSIGN_OR_RETURN(model_packet_, GetModelAsPacket(*cc));
+  MP_ASSIGN_OR_RETURN(model_packet_, GetModelAsPacket(*cc));
   const auto& model = *model_packet_.Get<TfLiteModelPtr>();
 
   tflite::ops::builtin::BuiltinOpResolverWithoutDefaultDelegates
diff --git a/third_party/mediapipe/src/mediapipe/calculators/tflite/tflite_tensors_to_classification_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/tflite/tflite_tensors_to_classification_calculator.cc
index 98ab4b1d..3307e76 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/tflite/tflite_tensors_to_classification_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/tflite/tflite_tensors_to_classification_calculator.cc
@@ -101,8 +101,8 @@
   top_k_ = options_.top_k();
   if (options_.has_label_map_path()) {
     std::string string_path;
-    ASSIGN_OR_RETURN(string_path,
-                     PathToResourceAsFile(options_.label_map_path()));
+    MP_ASSIGN_OR_RETURN(string_path,
+                        PathToResourceAsFile(options_.label_map_path()));
     std::string label_map_string;
     MP_RETURN_IF_ERROR(file::GetContents(string_path, &label_map_string));
 
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/BUILD b/third_party/mediapipe/src/mediapipe/calculators/util/BUILD
index ac69d96..375e380 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/util/BUILD
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/BUILD
@@ -36,6 +36,32 @@
 )
 
 mediapipe_proto_library(
+    name = "align_hand_to_pose_in_world_calculator_proto",
+    srcs = ["align_hand_to_pose_in_world_calculator.proto"],
+    deps = [
+        "//mediapipe/framework:calculator_options_proto",
+        "//mediapipe/framework:calculator_proto",
+    ],
+)
+
+cc_library(
+    name = "align_hand_to_pose_in_world_calculator",
+    srcs = ["align_hand_to_pose_in_world_calculator.cc"],
+    hdrs = ["align_hand_to_pose_in_world_calculator.h"],
+    deps = [
+        ":align_hand_to_pose_in_world_calculator_cc_proto",
+        "//mediapipe/framework:calculator_framework",
+        "//mediapipe/framework/api2:node",
+        "//mediapipe/framework/api2:port",
+        "//mediapipe/framework/formats:landmark_cc_proto",
+        "//mediapipe/framework/port:ret_check",
+        "//mediapipe/framework/port:status",
+        "@com_google_absl//absl/status",
+    ],
+    alwayslink = 1,
+)
+
+mediapipe_proto_library(
     name = "annotation_overlay_calculator_proto",
     srcs = ["annotation_overlay_calculator.proto"],
     deps = [
@@ -1618,6 +1644,91 @@
 )
 
 cc_library(
+    name = "combine_joints_calculator",
+    srcs = ["combine_joints_calculator.cc"],
+    hdrs = ["combine_joints_calculator.h"],
+    deps = [
+        ":combine_joints_calculator_cc_proto",
+        "//mediapipe/framework:calculator_framework",
+        "//mediapipe/framework/api2:node",
+        "//mediapipe/framework/formats:body_rig_cc_proto",
+        "//mediapipe/framework/port:ret_check",
+    ],
+    alwayslink = 1,
+)
+
+mediapipe_proto_library(
+    name = "combine_joints_calculator_proto",
+    srcs = ["combine_joints_calculator.proto"],
+    deps = [
+        "//mediapipe/framework:calculator_options_proto",
+        "//mediapipe/framework:calculator_proto",
+        "//mediapipe/framework/formats:body_rig_proto",
+    ],
+)
+
+cc_test(
+    name = "combine_joints_calculator_test",
+    srcs = ["combine_joints_calculator_test.cc"],
+    deps = [
+        ":combine_joints_calculator",
+        ":combine_joints_calculator_cc_proto",
+        "//mediapipe/framework:calculator_framework",
+        "//mediapipe/framework:calculator_runner",
+        "//mediapipe/framework:packet",
+        "//mediapipe/framework/formats:body_rig_cc_proto",
+        "//mediapipe/framework/port:gtest_main",
+        "//mediapipe/framework/port:parse_text_proto",
+        "//mediapipe/framework/port:status_matchers",
+        "@com_google_absl//absl/strings",
+        "@com_google_absl//absl/strings:str_format",
+    ],
+)
+
+cc_library(
+    name = "set_joints_visibility_calculator",
+    srcs = ["set_joints_visibility_calculator.cc"],
+    hdrs = ["set_joints_visibility_calculator.h"],
+    deps = [
+        ":set_joints_visibility_calculator_cc_proto",
+        "//mediapipe/framework:calculator_framework",
+        "//mediapipe/framework/api2:node",
+        "//mediapipe/framework/formats:body_rig_cc_proto",
+        "//mediapipe/framework/formats:landmark_cc_proto",
+        "//mediapipe/framework/port:ret_check",
+        "//mediapipe/framework/port:status",
+    ],
+    alwayslink = 1,
+)
+
+mediapipe_proto_library(
+    name = "set_joints_visibility_calculator_proto",
+    srcs = ["set_joints_visibility_calculator.proto"],
+    deps = [
+        "//mediapipe/framework:calculator_options_proto",
+        "//mediapipe/framework:calculator_proto",
+    ],
+)
+
+cc_test(
+    name = "set_joints_visibility_calculator_test",
+    srcs = ["set_joints_visibility_calculator_test.cc"],
+    deps = [
+        ":set_joints_visibility_calculator",
+        "//mediapipe/framework:calculator_framework",
+        "//mediapipe/framework:calculator_runner",
+        "//mediapipe/framework:packet",
+        "//mediapipe/framework/formats:body_rig_cc_proto",
+        "//mediapipe/framework/formats:landmark_cc_proto",
+        "//mediapipe/framework/port:gtest_main",
+        "//mediapipe/framework/port:parse_text_proto",
+        "//mediapipe/framework/port:status_matchers",
+        "@com_google_absl//absl/strings",
+        "@com_google_absl//absl/types:optional",
+    ],
+)
+
+cc_library(
     name = "pass_through_or_empty_detection_vector_calculator",
     srcs = ["pass_through_or_empty_detection_vector_calculator.cc"],
     hdrs = ["pass_through_or_empty_detection_vector_calculator.h"],
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/align_hand_to_pose_in_world_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/align_hand_to_pose_in_world_calculator.cc
new file mode 100644
index 0000000..38cee59
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/align_hand_to_pose_in_world_calculator.cc
@@ -0,0 +1,80 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "mediapipe/calculators/util/align_hand_to_pose_in_world_calculator.h"
+
+#include <utility>
+
+#include "absl/status/status.h"
+#include "mediapipe/calculators/util/align_hand_to_pose_in_world_calculator.pb.h"
+#include "mediapipe/framework/api2/node.h"
+#include "mediapipe/framework/calculator_framework.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+#include "mediapipe/framework/port/ret_check.h"
+
+namespace mediapipe::api2 {
+
+namespace {}  // namespace
+
+class AlignHandToPoseInWorldCalculatorImpl
+    : public NodeImpl<AlignHandToPoseInWorldCalculator> {
+ public:
+  absl::Status Open(CalculatorContext* cc) override {
+    const auto& options =
+        cc->Options<mediapipe::AlignHandToPoseInWorldCalculatorOptions>();
+    hand_wrist_idx_ = options.hand_wrist_idx();
+    pose_wrist_idx_ = options.pose_wrist_idx();
+    return absl::OkStatus();
+  }
+
+  absl::Status Process(CalculatorContext* cc) override {
+    // Check that landmarks are not empty.
+    if (kInHandLandmarks(cc).IsEmpty()) {
+      return absl::OkStatus();
+    }
+
+    // Check that pose landmarks are provided.
+    RET_CHECK(!kInPoseLandmarks(cc).IsEmpty());
+
+    const auto& in_hand_landmarks = kInHandLandmarks(cc).Get();
+    const auto& in_pose_landmarks = kInPoseLandmarks(cc).Get();
+
+    // Get hand and pose wrists.
+    RET_CHECK(hand_wrist_idx_ <= in_hand_landmarks.landmark_size());
+    const auto& hand_wrist = in_hand_landmarks.landmark(hand_wrist_idx_);
+    RET_CHECK(pose_wrist_idx_ <= in_pose_landmarks.landmark_size());
+    const auto& pose_wrist = in_pose_landmarks.landmark(pose_wrist_idx_);
+
+    LandmarkList out_hand_landmarks;
+    for (int i = 0; i < in_hand_landmarks.landmark_size(); ++i) {
+      const auto& in_landmark = in_hand_landmarks.landmark(i);
+      Landmark* out_landmark = out_hand_landmarks.add_landmark();
+      *out_landmark = in_landmark;
+      out_landmark->set_x(in_landmark.x() - hand_wrist.x() + pose_wrist.x());
+      out_landmark->set_y(in_landmark.y() - hand_wrist.y() + pose_wrist.y());
+      out_landmark->set_z(in_landmark.z() - hand_wrist.z() + pose_wrist.z());
+    }
+
+    kOutHandLandmarks(cc).Send(std::move(out_hand_landmarks));
+
+    return absl::OkStatus();
+  }
+
+ private:
+  int hand_wrist_idx_;
+  int pose_wrist_idx_;
+};
+MEDIAPIPE_NODE_IMPLEMENTATION(AlignHandToPoseInWorldCalculatorImpl);
+
+}  // namespace mediapipe::api2
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/align_hand_to_pose_in_world_calculator.h b/third_party/mediapipe/src/mediapipe/calculators/util/align_hand_to_pose_in_world_calculator.h
new file mode 100644
index 0000000..b2393d1
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/align_hand_to_pose_in_world_calculator.h
@@ -0,0 +1,74 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef MEDIAPIPE_CALCULATORS_UTIL_ALIGN_HAND_TO_POSE_IN_WORLD_CALCULATOR_H_
+#define MEDIAPIPE_CALCULATORS_UTIL_ALIGN_HAND_TO_POSE_IN_WORLD_CALCULATOR_H_
+
+#include "mediapipe/calculators/util/align_hand_to_pose_in_world_calculator.pb.h"
+#include "mediapipe/framework/api2/node.h"
+#include "mediapipe/framework/api2/port.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+
+namespace mediapipe::api2 {
+
+// A calculator to align hand world landmarks with pose world landmarks.
+//
+// When `mediapipe.aimatter.LandmarksDetector` projects world landmarks from ROI
+// local coordinates to original scene coordinates, it applies only rotation
+// (derived from ROI) but neither scale nor translation. This calculator
+// utilizes pose semantic to compensate this lack of information:
+//   - Translation is determined by matching wrist from hand landmarks with
+//     wrist from pose landmarks.
+//   - Scale can be determined (but is not at the moment) by calculating
+//     expected hand size from pose landmarks proportions.
+//
+// Input:
+//   HAND_LANDMARKS - LandmarkList
+//     Hand world landmarks.
+//   POSE_LANDMARKS - LandmarkList
+//     Pose world landmarks.
+//
+// Output:
+//   HAND_LANDMARKS - LandmarkList
+//     Aligned hand world landmarks.
+//
+// Example:
+//   node {
+//     calculator: "AlignHandToPoseInWorldCalculator"
+//     input_stream: "HAND_LANDMARKS:hand_world_landmarks"
+//     input_stream: "POSE_LANDMARKS:pose_world_landmarks"
+//     output_stream: "HAND_LANDMARKS:hand_world_landmarks"
+//     options: {
+//       [mediapipe.AlignHandToPoseInWorldCalculatorOptions.ext] {
+//         hand_wrist_idx: 0
+//         pose_wrist_idx: 15    # 16 for right
+//       }
+//     }
+//   }
+class AlignHandToPoseInWorldCalculator : public NodeIntf {
+ public:
+  static constexpr Input<mediapipe::LandmarkList> kInHandLandmarks{
+      "HAND_LANDMARKS"};
+  static constexpr Input<mediapipe::LandmarkList> kInPoseLandmarks{
+      "POSE_LANDMARKS"};
+  static constexpr Output<mediapipe::LandmarkList> kOutHandLandmarks{
+      "HAND_LANDMARKS"};
+  MEDIAPIPE_NODE_INTERFACE(::mediapipe::AlignHandToPoseInWorldCalculator,
+                           kInHandLandmarks, kInPoseLandmarks,
+                           kOutHandLandmarks);
+};
+
+}  // namespace mediapipe::api2
+
+#endif  // MEDIAPIPE_CALCULATORS_UTIL_ALIGN_HAND_TO_POSE_IN_WORLD_CALCULATOR_H_
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/align_hand_to_pose_in_world_calculator.proto b/third_party/mediapipe/src/mediapipe/calculators/util/align_hand_to_pose_in_world_calculator.proto
new file mode 100644
index 0000000..17b2a53
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/align_hand_to_pose_in_world_calculator.proto
@@ -0,0 +1,31 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto2";
+
+package mediapipe;
+
+import "mediapipe/framework/calculator.proto";
+
+message AlignHandToPoseInWorldCalculatorOptions {
+  extend CalculatorOptions {
+    optional AlignHandToPoseInWorldCalculatorOptions ext = 403449802;
+  }
+
+  // Hand wrist index.
+  optional int32 hand_wrist_idx = 1;
+
+  // Pose wrist index.
+  optional int32 pose_wrist_idx = 2;
+}
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/association_calculator.h b/third_party/mediapipe/src/mediapipe/calculators/util/association_calculator.h
index 1cec63c..ed939b9 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/util/association_calculator.h
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/association_calculator.h
@@ -171,13 +171,13 @@
     // Compare this element with elements of the input collection. If this
     // element has high overlap with elements of the collection, remove
     // those elements from the collection and add this element.
-    ASSIGN_OR_RETURN(auto cur_rect, GetRectangle(element));
+    MP_ASSIGN_OR_RETURN(auto cur_rect, GetRectangle(element));
 
     bool change_id = false;
     int new_elem_id = -1;
 
     for (auto uit = current->begin(); uit != current->end();) {
-      ASSIGN_OR_RETURN(auto prev_rect, GetRectangle(*uit));
+      MP_ASSIGN_OR_RETURN(auto prev_rect, GetRectangle(*uit));
       if (CalculateIou(cur_rect, prev_rect) >
           options_.min_similarity_threshold()) {
         std::pair<bool, int> prev_id = GetId(*uit);
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/combine_joints_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/combine_joints_calculator.cc
new file mode 100644
index 0000000..ac5e6b0
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/combine_joints_calculator.cc
@@ -0,0 +1,79 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "mediapipe/calculators/util/combine_joints_calculator.h"
+
+#include <utility>
+
+#include "mediapipe/calculators/util/combine_joints_calculator.pb.h"
+#include "mediapipe/framework/api2/node.h"
+#include "mediapipe/framework/calculator_framework.h"
+#include "mediapipe/framework/formats/body_rig.pb.h"
+#include "mediapipe/framework/port/ret_check.h"
+
+namespace mediapipe {
+namespace api2 {
+
+namespace {}  // namespace
+
+class CombineJointsCalculatorImpl : public NodeImpl<CombineJointsCalculator> {
+ public:
+  absl::Status Open(CalculatorContext* cc) override {
+    options_ = cc->Options<CombineJointsCalculatorOptions>();
+    RET_CHECK_GE(options_.num_joints(), 0);
+    RET_CHECK_GT(kInJoints(cc).Count(), 0);
+    RET_CHECK_EQ(kInJoints(cc).Count(), options_.joints_mapping_size());
+    RET_CHECK(options_.has_default_joint());
+    for (const auto& mapping : options_.joints_mapping()) {
+      for (int idx : mapping.idx()) {
+        RET_CHECK_GE(idx, 0);
+        RET_CHECK_LT(idx, options_.num_joints());
+      }
+    }
+    return absl::OkStatus();
+  }
+
+  absl::Status Process(CalculatorContext* cc) override {
+    // Initialize output joints with default values.
+    JointList out_joints;
+    for (int i = 0; i < options_.num_joints(); ++i) {
+      *out_joints.add_joint() = options_.default_joint();
+    }
+
+    // Override default joints with provided joints.
+    for (int i = 0; i < kInJoints(cc).Count(); ++i) {
+      // Skip empty joint streams.
+      if (kInJoints(cc)[i].IsEmpty()) {
+        continue;
+      }
+
+      const JointList& in_joints = kInJoints(cc)[i].Get();
+      const auto& mapping = options_.joints_mapping(i);
+      RET_CHECK_EQ(in_joints.joint_size(), mapping.idx_size());
+      for (int j = 0; j < in_joints.joint_size(); ++j) {
+        *out_joints.mutable_joint(mapping.idx(j)) = in_joints.joint(j);
+      }
+    }
+
+    kOutJoints(cc).Send(std::move(out_joints));
+    return absl::OkStatus();
+  }
+
+ private:
+  CombineJointsCalculatorOptions options_;
+};
+MEDIAPIPE_NODE_IMPLEMENTATION(CombineJointsCalculatorImpl);
+
+}  // namespace api2
+}  // namespace mediapipe
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/combine_joints_calculator.h b/third_party/mediapipe/src/mediapipe/calculators/util/combine_joints_calculator.h
new file mode 100644
index 0000000..41b3c31
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/combine_joints_calculator.h
@@ -0,0 +1,64 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef MEDIAPIPE_CALCULATORS_UTIL_COMBINE_JOINTS_CALCULATOR_H_
+#define MEDIAPIPE_CALCULATORS_UTIL_COMBINE_JOINTS_CALCULATOR_H_
+
+#include "mediapipe/framework/api2/node.h"
+#include "mediapipe/framework/calculator_framework.h"
+#include "mediapipe/framework/formats/body_rig.pb.h"
+
+namespace mediapipe {
+namespace api2 {
+
+// A calculator to combine several joint sets into one.
+//
+// Input:
+//   JOINTS - Multiple JointList
+//     Joint sets to combine into one. Subsets are applied in provided order and
+//     overwrite each other.
+//
+// Output:
+//   JOINTS - JointList
+//     Combined joints.
+//
+// Example:
+//   node {
+//     calculator: "CombineJointsCalculator"
+//     input_stream: "JOINTS:0:joints_0"
+//     input_stream: "JOINTS:1:joints_1"
+//     output_stream: "JOINTS:combined_joints"
+//     options: {
+//       [mediapipe.CombineJointsCalculatorOptions.ext] {
+//         num_joints: 63
+//         joints_mapping: { idx: [0, 1, 2] }
+//         joints_mapping: { idx: [2, 3] }
+//         default_joint: {
+//           rotation_6d: [1, 0, 0, 1, 0, 0]
+//           visibility: 1.0
+//         }
+//       }
+//     }
+//   }
+class CombineJointsCalculator : public NodeIntf {
+ public:
+  static constexpr Input<mediapipe::JointList>::Multiple kInJoints{"JOINTS"};
+  static constexpr Output<mediapipe::JointList> kOutJoints{"JOINTS"};
+  MEDIAPIPE_NODE_INTERFACE(CombineJointsCalculator, kInJoints, kOutJoints);
+};
+
+}  // namespace api2
+}  // namespace mediapipe
+
+#endif  // MEDIAPIPE_CALCULATORS_UTIL_COMBINE_JOINTS_CALCULATOR_H_
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/combine_joints_calculator.proto b/third_party/mediapipe/src/mediapipe/calculators/util/combine_joints_calculator.proto
new file mode 100644
index 0000000..d90f6df
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/combine_joints_calculator.proto
@@ -0,0 +1,46 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto2";
+
+package mediapipe;
+
+import "mediapipe/framework/calculator.proto";
+import "mediapipe/framework/formats/body_rig.proto";
+
+message CombineJointsCalculatorOptions {
+  extend CalculatorOptions {
+    optional CombineJointsCalculatorOptions ext = 406440185;
+  }
+
+  // Mapping from joint set to the resulting set.
+  message JointsMapping {
+    // Indexes of provided joints in the resulting joint set.
+    // All indexes must be within the [0, num_joints - 1] range.
+    repeated int32 idx = 1 [packed = true];
+  }
+
+  // Number of joints in the resulting set.
+  optional int32 num_joints = 1;
+
+  // Mapping from joint sets to the resulting set.
+  // Number of mappings must be equal to number of provided joint sets. Number
+  // of indexes in each mapping must be equal to number of joints in
+  // corresponding joint set. Mappings are applied in the provided order and can
+  // overwrite each other.
+  repeated JointsMapping joints_mapping = 2;
+
+  // Default joint to initialize joints in the resulting set.
+  optional Joint default_joint = 3;
+}
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/detection_label_id_to_text_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/detection_label_id_to_text_calculator.cc
index 44b7a210..2a11b58 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/util/detection_label_id_to_text_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/detection_label_id_to_text_calculator.cc
@@ -83,8 +83,8 @@
         << "Only can set one of the following fields in the CalculatorOptions: "
            "label_map_path, label, and label_items.";
     std::string string_path;
-    ASSIGN_OR_RETURN(string_path,
-                     PathToResourceAsFile(options.label_map_path()));
+    MP_ASSIGN_OR_RETURN(string_path,
+                        PathToResourceAsFile(options.label_map_path()));
     std::string label_map_string;
     MP_RETURN_IF_ERROR(
         mediapipe::GetResourceContents(string_path, &label_map_string));
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/detection_transformation_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/detection_transformation_calculator.cc
index 3eac315..6fa031e 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/util/detection_transformation_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/detection_transformation_calculator.cc
@@ -96,10 +96,10 @@
     std::vector<Detection>& detections) {
   RET_CHECK(!detections.empty());
   LocationData::Format output_format;
-  ASSIGN_OR_RETURN(output_format, GetLocationDataFormat(detections[0]));
+  MP_ASSIGN_OR_RETURN(output_format, GetLocationDataFormat(detections[0]));
   for (int i = 1; i < detections.size(); ++i) {
-    ASSIGN_OR_RETURN(LocationData::Format format,
-                     GetLocationDataFormat(detections[i]));
+    MP_ASSIGN_OR_RETURN(LocationData::Format format,
+                        GetLocationDataFormat(detections[i]));
     if (output_format != format) {
       return absl::InvalidArgumentError(
           "Input detections have different location data formats.");
@@ -243,8 +243,8 @@
         OutputEmptyDetections(cc);
         return absl::OkStatus();
       }
-      ASSIGN_OR_RETURN(input_location_data_format,
-                       GetLocationDataFormat(transformed_detections));
+      MP_ASSIGN_OR_RETURN(input_location_data_format,
+                          GetLocationDataFormat(transformed_detections));
       for (Detection& detection : transformed_detections) {
         MP_RETURN_IF_ERROR(ConvertBoundingBox(image_size, &detection));
       }
@@ -254,8 +254,8 @@
         OutputEmptyDetections(cc);
         return absl::OkStatus();
       }
-      ASSIGN_OR_RETURN(input_location_data_format,
-                       GetLocationDataFormat(kInDetection(cc).Get()));
+      MP_ASSIGN_OR_RETURN(input_location_data_format,
+                          GetLocationDataFormat(kInDetection(cc).Get()));
       MP_RETURN_IF_ERROR(
           ConvertBoundingBox(image_size, &transformed_detection));
       transformed_detections.push_back(transformed_detection);
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_refinement_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_refinement_calculator.cc
index 87394c6..7d50e18 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_refinement_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_refinement_calculator.cc
@@ -137,8 +137,8 @@
     }
 
     // Validate indexes mapping and get total number of refined landmarks.
-    ASSIGN_OR_RETURN(n_refined_landmarks_,
-                     GetNumberOfRefinedLandmarks(options_.refinement()));
+    MP_ASSIGN_OR_RETURN(n_refined_landmarks_,
+                        GetNumberOfRefinedLandmarks(options_.refinement()));
 
     // Validate that number of refinements and landmark streams is the same.
     RET_CHECK_EQ(kLandmarks(cc).Count(), options_.refinement_size())
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_smoothing_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_smoothing_calculator.cc
index bc75044..0bbee7c 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_smoothing_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_smoothing_calculator.cc
@@ -43,9 +43,10 @@
     : public NodeImpl<LandmarksSmoothingCalculator> {
  public:
   absl::Status Open(CalculatorContext* cc) override {
-    ASSIGN_OR_RETURN(landmarks_filter_,
-                     InitializeLandmarksFilter(
-                         cc->Options<LandmarksSmoothingCalculatorOptions>()));
+    MP_ASSIGN_OR_RETURN(
+        landmarks_filter_,
+        InitializeLandmarksFilter(
+            cc->Options<LandmarksSmoothingCalculatorOptions>()));
     return absl::OkStatus();
   }
 
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_smoothing_calculator_utils.cc b/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_smoothing_calculator_utils.cc
index 32e2821..d5ed37f 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_smoothing_calculator_utils.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_smoothing_calculator_utils.cc
@@ -348,7 +348,8 @@
     return it->second.get();
   }
 
-  ASSIGN_OR_RETURN(auto landmarks_filter, InitializeLandmarksFilter(options));
+  MP_ASSIGN_OR_RETURN(auto landmarks_filter,
+                      InitializeLandmarksFilter(options));
   filters_[tracking_id] = std::move(landmarks_filter);
   return filters_[tracking_id].get();
 }
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_transformation_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_transformation_calculator.cc
new file mode 100644
index 0000000..e3ab45f
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_transformation_calculator.cc
@@ -0,0 +1,142 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "mediapipe/calculators/util/landmarks_transformation_calculator.h"
+
+#include <utility>
+
+#include "mediapipe/calculators/util/landmarks_transformation_calculator.pb.h"
+#include "mediapipe/framework/api2/node.h"
+#include "mediapipe/framework/calculator_framework.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+#include "mediapipe/framework/port/ret_check.h"
+#include "mediapipe/framework/port/statusor.h"
+
+namespace mediapipe {
+namespace api2 {
+
+namespace {
+
+StatusOr<LandmarkList> NormalizeTranslation(const LandmarkList& in_landmarks) {
+  RET_CHECK_GT(in_landmarks.landmark_size(), 0);
+
+  double x_sum = 0.0f;
+  double y_sum = 0.0f;
+  double z_sum = 0.0f;
+  for (auto& in_landmark : in_landmarks.landmark()) {
+    x_sum += in_landmark.x();
+    y_sum += in_landmark.y();
+    z_sum += in_landmark.z();
+  }
+
+  float x_mean = x_sum / in_landmarks.landmark_size();
+  float y_mean = y_sum / in_landmarks.landmark_size();
+  float z_mean = z_sum / in_landmarks.landmark_size();
+
+  LandmarkList out_landmarks;
+  for (auto& in_landmark : in_landmarks.landmark()) {
+    auto* out_landmark = out_landmarks.add_landmark();
+    *out_landmark = in_landmark;
+    out_landmark->set_x(in_landmark.x() - x_mean);
+    out_landmark->set_y(in_landmark.y() - y_mean);
+    out_landmark->set_z(in_landmark.z() - z_mean);
+  }
+
+  return out_landmarks;
+}
+
+StatusOr<LandmarkList> FlipAxis(
+    const LandmarkList& in_landmarks,
+    const LandmarksTransformationCalculatorOptions::FlipAxis& options) {
+  float x_mul = options.flip_x() ? -1 : 1;
+  float y_mul = options.flip_y() ? -1 : 1;
+  float z_mul = options.flip_z() ? -1 : 1;
+
+  LandmarkList out_landmarks;
+  for (auto& in_landmark : in_landmarks.landmark()) {
+    auto* out_landmark = out_landmarks.add_landmark();
+    *out_landmark = in_landmark;
+    out_landmark->set_x(in_landmark.x() * x_mul);
+    out_landmark->set_y(in_landmark.y() * y_mul);
+    out_landmark->set_z(in_landmark.z() * z_mul);
+  }
+
+  return out_landmarks;
+}
+
+}  // namespace
+
+class LandmarksTransformationCalculatorImpl
+    : public NodeImpl<LandmarksTransformationCalculator> {
+ public:
+  static absl::Status UpdateContract(CalculatorContract* cc) {
+    // Check that if options input stream is connected there should be no static
+    // options in calculator. Currently there is no such functionality, so we'll
+    // just check for the number of transforms.
+    if (kInOptions(cc).IsConnected()) {
+      RET_CHECK_EQ(cc->Options<LandmarksTransformationCalculatorOptions>()
+                       .transformation_size(),
+                   0);
+    }
+    return absl::OkStatus();
+  }
+
+  absl::Status Open(CalculatorContext* cc) override {
+    options_ = cc->Options<LandmarksTransformationCalculatorOptions>();
+    return absl::OkStatus();
+  }
+
+  absl::Status Process(CalculatorContext* cc) override {
+    if (kInLandmarks(cc).IsEmpty()) {
+      return absl::OkStatus();
+    }
+
+    // Get transformation options for either calculator parameters or input
+    // stream. Input stream has higher priority.
+    LandmarksTransformationCalculatorOptions options;
+    if (kInOptions(cc).IsConnected()) {
+      // If input stream is connected but is empty - use no transformations and
+      // return landmarks as is.
+      if (!kInOptions(cc).IsEmpty()) {
+        options = kInOptions(cc).Get();
+      }
+    } else {
+      options = options_;
+    }
+
+    LandmarkList landmarks = kInLandmarks(cc).Get();
+
+    for (auto& transformation : options.transformation()) {
+      if (transformation.has_normalize_translation()) {
+        MP_ASSIGN_OR_RETURN(landmarks, NormalizeTranslation(landmarks));
+      } else if (transformation.has_flip_axis()) {
+        MP_ASSIGN_OR_RETURN(landmarks,
+                            FlipAxis(landmarks, transformation.flip_axis()));
+      } else {
+        RET_CHECK_FAIL() << "Unknown landmarks transformation";
+      }
+    }
+
+    kOutLandmarks(cc).Send(std::move(landmarks));
+
+    return absl::OkStatus();
+  }
+
+ private:
+  LandmarksTransformationCalculatorOptions options_;
+};
+MEDIAPIPE_NODE_IMPLEMENTATION(LandmarksTransformationCalculatorImpl);
+
+}  // namespace api2
+}  // namespace mediapipe
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_transformation_calculator.h b/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_transformation_calculator.h
new file mode 100644
index 0000000..5bc31492
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_transformation_calculator.h
@@ -0,0 +1,62 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef MEDIAPIPE_CALCULATORS_UTIL_LANDMARKS_TRANSFORMATION_CALCULATOR_H_
+#define MEDIAPIPE_CALCULATORS_UTIL_LANDMARKS_TRANSFORMATION_CALCULATOR_H_
+
+#include "mediapipe/calculators/util/landmarks_transformation_calculator.pb.h"
+#include "mediapipe/framework/api2/node.h"
+#include "mediapipe/framework/calculator_framework.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+
+namespace mediapipe {
+namespace api2 {
+
+// A calculator to transform landmarks.
+//
+// Input:
+//   LANDMARKS - LandmarkList
+//     Landmarks to transform.
+//
+// Output:
+//   LANDMARKS - LandmarkList
+//     Transformed landmarks.
+//
+// Example:
+//   node {
+//     calculator: "LandmarksTransformationCalculator"
+//     input_stream: "LANDMARKS:in_landmarks"
+//     output_stream: "LANDMARKS:out_landmarks"
+//     options: {
+//       [mediapipe.LandmarksTransformationCalculatorOptions.ext] {
+//         transformation: { normalize_translation: {} }
+//         transformation: { flip_axis: { flip_x: true } }
+//       }
+//     }
+//   }
+class LandmarksTransformationCalculator : public NodeIntf {
+ public:
+  static constexpr Input<mediapipe::LandmarkList> kInLandmarks{"LANDMARKS"};
+  static constexpr Input<
+      mediapipe::LandmarksTransformationCalculatorOptions>::Optional kInOptions{
+      "OPTIONS"};
+  static constexpr Output<mediapipe::LandmarkList> kOutLandmarks{"LANDMARKS"};
+  MEDIAPIPE_NODE_INTERFACE(LandmarksTransformationCalculator, kInLandmarks,
+                           kInOptions, kOutLandmarks);
+};
+
+}  // namespace api2
+}  // namespace mediapipe
+
+#endif  // MEDIAPIPE_CALCULATORS_UTIL_LANDMARKS_TRANSFORMATION_CALCULATOR_H_
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_transformation_calculator.proto b/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_transformation_calculator.proto
new file mode 100644
index 0000000..0ced6871
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/landmarks_transformation_calculator.proto
@@ -0,0 +1,45 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto2";
+
+package mediapipe;
+
+import "mediapipe/framework/calculator.proto";
+
+message LandmarksTransformationCalculatorOptions {
+  extend CalculatorOptions {
+    optional LandmarksTransformationCalculatorOptions ext = 421309928;
+  }
+
+  // Normalize translation so that center of mass is in (0, 0, 0).
+  message NormalizeTranslation {}
+
+  // Flip axis by multiplying coordinates along it by `-1`.
+  message FlipAxis {
+    optional bool flip_x = 1 [default = false];
+    optional bool flip_y = 2 [default = false];
+    optional bool flip_z = 3 [default = false];
+  }
+
+  message Transformation {
+    oneof transformation {
+      NormalizeTranslation normalize_translation = 1;
+      FlipAxis flip_axis = 2;
+    }
+  }
+
+  // Transformations applied in given order.
+  repeated Transformation transformation = 1;
+}
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/local_file_contents_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/local_file_contents_calculator.cc
index 4ad066f6..195c7da 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/util/local_file_contents_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/local_file_contents_calculator.cc
@@ -86,7 +86,7 @@
          ++input_id, ++output_id) {
       std::string file_path =
           cc->InputSidePackets().Get(input_id).Get<std::string>();
-      ASSIGN_OR_RETURN(file_path, PathToResourceAsFile(file_path));
+      MP_ASSIGN_OR_RETURN(file_path, PathToResourceAsFile(file_path));
 
       std::string contents;
       MP_RETURN_IF_ERROR(GetResourceContents(
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/multi_landmarks_smoothing_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/multi_landmarks_smoothing_calculator.cc
index 40098935..6281187 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/util/multi_landmarks_smoothing_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/multi_landmarks_smoothing_calculator.cc
@@ -83,10 +83,11 @@
                                       image_width, image_height);
       }
 
-      ASSIGN_OR_RETURN(auto* landmarks_filter,
-                       multi_filters_.GetOrCreate(
-                           tracking_ids[i],
-                           cc->Options<LandmarksSmoothingCalculatorOptions>()));
+      MP_ASSIGN_OR_RETURN(
+          auto* landmarks_filter,
+          multi_filters_.GetOrCreate(
+              tracking_ids[i],
+              cc->Options<LandmarksSmoothingCalculatorOptions>()));
 
       LandmarkList out_landmarks;
       MP_RETURN_IF_ERROR(landmarks_filter->Apply(in_landmarks, timestamp,
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/multi_world_landmarks_smoothing_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/multi_world_landmarks_smoothing_calculator.cc
index ddc16d2..44c56c6 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/util/multi_world_landmarks_smoothing_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/multi_world_landmarks_smoothing_calculator.cc
@@ -74,10 +74,11 @@
         object_scale = GetObjectScale(object_scale_roi_vec.value()[i]);
       }
 
-      ASSIGN_OR_RETURN(auto* landmarks_filter,
-                       multi_filters_.GetOrCreate(
-                           tracking_ids[i],
-                           cc->Options<LandmarksSmoothingCalculatorOptions>()));
+      MP_ASSIGN_OR_RETURN(
+          auto* landmarks_filter,
+          multi_filters_.GetOrCreate(
+              tracking_ids[i],
+              cc->Options<LandmarksSmoothingCalculatorOptions>()));
 
       LandmarkList out_landmarks;
       MP_RETURN_IF_ERROR(landmarks_filter->Apply(in_landmarks, timestamp,
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/pass_through_or_empty_detection_vector_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/pass_through_or_empty_detection_vector_calculator.cc
new file mode 100644
index 0000000..811c5ae
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/pass_through_or_empty_detection_vector_calculator.cc
@@ -0,0 +1,27 @@
+#include "mediapipe/calculators/util/pass_through_or_empty_detection_vector_calculator.h"
+
+#include <vector>
+
+#include "absl/status/status.h"
+#include "mediapipe/framework/api2/node.h"
+#include "mediapipe/framework/calculator_context.h"
+#include "mediapipe/framework/formats/detection.pb.h"
+
+namespace mediapipe {
+
+class PassThroughOrEmptyDetectionVectorCalculatorImpl
+    : public mediapipe::api2::NodeImpl<
+          PassThroughOrEmptyDetectionVectorCalculator> {
+ public:
+  absl::Status Process(CalculatorContext* cc) override {
+    if (kInputVector(cc).IsEmpty()) {
+      kOutputVector(cc).Send(std::vector<mediapipe::Detection>{});
+      return absl::OkStatus();
+    }
+    kOutputVector(cc).Send(kInputVector(cc));
+    return absl::OkStatus();
+  }
+};
+MEDIAPIPE_NODE_IMPLEMENTATION(PassThroughOrEmptyDetectionVectorCalculatorImpl);
+
+}  // namespace mediapipe
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/pass_through_or_empty_detection_vector_calculator.h b/third_party/mediapipe/src/mediapipe/calculators/util/pass_through_or_empty_detection_vector_calculator.h
new file mode 100644
index 0000000..ef8c5c5
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/pass_through_or_empty_detection_vector_calculator.h
@@ -0,0 +1,55 @@
+#ifndef MEDIAPIPE_CALCULATORS_UTILS_PASS_THROUGH_OR_EMPTY_DETECTION_VECTOR_CALCULATOR_H_
+#define MEDIAPIPE_CALCULATORS_UTILS_PASS_THROUGH_OR_EMPTY_DETECTION_VECTOR_CALCULATOR_H_
+
+#include <vector>
+
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/api2/node.h"
+#include "mediapipe/framework/api2/packet.h"
+#include "mediapipe/framework/api2/port.h"
+#include "mediapipe/framework/formats/detection.pb.h"
+
+namespace mediapipe {
+
+// Calculator to pass through input vector of detections if packet is not empty,
+// otherwise - outputing a new empty vector. So, instead of empty packet you get
+// a packet containing empty vector.
+//
+// Example:
+// node {
+//   calculator: "PassThroughOrEmptyDetectionVectorCalculator"
+//   input_stream: "TICK:tick"
+//   input_stream: "VECTOR:input_detections"
+//   output_stream: "VECTOR:output_detections"
+// }
+class PassThroughOrEmptyDetectionVectorCalculator
+    : public mediapipe::api2::NodeIntf {
+ public:
+  static constexpr mediapipe::api2::Input<std::vector<mediapipe::Detection>>
+      kInputVector{"VECTOR"};
+  static constexpr mediapipe::api2::Input<mediapipe::api2::AnyType> kTick{
+      "TICK"};
+  static constexpr mediapipe::api2::Output<std::vector<mediapipe::Detection>>
+      kOutputVector{"VECTOR"};
+
+  MEDIAPIPE_NODE_INTERFACE(
+      ::mediapipe::PassThroughOrEmptyDetectionVectorCalculator, kInputVector,
+      kTick, kOutputVector);
+};
+
+template <typename TickT>
+api2::builder::Stream<std::vector<mediapipe::Detection>>
+PassThroughOrEmptyDetectionVector(
+    api2::builder::Stream<std::vector<mediapipe::Detection>> detections,
+    api2::builder::Stream<TickT> tick, mediapipe::api2::builder::Graph& graph) {
+  auto& node =
+      graph.AddNode("mediapipe.PassThroughOrEmptyDetectionVectorCalculator");
+  detections.ConnectTo(
+      node[PassThroughOrEmptyDetectionVectorCalculator::kInputVector]);
+  tick.ConnectTo(node[PassThroughOrEmptyDetectionVectorCalculator::kTick]);
+  return node[PassThroughOrEmptyDetectionVectorCalculator::kOutputVector];
+}
+
+}  // namespace mediapipe
+
+#endif  // MEDIAPIPE_CALCULATORS_UTILS_PASS_THROUGH_OR_EMPTY_DETECTION_VECTOR_CALCULATOR_H_
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/refine_landmarks_from_heatmap_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/refine_landmarks_from_heatmap_calculator.cc
index 30dc11d..33470585 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/util/refine_landmarks_from_heatmap_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/refine_landmarks_from_heatmap_calculator.cc
@@ -77,7 +77,7 @@
     const auto& options =
         cc->Options<mediapipe::RefineLandmarksFromHeatmapCalculatorOptions>();
 
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         auto out_lms,
         RefineLandmarksFromHeatMap(
             in_lms, hm_raw, hm_tensor.shape().dims, options.kernel_size(),
@@ -108,7 +108,7 @@
     const float* heatmap_raw_data, const std::vector<int>& heatmap_dims,
     int kernel_size, float min_confidence_to_refine, bool refine_presence,
     bool refine_visibility) {
-  ASSIGN_OR_RETURN(auto hm_dims, GetHwcFromDims(heatmap_dims));
+  MP_ASSIGN_OR_RETURN(auto hm_dims, GetHwcFromDims(heatmap_dims));
   auto [hm_height, hm_width, hm_channels] = hm_dims;
 
   RET_CHECK_EQ(in_lms.landmark_size(), hm_channels)
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/set_joints_visibility_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/set_joints_visibility_calculator.cc
new file mode 100644
index 0000000..a8cb3f35
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/set_joints_visibility_calculator.cc
@@ -0,0 +1,108 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "mediapipe/calculators/util/set_joints_visibility_calculator.h"
+
+#include <algorithm>
+#include <optional>
+#include <utility>
+
+#include "mediapipe/calculators/util/set_joints_visibility_calculator.pb.h"
+#include "mediapipe/framework/api2/node.h"
+#include "mediapipe/framework/calculator_framework.h"
+#include "mediapipe/framework/formats/body_rig.pb.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+#include "mediapipe/framework/port/ret_check.h"
+
+namespace mediapipe {
+namespace api2 {
+
+namespace {}  // namespace
+
+class SetJointsVisibilityCalculatorImpl
+    : public NodeImpl<SetJointsVisibilityCalculator> {
+ public:
+  absl::Status Open(CalculatorContext* cc) override {
+    options_ = cc->Options<SetJointsVisibilityCalculatorOptions>();
+    return absl::OkStatus();
+  }
+
+  absl::Status Process(CalculatorContext* cc) override {
+    // Skip if Joints are empty.
+    if (kInJoints(cc).IsEmpty()) {
+      return absl::OkStatus();
+    }
+
+    // Get joints.
+    const JointList& in_joints = kInJoints(cc).Get();
+    RET_CHECK_EQ(in_joints.joint_size(), options_.mapping_size())
+        << "Number of joints doesn't match number of mappings";
+
+    // Get landmarks.
+    RET_CHECK(!kInLandmarks(cc).IsEmpty()) << "Landmarks must be provided";
+    const LandmarkList& in_landmarks = kInLandmarks(cc).Get();
+
+    // Set joints visibility.
+    JointList out_joints;
+    for (int i = 0; i < in_joints.joint_size(); ++i) {
+      // Initialize output joint.
+      Joint* out_joint = out_joints.add_joint();
+      *out_joint = in_joints.joint(i);
+
+      // Get visibility. But only if it exists in the source landmark(s).
+      std::optional<float> visibility;
+      auto& mapping = options_.mapping(i);
+      if (mapping.has_unchanged()) {
+        continue;
+      } else if (mapping.has_copy()) {
+        const int idx = mapping.copy().idx();
+        RET_CHECK(idx >= 0 && idx < in_landmarks.landmark_size())
+            << "Landmark index out of range";
+        if (in_landmarks.landmark(idx).has_visibility()) {
+          visibility = in_landmarks.landmark(idx).visibility();
+        }
+      } else if (mapping.has_highest()) {
+        RET_CHECK_GT(mapping.highest().idx_size(), 0) << "No indexes provided";
+        for (int idx : mapping.highest().idx()) {
+          RET_CHECK(idx >= 0 && idx < in_landmarks.landmark_size())
+              << "Landmark index out of range";
+          if (in_landmarks.landmark(idx).has_visibility()) {
+            const float landmark_visibility =
+                in_landmarks.landmark(idx).visibility();
+            visibility = visibility.has_value()
+                             ? std::max(visibility.value(), landmark_visibility)
+                             : landmark_visibility;
+          }
+        }
+      } else {
+        RET_CHECK_FAIL() << "Unknown mapping";
+      }
+
+      // Set visibility. But only if it was possible to obtain it.
+      if (visibility.has_value()) {
+        out_joint->set_visibility(visibility.value());
+      }
+    }
+
+    kOutJoints(cc).Send(std::move(out_joints));
+    return absl::OkStatus();
+  }
+
+ private:
+  SetJointsVisibilityCalculatorOptions options_;
+};
+MEDIAPIPE_NODE_IMPLEMENTATION(SetJointsVisibilityCalculatorImpl);
+
+}  // namespace api2
+}  // namespace mediapipe
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/set_joints_visibility_calculator.h b/third_party/mediapipe/src/mediapipe/calculators/util/set_joints_visibility_calculator.h
new file mode 100644
index 0000000..6a3a071
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/set_joints_visibility_calculator.h
@@ -0,0 +1,68 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef MEDIAPIPE_CALCULATORS_UTIL_SET_JOINTS_VISIBILITY_CALCULATOR_H_
+#define MEDIAPIPE_CALCULATORS_UTIL_SET_JOINTS_VISIBILITY_CALCULATOR_H_
+
+#include "mediapipe/framework/api2/node.h"
+#include "mediapipe/framework/calculator_framework.h"
+#include "mediapipe/framework/formats/body_rig.pb.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+
+namespace mediapipe {
+namespace api2 {
+
+// A calculator set Joints visibility from Landmarks.
+//
+// Calculator allows to either copy visibility right from the landmark or
+// somehow combine visibilities of several landmarks.
+//
+// Input:
+//   JOINTS - JointList
+//     Joints to to update visibility.
+//   LANDMARKS - LandmarkList
+//     Landmarks to take visibility from.
+//
+// Output:
+//   JOINTS - JointList
+//     Joints with updated visibility.
+//
+// Example:
+//   node {
+//     calculator: "SetJointsVisibilityCalculator"
+//     input_stream: "JOINTS:joints"
+//     input_stream: "LANDMARKS:landmarks"
+//     output_stream: "JOINTS:joints_with_visibility"
+//     options: {
+//       [mediapipe.SetJointsVisibilityCalculatorOptions.ext] {
+//         mapping: [
+//           { copy: { idx: 0 } },
+//           { highest: { idx: [5, 6] } }
+//         ]
+//       }
+//     }
+//   }
+class SetJointsVisibilityCalculator : public NodeIntf {
+ public:
+  static constexpr Input<mediapipe::JointList> kInJoints{"JOINTS"};
+  static constexpr Input<mediapipe::LandmarkList> kInLandmarks{"LANDMARKS"};
+  static constexpr Output<mediapipe::JointList> kOutJoints{"JOINTS"};
+  MEDIAPIPE_NODE_INTERFACE(SetJointsVisibilityCalculator, kInJoints,
+                           kInLandmarks, kOutJoints);
+};
+
+}  // namespace api2
+}  // namespace mediapipe
+
+#endif  // MEDIAPIPE_CALCULATORS_UTIL_SET_JOINTS_VISIBILITY_CALCULATOR_H_
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/set_joints_visibility_calculator.proto b/third_party/mediapipe/src/mediapipe/calculators/util/set_joints_visibility_calculator.proto
new file mode 100644
index 0000000..1cbf4899
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/set_joints_visibility_calculator.proto
@@ -0,0 +1,55 @@
+// Copyright 2023 The MediaPipe Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto2";
+
+package mediapipe;
+
+import "mediapipe/framework/calculator.proto";
+
+message SetJointsVisibilityCalculatorOptions {
+  extend CalculatorOptions {
+    optional SetJointsVisibilityCalculatorOptions ext = 406440186;
+  }
+
+  // Mapping that tells where to take visibility for the joint.
+  message Mapping {
+    // Keep visibility unchanged.
+    message Unchanged {}
+
+    // Copy visibility as is from the given landmark.
+    message Copy {
+      // Index of the landmark.
+      optional int32 idx = 1;
+    }
+
+    // Take the highest visibility among the given landmarks.
+    message Highest {
+      // Indexes of landmarks to take the highest visibility value from. At
+      // least one index must be provided.
+      repeated int32 idx = 1 [packed = true];
+    }
+
+    oneof mapping {
+      Unchanged unchanged = 1;
+      Copy copy = 2;
+      Highest highest = 3;
+    }
+  }
+
+  // Mapping that tells where to take visibility for each joint.
+  // Number of mappings must be equal to number of provided joints. Each mapping
+  // must contain exactly one rule for how to set the joint visibility.
+  repeated Mapping mapping = 1;
+}
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/timed_box_list_id_to_label_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/timed_box_list_id_to_label_calculator.cc
index 790b426..0c47c93 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/util/timed_box_list_id_to_label_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/timed_box_list_id_to_label_calculator.cc
@@ -73,7 +73,8 @@
       cc->Options<::mediapipe::TimedBoxListIdToLabelCalculatorOptions>();
 
   std::string string_path;
-  ASSIGN_OR_RETURN(string_path, PathToResourceAsFile(options.label_map_path()));
+  MP_ASSIGN_OR_RETURN(string_path,
+                      PathToResourceAsFile(options.label_map_path()));
   std::string label_map_string;
   MP_RETURN_IF_ERROR(file::GetContents(string_path, &label_map_string));
 
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/to_image_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/to_image_calculator.cc
index 22fedfd..067ede8 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/util/to_image_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/to_image_calculator.cc
@@ -86,7 +86,7 @@
 }
 
 absl::Status ToImageCalculator::Process(CalculatorContext* cc) {
-  ASSIGN_OR_RETURN(auto output, GetInputImage(cc));
+  MP_ASSIGN_OR_RETURN(auto output, GetInputImage(cc));
   kOut(cc).Send(output.At(cc->InputTimestamp()));
   return absl::OkStatus();
 }
diff --git a/third_party/mediapipe/src/mediapipe/calculators/util/top_k_scores_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/util/top_k_scores_calculator.cc
index b6bdf2f8..fe2d599 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/util/top_k_scores_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/util/top_k_scores_calculator.cc
@@ -227,7 +227,7 @@
 
 absl::Status TopKScoresCalculator::LoadLabelmap(std::string label_map_path) {
   std::string string_path;
-  ASSIGN_OR_RETURN(string_path, PathToResourceAsFile(label_map_path));
+  MP_ASSIGN_OR_RETURN(string_path, PathToResourceAsFile(label_map_path));
   std::string label_map_string;
   MP_RETURN_IF_ERROR(file::GetContents(string_path, &label_map_string));
 
diff --git a/third_party/mediapipe/src/mediapipe/calculators/video/box_detector_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/video/box_detector_calculator.cc
index 51f57b7..0c4be3d7 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/video/box_detector_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/video/box_detector_calculator.cc
@@ -207,7 +207,7 @@
 
   for (const auto& filename : options_.index_proto_filename()) {
     std::string string_path;
-    ASSIGN_OR_RETURN(string_path, PathToResourceAsFile(filename));
+    MP_ASSIGN_OR_RETURN(string_path, PathToResourceAsFile(filename));
     std::string index_string;
     MP_RETURN_IF_ERROR(file::GetContents(string_path, &index_string));
     BoxDetectorIndex predefined_index;
diff --git a/third_party/mediapipe/src/mediapipe/calculators/video/motion_analysis_calculator.cc b/third_party/mediapipe/src/mediapipe/calculators/video/motion_analysis_calculator.cc
index 601b8b0..a3451bf 100644
--- a/third_party/mediapipe/src/mediapipe/calculators/video/motion_analysis_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/calculators/video/motion_analysis_calculator.cc
@@ -478,7 +478,7 @@
 
     // Fill in timestamps we process.
     if (!selection_stream->Value().IsEmpty()) {
-      ASSIGN_OR_RETURN(
+      MP_ASSIGN_OR_RETURN(
           frame_selection_result,
           selection_stream->Value().ConsumeOrCopy<FrameSelectionResult>());
       use_frame = true;
diff --git a/third_party/mediapipe/src/mediapipe/framework/BUILD b/third_party/mediapipe/src/mediapipe/framework/BUILD
index ca8b005..e5e72cf 100644
--- a/third_party/mediapipe/src/mediapipe/framework/BUILD
+++ b/third_party/mediapipe/src/mediapipe/framework/BUILD
@@ -191,7 +191,10 @@
     name = "calculator_context",
     srcs = ["calculator_context.cc"],
     hdrs = ["calculator_context.h"],
-    visibility = [":mediapipe_internal"],
+    visibility = [
+        ":mediapipe_internal",
+        "//speech/videos/mediapipe/calculator:__pkg__",
+    ],
     deps = [
         ":calculator_state",
         ":counter",
@@ -233,6 +236,7 @@
     hdrs = ["calculator_contract.h"],
     visibility = [
         ":mediapipe_internal",
+        "//speech/videos/mediapipe/calculator:__pkg__",
     ],
     deps = [
         ":calculator_cc_proto",
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/BUILD b/third_party/mediapipe/src/mediapipe/framework/api2/stream/BUILD
index bca4d2b..127393d 100644
--- a/third_party/mediapipe/src/mediapipe/framework/api2/stream/BUILD
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/BUILD
@@ -238,6 +238,50 @@
 )
 
 cc_library(
+    name = "merge",
+    hdrs = ["merge.h"],
+    deps = [
+        "//mediapipe/calculators/core:merge_calculator",
+        "//mediapipe/framework/api2:builder",
+    ],
+)
+
+cc_test(
+    name = "merge_test",
+    srcs = ["merge_test.cc"],
+    deps = [
+        ":merge",
+        "//mediapipe/framework:calculator_framework",
+        "//mediapipe/framework/api2:builder",
+        "//mediapipe/framework/port:gtest",
+        "//mediapipe/framework/port:gtest_main",
+        "//mediapipe/framework/port:parse_text_proto",
+    ],
+)
+
+cc_library(
+    name = "presence",
+    hdrs = ["presence.h"],
+    deps = [
+        "//mediapipe/calculators/core:packet_presence_calculator",
+        "//mediapipe/framework/api2:builder",
+    ],
+)
+
+cc_test(
+    name = "presence_test",
+    srcs = ["presence_test.cc"],
+    deps = [
+        ":presence",
+        "//mediapipe/framework:calculator_cc_proto",
+        "//mediapipe/framework/api2:builder",
+        "//mediapipe/framework/port:gtest",
+        "//mediapipe/framework/port:gtest_main",
+        "//mediapipe/framework/port:parse_text_proto",
+    ],
+)
+
+cc_library(
     name = "rect_transformation",
     srcs = ["rect_transformation.cc"],
     hdrs = ["rect_transformation.h"],
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/concatenate.h b/third_party/mediapipe/src/mediapipe/framework/api2/stream/concatenate.h
new file mode 100644
index 0000000..573d436a
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/concatenate.h
@@ -0,0 +1,69 @@
+#ifndef MEDIAPIPE_FRAMEWORK_API2_STREAM_CONCATENATE_H_
+#define MEDIAPIPE_FRAMEWORK_API2_STREAM_CONCATENATE_H_
+
+#include <vector>
+
+#include "mediapipe/calculators/core/concatenate_vector_calculator.pb.h"
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/api2/port.h"
+#include "mediapipe/framework/formats/body_rig.pb.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+#include "mediapipe/framework/formats/tensor.h"
+
+namespace mediapipe::api2::builder {
+
+namespace internal_stream_concatenate {
+
+// Helper function that adds a node to a graph, that is capable of concatenating
+// a specific type (T).
+template <class T>
+GenericNode& AddConcatenateVectorNode(Graph& graph) {
+  if constexpr (std::is_same_v<T, mediapipe::LandmarkList>) {
+    return graph.AddNode("ConcatenateLandmarkListCalculator");
+  } else if constexpr (std::is_same_v<T, mediapipe::JointList>) {
+    return graph.AddNode("ConcatenateJointListCalculator");
+  } else if constexpr (std::is_same_v<T, std::vector<Tensor>>) {
+    return graph.AddNode("ConcatenateTensorVectorCalculator");
+  } else {
+    static_assert(dependent_false<T>::value,
+                  "Concatenate node is not available for the specified type.");
+  }
+}
+
+template <typename StreamsT,
+          typename PayloadT = typename StreamsT::value_type::PayloadT>
+Stream<PayloadT> Concatenate(StreamsT& streams,
+                             const bool only_emit_if_all_present,
+                             Graph& graph) {
+  auto& concatenator = AddConcatenateVectorNode<PayloadT>(graph);
+  for (int i = 0; i < streams.size(); ++i) {
+    streams[i].ConnectTo(concatenator.In("")[i]);
+  }
+
+  auto& concatenator_opts =
+      concatenator
+          .template GetOptions<mediapipe::ConcatenateVectorCalculatorOptions>();
+  concatenator_opts.set_only_emit_if_all_present(only_emit_if_all_present);
+
+  return concatenator.Out("").template Cast<PayloadT>();
+}
+
+}  // namespace internal_stream_concatenate
+
+template <typename StreamsT,
+          typename PayloadT = typename StreamsT::value_type::PayloadT>
+Stream<PayloadT> Concatenate(StreamsT& streams, Graph& graph) {
+  return internal_stream_concatenate::Concatenate(
+      streams, /*only_emit_if_all_present=*/false, graph);
+}
+
+template <typename StreamsT,
+          typename PayloadT = typename StreamsT::value_type::PayloadT>
+Stream<PayloadT> ConcatenateIfAllPresent(StreamsT& streams, Graph& graph) {
+  return internal_stream_concatenate::Concatenate(
+      streams, /*only_emit_if_all_present=*/true, graph);
+}
+
+}  // namespace mediapipe::api2::builder
+
+#endif  // MEDIAPIPE_FRAMEWORK_API2_STREAM_CONCATENATE_H_
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/detections_to_rects.cc b/third_party/mediapipe/src/mediapipe/framework/api2/stream/detections_to_rects.cc
new file mode 100644
index 0000000..f3daddae
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/detections_to_rects.cc
@@ -0,0 +1,100 @@
+#include "mediapipe/framework/api2/stream/detections_to_rects.h"
+
+#include <utility>
+#include <vector>
+
+#include "mediapipe/calculators/util/detections_to_rects_calculator.pb.h"
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/formats/detection.pb.h"
+#include "mediapipe/framework/formats/rect.pb.h"
+
+namespace mediapipe::api2::builder {
+
+namespace {
+
+using ::mediapipe::NormalizedRect;
+using ::mediapipe::api2::builder::Graph;
+
+void AddOptions(int start_keypoint_index, int end_keypoint_index,
+                float target_angle,
+                mediapipe::api2::builder::GenericNode& node) {
+  auto& options = node.GetOptions<DetectionsToRectsCalculatorOptions>();
+  options.set_rotation_vector_start_keypoint_index(start_keypoint_index);
+  options.set_rotation_vector_end_keypoint_index(end_keypoint_index);
+  options.set_rotation_vector_target_angle_degrees(target_angle);
+}
+
+}  // namespace
+
+Stream<NormalizedRect> ConvertAlignmentPointsDetectionToRect(
+    Stream<Detection> detection, Stream<std::pair<int, int>> image_size,
+    int start_keypoint_index, int end_keypoint_index, float target_angle,
+    Graph& graph) {
+  auto& align_node = graph.AddNode("AlignmentPointsRectsCalculator");
+  AddOptions(start_keypoint_index, end_keypoint_index, target_angle,
+             align_node);
+  detection.ConnectTo(align_node.In("DETECTION"));
+  image_size.ConnectTo(align_node.In("IMAGE_SIZE"));
+  return align_node.Out("NORM_RECT").Cast<NormalizedRect>();
+}
+
+Stream<NormalizedRect> ConvertAlignmentPointsDetectionsToRect(
+    Stream<std::vector<Detection>> detections,
+    Stream<std::pair<int, int>> image_size, int start_keypoint_index,
+    int end_keypoint_index, float target_angle, Graph& graph) {
+  auto& align_node = graph.AddNode("AlignmentPointsRectsCalculator");
+  AddOptions(start_keypoint_index, end_keypoint_index, target_angle,
+             align_node);
+  detections.ConnectTo(align_node.In("DETECTIONS"));
+  image_size.ConnectTo(align_node.In("IMAGE_SIZE"));
+  return align_node.Out("NORM_RECT").Cast<NormalizedRect>();
+}
+
+Stream<NormalizedRect> ConvertDetectionToRect(
+    Stream<Detection> detection, Stream<std::pair<int, int>> image_size,
+    int start_keypoint_index, int end_keypoint_index, float target_angle,
+    mediapipe::api2::builder::Graph& graph) {
+  auto& align_node = graph.AddNode("DetectionsToRectsCalculator");
+  AddOptions(start_keypoint_index, end_keypoint_index, target_angle,
+             align_node);
+  detection.ConnectTo(align_node.In("DETECTION"));
+  image_size.ConnectTo(align_node.In("IMAGE_SIZE"));
+  return align_node.Out("NORM_RECT").Cast<NormalizedRect>();
+}
+
+Stream<std::vector<NormalizedRect>> ConvertDetectionsToRects(
+    Stream<std::vector<Detection>> detections,
+    Stream<std::pair<int, int>> image_size, int start_keypoint_index,
+    int end_keypoint_index, float target_angle,
+    mediapipe::api2::builder::Graph& graph) {
+  // TODO: check if we can substitute DetectionsToRectsCalculator
+  // with AlignmentPointsRectsCalculator and use it instead. Ideally, merge or
+  // remove one of calculators.
+  auto& align_node = graph.AddNode("DetectionsToRectsCalculator");
+  AddOptions(start_keypoint_index, end_keypoint_index, target_angle,
+             align_node);
+  detections.ConnectTo(align_node.In("DETECTIONS"));
+  image_size.ConnectTo(align_node.In("IMAGE_SIZE"));
+  return align_node.Out("NORM_RECTS").Cast<std::vector<NormalizedRect>>();
+}
+
+Stream<NormalizedRect> ConvertDetectionsToRectUsingKeypoints(
+    Stream<std::vector<Detection>> detections,
+    Stream<std::pair<int, int>> image_size, int start_keypoint_index,
+    int end_keypoint_index, float target_angle,
+    mediapipe::api2::builder::Graph& graph) {
+  auto& node = graph.AddNode("DetectionsToRectsCalculator");
+
+  auto& options = node.GetOptions<DetectionsToRectsCalculatorOptions>();
+  options.set_rotation_vector_start_keypoint_index(start_keypoint_index);
+  options.set_rotation_vector_end_keypoint_index(end_keypoint_index);
+  options.set_rotation_vector_target_angle_degrees(target_angle);
+  options.set_conversion_mode(
+      DetectionsToRectsCalculatorOptions::USE_KEYPOINTS);
+
+  detections.ConnectTo(node.In("DETECTIONS"));
+  image_size.ConnectTo(node.In("IMAGE_SIZE"));
+  return node.Out("NORM_RECT").Cast<NormalizedRect>();
+}
+
+}  // namespace mediapipe::api2::builder
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/detections_to_rects.h b/third_party/mediapipe/src/mediapipe/framework/api2/stream/detections_to_rects.h
new file mode 100644
index 0000000..f1db9247
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/detections_to_rects.h
@@ -0,0 +1,55 @@
+#ifndef MEDIAPIPE_FRAMEWORK_API2_STREAM_DETECTIONS_TO_RECTS_H_
+#define MEDIAPIPE_FRAMEWORK_API2_STREAM_DETECTIONS_TO_RECTS_H_
+
+#include <utility>
+#include <vector>
+
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/formats/detection.pb.h"
+#include "mediapipe/framework/formats/rect.pb.h"
+
+namespace mediapipe::api2::builder {
+
+// Updates @graph to convert @detection into a `NormalizedRect` according to
+// passed parameters.
+Stream<mediapipe::NormalizedRect> ConvertAlignmentPointsDetectionToRect(
+    Stream<mediapipe::Detection> detection,
+    Stream<std::pair<int, int>> image_size, int start_keypoint_index,
+    int end_keypoint_index, float target_angle,
+    mediapipe::api2::builder::Graph& graph);
+
+// Updates @graph to convert first detection from @detections into a
+// `NormalizedRect` according to passed parameters.
+Stream<mediapipe::NormalizedRect> ConvertAlignmentPointsDetectionsToRect(
+    Stream<std::vector<mediapipe::Detection>> detections,
+    Stream<std::pair<int, int>> image_size, int start_keypoint_index,
+    int end_keypoint_index, float target_angle,
+    mediapipe::api2::builder::Graph& graph);
+
+// Updates @graph to convert @detection into a `NormalizedRect` according to
+// passed parameters.
+Stream<mediapipe::NormalizedRect> ConvertDetectionToRect(
+    Stream<mediapipe::Detection> detections,
+    Stream<std::pair<int, int>> image_size, int start_keypoint_index,
+    int end_keypoint_index, float target_angle,
+    mediapipe::api2::builder::Graph& graph);
+
+// Updates @graph to convert @detections into a stream holding vector of
+// `NormalizedRect` according to passed parameters.
+Stream<std::vector<mediapipe::NormalizedRect>> ConvertDetectionsToRects(
+    Stream<std::vector<mediapipe::Detection>> detections,
+    Stream<std::pair<int, int>> image_size, int start_keypoint_index,
+    int end_keypoint_index, float target_angle,
+    mediapipe::api2::builder::Graph& graph);
+
+// Updates @graph to convert @detections into a stream holding vector of
+// `NormalizedRect` according to passed parameters and using keypoints.
+Stream<mediapipe::NormalizedRect> ConvertDetectionsToRectUsingKeypoints(
+    Stream<std::vector<mediapipe::Detection>> detections,
+    Stream<std::pair<int, int>> image_size, int start_keypoint_index,
+    int end_keypoint_index, float target_angle,
+    mediapipe::api2::builder::Graph& graph);
+
+}  // namespace mediapipe::api2::builder
+
+#endif  // MEDIAPIPE_FRAMEWORK_API2_STREAM_DETECTIONS_TO_RECTS_H_
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/get_vector_item.h b/third_party/mediapipe/src/mediapipe/framework/api2/stream/get_vector_item.h
new file mode 100644
index 0000000..acddded
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/get_vector_item.h
@@ -0,0 +1,66 @@
+#ifndef MEDIAPIPE_FRAMEWORK_API2_STREAM_GET_VECTOR_ITEM_H_
+#define MEDIAPIPE_FRAMEWORK_API2_STREAM_GET_VECTOR_ITEM_H_
+
+#include <type_traits>
+#include <vector>
+
+#include "mediapipe/calculators/core/get_vector_item_calculator.h"
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/api2/port.h"
+#include "mediapipe/framework/formats/classification.pb.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+#include "mediapipe/framework/formats/rect.pb.h"
+#include "tensorflow/lite/c/common.h"
+
+namespace mediapipe::api2::builder {
+
+namespace internal_get_vector_item {
+
+// Helper function that adds a node to a graph, that is capable of getting item
+// from a vector of type (T).
+template <class T>
+mediapipe::api2::builder::GenericNode& AddGetVectorItemNode(
+    mediapipe::api2::builder::Graph& graph) {
+  if constexpr (std::is_same_v<T, mediapipe::NormalizedLandmarkList>) {
+    return graph.AddNode("GetNormalizedLandmarkListVectorItemCalculator");
+  } else if constexpr (std::is_same_v<T, mediapipe::LandmarkList>) {
+    return graph.AddNode("GetLandmarkListVectorItemCalculator");
+  } else if constexpr (std::is_same_v<T, mediapipe::ClassificationList>) {
+    return graph.AddNode("GetClassificationListVectorItemCalculator");
+  } else if constexpr (std::is_same_v<T, mediapipe::NormalizedRect>) {
+    return graph.AddNode("GetNormalizedRectVectorItemCalculator");
+  } else if constexpr (std::is_same_v<T, mediapipe::Rect>) {
+    return graph.AddNode("GetRectVectorItemCalculator");
+  } else {
+    static_assert(
+        dependent_false<T>::value,
+        "Get vector item node is not available for the specified type.");
+  }
+}
+
+}  // namespace internal_get_vector_item
+
+// Gets item from the vector.
+//
+// Example:
+// ```
+//
+//   Graph graph;
+//
+//   Stream<std::vector<LandmarkList>> multi_landmarks = ...;
+//   Stream<LandmarkList> landmarks =
+//       GetItem(multi_landmarks, 0, graph);
+//
+// ```
+template <typename T>
+Stream<T> GetItem(Stream<std::vector<T>> items, Stream<int> idx,
+                  mediapipe::api2::builder::Graph& graph) {
+  auto& getter = internal_get_vector_item::AddGetVectorItemNode<T>(graph);
+  items.ConnectTo(getter.In("VECTOR"));
+  idx.ConnectTo(getter.In("INDEX"));
+  return getter.Out("ITEM").template Cast<T>();
+}
+
+}  // namespace mediapipe::api2::builder
+
+#endif  // MEDIAPIPE_FRAMEWORK_API2_STREAM_GET_VECTOR_ITEM_H_
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_projection.cc b/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_projection.cc
new file mode 100644
index 0000000..1735dc1d
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_projection.cc
@@ -0,0 +1,20 @@
+#include "mediapipe/framework/api2/stream/landmarks_projection.h"
+
+#include <array>
+
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+
+namespace mediapipe::api2::builder {
+
+Stream<mediapipe::NormalizedLandmarkList> ProjectLandmarks(
+    Stream<mediapipe::NormalizedLandmarkList> landmarks,
+    Stream<std::array<float, 16>> projection_matrix, Graph& graph) {
+  auto& projector = graph.AddNode("LandmarkProjectionCalculator");
+  landmarks.ConnectTo(projector.In("NORM_LANDMARKS"));
+  projection_matrix.ConnectTo(projector.In("PROJECTION_MATRIX"));
+  return projector.Out("NORM_LANDMARKS")
+      .Cast<mediapipe::NormalizedLandmarkList>();
+}
+
+}  // namespace mediapipe::api2::builder
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_projection.h b/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_projection.h
new file mode 100644
index 0000000..3a9508a
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_projection.h
@@ -0,0 +1,23 @@
+#ifndef MEDIAPIPE_FRAMEWORK_API2_STREAM_LANDMARKS_PROJECTION_H_
+#define MEDIAPIPE_FRAMEWORK_API2_STREAM_LANDMARKS_PROJECTION_H_
+
+#include <array>
+
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+
+namespace mediapipe::api2::builder {
+
+// Updates @graph to project predicted @landmarks back to the original @image
+// based on @projection_matrix
+//
+// @landmarks - landmarks (NormalizedLandmarkList) stream, output from the model
+// @projection_matrix - matrix that stores the preprocessing information
+// @graph - mediapipe graph to update.
+Stream<mediapipe::NormalizedLandmarkList> ProjectLandmarks(
+    Stream<mediapipe::NormalizedLandmarkList> landmarks,
+    Stream<std::array<float, 16>> projection_matrix, Graph& graph);
+
+}  // namespace mediapipe::api2::builder
+
+#endif  // MEDIAPIPE_FRAMEWORK_API2_STREAM_LANDMARKS_PROJECTION_H_
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_to_detection.cc b/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_to_detection.cc
new file mode 100644
index 0000000..99e576ba
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_to_detection.cc
@@ -0,0 +1,17 @@
+#include "mediapipe/framework/api2/stream/landmarks_to_detection.h"
+
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/formats/detection.pb.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+
+namespace mediapipe::api2::builder {
+
+Stream<mediapipe::Detection> ConvertLandmarksToDetection(
+    Stream<mediapipe::NormalizedLandmarkList> landmarks, Graph& graph) {
+  auto& landmarks_to_detection =
+      graph.AddNode("LandmarksToDetectionCalculator");
+  landmarks.ConnectTo(landmarks_to_detection.In("NORM_LANDMARKS"));
+  return landmarks_to_detection.Out("DETECTION").Cast<mediapipe::Detection>();
+}
+
+}  // namespace mediapipe::api2::builder
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_to_detection.h b/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_to_detection.h
new file mode 100644
index 0000000..0f0004b
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_to_detection.h
@@ -0,0 +1,16 @@
+#ifndef MEDIAPIPE_FRAMEWORK_API2_STREAM_LANDMARKS_TO_DETECTION_H_
+#define MEDIAPIPE_FRAMEWORK_API2_STREAM_LANDMARKS_TO_DETECTION_H_
+
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/formats/detection.pb.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+
+namespace mediapipe::api2::builder {
+
+// Updates @graph to convert @landmarks to a detection.
+Stream<mediapipe::Detection> ConvertLandmarksToDetection(
+    Stream<mediapipe::NormalizedLandmarkList> landmarks, Graph& graph);
+
+}  // namespace mediapipe::api2::builder
+
+#endif  // MEDIAPIPE_FRAMEWORK_API2_STREAM_LANDMARKS_TO_DETECTION_H_
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_to_tensor.cc b/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_to_tensor.cc
new file mode 100644
index 0000000..85ce7a0
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_to_tensor.cc
@@ -0,0 +1,64 @@
+#include "mediapipe/framework/api2/stream/landmarks_to_tensor.h"
+
+#include <optional>
+#include <utility>
+#include <vector>
+
+#include "mediapipe/calculators/tensor/landmarks_to_tensor_calculator.h"
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/api2/port.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+#include "mediapipe/framework/formats/tensor.h"
+
+namespace mediapipe::api2::builder {
+
+namespace {
+
+using ::mediapipe::api2::LandmarksToTensorCalculator;
+
+template <typename LandmarkListType>
+Stream<std::vector<Tensor>> InternalConvertToTensor(
+    Stream<LandmarkListType> landmarks,
+    std::optional<Stream<std::pair<int, int>>> image_size,
+    absl::Span<const LandmarksToTensorCalculatorOptions::Attribute> attributes,
+    const bool flatten, Graph& graph) {
+  auto& to_tensor = graph.AddNode<LandmarksToTensorCalculator>();
+  auto& to_tensor_options =
+      to_tensor.GetOptions<LandmarksToTensorCalculatorOptions>();
+  for (const auto& attribute : attributes) {
+    to_tensor_options.add_attributes(attribute);
+  }
+  to_tensor_options.set_flatten(flatten);
+  if constexpr (std::is_same_v<LandmarkListType, LandmarkList>) {
+    landmarks.ConnectTo(
+        to_tensor[LandmarksToTensorCalculator::kInLandmarkList]);
+  } else {
+    landmarks.ConnectTo(
+        to_tensor[LandmarksToTensorCalculator::kInNormLandmarkList]);
+  }
+  if (image_size.has_value()) {
+    image_size->ConnectTo(to_tensor[LandmarksToTensorCalculator::kImageSize]);
+  }
+  return to_tensor[LandmarksToTensorCalculator::kOutTensors];
+}
+
+}  // namespace
+
+Stream<std::vector<Tensor>> ConvertLandmarksToTensor(
+    Stream<LandmarkList> landmarks,
+    absl::Span<const LandmarksToTensorCalculatorOptions::Attribute> attributes,
+    const bool flatten, Graph& graph) {
+  return InternalConvertToTensor(landmarks, /*image_size=*/std::nullopt,
+                                 attributes, flatten, graph);
+}
+
+Stream<std::vector<Tensor>> ConvertNormalizedLandmarksToTensor(
+    Stream<NormalizedLandmarkList> normalized_landmarks,
+    Stream<std::pair<int, int>> image_size,
+    absl::Span<const LandmarksToTensorCalculatorOptions::Attribute> attributes,
+    const bool flatten, Graph& graph) {
+  return InternalConvertToTensor(normalized_landmarks, image_size, attributes,
+                                 flatten, graph);
+}
+
+}  // namespace mediapipe::api2::builder
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_to_tensor.h b/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_to_tensor.h
new file mode 100644
index 0000000..3766c53d
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/landmarks_to_tensor.h
@@ -0,0 +1,37 @@
+#ifndef MEDIAPIPE_FRAMEWORK_API2_STREAM_LANDMARKS_TO_TENSOR_H_
+#define MEDIAPIPE_FRAMEWORK_API2_STREAM_LANDMARKS_TO_TENSOR_H_
+
+#include <utility>
+#include <vector>
+
+#include "absl/types/span.h"
+#include "mediapipe/calculators/tensor/landmarks_to_tensor_calculator.pb.h"
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+#include "mediapipe/framework/formats/tensor.h"
+
+namespace mediapipe::api2::builder {
+
+// Updates @graph to convert @landmarks to a Tensor. Values and their order are
+// defined by @attributes. If @flatten is true resulting tensor will be 1D,
+// otherwise tensor will be 2D with (n_landmarks, n_attributes) shape.
+Stream<std::vector<Tensor>> ConvertLandmarksToTensor(
+    Stream<mediapipe::LandmarkList> landmarks,
+    absl::Span<const mediapipe::LandmarksToTensorCalculatorOptions::Attribute>
+        attributes,
+    bool flatten, Graph& graph);
+
+// Updates @graph to convert @normalized_landmarks to a Tensor. Values and their
+// order are defined by @attributes. X, Y and Z values are scaled using
+// @image_size. If @flatten is true resulting tensor will be 1D, otherwise
+// tensor will be 2D with (n_landmarks, n_attributes) shape.
+Stream<std::vector<Tensor>> ConvertNormalizedLandmarksToTensor(
+    Stream<mediapipe::NormalizedLandmarkList> normalized_landmarks,
+    Stream<std::pair<int, int>> image_size,
+    absl::Span<const mediapipe::LandmarksToTensorCalculatorOptions::Attribute>
+        attributes,
+    bool flatten, Graph& graph);
+
+}  // namespace mediapipe::api2::builder
+
+#endif  // MEDIAPIPE_FRAMEWORK_API2_STREAM_LANDMARKS_TO_TENSOR_H_
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/merge.h b/third_party/mediapipe/src/mediapipe/framework/api2/stream/merge.h
new file mode 100644
index 0000000..f3e54f9
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/merge.h
@@ -0,0 +1,20 @@
+#ifndef MEDIAPIPE_FRAMEWORK_API2_STREAM_MERGE_H_
+#define MEDIAPIPE_FRAMEWORK_API2_STREAM_MERGE_H_
+
+#include "mediapipe/framework/api2/builder.h"
+
+namespace mediapipe::api2::builder {
+
+// Updates @graph to choose @a stream if it's available (not empty stream at
+// specific timestamp) or @b stream otherwise.
+template <typename T>
+Stream<T> Merge(Stream<T> a, Stream<T> b, Graph& graph) {
+  auto& merge_node = graph.AddNode("MergeCalculator");
+  a.ConnectTo(merge_node.In("")[0]);
+  b.ConnectTo(merge_node.In("")[1]);
+  return merge_node.Out("").template Cast<T>();
+}
+
+}  // namespace mediapipe::api2::builder
+
+#endif  // MEDIAPIPE_FRAMEWORK_API2_STREAM_MERGE_H_
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/presence.h b/third_party/mediapipe/src/mediapipe/framework/api2/stream/presence.h
new file mode 100644
index 0000000..9b6d7fa
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/presence.h
@@ -0,0 +1,19 @@
+#ifndef MEDIAPIPE_FRAMEWORK_API2_STREAM_PRESENCE_H_
+#define MEDIAPIPE_FRAMEWORK_API2_STREAM_PRESENCE_H_
+
+#include "mediapipe/framework/api2/builder.h"
+
+namespace mediapipe::api2::builder {
+
+// Updates @graph to emit a stream containing `bool` packets, where each packet
+// indicates whether @stream has a packet with corresponding timestamp or not.
+template <typename T>
+Stream<bool> IsPresent(Stream<T> stream, Graph& graph) {
+  auto& presence_node = graph.AddNode("PacketPresenceCalculator");
+  stream.ConnectTo(presence_node.In("PACKET"));
+  return presence_node.Out("PRESENCE").Cast<bool>();
+}
+
+}  // namespace mediapipe::api2::builder
+
+#endif  // MEDIAPIPE_FRAMEWORK_API2_STREAM_PRESENCE_H_
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/segmentation_smoothing.cc b/third_party/mediapipe/src/mediapipe/framework/api2/stream/segmentation_smoothing.cc
new file mode 100644
index 0000000..350316ef
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/segmentation_smoothing.cc
@@ -0,0 +1,24 @@
+#include "mediapipe/framework/api2/stream/segmentation_smoothing.h"
+
+#include "mediapipe/calculators/image/segmentation_smoothing_calculator.pb.h"
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/formats/image.h"
+
+namespace mediapipe::api2::builder {
+
+Stream<Image> SmoothSegmentationMask(Stream<Image> mask,
+                                     Stream<Image> previous_mask,
+                                     float combine_with_previous_ratio,
+                                     Graph& graph) {
+  auto& smoothing_node = graph.AddNode("SegmentationSmoothingCalculator");
+  auto& smoothing_node_opts =
+      smoothing_node
+          .GetOptions<mediapipe::SegmentationSmoothingCalculatorOptions>();
+  smoothing_node_opts.set_combine_with_previous_ratio(
+      combine_with_previous_ratio);
+  mask.ConnectTo(smoothing_node.In("MASK"));
+  previous_mask.ConnectTo(smoothing_node.In("MASK_PREVIOUS"));
+  return smoothing_node.Out("MASK_SMOOTHED").Cast<Image>();
+}
+
+}  // namespace mediapipe::api2::builder
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/segmentation_smoothing.h b/third_party/mediapipe/src/mediapipe/framework/api2/stream/segmentation_smoothing.h
new file mode 100644
index 0000000..174d80f
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/segmentation_smoothing.h
@@ -0,0 +1,19 @@
+#ifndef MEDIAPIPE_FRAMEWORK_API2_STREAM_SEGMENTATION_SMOOTHING_H_
+#define MEDIAPIPE_FRAMEWORK_API2_STREAM_SEGMENTATION_SMOOTHING_H_
+
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/formats/image.h"
+
+namespace mediapipe::api2::builder {
+
+// Updates @graph to smooth @mask by mixing @mask and @previous_mask based on an
+// uncertantity probability estimate calculated per each @mask pixel multiplied
+// by @combine_with_previous_ratio.
+Stream<Image> SmoothSegmentationMask(Stream<Image> mask,
+                                     Stream<Image> previous_mask,
+                                     float combine_with_previous_ratio,
+                                     Graph& graph);
+
+}  // namespace mediapipe::api2::builder
+
+#endif  // MEDIAPIPE_FRAMEWORK_API2_STREAM_SEGMENTATION_SMOOTHING_H_
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/smoothing.cc b/third_party/mediapipe/src/mediapipe/framework/api2/stream/smoothing.cc
new file mode 100644
index 0000000..5ef0425
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/smoothing.cc
@@ -0,0 +1,131 @@
+#include "mediapipe/framework/api2/stream/smoothing.h"
+
+#include <optional>
+#include <utility>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "mediapipe/calculators/util/landmarks_smoothing_calculator.pb.h"
+#include "mediapipe/calculators/util/visibility_smoothing_calculator.pb.h"
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+
+namespace mediapipe::api2::builder {
+
+namespace {
+
+void SetFilterConfig(const OneEuroFilterConfig& config,
+                     bool disable_value_scaling, GenericNode& node) {
+  auto& smoothing_node_opts =
+      node.GetOptions<LandmarksSmoothingCalculatorOptions>();
+  auto& one_euro_filter = *smoothing_node_opts.mutable_one_euro_filter();
+  one_euro_filter.set_min_cutoff(config.min_cutoff);
+  one_euro_filter.set_derivate_cutoff(config.derivate_cutoff);
+  one_euro_filter.set_beta(config.beta);
+  one_euro_filter.set_disable_value_scaling(disable_value_scaling);
+}
+
+void SetFilterConfig(const LandmarksSmoothingCalculatorOptions& config,
+                     GenericNode& node) {
+  auto& smoothing_node_opts =
+      node.GetOptions<LandmarksSmoothingCalculatorOptions>();
+  smoothing_node_opts = config;
+}
+
+GenericNode& AddVisibilitySmoothingNode(float low_pass_filter_alpha,
+                                        Graph& graph) {
+  auto& smoothing_node = graph.AddNode("VisibilitySmoothingCalculator");
+  auto& smoothing_node_opts =
+      smoothing_node.GetOptions<VisibilitySmoothingCalculatorOptions>();
+  smoothing_node_opts.mutable_low_pass_filter()->set_alpha(
+      low_pass_filter_alpha);
+  return smoothing_node;
+}
+
+}  // namespace
+
+Stream<NormalizedLandmarkList> SmoothLandmarks(
+    Stream<NormalizedLandmarkList> landmarks,
+    Stream<std::pair<int, int>> image_size,
+    std::optional<Stream<NormalizedRect>> scale_roi,
+    const OneEuroFilterConfig& config, Graph& graph) {
+  auto& smoothing_node = graph.AddNode("LandmarksSmoothingCalculator");
+  SetFilterConfig(config, /*disable_value_scaling=*/false, smoothing_node);
+
+  landmarks.ConnectTo(smoothing_node.In("NORM_LANDMARKS"));
+  image_size.ConnectTo(smoothing_node.In("IMAGE_SIZE"));
+  if (scale_roi) {
+    scale_roi->ConnectTo(smoothing_node.In("OBJECT_SCALE_ROI"));
+  }
+  return smoothing_node.Out("NORM_FILTERED_LANDMARKS")
+      .Cast<NormalizedLandmarkList>();
+}
+
+Stream<LandmarkList> SmoothLandmarks(
+    Stream<LandmarkList> landmarks,
+    std::optional<Stream<NormalizedRect>> scale_roi,
+    const OneEuroFilterConfig& config, Graph& graph) {
+  auto& smoothing_node = graph.AddNode("LandmarksSmoothingCalculator");
+  SetFilterConfig(config, /*disable_value_scaling=*/true, smoothing_node);
+
+  landmarks.ConnectTo(smoothing_node.In("LANDMARKS"));
+  if (scale_roi) {
+    scale_roi->ConnectTo(smoothing_node.In("OBJECT_SCALE_ROI"));
+  }
+  return smoothing_node.Out("FILTERED_LANDMARKS").Cast<LandmarkList>();
+}
+
+Stream<std::vector<NormalizedLandmarkList>> SmoothMultiLandmarks(
+    Stream<std::vector<NormalizedLandmarkList>> landmarks,
+    Stream<std::vector<int64_t>> tracking_ids,
+    Stream<std::pair<int, int>> image_size,
+    std::optional<Stream<std::vector<NormalizedRect>>> scale_roi,
+    const LandmarksSmoothingCalculatorOptions& config, Graph& graph) {
+  auto& smoothing_node = graph.AddNode("MultiLandmarksSmoothingCalculator");
+  SetFilterConfig(config, smoothing_node);
+
+  landmarks.ConnectTo(smoothing_node.In("NORM_LANDMARKS"));
+  tracking_ids.ConnectTo(smoothing_node.In("TRACKING_IDS"));
+  image_size.ConnectTo(smoothing_node.In("IMAGE_SIZE"));
+  if (scale_roi) {
+    scale_roi->ConnectTo(smoothing_node.In("OBJECT_SCALE_ROI"));
+  }
+  return smoothing_node.Out("NORM_FILTERED_LANDMARKS")
+      .Cast<std::vector<NormalizedLandmarkList>>();
+}
+
+Stream<std::vector<LandmarkList>> SmoothMultiWorldLandmarks(
+    Stream<std::vector<LandmarkList>> landmarks,
+    Stream<std::vector<int64_t>> tracking_ids,
+    std::optional<Stream<std::vector<Rect>>> scale_roi,
+    const LandmarksSmoothingCalculatorOptions& config, Graph& graph) {
+  auto& smoothing_node =
+      graph.AddNode("MultiWorldLandmarksSmoothingCalculator");
+  SetFilterConfig(config, smoothing_node);
+
+  landmarks.ConnectTo(smoothing_node.In("LANDMARKS"));
+  tracking_ids.ConnectTo(smoothing_node.In("TRACKING_IDS"));
+  if (scale_roi) {
+    scale_roi->ConnectTo(smoothing_node.In("OBJECT_SCALE_ROI"));
+  }
+  return smoothing_node.Out("FILTERED_LANDMARKS")
+      .Cast<std::vector<LandmarkList>>();
+}
+
+Stream<NormalizedLandmarkList> SmoothLandmarksVisibility(
+    Stream<NormalizedLandmarkList> landmarks, float low_pass_filter_alpha,
+    Graph& graph) {
+  auto& node = AddVisibilitySmoothingNode(low_pass_filter_alpha, graph);
+  landmarks.ConnectTo(node.In("NORM_LANDMARKS"));
+  return node.Out("NORM_FILTERED_LANDMARKS").Cast<NormalizedLandmarkList>();
+}
+
+Stream<LandmarkList> SmoothLandmarksVisibility(Stream<LandmarkList> landmarks,
+                                               float low_pass_filter_alpha,
+                                               Graph& graph) {
+  auto& node = AddVisibilitySmoothingNode(low_pass_filter_alpha, graph);
+  landmarks.ConnectTo(node.In("LANDMARKS"));
+  return node.Out("FILTERED_LANDMARKS").Cast<LandmarkList>();
+}
+
+}  // namespace mediapipe::api2::builder
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/smoothing.h b/third_party/mediapipe/src/mediapipe/framework/api2/stream/smoothing.h
new file mode 100644
index 0000000..4c39514
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/smoothing.h
@@ -0,0 +1,119 @@
+#ifndef MEDIAPIPE_FRAMEWORK_API2_STREAM_SMOOTHING_H_
+#define MEDIAPIPE_FRAMEWORK_API2_STREAM_SMOOTHING_H_
+
+#include <cstdint>
+#include <optional>
+#include <utility>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "mediapipe/calculators/util/landmarks_smoothing_calculator.pb.h"
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+#include "mediapipe/framework/formats/rect.pb.h"
+
+namespace mediapipe::api2::builder {
+
+struct OneEuroFilterConfig {
+  float min_cutoff;
+  float beta;
+  float derivate_cutoff;
+};
+
+// Updates graph to smooth normalized landmarks and returns resulting stream.
+//
+// @landmarks - normalized landmarks.
+// @image_size - size of image where landmarks were detected.
+// @scale_roi - can be used to specify object scale.
+// @config - filter config.
+// @graph - graph to update.
+//
+// Returns: smoothed/filtered normalized landmarks.
+//
+// NOTE: one-euro filter is exposed only. Other filter options can be exposed
+//   on demand.
+Stream<mediapipe::NormalizedLandmarkList> SmoothLandmarks(
+    Stream<mediapipe::NormalizedLandmarkList> landmarks,
+    Stream<std::pair<int, int>> image_size,
+    std::optional<Stream<NormalizedRect>> scale_roi,
+    const OneEuroFilterConfig& config, Graph& graph);
+
+// Updates graph to smooth absolute landmarks and returns resulting stream.
+//
+// @landmarks - absolute landmarks.
+// @scale_roi - can be used to specify object scale.
+// @config - filter config.
+// @graph - graph to update.
+//
+// Returns: smoothed/filtered absolute landmarks.
+//
+// NOTE: one-euro filter is exposed only. Other filter options can be exposed
+//   on demand.
+Stream<mediapipe::LandmarkList> SmoothLandmarks(
+    Stream<mediapipe::LandmarkList> landmarks,
+    std::optional<Stream<NormalizedRect>> scale_roi,
+    const OneEuroFilterConfig& config, Graph& graph);
+
+// Updates graph to smooth normalized landmarks and returns resulting stream.
+//
+// @landmarks - normalized landmarks vector.
+// @tracking_ids - tracking IDs associated with landmarks
+// @image_size - size of image where landmarks were detected.
+// @scale_roi - can be used to specify object scales.
+// @config - filter config.
+// @graph - graph to update.
+//
+// Returns: smoothed/filtered normalized landmarks.
+//
+// NOTE: one-euro filter is exposed only. Other filter options can be exposed
+//   on demand.
+Stream<std::vector<mediapipe::NormalizedLandmarkList>> SmoothMultiLandmarks(
+    Stream<std::vector<mediapipe::NormalizedLandmarkList>> landmarks,
+    Stream<std::vector<int64_t>> tracking_ids,
+    Stream<std::pair<int, int>> image_size,
+    std::optional<Stream<std::vector<NormalizedRect>>> scale_roi,
+    const mediapipe::LandmarksSmoothingCalculatorOptions& config, Graph& graph);
+
+// Updates graph to smooth absolute landmarks and returns resulting stream.
+//
+// @landmarks - absolute landmarks vector.
+// @tracking_ids - tracking IDs associated with landmarks
+// @scale_roi - can be used to specify object scales.
+// @config - filter config.
+// @graph - graph to update.
+//
+// Returns: smoothed/filtered absolute landmarks.
+//
+// NOTE: one-euro filter is exposed only. Other filter options can be exposed
+//   on demand.
+Stream<std::vector<mediapipe::LandmarkList>> SmoothMultiWorldLandmarks(
+    Stream<std::vector<mediapipe::LandmarkList>> landmarks,
+    Stream<std::vector<int64_t>> tracking_ids,
+    std::optional<Stream<std::vector<mediapipe::Rect>>> scale_roi,
+    const mediapipe::LandmarksSmoothingCalculatorOptions& config, Graph& graph);
+
+// Updates graph to smooth visibility of landmarks.
+//
+// @landmarks - normalized landmarks.
+// @low_pass_filter_alpha - low pass filter alpha to use for smoothing.
+// @graph - graph to update.
+//
+// Returns: normalized landmarks containing smoothed visibility.
+Stream<mediapipe::NormalizedLandmarkList> SmoothLandmarksVisibility(
+    Stream<mediapipe::NormalizedLandmarkList> landmarks,
+    float low_pass_filter_alpha, Graph& graph);
+
+// Updates graph to smooth visibility of landmarks.
+//
+// @landmarks - absolute landmarks.
+// @low_pass_filter_alpha - low pass filter alpha to use for smoothing.
+// @graph - graph to update.
+//
+// Returns: absolute landmarks containing smoothed visibility.
+Stream<mediapipe::LandmarkList> SmoothLandmarksVisibility(
+    Stream<mediapipe::LandmarkList> landmarks, float low_pass_filter_alpha,
+    mediapipe::api2::builder::Graph& graph);
+
+}  // namespace mediapipe::api2::builder
+
+#endif  // MEDIAPIPE_FRAMEWORK_API2_STREAM_SMOOTHING_H_
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/split.h b/third_party/mediapipe/src/mediapipe/framework/api2/stream/split.h
new file mode 100644
index 0000000..6e72333
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/split.h
@@ -0,0 +1,335 @@
+#ifndef MEDIAPIPE_FRAMEWORK_API2_STREAM_SPLIT_H_
+#define MEDIAPIPE_FRAMEWORK_API2_STREAM_SPLIT_H_
+
+#include <initializer_list>
+#include <iterator>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "mediapipe/calculators/core/split_vector_calculator.pb.h"
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/api2/port.h"
+#include "mediapipe/framework/formats/body_rig.pb.h"
+#include "mediapipe/framework/formats/classification.pb.h"
+#include "mediapipe/framework/formats/detection.pb.h"
+#include "mediapipe/framework/formats/landmark.pb.h"
+#include "mediapipe/framework/formats/matrix.h"
+#include "mediapipe/framework/formats/rect.pb.h"
+#include "mediapipe/framework/formats/tensor.h"
+#include "tensorflow/lite/c/common.h"
+
+namespace mediapipe::api2::builder {
+
+namespace stream_split_internal {
+
+// Helper function that adds a node to a graph, that is capable of splitting a
+// specific type (T).
+template <class T>
+mediapipe::api2::builder::GenericNode& AddSplitVectorNode(
+    mediapipe::api2::builder::Graph& graph) {
+  if constexpr (std::is_same_v<T, std::vector<TfLiteTensor>>) {
+    return graph.AddNode("SplitTfLiteTensorVectorCalculator");
+  } else if constexpr (std::is_same_v<T, std::vector<mediapipe::Tensor>>) {
+    return graph.AddNode("SplitTensorVectorCalculator");
+  } else if constexpr (std::is_same_v<T, std::vector<uint64_t>>) {
+    return graph.AddNode("SplitUint64tVectorCalculator");
+  } else if constexpr (std::is_same_v<
+                           T, std::vector<mediapipe::NormalizedLandmark>>) {
+    return graph.AddNode("SplitLandmarkVectorCalculator");
+  } else if constexpr (std::is_same_v<
+                           T, std::vector<mediapipe::NormalizedLandmarkList>>) {
+    return graph.AddNode("SplitNormalizedLandmarkListVectorCalculator");
+  } else if constexpr (std::is_same_v<T,
+                                      std::vector<mediapipe::NormalizedRect>>) {
+    return graph.AddNode("SplitNormalizedRectVectorCalculator");
+  } else if constexpr (std::is_same_v<T, std::vector<Matrix>>) {
+    return graph.AddNode("SplitMatrixVectorCalculator");
+  } else if constexpr (std::is_same_v<T, std::vector<mediapipe::Detection>>) {
+    return graph.AddNode("SplitDetectionVectorCalculator");
+  } else if constexpr (std::is_same_v<
+                           T, std::vector<mediapipe::ClassificationList>>) {
+    return graph.AddNode("SplitClassificationListVectorCalculator");
+  } else if constexpr (std::is_same_v<T, mediapipe::NormalizedLandmarkList>) {
+    return graph.AddNode("SplitNormalizedLandmarkListCalculator");
+  } else if constexpr (std::is_same_v<T, mediapipe::LandmarkList>) {
+    return graph.AddNode("SplitLandmarkListCalculator");
+  } else if constexpr (std::is_same_v<T, mediapipe::JointList>) {
+    return graph.AddNode("SplitJointListCalculator");
+  } else {
+    static_assert(dependent_false<T>::value,
+                  "Split node is not available for the specified type.");
+  }
+}
+
+template <typename T, bool kIteratorContainsRanges = false>
+struct split_result_item {
+  using type = typename T::value_type;
+};
+template <>
+struct split_result_item<mediapipe::NormalizedLandmarkList,
+                         /*kIteratorContainsRanges=*/false> {
+  using type = mediapipe::NormalizedLandmark;
+};
+template <>
+struct split_result_item<mediapipe::LandmarkList,
+                         /*kIteratorContainsRanges=*/false> {
+  using type = mediapipe::Landmark;
+};
+
+template <typename T>
+struct split_result_item<T, /*kIteratorContainsRanges=*/true> {
+  using type = std::vector<typename T::value_type>;
+};
+template <>
+struct split_result_item<mediapipe::NormalizedLandmarkList,
+                         /*kIteratorContainsRanges=*/true> {
+  using type = mediapipe::NormalizedLandmarkList;
+};
+template <>
+struct split_result_item<mediapipe::LandmarkList,
+                         /*kIteratorContainsRanges=*/true> {
+  using type = mediapipe::LandmarkList;
+};
+
+template <typename CollectionT, typename I>
+auto Split(Stream<CollectionT> items, I begin, I end,
+           mediapipe::api2::builder::Graph& graph) {
+  auto& splitter = AddSplitVectorNode<CollectionT>(graph);
+  items.ConnectTo(splitter.In(""));
+
+  constexpr bool kIteratorContainsRanges =
+      std::is_same_v<typename std::iterator_traits<I>::value_type,
+                     std::pair<int, int>>;
+  using R =
+      typename split_result_item<CollectionT, kIteratorContainsRanges>::type;
+  auto& splitter_opts =
+      splitter.template GetOptions<mediapipe::SplitVectorCalculatorOptions>();
+  if constexpr (!kIteratorContainsRanges) {
+    splitter_opts.set_element_only(true);
+  }
+  std::vector<Stream<R>> result;
+  int output = 0;
+  for (auto it = begin; it != end; ++it) {
+    auto* range = splitter_opts.add_ranges();
+    if constexpr (kIteratorContainsRanges) {
+      range->set_begin(it->first);
+      range->set_end(it->second);
+    } else {
+      range->set_begin(*it);
+      range->set_end(*it + 1);
+    }
+    result.push_back(splitter.Out("")[output++].template Cast<R>());
+  }
+  return result;
+}
+
+template <typename CollectionT, typename I>
+Stream<CollectionT> SplitAndCombine(Stream<CollectionT> items, I begin, I end,
+                                    mediapipe::api2::builder::Graph& graph) {
+  auto& splitter = AddSplitVectorNode<CollectionT>(graph);
+  items.ConnectTo(splitter.In(""));
+
+  constexpr bool kIteratorContainsRanges =
+      std::is_same_v<typename std::iterator_traits<I>::value_type,
+                     std::pair<int, int>>;
+
+  auto& splitter_opts =
+      splitter.template GetOptions<mediapipe::SplitVectorCalculatorOptions>();
+  splitter_opts.set_combine_outputs(true);
+
+  for (auto it = begin; it != end; ++it) {
+    auto* range = splitter_opts.add_ranges();
+    if constexpr (kIteratorContainsRanges) {
+      range->set_begin(it->first);
+      range->set_end(it->second);
+    } else {
+      range->set_begin(*it);
+      range->set_end(*it + 1);
+    }
+  }
+  return splitter.Out("").template Cast<CollectionT>();
+}
+
+}  // namespace stream_split_internal
+
+// Splits stream containing a collection based on passed @indices into a vector
+// of streams where each steam repesents individual item of a collection.
+//
+// Example:
+// ```
+//
+//   Graph graph;
+//   std::vector<int> indices = {0, 1, 2, 3};
+//
+//   Stream<std::vector<Detection>> detections = ...;
+//   std::vector<Stream<Detection>> detections_split =
+//       Split(detections, indices, graph);
+//
+//   Stream<NormalizedLandmarkList> landmarks = ...;
+//   std::vector<Stream<NormalizedLandmark>> landmarks_split =
+//       Split(landmarks, indices, graph);
+//
+// ```
+template <typename CollectionT, typename I>
+auto Split(Stream<CollectionT> items, const I& indices,
+           mediapipe::api2::builder::Graph& graph) {
+  return stream_split_internal::Split(items, indices.begin(), indices.end(),
+                                      graph);
+}
+// Splits stream containing a collection based on passed @indices into a vector
+// of streams where each steam repesents individual item of a collection.
+//
+// Example:
+// ```
+//
+//   Graph graph;
+//   std::vector<int> indices = {0, 1, 2, 3};
+//
+//   Stream<std::vector<Detection>> detections = ...;
+//   std::vector<Stream<Detection>> detections_split =
+//       Split(detections, indices, graph);
+//
+//   Stream<NormalizedLandmarkList> landmarks = ...;
+//   std::vector<Stream<NormalizedLandmark>> landmarks_split =
+//       Split(landmarks, indices, graph);
+//
+// ```
+template <typename CollectionT>
+auto Split(Stream<CollectionT> items, std::initializer_list<int> indices,
+           mediapipe::api2::builder::Graph& graph) {
+  return stream_split_internal::Split(items, indices.begin(), indices.end(),
+                                      graph);
+}
+
+// Splits stream containing a collection into a sub ranges, each represented as
+// a stream containing same collection type.
+//
+// Example:
+// ```
+//
+//   Graph graph;
+//   std::vector<std::pair<int, int>> ranges = {{0, 3}, {7, 10}};
+//
+//   Stream<std::vector<Detection>> detections = ...;
+//   std::vector<Stream<std::vector<Detection>>> detections_split =
+//       SplitToRanges(detections, ranges, graph);
+//
+//   Stream<NormalizedLandmarkList> landmarks = ...;
+//   std::vector<Stream<NormalizedLandmarkList>> landmarks_split =
+//       SplitToRanges(landmarks, ranges, graph);
+//
+// ```
+template <typename CollectionT, typename RangeT>
+auto SplitToRanges(Stream<CollectionT> items, const RangeT& ranges,
+                   mediapipe::api2::builder::Graph& graph) {
+  return stream_split_internal::Split(items, ranges.begin(), ranges.end(),
+                                      graph);
+}
+
+// Splits stream containing a collection into a sub ranges, each represented as
+// a stream containing same collection type.
+//
+// Example:
+// ```
+//
+//   Graph graph;
+//   std::vector<std::pair<int, int>> ranges = {{0, 3}, {7, 10}};
+//
+//   Stream<std::vector<Detection>> detections = ...;
+//   std::vector<Stream<std::vector<Detection>>> detections_split =
+//       SplitToRanges(detections, ranges, graph);
+//
+//   Stream<NormalizedLandmarkList> landmarks = ...;
+//   std::vector<Stream<NormalizedLandmarkList>> landmarks_split =
+//       SplitToRanges(landmarks, ranges, graph);
+//
+// ```
+template <typename CollectionT>
+auto SplitToRanges(Stream<CollectionT> items,
+                   std::initializer_list<std::pair<int, int>> ranges,
+                   mediapipe::api2::builder::Graph& graph) {
+  return stream_split_internal::Split(items, ranges.begin(), ranges.end(),
+                                      graph);
+}
+
+// Splits stream containing a collection into a sub ranges and combines them
+// into a stream containing same collection type.
+//
+// Example:
+// ```
+//
+//   Graph graph;
+//   std::vector<std::pair<int, int>> ranges = {{0, 3}, {7, 10}};
+//
+//   Stream<std::vector<Detection>> detections = ...;
+//   Stream<std::vector<Detection>> detections_split_and_combined =
+//       SplitAndCombine(detections, ranges, graph);
+//
+//   Stream<NormalizedLandmarkList> landmarks = ...;
+//   Stream<NormalizedLandmarkList> landmarks_split_and_combined =
+//       SplitAndCombine(landmarks, ranges, graph);
+//
+// ```
+template <typename CollectionT, typename RangeT>
+Stream<CollectionT> SplitAndCombine(Stream<CollectionT> items,
+                                    const RangeT& ranges,
+                                    mediapipe::api2::builder::Graph& graph) {
+  return stream_split_internal::SplitAndCombine(items, ranges.begin(),
+                                                ranges.end(), graph);
+}
+
+// Splits stream containing a collection into a sub ranges and combines them
+// into a stream containing same collection type.
+//
+// Example:
+// ```
+//
+//   Graph graph;
+//
+//   Stream<std::vector<Detection>> detections = ...;
+//   Stream<std::vector<Detection>> detections_split_and_combined =
+//       SplitAndCombine(detections, {{0, 3}, {7, 10}}, graph);
+//
+//   Stream<NormalizedLandmarkList> landmarks = ...;
+//   Stream<NormalizedLandmarkList> landmarks_split_and_combined =
+//       SplitAndCombine(landmarks, {{0, 3}, {7, 10}}, graph);
+//
+// ```
+template <typename CollectionT>
+Stream<CollectionT> SplitAndCombine(
+    Stream<CollectionT> items,
+    std::initializer_list<std::pair<int, int>> ranges,
+    mediapipe::api2::builder::Graph& graph) {
+  return stream_split_internal::SplitAndCombine(items, ranges.begin(),
+                                                ranges.end(), graph);
+}
+
+// Splits stream containing a collection into individual items and combines them
+// into a stream containing same collection type.
+//
+// Example:
+// ```
+//
+//   Graph graph;
+//
+//   Stream<std::vector<Detection>> detections = ...;
+//   Stream<std::vector<Detection>> detections_split_and_combined =
+//       SplitAndCombine(detections, {0, 7, 10}, graph);
+//
+//   Stream<NormalizedLandmarkList> landmarks = ...;
+//   Stream<NormalizedLandmarkList> landmarks_split_and_combined =
+//       SplitAndCombine(landmarks, {0, 7, 10}, graph);
+//
+// ```
+template <typename CollectionT>
+Stream<CollectionT> SplitAndCombine(Stream<CollectionT> items,
+                                    std::initializer_list<int> ranges,
+                                    mediapipe::api2::builder::Graph& graph) {
+  return stream_split_internal::SplitAndCombine(items, ranges.begin(),
+                                                ranges.end(), graph);
+}
+
+}  // namespace mediapipe::api2::builder
+
+#endif  // MEDIAPIPE_FRAMEWORK_API2_STREAM_SPLIT_H_
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/tensor_to_joints.cc b/third_party/mediapipe/src/mediapipe/framework/api2/stream/tensor_to_joints.cc
new file mode 100644
index 0000000..cce4001
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/tensor_to_joints.cc
@@ -0,0 +1,27 @@
+#include "mediapipe/framework/api2/stream/tensor_to_joints.h"
+
+#include "mediapipe/calculators/tensor/tensor_to_joints_calculator.h"
+#include "mediapipe/calculators/tensor/tensor_to_joints_calculator.pb.h"
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/api2/port.h"
+#include "mediapipe/framework/formats/body_rig.pb.h"
+#include "mediapipe/framework/formats/tensor.h"
+
+namespace mediapipe::api2::builder {
+
+namespace {}  // namespace
+
+Stream<JointList> ConvertTensorToJointsAtIndex(Stream<Tensor> tensor,
+                                               const int num_joints,
+                                               const int start_index,
+                                               Graph& graph) {
+  auto& to_joints = graph.AddNode("TensorToJointsCalculator");
+  auto& to_joints_options =
+      to_joints.GetOptions<TensorToJointsCalculatorOptions>();
+  to_joints_options.set_num_joints(num_joints);
+  to_joints_options.set_start_index(start_index);
+  tensor.ConnectTo(to_joints[TensorToJointsCalculator::kInTensor]);
+  return to_joints[TensorToJointsCalculator::kOutJoints];
+}
+
+}  // namespace mediapipe::api2::builder
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/tensor_to_joints.h b/third_party/mediapipe/src/mediapipe/framework/api2/stream/tensor_to_joints.h
new file mode 100644
index 0000000..54d8f82
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/tensor_to_joints.h
@@ -0,0 +1,26 @@
+#ifndef MEDIAPIPE_FRAMEWORK_API2_STREAM_TENSOR_TO_JOINTS_H_
+#define MEDIAPIPE_FRAMEWORK_API2_STREAM_TENSOR_TO_JOINTS_H_
+
+#include "mediapipe/framework/api2/builder.h"
+#include "mediapipe/framework/formats/body_rig.pb.h"
+#include "mediapipe/framework/formats/tensor.h"
+
+namespace mediapipe::api2::builder {
+
+// Updates @graph to convert @tensor to a JointList skipping first @start_index
+// values of a @tensor.
+Stream<mediapipe::JointList> ConvertTensorToJointsAtIndex(Stream<Tensor> tensor,
+                                                          const int num_joints,
+                                                          const int start_index,
+                                                          Graph& graph);
+
+// Updates @graph to convert @tensor to a JointList.
+inline Stream<::mediapipe::JointList> ConvertTensorToJoints(
+    Stream<Tensor> tensor, const int num_joints, Graph& graph) {
+  return ConvertTensorToJointsAtIndex(tensor, num_joints, /*start_index=*/0,
+                                      graph);
+}
+
+}  // namespace mediapipe::api2::builder
+
+#endif  // MEDIAPIPE_FRAMEWORK_API2_STREAM_TENSOR_TO_JOINTS_H_
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/threshold.cc b/third_party/mediapipe/src/mediapipe/framework/api2/stream/threshold.cc
new file mode 100644
index 0000000..48912b0
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/threshold.cc
@@ -0,0 +1,17 @@
+#include "mediapipe/framework/api2/stream/threshold.h"
+
+#include "mediapipe/calculators/util/thresholding_calculator.pb.h"
+#include "mediapipe/framework/api2/builder.h"
+
+namespace mediapipe::api2::builder {
+
+Stream<bool> IsOverThreshold(Stream<float> value, double threshold,
+                             mediapipe::api2::builder::Graph& graph) {
+  auto& node = graph.AddNode("ThresholdingCalculator");
+  auto& node_opts = node.GetOptions<mediapipe::ThresholdingCalculatorOptions>();
+  node_opts.set_threshold(threshold);
+  value.ConnectTo(node.In("FLOAT"));
+  return node.Out("FLAG").Cast<bool>();
+}
+
+}  // namespace mediapipe::api2::builder
diff --git a/third_party/mediapipe/src/mediapipe/framework/api2/stream/threshold.h b/third_party/mediapipe/src/mediapipe/framework/api2/stream/threshold.h
new file mode 100644
index 0000000..8bb3bf2
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/framework/api2/stream/threshold.h
@@ -0,0 +1,13 @@
+#ifndef MEDIAPIPE_FRAMEWORK_API2_STREAM_THRESHOLD_H_
+#define MEDIAPIPE_FRAMEWORK_API2_STREAM_THRESHOLD_H_
+
+#include "mediapipe/framework/api2/builder.h"
+
+namespace mediapipe::api2::builder {
+
+Stream<bool> IsOverThreshold(Stream<float> value, double threshold,
+                             Graph& graph);
+
+}  // namespace mediapipe::api2::builder
+
+#endif  // MEDIAPIPE_FRAMEWORK_API2_STREAM_THRESHOLD_H_
diff --git a/third_party/mediapipe/src/mediapipe/framework/calculator_graph.cc b/third_party/mediapipe/src/mediapipe/framework/calculator_graph.cc
index 03c5d229..1890d799 100644
--- a/third_party/mediapipe/src/mediapipe/framework/calculator_graph.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/calculator_graph.cc
@@ -207,7 +207,7 @@
 
   // Initialize GraphInputStreams.
   int graph_input_stream_count = 0;
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       auto input_tag_map,
       tool::TagMap::Create(validated_graph_->Config().input_stream()));
   for (const auto& stream_name : input_tag_map->Names()) {
@@ -371,7 +371,7 @@
                 "CalculatorGraph::SetExecutor() call.";
     }
     // clang-format off
-    ASSIGN_OR_RETURN(Executor* executor,
+    MP_ASSIGN_OR_RETURN(Executor* executor,
                      ExecutorRegistry::CreateByNameInNamespace(
                          validated_graph_->Package(),
                          executor_config.type(), executor_config.options()));
@@ -1335,7 +1335,7 @@
   }
   options->set_num_threads(num_threads);
   // clang-format off
-  ASSIGN_OR_RETURN(Executor* executor,
+  MP_ASSIGN_OR_RETURN(Executor* executor,
                    ThreadPoolExecutor::Create(extendable_options));
   // clang-format on
   return SetExecutorInternal("", std::shared_ptr<Executor>(executor));
diff --git a/third_party/mediapipe/src/mediapipe/framework/calculator_node.cc b/third_party/mediapipe/src/mediapipe/framework/calculator_node.cc
index c0aff3b..27661dc 100644
--- a/third_party/mediapipe/src/mediapipe/framework/calculator_node.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/calculator_node.cc
@@ -303,14 +303,15 @@
   const ProtoString& input_stream_handler_name =
       handler_config.input_stream_handler();
   RET_CHECK(!input_stream_handler_name.empty());
-  ASSIGN_OR_RETURN(input_stream_handler_,
-                   InputStreamHandlerRegistry::CreateByNameInNamespace(
-                       validated_graph_->Package(), input_stream_handler_name,
-                       input_stream_types.TagMap(),
-                       &calculator_context_manager_, handler_config.options(),
-                       /*calculator_run_in_parallel=*/max_in_flight_ > 1),
-                   _ << "\"" << input_stream_handler_name
-                     << "\" is not a registered input stream handler.");
+  MP_ASSIGN_OR_RETURN(
+      input_stream_handler_,
+      InputStreamHandlerRegistry::CreateByNameInNamespace(
+          validated_graph_->Package(), input_stream_handler_name,
+          input_stream_types.TagMap(), &calculator_context_manager_,
+          handler_config.options(),
+          /*calculator_run_in_parallel=*/max_in_flight_ > 1),
+      _ << "\"" << input_stream_handler_name
+        << "\" is not a registered input stream handler.");
 
   return absl::OkStatus();
 }
@@ -321,14 +322,15 @@
   const ProtoString& output_stream_handler_name =
       handler_config.output_stream_handler();
   RET_CHECK(!output_stream_handler_name.empty());
-  ASSIGN_OR_RETURN(output_stream_handler_,
-                   OutputStreamHandlerRegistry::CreateByNameInNamespace(
-                       validated_graph_->Package(), output_stream_handler_name,
-                       output_stream_types.TagMap(),
-                       &calculator_context_manager_, handler_config.options(),
-                       /*calculator_run_in_parallel=*/max_in_flight_ > 1),
-                   _ << "\"" << output_stream_handler_name
-                     << "\" is not a registered output stream handler.");
+  MP_ASSIGN_OR_RETURN(
+      output_stream_handler_,
+      OutputStreamHandlerRegistry::CreateByNameInNamespace(
+          validated_graph_->Package(), output_stream_handler_name,
+          output_stream_types.TagMap(), &calculator_context_manager_,
+          handler_config.options(),
+          /*calculator_run_in_parallel=*/max_in_flight_ > 1),
+      _ << "\"" << output_stream_handler_name
+        << "\" is not a registered output stream handler.");
   return absl::OkStatus();
 }
 
@@ -420,7 +422,7 @@
   MP_RETURN_IF_ERROR(calculator_context_manager_.PrepareForRun(std::bind(
       &CalculatorNode::ConnectShardsToStreams, this, std::placeholders::_1)));
 
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       auto calculator_factory,
       CalculatorBaseRegistry::CreateByNameInNamespace(
           validated_graph_->Package(), calculator_state_->CalculatorType()));
diff --git a/third_party/mediapipe/src/mediapipe/framework/calculator_runner.cc b/third_party/mediapipe/src/mediapipe/framework/calculator_runner.cc
index 800f041c..1066ecf 100644
--- a/third_party/mediapipe/src/mediapipe/framework/calculator_runner.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/calculator_runner.cc
@@ -111,20 +111,20 @@
         node_config_.mutable_input_side_packet());
   }
 
-  ASSIGN_OR_RETURN(auto input_map,
-                   tool::TagMap::Create(node_config_.input_stream()));
+  MP_ASSIGN_OR_RETURN(auto input_map,
+                      tool::TagMap::Create(node_config_.input_stream()));
   inputs_ = absl::make_unique<StreamContentsSet>(input_map);
 
-  ASSIGN_OR_RETURN(auto output_map,
-                   tool::TagMap::Create(node_config_.output_stream()));
+  MP_ASSIGN_OR_RETURN(auto output_map,
+                      tool::TagMap::Create(node_config_.output_stream()));
   outputs_ = absl::make_unique<StreamContentsSet>(output_map);
 
-  ASSIGN_OR_RETURN(auto input_side_map,
-                   tool::TagMap::Create(node_config_.input_side_packet()));
+  MP_ASSIGN_OR_RETURN(auto input_side_map,
+                      tool::TagMap::Create(node_config_.input_side_packet()));
   input_side_packets_ = absl::make_unique<PacketSet>(input_side_map);
 
-  ASSIGN_OR_RETURN(auto output_side_map,
-                   tool::TagMap::Create(node_config_.output_side_packet()));
+  MP_ASSIGN_OR_RETURN(auto output_side_map,
+                      tool::TagMap::Create(node_config_.output_side_packet()));
   output_side_packets_ = absl::make_unique<PacketSet>(output_side_map);
 
   return absl::OkStatus();
@@ -353,7 +353,7 @@
         node_config_.output_side_packet(i), &tag, &index, &name));
     Packet& contents = output_side_packets_->Get(
         tag, (index == -1) ? ++positional_index : index);
-    ASSIGN_OR_RETURN(contents, graph_->GetOutputSidePacket(name));
+    MP_ASSIGN_OR_RETURN(contents, graph_->GetOutputSidePacket(name));
   }
   return absl::OkStatus();
 }
diff --git a/third_party/mediapipe/src/mediapipe/framework/deps/status_macros.h b/third_party/mediapipe/src/mediapipe/framework/deps/status_macros.h
index 92bbf0b..02da280 100644
--- a/third_party/mediapipe/src/mediapipe/framework/deps/status_macros.h
+++ b/third_party/mediapipe/src/mediapipe/framework/deps/status_macros.h
@@ -82,7 +82,7 @@
 //     return absl::OkStatus();
 //   }
 #define MP_RETURN_IF_ERROR(expr)                                     \
-  STATUS_MACROS_IMPL_ELSE_BLOCKER_                                   \
+  MP_STATUS_MACROS_IMPL_ELSE_BLOCKER_                                \
   if (mediapipe::status_macro_internal::StatusAdaptorForMacros       \
           status_macro_internal_adaptor = {(expr), MEDIAPIPE_LOC}) { \
   } else /* NOLINT */                                                \
@@ -97,27 +97,27 @@
 //
 // Interface:
 //
-//   ASSIGN_OR_RETURN(lhs, rexpr)
-//   ASSIGN_OR_RETURN(lhs, rexpr, error_expression);
+//   MP_ASSIGN_OR_RETURN(lhs, rexpr)
+//   MP_ASSIGN_OR_RETURN(lhs, rexpr, error_expression);
 //
 // WARNING: expands into multiple statements; it cannot be used in a single
 // statement (e.g. as the body of an if statement without {})!
 //
 // Example: Declaring and initializing a new variable (ValueType can be anything
 //          that can be initialized with assignment, including references):
-//   ASSIGN_OR_RETURN(ValueType value, MaybeGetValue(arg));
+//   MP_ASSIGN_OR_RETURN(ValueType value, MaybeGetValue(arg));
 //
 // Example: Assigning to an existing variable:
 //   ValueType value;
-//   ASSIGN_OR_RETURN(value, MaybeGetValue(arg));
+//   MP_ASSIGN_OR_RETURN(value, MaybeGetValue(arg));
 //
 // Example: Assigning to an expression with side effects:
 //   MyProto data;
-//   ASSIGN_OR_RETURN(*data.mutable_str(), MaybeGetValue(arg));
+//   MP_ASSIGN_OR_RETURN(*data.mutable_str(), MaybeGetValue(arg));
 //   // No field "str" is added on error.
 //
 // Example: Assigning to a std::unique_ptr.
-//   ASSIGN_OR_RETURN(std::unique_ptr<T> ptr, MaybeGetPtr(arg));
+//   MP_ASSIGN_OR_RETURN(std::unique_ptr<T> ptr, MaybeGetPtr(arg));
 //
 // If passed, the `error_expression` is evaluated to produce the return
 // value. The expression may reference any variable visible in scope, as
@@ -128,16 +128,16 @@
 // returnable by the function, including (void). For example:
 //
 // Example: Adjusting the error message.
-//   ASSIGN_OR_RETURN(ValueType value, MaybeGetValue(query),
+//   MP_ASSIGN_OR_RETURN(ValueType value, MaybeGetValue(query),
 //                    _ << "while processing query " << query.DebugString());
 //
 // Example: Logging the error on failure.
-//   ASSIGN_OR_RETURN(ValueType value, MaybeGetValue(query), _.LogError());
+//   MP_ASSIGN_OR_RETURN(ValueType value, MaybeGetValue(query), _.LogError());
 //
-#define ASSIGN_OR_RETURN(...)                                                \
-  STATUS_MACROS_IMPL_GET_VARIADIC_((__VA_ARGS__,                             \
-                                    STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_3_,  \
-                                    STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_2_)) \
+#define MP_ASSIGN_OR_RETURN(...)                                  \
+  MP_STATUS_MACROS_IMPL_GET_VARIADIC_(                            \
+      (__VA_ARGS__, MP_STATUS_MACROS_IMPL_MP_ASSIGN_OR_RETURN_3_, \
+       MP_STATUS_MACROS_IMPL_MP_ASSIGN_OR_RETURN_2_))             \
   (__VA_ARGS__)
 
 // =================================================================
@@ -146,37 +146,39 @@
 
 // MSVC incorrectly expands variadic macros, splice together a macro call to
 // work around the bug.
-#define STATUS_MACROS_IMPL_GET_VARIADIC_HELPER_(_1, _2, _3, NAME, ...) NAME
-#define STATUS_MACROS_IMPL_GET_VARIADIC_(args) \
-  STATUS_MACROS_IMPL_GET_VARIADIC_HELPER_ args
+#define MP_STATUS_MACROS_IMPL_GET_VARIADIC_HELPER_(_1, _2, _3, NAME, ...) NAME
+#define MP_STATUS_MACROS_IMPL_GET_VARIADIC_(args) \
+  MP_STATUS_MACROS_IMPL_GET_VARIADIC_HELPER_ args
 
-#define STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_2_(lhs, rexpr)                  \
-  STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_(                                     \
-      STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__), lhs, rexpr,   \
-      return mediapipe::StatusBuilder(                                      \
-          std::move(STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__)) \
-              .status(),                                                    \
+#define MP_STATUS_MACROS_IMPL_MP_ASSIGN_OR_RETURN_2_(lhs, rexpr)               \
+  MP_STATUS_MACROS_IMPL_MP_ASSIGN_OR_RETURN_(                                  \
+      MP_STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__), lhs, rexpr,   \
+      return mediapipe::StatusBuilder(                                         \
+          std::move(MP_STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__)) \
+              .status(),                                                       \
           MEDIAPIPE_LOC))
-#define STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_3_(lhs, rexpr, error_expression) \
-  STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_(                                      \
-      STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__), lhs, rexpr,    \
-      mediapipe::StatusBuilder _(                                            \
-          std::move(STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__))  \
-              .status(),                                                     \
-          MEDIAPIPE_LOC);                                                    \
-      (void)_; /* error_expression is allowed to not use this variable */    \
+#define MP_STATUS_MACROS_IMPL_MP_ASSIGN_OR_RETURN_3_(lhs, rexpr,               \
+                                                     error_expression)         \
+  MP_STATUS_MACROS_IMPL_MP_ASSIGN_OR_RETURN_(                                  \
+      MP_STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__), lhs, rexpr,   \
+      mediapipe::StatusBuilder _(                                              \
+          std::move(MP_STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__)) \
+              .status(),                                                       \
+          MEDIAPIPE_LOC);                                                      \
+      (void)_; /* error_expression is allowed to not use this variable */      \
       return (error_expression))
-#define STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_(statusor, lhs, rexpr, \
-                                             error_expression)     \
-  auto statusor = (rexpr);                                         \
-  if (ABSL_PREDICT_FALSE(!statusor.ok())) {                        \
-    error_expression;                                              \
-  }                                                                \
+#define MP_STATUS_MACROS_IMPL_MP_ASSIGN_OR_RETURN_(statusor, lhs, rexpr, \
+                                                   error_expression)     \
+  auto statusor = (rexpr);                                               \
+  if (ABSL_PREDICT_FALSE(!statusor.ok())) {                              \
+    error_expression;                                                    \
+  }                                                                      \
   lhs = std::move(statusor).value()
 
 // Internal helper for concatenating macro values.
-#define STATUS_MACROS_IMPL_CONCAT_INNER_(x, y) x##y
-#define STATUS_MACROS_IMPL_CONCAT_(x, y) STATUS_MACROS_IMPL_CONCAT_INNER_(x, y)
+#define MP_STATUS_MACROS_IMPL_CONCAT_INNER_(x, y) x##y
+#define MP_STATUS_MACROS_IMPL_CONCAT_(x, y) \
+  MP_STATUS_MACROS_IMPL_CONCAT_INNER_(x, y)
 
 // The GNU compiler emits a warning for code like:
 //
@@ -189,9 +191,9 @@
 //   if (do_expr) MP_RETURN_IF_ERROR(expr) << "Some message";
 //
 // The "switch (0) case 0:" idiom is used to suppress this.
-#define STATUS_MACROS_IMPL_ELSE_BLOCKER_ \
-  switch (0)                             \
-  case 0:                                \
+#define MP_STATUS_MACROS_IMPL_ELSE_BLOCKER_ \
+  switch (0)                                \
+  case 0:                                   \
   default:  // NOLINT
 
 namespace mediapipe {
diff --git a/third_party/mediapipe/src/mediapipe/framework/formats/BUILD b/third_party/mediapipe/src/mediapipe/framework/formats/BUILD
index 7f1792a..5e94037 100644
--- a/third_party/mediapipe/src/mediapipe/framework/formats/BUILD
+++ b/third_party/mediapipe/src/mediapipe/framework/formats/BUILD
@@ -482,28 +482,30 @@
             "-framework MetalKit",
         ],
         "//conditions:default": [],
+        # Option for vendor binaries to avoid linking libandroid.so.
         "//mediapipe/framework:android_no_jni": [],
-        "//mediapipe:android": [
-            "-landroid",
-        ],
+        "//mediapipe:android": ["-landroid"],
         ":android_link_native_window": [
-            "-lnativewindow",  # Provides <android/hardware_buffer.h> to vendor processes on Android API >= 26.
+            "-lnativewindow",  # Provides <android/hardware_buffer.h> to vendor binaries on Android API >= 26.
         ],
     }),
     deps = [
-        "//mediapipe/framework:port",
-        "@com_google_absl//absl/container:flat_hash_map",
-        "@com_google_absl//absl/log:absl_check",
-        "@com_google_absl//absl/log:absl_log",
-        "@com_google_absl//absl/memory",
-        "@com_google_absl//absl/synchronization",
-    ] + select({
-        "//mediapipe/gpu:disable_gpu": [],
-        "//conditions:default": [
-            "//mediapipe/gpu:gl_base",
-            "//mediapipe/gpu:gl_context",
-        ],
-    }),
+               "//mediapipe/framework:port",
+               "@com_google_absl//absl/container:flat_hash_map",
+               "@com_google_absl//absl/log:absl_check",
+               "@com_google_absl//absl/log:absl_log",
+               "@com_google_absl//absl/memory",
+               "@com_google_absl//absl/synchronization",
+           ] + select({
+               "//mediapipe/gpu:disable_gpu": [],
+               "//conditions:default": [
+                   "//mediapipe/gpu:gl_base",
+                   "//mediapipe/gpu:gl_context",
+               ],
+           }) +
+           select({
+               "//conditions:default": [],
+           }),
 )
 
 cc_test(
diff --git a/third_party/mediapipe/src/mediapipe/framework/input_side_packet_handler.cc b/third_party/mediapipe/src/mediapipe/framework/input_side_packet_handler.cc
index b2eccf0..9e29291 100644
--- a/third_party/mediapipe/src/mediapipe/framework/input_side_packet_handler.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/input_side_packet_handler.cc
@@ -29,7 +29,7 @@
     std::function<void(absl::Status)> error_callback) {
   int missing_input_side_packet_count;
   prev_input_side_packets_ = std::move(input_side_packets_);
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       input_side_packets_,
       tool::FillPacketSet(*input_side_packet_types, all_side_packets,
                           &missing_input_side_packet_count));
diff --git a/third_party/mediapipe/src/mediapipe/framework/output_stream_poller.h b/third_party/mediapipe/src/mediapipe/framework/output_stream_poller.h
index 98ebda3..d8c83b0d 100644
--- a/third_party/mediapipe/src/mediapipe/framework/output_stream_poller.h
+++ b/third_party/mediapipe/src/mediapipe/framework/output_stream_poller.h
@@ -28,8 +28,8 @@
   OutputStreamPoller(const OutputStreamPoller&) = delete;
   OutputStreamPoller& operator=(const OutputStreamPoller&) = delete;
   OutputStreamPoller(OutputStreamPoller&&) = default;
-  // Move assignment needs to be explicitly defaulted to allow ASSIGN_OR_RETURN
-  // on `StatusOr<OutputStreamPoller>`.
+  // Move assignment needs to be explicitly defaulted to allow
+  // MP_ASSIGN_OR_RETURN on `StatusOr<OutputStreamPoller>`.
   OutputStreamPoller& operator=(OutputStreamPoller&&) = default;
 
   // Resets OutputStramPollerImpl and cleans the internal packet queue.
diff --git a/third_party/mediapipe/src/mediapipe/framework/packet.cc b/third_party/mediapipe/src/mediapipe/framework/packet.cc
index edcdaf19..e0fa5a0 100644
--- a/third_party/mediapipe/src/mediapipe/framework/packet.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/packet.cc
@@ -55,7 +55,7 @@
 
 absl::StatusOr<Packet> PacketFromDynamicProto(const std::string& type_name,
                                               const std::string& serialized) {
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       auto message_holder,
       packet_internal::MessageHolderRegistry::CreateByName(type_name));
   auto* message =
diff --git a/third_party/mediapipe/src/mediapipe/framework/packet.h b/third_party/mediapipe/src/mediapipe/framework/packet.h
index 84ae94d..0b660f0 100644
--- a/third_party/mediapipe/src/mediapipe/framework/packet.h
+++ b/third_party/mediapipe/src/mediapipe/framework/packet.h
@@ -150,16 +150,16 @@
   // general recommendation is to avoid calling this function.
   //
   // Example usage:
-  //   ASSIGN_OR_RETURN(std::unique_ptr<Detection> detection,
+  //   MP_ASSIGN_OR_RETURN(std::unique_ptr<Detection> detection,
   //                    p.ConsumeOrCopy<Detection>());
   //   // The unique_ptr type can be omitted with auto.
-  //   ASSIGN_OR_RETURN(auto detection, p.ConsumeOrCopy<Detection>());
-  //   If you would like to crash on failure (prefer ASSIGN_OR_RETURN):
+  //   MP_ASSIGN_OR_RETURN(auto detection, p.ConsumeOrCopy<Detection>());
+  //   If you would like to crash on failure (prefer MP_ASSIGN_OR_RETURN):
   //   auto detection = p.ConsumeOrCopy<Detection>().value();
   //   // In functions which do not return absl::Status use an adaptor
-  //   // function as the third argument to ASSIGN_OR_RETURN.  In tests,
+  //   // function as the third argument to MP_ASSIGN_OR_RETURN.  In tests,
   //   // use an adaptor which returns void.
-  //   ASSIGN_OR_RETURN(auto detection, p.ConsumeOrCopy<Detection>(),
+  //   MP_ASSIGN_OR_RETURN(auto detection, p.ConsumeOrCopy<Detection>(),
   //                    _.With([](const absl::Status& status) {
   //                      MP_EXPECT_OK(status);
   //                      // Use CHECK_OK to crash and report a usable line
diff --git a/third_party/mediapipe/src/mediapipe/framework/packet_generator_graph.cc b/third_party/mediapipe/src/mediapipe/framework/packet_generator_graph.cc
index 31ec3ea3..c59515e 100644
--- a/third_party/mediapipe/src/mediapipe/framework/packet_generator_graph.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/packet_generator_graph.cc
@@ -97,7 +97,7 @@
       validated_graph.Config().packet_generator(generator_index);
   const auto& generator_name = generator_config.packet_generator();
 
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       auto static_access,
       internal::StaticAccessToGeneratorRegistry::CreateByNameInNamespace(
           validated_graph.Package(), generator_name),
diff --git a/third_party/mediapipe/src/mediapipe/framework/profiler/graph_profiler.cc b/third_party/mediapipe/src/mediapipe/framework/profiler/graph_profiler.cc
index 94995511..f5ea01e 100644
--- a/third_party/mediapipe/src/mediapipe/framework/profiler/graph_profiler.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/profiler/graph_profiler.cc
@@ -246,7 +246,7 @@
   if (is_tracing_ && IsTraceIntervalEnabled(profiler_config_, tracer()) &&
       executor != nullptr) {
     // Inform the user via logging the path to the trace logs.
-    ASSIGN_OR_RETURN(std::string trace_log_path, GetTraceLogPath());
+    MP_ASSIGN_OR_RETURN(std::string trace_log_path, GetTraceLogPath());
     // Check that we can actually write to it.
     auto status =
         file::SetContents(absl::StrCat(trace_log_path, "trace_writing_check"),
@@ -655,7 +655,8 @@
         "Trace log writing is disabled, unable to get trace_log_path.");
   }
   if (profiler_config_.trace_log_path().empty()) {
-    ASSIGN_OR_RETURN(std::string directory_path, GetDefaultTraceLogDirectory());
+    MP_ASSIGN_OR_RETURN(std::string directory_path,
+                        GetDefaultTraceLogDirectory());
     std::string trace_log_path =
         absl::StrCat(directory_path, "/", kDefaultLogFilePrefix);
     return trace_log_path;
@@ -705,7 +706,7 @@
     // Logging is disabled, so we can exit writing without error.
     return absl::OkStatus();
   }
-  ASSIGN_OR_RETURN(std::string trace_log_path, GetTraceLogPath());
+  MP_ASSIGN_OR_RETURN(std::string trace_log_path, GetTraceLogPath());
   int log_interval_count = GetLogIntervalCount(profiler_config_);
   int log_file_count = GetLogFileCount(profiler_config_);
   GraphProfile profile;
diff --git a/third_party/mediapipe/src/mediapipe/framework/profiler/profiler_resource_util_common.cc b/third_party/mediapipe/src/mediapipe/framework/profiler/profiler_resource_util_common.cc
index d75ea97..cc573b703 100644
--- a/third_party/mediapipe/src/mediapipe/framework/profiler/profiler_resource_util_common.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/profiler/profiler_resource_util_common.cc
@@ -33,7 +33,7 @@
 }
 
 absl::StatusOr<std::string> PathToLogFile(const std::string& path) {
-  ASSIGN_OR_RETURN(std::string log_dir, GetLogDirectory());
+  MP_ASSIGN_OR_RETURN(std::string log_dir, GetLogDirectory());
   std::string result = file::JoinPath(log_dir, path);
   MP_RETURN_IF_ERROR(
       mediapipe::file::RecursivelyCreateDir(file::Dirname(result)));
diff --git a/third_party/mediapipe/src/mediapipe/framework/tool/mediapipe_proto_allowlist.bzl b/third_party/mediapipe/src/mediapipe/framework/tool/mediapipe_proto_allowlist.bzl
index da02e3c..26c20ae8 100644
--- a/third_party/mediapipe/src/mediapipe/framework/tool/mediapipe_proto_allowlist.bzl
+++ b/third_party/mediapipe/src/mediapipe/framework/tool/mediapipe_proto_allowlist.bzl
@@ -5,7 +5,6 @@
     "adaptive_crop_calculator_proto",
     "affine_transform_data_proto",
     "affine_transform_from_rect_calculator_proto",
-    "align_hand_to_pose_in_world_calculator_proto",
     "anchor_proto",
     "annotation_overlay_calculator_proto",
     "annotation_proto",
@@ -248,7 +247,6 @@
     "segmenter_proto",
     "sequence_shift_calculator_proto",
     "set_alpha_calculator_proto",
-    "set_joints_visibility_calculator_proto",
     "sharpen_calculator_gl_proto",
     "simple_calculator_proto",
     "single_shot_detector_gpu_cpu_proto",
diff --git a/third_party/mediapipe/src/mediapipe/framework/tool/options_field_util.cc b/third_party/mediapipe/src/mediapipe/framework/tool/options_field_util.cc
index 248028c2..164da2c5 100644
--- a/third_party/mediapipe/src/mediapipe/framework/tool/options_field_util.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/tool/options_field_util.cc
@@ -175,7 +175,8 @@
   }
   std::string& extension_type = entry->extension_type;
   std::vector<FieldData> field_values;
-  ASSIGN_OR_RETURN(field_values, GetFieldValues(message_data, *entry->field));
+  MP_ASSIGN_OR_RETURN(field_values,
+                      GetFieldValues(message_data, *entry->field));
   for (int i = 0; i < field_values.size(); ++i) {
     FieldData extension = ParseProtobufAny(field_values[i]);
     if (extension_type == "*" ||
@@ -275,7 +276,7 @@
   }
 
   // For repeated protobuf::Any, find the index for the extension_type.
-  ASSIGN_OR_RETURN(int index, FindExtensionIndex(message_data, entry));
+  MP_ASSIGN_OR_RETURN(int index, FindExtensionIndex(message_data, entry));
   if (index != -1) {
     entry->index = index;
     return absl::OkStatus();
@@ -367,7 +368,7 @@
     MP_RETURN_IF_ERROR(FindExtension(message_data, &head));
   }
   RET_CHECK_NE(head.field, nullptr);
-  ASSIGN_OR_RETURN(results, GetFieldValues(message_data, *head.field));
+  MP_ASSIGN_OR_RETURN(results, GetFieldValues(message_data, *head.field));
   if (IsProtobufAny(head.field)) {
     for (int i = 0; i < results.size(); ++i) {
       results[i] = ParseProtobufAny(results[i]);
@@ -381,7 +382,7 @@
   }
   if (!tail.empty()) {
     FieldData child = results.at(index);
-    ASSIGN_OR_RETURN(results, GetFieldValues(child, tail));
+    MP_ASSIGN_OR_RETURN(results, GetFieldValues(child, tail));
   } else if (index > -1) {
     FieldData child = results.at(index);
     results.clear();
@@ -394,7 +395,7 @@
 absl::StatusOr<FieldData> GetField(const FieldData& message_data,
                                    const FieldPath& field_path) {
   std::vector<FieldData> results;
-  ASSIGN_OR_RETURN(results, GetFieldValues(message_data, field_path));
+  MP_ASSIGN_OR_RETURN(results, GetFieldValues(message_data, field_path));
   if (results.empty()) {
     FieldPathEntry tail = field_path.back();
     return absl::OutOfRangeError(absl::StrCat(
@@ -452,12 +453,12 @@
                                             : field_path.back().field->type();
   std::vector<FieldData> results = values;
   std::vector<FieldData> prevs;
-  ASSIGN_OR_RETURN(prevs, GetFieldValues(message_data, field_path));
+  MP_ASSIGN_OR_RETURN(prevs, GetFieldValues(message_data, field_path));
   if (field_type == FieldType::TYPE_MESSAGE) {
     for (int i = 0; i < std::min(values.size(), prevs.size()); ++i) {
       FieldData& v = results[i];
       FieldData& b = prevs[i];
-      ASSIGN_OR_RETURN(v, MergeMessages(b, v));
+      MP_ASSIGN_OR_RETURN(v, MergeMessages(b, v));
     }
   }
   status.Update(SetFieldValues(message_data, field_path, results));
diff --git a/third_party/mediapipe/src/mediapipe/framework/tool/options_util.cc b/third_party/mediapipe/src/mediapipe/framework/tool/options_util.cc
index 80b2f9d..f0c8c002 100644
--- a/third_party/mediapipe/src/mediapipe/framework/tool/options_util.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/tool/options_util.cc
@@ -88,11 +88,11 @@
       FieldData parent_options;
       ASSIGN_IF_OK(parent_options,
                    GetNodeOptions(parent_data, graph_extension_type));
-      ASSIGN_OR_RETURN(graph_options,
-                       MergeMessages(graph_options, parent_options));
+      MP_ASSIGN_OR_RETURN(graph_options,
+                          MergeMessages(graph_options, parent_options));
       FieldData node_options;
-      ASSIGN_OR_RETURN(node_options,
-                       GetNodeOptions(node_data, node_extension_type));
+      MP_ASSIGN_OR_RETURN(node_options,
+                          GetNodeOptions(node_data, node_extension_type));
       if (!node_options.has_message_value() ||
           !graph_options.has_message_value()) {
         continue;
@@ -100,7 +100,8 @@
       FieldPath graph_path = GetPath(graph_tag, MessageType(graph_options));
       FieldPath node_path = GetPath(node_tag, MessageType(node_options));
       std::vector<FieldData> packet_data;
-      ASSIGN_OR_RETURN(packet_data, GetFieldValues(graph_options, graph_path));
+      MP_ASSIGN_OR_RETURN(packet_data,
+                          GetFieldValues(graph_options, graph_path));
       MP_RETURN_IF_ERROR(
           MergeFieldValues(node_options, node_path, packet_data));
       options_field_util::SetOptionsMessage(node_options, &node);
diff --git a/third_party/mediapipe/src/mediapipe/framework/tool/packet_generator_wrapper_calculator.cc b/third_party/mediapipe/src/mediapipe/framework/tool/packet_generator_wrapper_calculator.cc
index 07eae6f..bbcf4673 100644
--- a/third_party/mediapipe/src/mediapipe/framework/tool/packet_generator_wrapper_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/tool/packet_generator_wrapper_calculator.cc
@@ -15,10 +15,10 @@
     CalculatorContract* cc) {
   const auto& options =
       cc->Options<::mediapipe::PacketGeneratorWrapperCalculatorOptions>();
-  ASSIGN_OR_RETURN(auto static_access,
-                   mediapipe::internal::StaticAccessToGeneratorRegistry::
-                       CreateByNameInNamespace(options.package(),
-                                               options.packet_generator()));
+  MP_ASSIGN_OR_RETURN(auto static_access,
+                      mediapipe::internal::StaticAccessToGeneratorRegistry::
+                          CreateByNameInNamespace(options.package(),
+                                                  options.packet_generator()));
   MP_RETURN_IF_ERROR(static_access->FillExpectations(options.options(),
                                                      &cc->InputSidePackets(),
                                                      &cc->OutputSidePackets()))
@@ -30,10 +30,10 @@
 absl::Status PacketGeneratorWrapperCalculator::Open(CalculatorContext* cc) {
   const auto& options =
       cc->Options<::mediapipe::PacketGeneratorWrapperCalculatorOptions>();
-  ASSIGN_OR_RETURN(auto static_access,
-                   mediapipe::internal::StaticAccessToGeneratorRegistry::
-                       CreateByNameInNamespace(options.package(),
-                                               options.packet_generator()));
+  MP_ASSIGN_OR_RETURN(auto static_access,
+                      mediapipe::internal::StaticAccessToGeneratorRegistry::
+                          CreateByNameInNamespace(options.package(),
+                                                  options.packet_generator()));
   mediapipe::PacketSet output_packets(cc->OutputSidePackets().TagMap());
   MP_RETURN_IF_ERROR(static_access->Generate(options.options(),
                                              cc->InputSidePackets(),
diff --git a/third_party/mediapipe/src/mediapipe/framework/tool/proto_util_lite.cc b/third_party/mediapipe/src/mediapipe/framework/tool/proto_util_lite.cc
index 285aa22..1cc6e1e 100644
--- a/third_party/mediapipe/src/mediapipe/framework/tool/proto_util_lite.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/tool/proto_util_lite.cc
@@ -196,7 +196,7 @@
   proto_path.erase(proto_path.begin());
   FieldType type =
       !proto_path.empty() ? WireFormatLite::TYPE_MESSAGE : field_type;
-  ASSIGN_OR_RETURN(auto r, AccessField(entry, type, *message));
+  MP_ASSIGN_OR_RETURN(auto r, AccessField(entry, type, *message));
   FieldAccess& access = r.first;
   int index = r.second;
   std::vector<FieldValue>& v = *access.mutable_field_values();
@@ -223,7 +223,7 @@
   proto_path.erase(proto_path.begin());
   FieldType type =
       !proto_path.empty() ? WireFormatLite::TYPE_MESSAGE : field_type;
-  ASSIGN_OR_RETURN(auto r, AccessField(entry, type, message));
+  MP_ASSIGN_OR_RETURN(auto r, AccessField(entry, type, message));
   FieldAccess& access = r.first;
   int index = r.second;
   std::vector<FieldValue>& v = *access.mutable_field_values();
@@ -252,7 +252,7 @@
   proto_path.erase(proto_path.begin());
   FieldType type =
       !proto_path.empty() ? WireFormatLite::TYPE_MESSAGE : field_type;
-  ASSIGN_OR_RETURN(auto r, AccessField(entry, type, message));
+  MP_ASSIGN_OR_RETURN(auto r, AccessField(entry, type, message));
   FieldAccess& access = r.first;
   int index = r.second;
   std::vector<FieldValue>& v = *access.mutable_field_values();
diff --git a/third_party/mediapipe/src/mediapipe/framework/tool/subgraph_expansion.cc b/third_party/mediapipe/src/mediapipe/framework/tool/subgraph_expansion.cc
index dcd055f..59373fd 100644
--- a/third_party/mediapipe/src/mediapipe/framework/tool/subgraph_expansion.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/tool/subgraph_expansion.cc
@@ -62,8 +62,8 @@
     const proto_ns::RepeatedPtrField<ProtoString>& src_streams,
     const proto_ns::RepeatedPtrField<ProtoString>& dst_streams,
     std::set<std::string>* result) {
-  ASSIGN_OR_RETURN(auto src_map, tool::TagMap::Create(src_streams));
-  ASSIGN_OR_RETURN(auto dst_map, tool::TagMap::Create(dst_streams));
+  MP_ASSIGN_OR_RETURN(auto src_map, tool::TagMap::Create(src_streams));
+  MP_ASSIGN_OR_RETURN(auto dst_map, tool::TagMap::Create(dst_streams));
   for (auto id = src_map->BeginId(); id < src_map->EndId(); ++id) {
     std::pair<std::string, int> tag_index = src_map->TagAndIndexFromId(id);
     if (!dst_map->GetId(tag_index.first, tag_index.second).IsValid()) {
@@ -149,8 +149,8 @@
     std::map<std::string, std::string>* stream_map,
     const proto_ns::RepeatedPtrField<ProtoString>& src_streams,
     const proto_ns::RepeatedPtrField<ProtoString>& dst_streams) {
-  ASSIGN_OR_RETURN(auto src_map, tool::TagMap::Create(src_streams));
-  ASSIGN_OR_RETURN(auto dst_map, tool::TagMap::Create(dst_streams));
+  MP_ASSIGN_OR_RETURN(auto src_map, tool::TagMap::Create(src_streams));
+  MP_ASSIGN_OR_RETURN(auto dst_map, tool::TagMap::Create(dst_streams));
   for (const auto& it : dst_map->Mapping()) {
     const std::string& tag = it.first;
     const TagMap::TagData* src_tag_data =
@@ -299,9 +299,10 @@
       std::string node_name = CanonicalNodeName(*config, node_id);
       MP_RETURN_IF_ERROR(ValidateSubgraphFields(node));
       SubgraphContext subgraph_context(&node, service_manager);
-      ASSIGN_OR_RETURN(auto subgraph, graph_registry->CreateByName(
-                                          config->package(), node.calculator(),
-                                          &subgraph_context));
+      MP_ASSIGN_OR_RETURN(
+          auto subgraph,
+          graph_registry->CreateByName(config->package(), node.calculator(),
+                                       &subgraph_context));
       MP_RETURN_IF_ERROR(mediapipe::tool::DefineGraphOptions(node, &subgraph));
       MP_RETURN_IF_ERROR(PrefixNames(node_name, &subgraph));
       MP_RETURN_IF_ERROR(ConnectSubgraphStreams(node, &subgraph));
diff --git a/third_party/mediapipe/src/mediapipe/framework/tool/switch/graph_processor.cc b/third_party/mediapipe/src/mediapipe/framework/tool/switch/graph_processor.cc
index f357307..34a10b99 100644
--- a/third_party/mediapipe/src/mediapipe/framework/tool/switch/graph_processor.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/tool/switch/graph_processor.cc
@@ -8,10 +8,10 @@
 absl::Status GraphProcessor::Initialize(CalculatorGraphConfig graph_config) {
   graph_config_ = graph_config;
 
-  ASSIGN_OR_RETURN(graph_input_map_,
-                   tool::TagMap::Create(graph_config_.input_stream()));
-  ASSIGN_OR_RETURN(graph_output_map_,
-                   tool::TagMap::Create(graph_config_.output_stream()));
+  MP_ASSIGN_OR_RETURN(graph_input_map_,
+                      tool::TagMap::Create(graph_config_.input_stream()));
+  MP_ASSIGN_OR_RETURN(graph_output_map_,
+                      tool::TagMap::Create(graph_config_.output_stream()));
   return absl::OkStatus();
 }
 
diff --git a/third_party/mediapipe/src/mediapipe/framework/tool/switch_demux_calculator.cc b/third_party/mediapipe/src/mediapipe/framework/tool/switch_demux_calculator.cc
index c066d47..a326621d 100644
--- a/third_party/mediapipe/src/mediapipe/framework/tool/switch_demux_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/tool/switch_demux_calculator.cc
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 #include <algorithm>
+#include <iterator>
 #include <memory>
 #include <queue>
 #include <set>
@@ -223,8 +224,8 @@
 
 // Returns the channel index for a Timestamp.
 int SwitchDemuxCalculator::ChannelIndex(Timestamp timestamp) {
-  auto it = std::prev(channel_history_.upper_bound(timestamp));
-  return it->second;
+  auto it = channel_history_.upper_bound(timestamp);
+  return it == channel_history_.begin() ? -1 : std::prev(it)->second;
 }
 
 // Dispatches all queued input packets with known channels.
@@ -237,10 +238,12 @@
       auto& queue = input_queue_[input_id];
       while (!queue.empty() && queue.front().Timestamp() <= channel_settled) {
         int channel_index = ChannelIndex(queue.front().Timestamp());
-        std::string output_tag = tool::ChannelTag(tag, channel_index);
-        auto output_id = cc->Outputs().GetId(output_tag, index);
-        if (output_id.IsValid()) {
-          cc->Outputs().Get(output_id).AddPacket(queue.front());
+        if (channel_index != -1) {
+          std::string output_tag = tool::ChannelTag(tag, channel_index);
+          auto output_id = cc->Outputs().GetId(output_tag, index);
+          if (output_id.IsValid()) {
+            cc->Outputs().Get(output_id).AddPacket(queue.front());
+          }
         }
         queue.pop();
       }
diff --git a/third_party/mediapipe/src/mediapipe/framework/tool/tag_map.h b/third_party/mediapipe/src/mediapipe/framework/tool/tag_map.h
index 6ac23df0..e785acf 100644
--- a/third_party/mediapipe/src/mediapipe/framework/tool/tag_map.h
+++ b/third_party/mediapipe/src/mediapipe/framework/tool/tag_map.h
@@ -53,7 +53,7 @@
 
   // Create a TagMap from a repeated string proto field of TAG:<index>:name.
   // This is the most common usage:
-  // ASSIGN_OR_RETURN(std::shared_ptr<TagMap> tag_map,
+  // MP_ASSIGN_OR_RETURN(std::shared_ptr<TagMap> tag_map,
   //                  tool::TagMap::Create(node.input_streams()));
   static absl::StatusOr<std::shared_ptr<TagMap>> Create(
       const proto_ns::RepeatedPtrField<ProtoString>& tag_index_names) {
diff --git a/third_party/mediapipe/src/mediapipe/framework/tool/validate_name.cc b/third_party/mediapipe/src/mediapipe/framework/tool/validate_name.cc
index ad66b43d..8f9be76 100644
--- a/third_party/mediapipe/src/mediapipe/framework/tool/validate_name.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/tool/validate_name.cc
@@ -127,7 +127,7 @@
                    "\" does not match \"" MEDIAPIPE_TAG_REGEX "\"."));
 }
 
-absl::Status ParseTagAndName(const std::string& tag_and_name, std::string* tag,
+absl::Status ParseTagAndName(absl::string_view tag_and_name, std::string* tag,
                              std::string* name) {
   // An optional tag and colon, followed by a name.
   RET_CHECK(tag);
diff --git a/third_party/mediapipe/src/mediapipe/framework/tool/validate_name.h b/third_party/mediapipe/src/mediapipe/framework/tool/validate_name.h
index 274d0672..8646203 100644
--- a/third_party/mediapipe/src/mediapipe/framework/tool/validate_name.h
+++ b/third_party/mediapipe/src/mediapipe/framework/tool/validate_name.h
@@ -22,6 +22,7 @@
 #include <vector>
 
 #include "absl/base/macros.h"
+#include "absl/strings/string_view.h"
 #include "mediapipe/framework/port/proto_ns.h"
 #include "mediapipe/framework/port/status.h"
 
@@ -85,7 +86,7 @@
 // The format is an optional tag and colon, followed by a name.
 // Example 1: "VIDEO:frames2" -> tag: "VIDEO", name: "frames2"
 // Example 2: "video_frames_1" -> tag: "", name: "video_frames_1"
-absl::Status ParseTagAndName(const std::string& tag_and_name, std::string* tag,
+absl::Status ParseTagAndName(absl::string_view tag_and_name, std::string* tag,
                              std::string* name);
 
 // Parse a generic TAG:index:name string.  The format is a tag, then an
diff --git a/third_party/mediapipe/src/mediapipe/framework/tool/validate_type.cc b/third_party/mediapipe/src/mediapipe/framework/tool/validate_type.cc
index 38c04fa87..29c871d2 100644
--- a/third_party/mediapipe/src/mediapipe/framework/tool/validate_type.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/tool/validate_type.cc
@@ -46,7 +46,7 @@
   // side packet.
   PacketGeneratorConfig config = input_config;
 
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       auto static_access,
       internal::StaticAccessToGeneratorRegistry::CreateByNameInNamespace(
           package, config.packet_generator()),
@@ -81,7 +81,7 @@
     const std::string& package) {
   ABSL_CHECK(output_side_packets);
   // Get static access to functions.
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       auto static_access,
       internal::StaticAccessToGeneratorRegistry::CreateByNameInNamespace(
           package, packet_generator_name),
diff --git a/third_party/mediapipe/src/mediapipe/framework/validated_graph_config.cc b/third_party/mediapipe/src/mediapipe/framework/validated_graph_config.cc
index 4f91824..293d68d 100644
--- a/third_party/mediapipe/src/mediapipe/framework/validated_graph_config.cc
+++ b/third_party/mediapipe/src/mediapipe/framework/validated_graph_config.cc
@@ -216,10 +216,11 @@
   LegacyCalculatorSupport::Scoped<CalculatorContract> s(&contract_);
   // A number of calculators use the non-CC methods on GlCalculatorHelper
   // even though they are CalculatorBase-based.
-  ASSIGN_OR_RETURN(auto calculator_factory,
-                   CalculatorBaseRegistry::CreateByNameInNamespace(
-                       validated_graph.Package(), node_class),
-                   _ << "Unable to find Calculator \"" << node_class << "\"");
+  MP_ASSIGN_OR_RETURN(
+      auto calculator_factory,
+      CalculatorBaseRegistry::CreateByNameInNamespace(validated_graph.Package(),
+                                                      node_class),
+      _ << "Unable to find Calculator \"" << node_class << "\"");
   MP_RETURN_IF_ERROR(calculator_factory->GetContract(&contract_)).SetPrepend()
       << node_class << ": ";
 
@@ -261,7 +262,7 @@
 
   // Run FillExpectations.
   const std::string& node_class = node.packet_generator();
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       auto static_access,
       internal::StaticAccessToGeneratorRegistry::CreateByNameInNamespace(
           validated_graph.Package(), node_class),
@@ -302,7 +303,7 @@
 
   // Run FillExpectations.
   const std::string& node_class = node.status_handler();
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       auto static_access,
       internal::StaticAccessToStatusHandlerRegistry::CreateByNameInNamespace(
           validated_graph.Package(), node_class),
@@ -602,8 +603,8 @@
 absl::Status ValidatedGraphConfig::InitializeStreamInfo(
     bool* need_sorting_ptr) {
   // Define output streams for graph input streams.
-  ASSIGN_OR_RETURN(std::shared_ptr<tool::TagMap> graph_input_streams,
-                   tool::TagMap::Create(config_.input_stream()));
+  MP_ASSIGN_OR_RETURN(std::shared_ptr<tool::TagMap> graph_input_streams,
+                      tool::TagMap::Create(config_.input_stream()));
   for (int index = 0; index < graph_input_streams->Names().size(); ++index) {
     std::string name = graph_input_streams->Names()[index];
     owned_packet_types_.emplace_back(new PacketType());
diff --git a/third_party/mediapipe/src/mediapipe/gpu/BUILD b/third_party/mediapipe/src/mediapipe/gpu/BUILD
index b7c1a27..2c6d5a26 100644
--- a/third_party/mediapipe/src/mediapipe/gpu/BUILD
+++ b/third_party/mediapipe/src/mediapipe/gpu/BUILD
@@ -12,11 +12,11 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-load("@bazel_skylib//lib:selects.bzl", "selects")
+load("@bazel_skylib//lib:selects.bzl", "selects")  # buildifier: disable=out-of-order-load
 load("//mediapipe/gpu:metal.bzl", "metal_library")
 load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test")
-load("//mediapipe/framework/port:build_config.bzl", "mediapipe_proto_library")
-load("//mediapipe/framework:mediapipe_cc_test.bzl", "mediapipe_cc_test")
+load("//mediapipe/framework/port:build_config.bzl", "mediapipe_proto_library")  # buildifier: disable=out-of-order-load
+load("//mediapipe/framework:mediapipe_cc_test.bzl", "mediapipe_cc_test")  # buildifier: disable=out-of-order-load
 load("//mediapipe/framework:more_selects.bzl", "more_selects")
 
 licenses(["notice"])
diff --git a/third_party/mediapipe/src/mediapipe/gpu/gl_calculator_helper.cc b/third_party/mediapipe/src/mediapipe/gpu/gl_calculator_helper.cc
index 763ac38..1b113f8 100644
--- a/third_party/mediapipe/src/mediapipe/gpu/gl_calculator_helper.cc
+++ b/third_party/mediapipe/src/mediapipe/gpu/gl_calculator_helper.cc
@@ -56,8 +56,13 @@
 }
 
 // static
-absl::Status GlCalculatorHelper::UpdateContract(CalculatorContract* cc) {
-  cc->UseService(kGpuService);
+absl::Status GlCalculatorHelper::UpdateContract(CalculatorContract* cc,
+                                                bool requesst_gpu_as_optional) {
+  if (requesst_gpu_as_optional) {
+    cc->UseService(kGpuService).Optional();
+  } else {
+    cc->UseService(kGpuService);
+  }
   // Allow the legacy side packet to be provided, too, for backwards
   // compatibility with existing graphs. It will just be ignored.
   auto& input_side_packets = cc->InputSidePackets();
diff --git a/third_party/mediapipe/src/mediapipe/gpu/gl_calculator_helper.h b/third_party/mediapipe/src/mediapipe/gpu/gl_calculator_helper.h
index 300cc17..dc9651b 100644
--- a/third_party/mediapipe/src/mediapipe/gpu/gl_calculator_helper.h
+++ b/third_party/mediapipe/src/mediapipe/gpu/gl_calculator_helper.h
@@ -68,7 +68,8 @@
 
   // This method can be called from GetContract to set up the needed GPU
   // resources.
-  static absl::Status UpdateContract(CalculatorContract* cc);
+  static absl::Status UpdateContract(CalculatorContract* cc,
+                                     bool requesst_gpu_as_optional = false);
 
   // This method can be called from FillExpectations to set the correct types
   // for the shared GL input side packet(s).
diff --git a/third_party/mediapipe/src/mediapipe/gpu/gl_context_egl.cc b/third_party/mediapipe/src/mediapipe/gpu/gl_context_egl.cc
index bddf61c..ea35829 100644
--- a/third_party/mediapipe/src/mediapipe/gpu/gl_context_egl.cc
+++ b/third_party/mediapipe/src/mediapipe/gpu/gl_context_egl.cc
@@ -179,7 +179,7 @@
 }
 
 absl::Status GlContext::CreateContext(EGLContext share_context) {
-  ASSIGN_OR_RETURN(display_, GetInitializedEglDisplay());
+  MP_ASSIGN_OR_RETURN(display_, GetInitializedEglDisplay());
 
   auto status = CreateContextInternal(share_context, 3);
   if (!status.ok()) {
diff --git a/third_party/mediapipe/src/mediapipe/gpu/gpu_shared_data_internal.cc b/third_party/mediapipe/src/mediapipe/gpu/gpu_shared_data_internal.cc
index 1fa8135..3edb91f 100644
--- a/third_party/mediapipe/src/mediapipe/gpu/gpu_shared_data_internal.cc
+++ b/third_party/mediapipe/src/mediapipe/gpu/gpu_shared_data_internal.cc
@@ -74,7 +74,7 @@
 
 GpuResources::StatusOrGpuResources GpuResources::Create(
     PlatformGlContext external_context) {
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       std::shared_ptr<GlContext> context,
       GlContext::Create(external_context, kGlContextUseDedicatedThread));
   std::shared_ptr<GpuResources> gpu_resources(
@@ -148,8 +148,8 @@
 #endif  // !__EMSCRIPTEN__
   node_key_[node_id] = context_key;
 
-  ASSIGN_OR_RETURN(std::shared_ptr<GlContext> context,
-                   GetOrCreateGlContext(context_key));
+  MP_ASSIGN_OR_RETURN(std::shared_ptr<GlContext> context,
+                      GetOrCreateGlContext(context_key));
 
   if (kGlContextUseDedicatedThread) {
     std::string executor_name =
@@ -184,9 +184,9 @@
     const std::string& key) {
   auto it = gl_key_context_.find(key);
   if (it == gl_key_context_.end()) {
-    ASSIGN_OR_RETURN(std::shared_ptr<GlContext> new_context,
-                     GlContext::Create(*gl_key_context_[SharedContextKey()],
-                                       kGlContextUseDedicatedThread));
+    MP_ASSIGN_OR_RETURN(std::shared_ptr<GlContext> new_context,
+                        GlContext::Create(*gl_key_context_[SharedContextKey()],
+                                          kGlContextUseDedicatedThread));
     it = gl_key_context_.emplace(key, new_context).first;
 #if MEDIAPIPE_GPU_BUFFER_USE_CV_PIXEL_BUFFER
     texture_caches_->RegisterTextureCache(it->second->cv_texture_cache());
diff --git a/third_party/mediapipe/src/mediapipe/gpu/metal.bzl b/third_party/mediapipe/src/mediapipe/gpu/metal.bzl
index dcfb268..77129ba 100644
--- a/third_party/mediapipe/src/mediapipe/gpu/metal.bzl
+++ b/third_party/mediapipe/src/mediapipe/gpu/metal.bzl
@@ -107,6 +107,7 @@
             outputs = [obj, diagnostics, deps_dump],
             mnemonic = "MetalCompile",
             executable = "/usr/bin/xcrun",
+            toolchain = None,
             arguments = args,
             use_default_shell_env = False,
             progress_message = ("Compiling Metal shader %s" %
@@ -128,6 +129,7 @@
         outputs = (output_lib,),
         mnemonic = "MetalLink",
         executable = "/usr/bin/xcrun",
+        toolchain = None,
         arguments = args,
         progress_message = (
             "Linking Metal library %s" % ctx.label.name
diff --git a/third_party/mediapipe/src/mediapipe/modules/face_geometry/effect_renderer_calculator.cc b/third_party/mediapipe/src/mediapipe/modules/face_geometry/effect_renderer_calculator.cc
index f353b8f..ce83915 100644
--- a/third_party/mediapipe/src/mediapipe/modules/face_geometry/effect_renderer_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/modules/face_geometry/effect_renderer_calculator.cc
@@ -119,22 +119,22 @@
 
       absl::optional<face_geometry::Mesh3d> effect_mesh_3d;
       if (options.has_effect_mesh_3d_path()) {
-        ASSIGN_OR_RETURN(effect_mesh_3d,
-                         ReadMesh3dFromFile(options.effect_mesh_3d_path()),
-                         _ << "Failed to read the effect 3D mesh from file!");
+        MP_ASSIGN_OR_RETURN(
+            effect_mesh_3d, ReadMesh3dFromFile(options.effect_mesh_3d_path()),
+            _ << "Failed to read the effect 3D mesh from file!");
 
         MP_RETURN_IF_ERROR(face_geometry::ValidateMesh3d(*effect_mesh_3d))
             << "Invalid effect 3D mesh!";
       }
 
-      ASSIGN_OR_RETURN(ImageFrame effect_texture,
-                       ReadTextureFromFile(options.effect_texture_path()),
-                       _ << "Failed to read the effect texture from file!");
+      MP_ASSIGN_OR_RETURN(ImageFrame effect_texture,
+                          ReadTextureFromFile(options.effect_texture_path()),
+                          _ << "Failed to read the effect texture from file!");
 
-      ASSIGN_OR_RETURN(effect_renderer_,
-                       CreateEffectRenderer(environment, effect_mesh_3d,
-                                            std::move(effect_texture)),
-                       _ << "Failed to create the effect renderer!");
+      MP_ASSIGN_OR_RETURN(effect_renderer_,
+                          CreateEffectRenderer(environment, effect_mesh_3d,
+                                               std::move(effect_texture)),
+                          _ << "Failed to create the effect renderer!");
 
       return absl::OkStatus();
     });
@@ -202,9 +202,9 @@
  private:
   static absl::StatusOr<ImageFrame> ReadTextureFromFile(
       const std::string& texture_path) {
-    ASSIGN_OR_RETURN(std::string texture_blob,
-                     ReadContentBlobFromFile(texture_path),
-                     _ << "Failed to read texture blob from file!");
+    MP_ASSIGN_OR_RETURN(std::string texture_blob,
+                        ReadContentBlobFromFile(texture_path),
+                        _ << "Failed to read texture blob from file!");
 
     // Use OpenCV image decoding functionality to finish reading the texture.
     std::vector<char> texture_blob_vector(texture_blob.begin(),
@@ -246,9 +246,9 @@
 
   static absl::StatusOr<face_geometry::Mesh3d> ReadMesh3dFromFile(
       const std::string& mesh_3d_path) {
-    ASSIGN_OR_RETURN(std::string mesh_3d_blob,
-                     ReadContentBlobFromFile(mesh_3d_path),
-                     _ << "Failed to read mesh 3D blob from file!");
+    MP_ASSIGN_OR_RETURN(std::string mesh_3d_blob,
+                        ReadContentBlobFromFile(mesh_3d_path),
+                        _ << "Failed to read mesh 3D blob from file!");
 
     face_geometry::Mesh3d mesh_3d;
     RET_CHECK(mesh_3d.ParseFromString(mesh_3d_blob))
@@ -259,9 +259,10 @@
 
   static absl::StatusOr<std::string> ReadContentBlobFromFile(
       const std::string& unresolved_path) {
-    ASSIGN_OR_RETURN(std::string resolved_path,
-                     mediapipe::PathToResourceAsFile(unresolved_path),
-                     _ << "Failed to resolve path! Path = " << unresolved_path);
+    MP_ASSIGN_OR_RETURN(
+        std::string resolved_path,
+        mediapipe::PathToResourceAsFile(unresolved_path),
+        _ << "Failed to resolve path! Path = " << unresolved_path);
 
     std::string content_blob;
     MP_RETURN_IF_ERROR(
diff --git a/third_party/mediapipe/src/mediapipe/modules/face_geometry/geometry_pipeline_calculator.cc b/third_party/mediapipe/src/mediapipe/modules/face_geometry/geometry_pipeline_calculator.cc
index 87e710e..6aa98a5 100644
--- a/third_party/mediapipe/src/mediapipe/modules/face_geometry/geometry_pipeline_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/modules/face_geometry/geometry_pipeline_calculator.cc
@@ -92,7 +92,7 @@
 
     const auto& options = cc->Options<FaceGeometryPipelineCalculatorOptions>();
 
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         face_geometry::GeometryPipelineMetadata metadata,
         ReadMetadataFromFile(options.metadata_path()),
         _ << "Failed to read the geometry pipeline metadata from file!");
@@ -109,7 +109,7 @@
     MP_RETURN_IF_ERROR(face_geometry::ValidateEnvironment(environment))
         << "Invalid environment!";
 
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         geometry_pipeline_,
         face_geometry::CreateGeometryPipeline(environment, metadata),
         _ << "Failed to create a geometry pipeline!");
@@ -136,7 +136,7 @@
     auto multi_face_geometry =
         absl::make_unique<std::vector<face_geometry::FaceGeometry>>();
 
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         *multi_face_geometry,
         geometry_pipeline_->EstimateFaceGeometry(
             multi_face_landmarks,  //
@@ -160,9 +160,9 @@
  private:
   static absl::StatusOr<face_geometry::GeometryPipelineMetadata>
   ReadMetadataFromFile(const std::string& metadata_path) {
-    ASSIGN_OR_RETURN(std::string metadata_blob,
-                     ReadContentBlobFromFile(metadata_path),
-                     _ << "Failed to read a metadata blob from file!");
+    MP_ASSIGN_OR_RETURN(std::string metadata_blob,
+                        ReadContentBlobFromFile(metadata_path),
+                        _ << "Failed to read a metadata blob from file!");
 
     face_geometry::GeometryPipelineMetadata metadata;
     RET_CHECK(metadata.ParseFromString(metadata_blob))
@@ -173,9 +173,10 @@
 
   static absl::StatusOr<std::string> ReadContentBlobFromFile(
       const std::string& unresolved_path) {
-    ASSIGN_OR_RETURN(std::string resolved_path,
-                     mediapipe::PathToResourceAsFile(unresolved_path),
-                     _ << "Failed to resolve path! Path = " << unresolved_path);
+    MP_ASSIGN_OR_RETURN(
+        std::string resolved_path,
+        mediapipe::PathToResourceAsFile(unresolved_path),
+        _ << "Failed to resolve path! Path = " << unresolved_path);
 
     std::string content_blob;
     MP_RETURN_IF_ERROR(
diff --git a/third_party/mediapipe/src/mediapipe/modules/face_geometry/libs/effect_renderer.cc b/third_party/mediapipe/src/mediapipe/modules/face_geometry/libs/effect_renderer.cc
index 73f47308..90e2c2f 100644
--- a/third_party/mediapipe/src/mediapipe/modules/face_geometry/libs/effect_renderer.cc
+++ b/third_party/mediapipe/src/mediapipe/modules/face_geometry/libs/effect_renderer.cc
@@ -48,19 +48,19 @@
 
     RenderableMesh3d renderable_mesh_3d;
     renderable_mesh_3d.vertex_size = GetVertexSize(vertex_type);
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         renderable_mesh_3d.vertex_position_size,
         GetVertexComponentSize(vertex_type, VertexComponent::POSITION),
         _ << "Failed to get the position vertex size!");
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         renderable_mesh_3d.tex_coord_position_size,
         GetVertexComponentSize(vertex_type, VertexComponent::TEX_COORD),
         _ << "Failed to get the tex coord vertex size!");
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         renderable_mesh_3d.vertex_position_offset,
         GetVertexComponentOffset(vertex_type, VertexComponent::POSITION),
         _ << "Failed to get the position vertex offset!");
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         renderable_mesh_3d.tex_coord_position_offset,
         GetVertexComponentOffset(vertex_type, VertexComponent::TEX_COORD),
         _ << "Failed to get the tex coord vertex offset!");
@@ -473,12 +473,12 @@
     }
 
     // Wrap both source and destination textures.
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         std::unique_ptr<Texture> src_texture,
         Texture::WrapExternalTexture(src_texture_name, src_texture_target,
                                      frame_width, frame_height),
         _ << "Failed to wrap the external source texture");
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         std::unique_ptr<Texture> dst_texture,
         Texture::WrapExternalTexture(dst_texture_name, dst_texture_target,
                                      frame_width, frame_height),
@@ -506,14 +506,14 @@
       const FaceGeometry& face_geometry = multi_face_geometry[i];
 
       // Extract the face pose transformation matrix.
-      ASSIGN_OR_RETURN(
+      MP_ASSIGN_OR_RETURN(
           face_pose_transform_matrices[i],
           Convert4x4MatrixDataToArrayFormat(
               face_geometry.pose_transform_matrix()),
           _ << "Failed to extract the face pose transformation matrix!");
 
       // Extract the face mesh as a renderable.
-      ASSIGN_OR_RETURN(
+      MP_ASSIGN_OR_RETURN(
           renderable_face_meshes[i],
           RenderableMesh3d::CreateFromProtoMesh3d(face_geometry.mesh()),
           _ << "Failed to extract a renderable face mesh!");
@@ -699,26 +699,28 @@
         << "Invalid effect 3D mesh!";
   }
 
-  ASSIGN_OR_RETURN(std::unique_ptr<RenderTarget> render_target,
-                   RenderTarget::Create(),
-                   _ << "Failed to create a render target!");
-  ASSIGN_OR_RETURN(std::unique_ptr<Renderer> renderer, Renderer::Create(),
-                   _ << "Failed to create a renderer!");
-  ASSIGN_OR_RETURN(RenderableMesh3d renderable_quad_mesh_3d,
-                   RenderableMesh3d::CreateFromProtoMesh3d(CreateQuadMesh3d()),
-                   _ << "Failed to create a renderable quad mesh!");
+  MP_ASSIGN_OR_RETURN(std::unique_ptr<RenderTarget> render_target,
+                      RenderTarget::Create(),
+                      _ << "Failed to create a render target!");
+  MP_ASSIGN_OR_RETURN(std::unique_ptr<Renderer> renderer, Renderer::Create(),
+                      _ << "Failed to create a renderer!");
+  MP_ASSIGN_OR_RETURN(
+      RenderableMesh3d renderable_quad_mesh_3d,
+      RenderableMesh3d::CreateFromProtoMesh3d(CreateQuadMesh3d()),
+      _ << "Failed to create a renderable quad mesh!");
   absl::optional<RenderableMesh3d> renderable_effect_mesh_3d;
   if (effect_mesh_3d) {
-    ASSIGN_OR_RETURN(renderable_effect_mesh_3d,
-                     RenderableMesh3d::CreateFromProtoMesh3d(*effect_mesh_3d),
-                     _ << "Failed to create a renderable effect mesh!");
+    MP_ASSIGN_OR_RETURN(
+        renderable_effect_mesh_3d,
+        RenderableMesh3d::CreateFromProtoMesh3d(*effect_mesh_3d),
+        _ << "Failed to create a renderable effect mesh!");
   }
-  ASSIGN_OR_RETURN(std::unique_ptr<Texture> empty_color_gl_texture,
-                   Texture::CreateFromImageFrame(CreateEmptyColorTexture()),
-                   _ << "Failed to create an empty color texture!");
-  ASSIGN_OR_RETURN(std::unique_ptr<Texture> effect_gl_texture,
-                   Texture::CreateFromImageFrame(effect_texture),
-                   _ << "Failed to create an effect texture!");
+  MP_ASSIGN_OR_RETURN(std::unique_ptr<Texture> empty_color_gl_texture,
+                      Texture::CreateFromImageFrame(CreateEmptyColorTexture()),
+                      _ << "Failed to create an empty color texture!");
+  MP_ASSIGN_OR_RETURN(std::unique_ptr<Texture> effect_gl_texture,
+                      Texture::CreateFromImageFrame(effect_texture),
+                      _ << "Failed to create an effect texture!");
 
   std::unique_ptr<EffectRenderer> result =
       absl::make_unique<EffectRendererImpl>(
diff --git a/third_party/mediapipe/src/mediapipe/modules/face_geometry/libs/geometry_pipeline.cc b/third_party/mediapipe/src/mediapipe/modules/face_geometry/libs/geometry_pipeline.cc
index bcfce7c..3d00f8a 100644
--- a/third_party/mediapipe/src/mediapipe/modules/face_geometry/libs/geometry_pipeline.cc
+++ b/third_party/mediapipe/src/mediapipe/modules/face_geometry/libs/geometry_pipeline.cc
@@ -142,9 +142,9 @@
     Eigen::Matrix3Xf intermediate_landmarks(screen_landmarks);
     ChangeHandedness(intermediate_landmarks);
 
-    ASSIGN_OR_RETURN(const float first_iteration_scale,
-                     EstimateScale(intermediate_landmarks),
-                     _ << "Failed to estimate first iteration scale!");
+    MP_ASSIGN_OR_RETURN(const float first_iteration_scale,
+                        EstimateScale(intermediate_landmarks),
+                        _ << "Failed to estimate first iteration scale!");
 
     // 2nd iteration: unproject XY using the scale from the 1st iteration.
     intermediate_landmarks = screen_landmarks;
@@ -167,9 +167,9 @@
            canonical_metric_landmarks_.colwise().homogeneous())
               .row(2);
     }
-    ASSIGN_OR_RETURN(const float second_iteration_scale,
-                     EstimateScale(intermediate_landmarks),
-                     _ << "Failed to estimate second iteration scale!");
+    MP_ASSIGN_OR_RETURN(const float second_iteration_scale,
+                        EstimateScale(intermediate_landmarks),
+                        _ << "Failed to estimate second iteration scale!");
 
     // Use the total scale to unproject the screen landmarks.
     const float total_scale = first_iteration_scale * second_iteration_scale;
diff --git a/third_party/mediapipe/src/mediapipe/modules/face_geometry/libs/procrustes_solver.cc b/third_party/mediapipe/src/mediapipe/modules/face_geometry/libs/procrustes_solver.cc
index 2ffae0e..2a29519 100644
--- a/third_party/mediapipe/src/mediapipe/modules/face_geometry/libs/procrustes_solver.cc
+++ b/third_party/mediapipe/src/mediapipe/modules/face_geometry/libs/procrustes_solver.cc
@@ -172,7 +172,7 @@
     MP_RETURN_IF_ERROR(ComputeOptimalRotation(
         weighted_targets * centered_weighted_sources.transpose(), rotation))
         << "Failed to compute the optimal rotation!";
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         float scale,
         ComputeOptimalScale(centered_weighted_sources, weighted_sources,
                             weighted_targets, rotation),
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/BUILD b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/BUILD
index fd00261..4bb5808 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/BUILD
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/BUILD
@@ -71,3 +71,53 @@
         "@com_google_googletest//:gtest_main",
     ],
 )
+
+cc_library(
+    name = "embedding_result",
+    hdrs = ["embedding_result.h"],
+)
+
+cc_library(
+    name = "embedding_result_converter",
+    srcs = ["embedding_result_converter.cc"],
+    hdrs = ["embedding_result_converter.h"],
+    deps = [
+        ":embedding_result",
+        "//mediapipe/tasks/cc/components/containers:embedding_result",
+    ],
+)
+
+cc_test(
+    name = "embedding_result_converter_test",
+    srcs = ["embedding_result_converter_test.cc"],
+    deps = [
+        ":embedding_result",
+        ":embedding_result_converter",
+        "//mediapipe/framework/port:gtest",
+        "//mediapipe/tasks/cc/components/containers:embedding_result",
+        "@com_google_googletest//:gtest_main",
+    ],
+)
+
+cc_library(
+    name = "language_detection_result_converter",
+    srcs = ["language_detection_result_converter.cc"],
+    hdrs = ["language_detection_result_converter.h"],
+    deps = [
+        "//mediapipe/tasks/c/text/language_detector",
+        "//mediapipe/tasks/cc/text/language_detector",
+    ],
+)
+
+cc_test(
+    name = "language_detection_result_converter_test",
+    srcs = ["language_detection_result_converter_test.cc"],
+    linkstatic = 1,
+    deps = [
+        ":language_detection_result_converter",
+        "//mediapipe/framework/port:gtest",
+        "//mediapipe/tasks/c/text/language_detector",
+        "//mediapipe/tasks/cc/text/language_detector",
+        "@com_google_googletest//:gtest_main",
+    ],
+)
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/category_converter.cc b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/category_converter.cc
new file mode 100644
index 0000000..b04f86c9
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/category_converter.cc
@@ -0,0 +1,44 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "mediapipe/tasks/c/components/containers/category_converter.h"
+
+#include <cstdlib>
+
+#include "mediapipe/tasks/c/components/containers/category.h"
+#include "mediapipe/tasks/cc/components/containers/category.h"
+
+namespace mediapipe::tasks::c::components::containers {
+
+void CppConvertToCategory(
+    const mediapipe::tasks::components::containers::Category& in,
+    Category* out) {
+  out->index = in.index;
+  out->score = in.score;
+  out->category_name = in.category_name.has_value()
+                           ? strdup(in.category_name->c_str())
+                           : nullptr;
+  out->display_name =
+      in.display_name.has_value() ? strdup(in.display_name->c_str()) : nullptr;
+}
+
+void CppCloseCategory(Category* in) {
+  free(in->category_name);
+  in->category_name = nullptr;
+  free(in->display_name);
+  in->display_name = nullptr;
+}
+
+}  // namespace mediapipe::tasks::c::components::containers
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/category_converter.h b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/category_converter.h
new file mode 100644
index 0000000..9edf539b
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/category_converter.h
@@ -0,0 +1,32 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#ifndef MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_CATEGORY_CONVERTER_H_
+#define MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_CATEGORY_CONVERTER_H_
+
+#include "mediapipe/tasks/c/components/containers/category.h"
+#include "mediapipe/tasks/cc/components/containers/category.h"
+
+namespace mediapipe::tasks::c::components::containers {
+
+void CppConvertToCategory(
+    const mediapipe::tasks::components::containers::Category& in,
+    Category* out);
+
+void CppCloseCategory(Category* in);
+
+}  // namespace mediapipe::tasks::c::components::containers
+
+#endif  // MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_CATEGORY_CONVERTER_H_
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/classification_result_converter.cc b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/classification_result_converter.cc
new file mode 100644
index 0000000..b7190c9
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/classification_result_converter.cc
@@ -0,0 +1,79 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "mediapipe/tasks/c/components/containers/classification_result_converter.h"
+
+#include <cstdint>
+#include <cstdlib>
+
+#include "mediapipe/tasks/c/components/containers/category.h"
+#include "mediapipe/tasks/c/components/containers/category_converter.h"
+#include "mediapipe/tasks/c/components/containers/classification_result.h"
+#include "mediapipe/tasks/cc/components/containers/classification_result.h"
+
+namespace mediapipe::tasks::c::components::containers {
+
+void CppConvertToClassificationResult(
+    const mediapipe::tasks::components::containers::ClassificationResult& in,
+    ClassificationResult* out) {
+  out->has_timestamp_ms = in.timestamp_ms.has_value();
+  out->timestamp_ms = out->has_timestamp_ms ? in.timestamp_ms.value() : 0;
+
+  out->classifications_count = in.classifications.size();
+  out->classifications = out->classifications_count
+                             ? new Classifications[out->classifications_count]
+                             : nullptr;
+
+  for (uint32_t i = 0; i < out->classifications_count; ++i) {
+    auto classification_in = in.classifications[i];
+    auto& classification_out = out->classifications[i];
+
+    classification_out.categories_count = classification_in.categories.size();
+    classification_out.categories =
+        classification_out.categories_count
+            ? new Category[classification_out.categories_count]
+            : nullptr;
+    for (uint32_t j = 0; j < classification_out.categories_count; ++j) {
+      CppConvertToCategory(classification_in.categories[j],
+                           &(classification_out.categories[j]));
+    }
+
+    classification_out.head_index = classification_in.head_index;
+    classification_out.head_name =
+        classification_in.head_name.has_value()
+            ? strdup(classification_in.head_name->c_str())
+            : nullptr;
+  }
+}
+
+void CppCloseClassificationResult(ClassificationResult* in) {
+  for (uint32_t i = 0; i < in->classifications_count; ++i) {
+    auto& classification_in = in->classifications[i];
+
+    for (uint32_t j = 0; j < classification_in.categories_count; ++j) {
+      CppCloseCategory(&classification_in.categories[j]);
+    }
+    delete[] classification_in.categories;
+    classification_in.categories = nullptr;
+
+    free(classification_in.head_name);
+    classification_in.head_name = nullptr;
+  }
+
+  delete[] in->classifications;
+  in->classifications = nullptr;
+}
+
+}  // namespace mediapipe::tasks::c::components::containers
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/classification_result_converter.h b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/classification_result_converter.h
new file mode 100644
index 0000000..2e84d019
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/classification_result_converter.h
@@ -0,0 +1,32 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#ifndef MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_CLASSIFICATION_RESULT_CONVERTER_H_
+#define MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_CLASSIFICATION_RESULT_CONVERTER_H_
+
+#include "mediapipe/tasks/c/components/containers/classification_result.h"
+#include "mediapipe/tasks/cc/components/containers/classification_result.h"
+
+namespace mediapipe::tasks::c::components::containers {
+
+void CppConvertToClassificationResult(
+    const mediapipe::tasks::components::containers::ClassificationResult& in,
+    ClassificationResult* out);
+
+void CppCloseClassificationResult(ClassificationResult* in);
+
+}  // namespace mediapipe::tasks::c::components::containers
+
+#endif  // MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_CLASSIFICATION_RESULT_CONVERTER_H_
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/embedding_result.h b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/embedding_result.h
new file mode 100644
index 0000000..62735628
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/embedding_result.h
@@ -0,0 +1,79 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#ifndef MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_EMBEDDING_RESULT_H_
+#define MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_EMBEDDING_RESULT_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Embedding result for a given embedder head.
+//
+// One and only one of the two 'float_embedding' and 'quantized_embedding' will
+// contain data, based on whether or not the embedder was configured to perform
+// scalar quantization.
+struct Embedding {
+  // Floating-point embedding. `nullptr` if the embedder was configured to
+  // perform scalar-quantization.
+  float* float_embedding;
+
+  // Scalar-quantized embedding. `nullptr` if the embedder was not configured to
+  // perform scalar quantization.
+  char* quantized_embedding;
+
+  // Keep the count of embedding values.
+  uint32_t values_count;
+
+  // The index of the embedder head (i.e. output tensor) this embedding comes
+  // from. This is useful for multi-head models.
+  int head_index;
+
+  // The optional name of the embedder head, as provided in the TFLite Model
+  // Metadata [1] if present. This is useful for multi-head models.
+  // Defaults to nullptr.
+  //
+  // [1]: https://www.tensorflow.org/lite/convert/metadata
+  char* head_name;
+};
+
+// Defines embedding results of a model.
+struct EmbeddingResult {
+  // The embedding results for each head of the model.
+  struct Embedding* embeddings;
+
+  // Keep the count of embeddings.
+  uint32_t embeddings_count;
+
+  // The optional timestamp (in milliseconds) of the start of the chunk of data
+  // corresponding to these results.
+  //
+  // This is only used for embedding extraction on time series (e.g. audio
+  // embedding). In these use cases, the amount of data to process might
+  // exceed the maximum size that the model can process: to solve this, the
+  // input data is split into multiple chunks starting at different timestamps.
+  int64_t timestamp_ms;
+
+  // Specifies whether the timestamp contains a valid value.
+  bool has_timestamp_ms;
+};
+
+#ifdef __cplusplus
+}  // extern C
+#endif
+
+#endif  // MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_EMBEDDING_RESULT_H_
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/embedding_result_converter.cc b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/embedding_result_converter.cc
new file mode 100644
index 0000000..ba72c0994
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/embedding_result_converter.cc
@@ -0,0 +1,84 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "mediapipe/tasks/c/components/containers/embedding_result_converter.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <cstdlib>
+
+#include "mediapipe/tasks/c/components/containers/embedding_result.h"
+#include "mediapipe/tasks/cc/components/containers/embedding_result.h"
+
+namespace mediapipe::tasks::c::components::containers {
+
+void CppConvertToEmbeddingResult(
+    const mediapipe::tasks::components::containers::EmbeddingResult& in,
+    EmbeddingResult* out) {
+  out->has_timestamp_ms = in.timestamp_ms.has_value();
+  out->timestamp_ms = out->has_timestamp_ms ? in.timestamp_ms.value() : 0;
+
+  out->embeddings_count = in.embeddings.size();
+  out->embeddings =
+      out->embeddings_count ? new Embedding[out->embeddings_count] : nullptr;
+
+  for (uint32_t i = 0; i < out->embeddings_count; ++i) {
+    auto embedding_in = in.embeddings[i];
+    auto& embedding_out = out->embeddings[i];
+    if (!embedding_in.float_embedding.empty()) {
+      // Handle float embeddings
+      embedding_out.values_count = embedding_in.float_embedding.size();
+      embedding_out.float_embedding = new float[embedding_out.values_count];
+
+      std::copy(embedding_in.float_embedding.begin(),
+                embedding_in.float_embedding.end(),
+                embedding_out.float_embedding);
+
+      embedding_out.quantized_embedding = nullptr;
+    } else if (!embedding_in.quantized_embedding.empty()) {
+      // Handle quantized embeddings
+      embedding_out.values_count = embedding_in.quantized_embedding.size();
+      embedding_out.quantized_embedding = new char[embedding_out.values_count];
+
+      std::copy(embedding_in.quantized_embedding.begin(),
+                embedding_in.quantized_embedding.end(),
+                embedding_out.quantized_embedding);
+
+      embedding_out.float_embedding = nullptr;
+    }
+
+    embedding_out.head_index = embedding_in.head_index;
+    embedding_out.head_name = embedding_in.head_name.has_value()
+                                  ? strdup(embedding_in.head_name->c_str())
+                                  : nullptr;
+  }
+}
+
+void CppCloseEmbeddingResult(EmbeddingResult* in) {
+  for (uint32_t i = 0; i < in->embeddings_count; ++i) {
+    auto embedding_in = in->embeddings[i];
+
+    delete[] embedding_in.float_embedding;
+    delete[] embedding_in.quantized_embedding;
+    embedding_in.float_embedding = nullptr;
+    embedding_in.quantized_embedding = nullptr;
+
+    free(embedding_in.head_name);
+  }
+  delete[] in->embeddings;
+  in->embeddings = nullptr;
+}
+
+}  // namespace mediapipe::tasks::c::components::containers
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/embedding_result_converter.h b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/embedding_result_converter.h
new file mode 100644
index 0000000..15bcdbd
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/embedding_result_converter.h
@@ -0,0 +1,38 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#ifndef MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_EMBEDDING_RESULT_CONVERTER_H_
+#define MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_EMBEDDING_RESULT_CONVERTER_H_
+
+#include "mediapipe/tasks/c/components/containers/embedding_result.h"
+#include "mediapipe/tasks/cc/components/containers/embedding_result.h"
+
+namespace mediapipe::tasks::c::components::containers {
+
+void CppConvertToEmbedding(
+    const mediapipe::tasks::components::containers::EmbeddingResult& in,
+    Embedding* out);
+
+void CppConvertToEmbeddingResult(
+    const mediapipe::tasks::components::containers::EmbeddingResult& in,
+    EmbeddingResult* out);
+
+void CppCloseEmbedding(Embedding* in);
+
+void CppCloseEmbeddingResult(EmbeddingResult* in);
+
+}  // namespace mediapipe::tasks::c::components::containers
+
+#endif  // MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_EMBEDDING_RESULT_CONVERTER_H_
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/language_detection_result_converter.cc b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/language_detection_result_converter.cc
new file mode 100644
index 0000000..89b112e
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/language_detection_result_converter.cc
@@ -0,0 +1,56 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "mediapipe/tasks/c/components/containers/language_detection_result_converter.h"
+
+#include <cstdint>
+#include <cstdlib>
+
+#include "mediapipe/tasks/c/text/language_detector/language_detector.h"
+#include "mediapipe/tasks/cc/text/language_detector/language_detector.h"
+
+namespace mediapipe::tasks::c::components::containers {
+
+void CppConvertToLanguageDetectionResult(
+    const mediapipe::tasks::text::language_detector::LanguageDetectorResult& in,
+    LanguageDetectorResult* out) {
+  out->predictions_count = in.size();
+  out->predictions =
+      out->predictions_count
+          ? new LanguageDetectorPrediction[out->predictions_count]
+          : nullptr;
+
+  for (uint32_t i = 0; i < out->predictions_count; ++i) {
+    auto language_detection_prediction_in = in[i];
+    auto& language_detection_prediction_out = out->predictions[i];
+    language_detection_prediction_out.probability =
+        language_detection_prediction_in.probability;
+    language_detection_prediction_out.language_code =
+        strdup(language_detection_prediction_in.language_code.c_str());
+  }
+}
+
+void CppCloseLanguageDetectionResult(LanguageDetectorResult* in) {
+  for (uint32_t i = 0; i < in->predictions_count; ++i) {
+    auto prediction_in = in->predictions[i];
+
+    free(prediction_in.language_code);
+    prediction_in.language_code = nullptr;
+  }
+  delete[] in->predictions;
+  in->predictions = nullptr;
+}
+
+}  // namespace mediapipe::tasks::c::components::containers
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/language_detection_result_converter.h b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/language_detection_result_converter.h
new file mode 100644
index 0000000..c9cfd55b
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/containers/language_detection_result_converter.h
@@ -0,0 +1,32 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#ifndef MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_LANGUAGE_DETECTION_RESULT_CONVERTER_H_
+#define MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_LANGUAGE_DETECTION_RESULT_CONVERTER_H_
+
+#include "mediapipe/tasks/c/text/language_detector/language_detector.h"
+#include "mediapipe/tasks/cc/text/language_detector/language_detector.h"
+
+namespace mediapipe::tasks::c::components::containers {
+
+void CppConvertToLanguageDetectionResult(
+    const mediapipe::tasks::text::language_detector::LanguageDetectorResult& in,
+    LanguageDetectorResult* out);
+
+void CppCloseLanguageDetectionResult(LanguageDetectorResult* in);
+
+}  // namespace mediapipe::tasks::c::components::containers
+
+#endif  // MEDIAPIPE_TASKS_C_COMPONENTS_CONTAINERS_LANGUAGE_DETECTION_RESULT_CONVERTER_H_
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/BUILD b/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/BUILD
index e90437d..dbc7c82 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/BUILD
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/BUILD
@@ -30,3 +30,42 @@
         "//mediapipe/tasks/cc/components/processors:classifier_options",
     ],
 )
+
+cc_test(
+    name = "classifier_options_converter_test",
+    srcs = ["classifier_options_converter_test.cc"],
+    deps = [
+        ":classifier_options",
+        ":classifier_options_converter",
+        "//mediapipe/framework/port:gtest",
+        "//mediapipe/tasks/cc/components/processors:classifier_options",
+        "@com_google_googletest//:gtest_main",
+    ],
+)
+
+cc_library(
+    name = "embedder_options",
+    hdrs = ["embedder_options.h"],
+)
+
+cc_library(
+    name = "embedder_options_converter",
+    srcs = ["embedder_options_converter.cc"],
+    hdrs = ["embedder_options_converter.h"],
+    deps = [
+        ":embedder_options",
+        "//mediapipe/tasks/cc/components/processors:embedder_options",
+    ],
+)
+
+cc_test(
+    name = "embedder_options_converter_test",
+    srcs = ["embedder_options_converter_test.cc"],
+    deps = [
+        ":embedder_options",
+        ":embedder_options_converter",
+        "//mediapipe/framework/port:gtest",
+        "//mediapipe/tasks/cc/components/processors:embedder_options",
+        "@com_google_googletest//:gtest_main",
+    ],
+)
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/classifier_options.h b/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/classifier_options.h
index 4658fb4..32ad22b 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/classifier_options.h
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/classifier_options.h
@@ -26,7 +26,7 @@
 struct ClassifierOptions {
   // The locale to use for display names specified through the TFLite Model
   // Metadata, if any. Defaults to English.
-  char* display_names_locale;
+  const char* display_names_locale;
 
   // The maximum number of top-scored classification results to return. If < 0,
   // all available results will be returned. If 0, an invalid argument error is
@@ -40,14 +40,14 @@
   // The allowlist of category names. If non-empty, detection results whose
   // category name is not in this set will be filtered out. Duplicate or unknown
   // category names are ignored. Mutually exclusive with category_denylist.
-  char** category_allowlist;
+  const char** category_allowlist;
   // The number of elements in the category allowlist.
   uint32_t category_allowlist_count;
 
   // The denylist of category names. If non-empty, detection results whose
   // category name is in this set will be filtered out. Duplicate or unknown
   // category names are ignored. Mutually exclusive with category_allowlist.
-  char** category_denylist;
+  const char** category_denylist;
   // The number of elements in the category denylist.
   uint32_t category_denylist_count;
 };
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/classifier_options_converter.cc b/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/classifier_options_converter.cc
new file mode 100644
index 0000000..2a026ba
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/classifier_options_converter.cc
@@ -0,0 +1,43 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+#include "mediapipe/tasks/c/components/processors/classifier_options.h"
+#include "mediapipe/tasks/cc/components/processors/classifier_options.h"
+
+namespace mediapipe::tasks::c::components::processors {
+
+void CppConvertToClassifierOptions(
+    const ClassifierOptions& in,
+    mediapipe::tasks::components::processors::ClassifierOptions* out) {
+  out->display_names_locale =
+      in.display_names_locale ? std::string(in.display_names_locale) : "en";
+  out->max_results = in.max_results;
+  out->score_threshold = in.score_threshold;
+  out->category_allowlist =
+      std::vector<std::string>(in.category_allowlist_count);
+  for (uint32_t i = 0; i < in.category_allowlist_count; ++i) {
+    out->category_allowlist[i] = in.category_allowlist[i];
+  }
+  out->category_denylist = std::vector<std::string>(in.category_denylist_count);
+  for (uint32_t i = 0; i < in.category_denylist_count; ++i) {
+    out->category_denylist[i] = in.category_denylist[i];
+  }
+}
+
+}  // namespace mediapipe::tasks::c::components::processors
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/classifier_options_converter.h b/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/classifier_options_converter.h
new file mode 100644
index 0000000..2daa5c1
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/classifier_options_converter.h
@@ -0,0 +1,30 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#ifndef MEDIAPIPE_TASKS_C_COMPONENTS_PROCESSORS_CLASSIFIER_OPTIONS_CONVERTER_H_
+#define MEDIAPIPE_TASKS_C_COMPONENTS_PROCESSORS_CLASSIFIER_OPTIONS_CONVERTER_H_
+
+#include "mediapipe/tasks/c/components/processors/classifier_options.h"
+#include "mediapipe/tasks/cc/components/processors/classifier_options.h"
+
+namespace mediapipe::tasks::c::components::processors {
+
+void CppConvertToClassifierOptions(
+    const ClassifierOptions& in,
+    mediapipe::tasks::components::processors::ClassifierOptions* out);
+
+}  // namespace mediapipe::tasks::c::components::processors
+
+#endif  // MEDIAPIPE_TASKS_C_COMPONENTS_PROCESSORS_CLASSIFIER_OPTIONS_CONVERTER_H_
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/embedder_options.h b/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/embedder_options.h
new file mode 100644
index 0000000..99466dc
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/embedder_options.h
@@ -0,0 +1,42 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#ifndef MEDIAPIPE_TASKS_C_COMPONENTS_PROCESSORS_EMBEDDER_OPTIONS_H_
+#define MEDIAPIPE_TASKS_C_COMPONENTS_PROCESSORS_EMBEDDER_OPTIONS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Embedder options for MediaPipe C embedding extraction tasks.
+struct EmbedderOptions {
+  // Whether to normalize the returned feature vector with L2 norm. Use this
+  // option only if the model does not already contain a native L2_NORMALIZATION
+  // TF Lite Op. In most cases, this is already the case and L2 norm is thus
+  // achieved through TF Lite inference.
+  bool l2_normalize;
+
+  // Whether the returned embedding should be quantized to bytes via scalar
+  // quantization. Embeddings are implicitly assumed to be unit-norm and
+  // therefore any dimension is guaranteed to have a value in [-1.0, 1.0]. Use
+  // the l2_normalize option if this is not the case.
+  bool quantize;
+};
+
+#ifdef __cplusplus
+}  // extern C
+#endif
+
+#endif  // MEDIAPIPE_TASKS_C_COMPONENTS_PROCESSORS_EMBEDDER_OPTIONS_H_
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/embedder_options_converter.cc b/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/embedder_options_converter.cc
new file mode 100644
index 0000000..db1ac87a
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/embedder_options_converter.cc
@@ -0,0 +1,28 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "mediapipe/tasks/c/components/processors/embedder_options.h"
+#include "mediapipe/tasks/cc/components/processors/embedder_options.h"
+
+namespace mediapipe::tasks::c::components::processors {
+
+void CppConvertToEmbedderOptions(
+    const EmbedderOptions& in,
+    mediapipe::tasks::components::processors::EmbedderOptions* out) {
+  out->l2_normalize = in.l2_normalize;
+  out->quantize = in.quantize;
+}
+
+}  // namespace mediapipe::tasks::c::components::processors
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/embedder_options_converter.h b/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/embedder_options_converter.h
new file mode 100644
index 0000000..16b3c52
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/components/processors/embedder_options_converter.h
@@ -0,0 +1,30 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#ifndef MEDIAPIPE_TASKS_C_COMPONENTS_PROCESSORS_EMBEDDER_OPTIONS_CONVERTER_H_
+#define MEDIAPIPE_TASKS_C_COMPONENTS_PROCESSORS_EMBEDDER_OPTIONS_CONVERTER_H_
+
+#include "mediapipe/tasks/c/components/processors/embedder_options.h"
+#include "mediapipe/tasks/cc/components/processors/embedder_options.h"
+
+namespace mediapipe::tasks::c::components::processors {
+
+void CppConvertToEmbedderOptions(
+    const EmbedderOptions& in,
+    mediapipe::tasks::components::processors::EmbedderOptions* out);
+
+}  // namespace mediapipe::tasks::c::components::processors
+
+#endif  // MEDIAPIPE_TASKS_C_COMPONENTS_PROCESSORS_EMBEDDER_OPTIONS_CONVERTER_H_
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/core/BUILD b/third_party/mediapipe/src/mediapipe/tasks/c/core/BUILD
index 9a360404..a7c3aa9c 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/c/core/BUILD
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/core/BUILD
@@ -30,3 +30,15 @@
         "//mediapipe/tasks/cc/core:base_options",
     ],
 )
+
+cc_test(
+    name = "base_options_converter_test",
+    srcs = ["base_options_converter_test.cc"],
+    deps = [
+        ":base_options",
+        ":base_options_converter",
+        "//mediapipe/framework/port:gtest",
+        "//mediapipe/tasks/cc/core:base_options",
+        "@com_google_googletest//:gtest_main",
+    ],
+)
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/core/base_options.h b/third_party/mediapipe/src/mediapipe/tasks/c/core/base_options.h
index d23b688..78d89ce 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/c/core/base_options.h
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/core/base_options.h
@@ -23,10 +23,10 @@
 // Base options for MediaPipe C Tasks.
 struct BaseOptions {
   // The model asset file contents as a string.
-  char* model_asset_buffer;
+  const char* model_asset_buffer;
 
   // The path to the model asset to open and mmap in memory.
-  char* model_asset_path;
+  const char* model_asset_path;
 };
 
 #ifdef __cplusplus
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/core/base_options_converter.cc b/third_party/mediapipe/src/mediapipe/tasks/c/core/base_options_converter.cc
new file mode 100644
index 0000000..3f12616
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/core/base_options_converter.cc
@@ -0,0 +1,36 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "mediapipe/tasks/c/core/base_options_converter.h"
+
+#include <memory>
+#include <string>
+
+#include "mediapipe/tasks/c/core/base_options.h"
+#include "mediapipe/tasks/cc/core/base_options.h"
+
+namespace mediapipe::tasks::c::core {
+
+void CppConvertToBaseOptions(const BaseOptions& in,
+                             mediapipe::tasks::core::BaseOptions* out) {
+  out->model_asset_buffer =
+      in.model_asset_buffer
+          ? std::make_unique<std::string>(in.model_asset_buffer)
+          : nullptr;
+  out->model_asset_path =
+      in.model_asset_path ? std::string(in.model_asset_path) : "";
+}
+
+}  // namespace mediapipe::tasks::c::core
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/core/base_options_converter.h b/third_party/mediapipe/src/mediapipe/tasks/c/core/base_options_converter.h
new file mode 100644
index 0000000..f22740b
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/core/base_options_converter.h
@@ -0,0 +1,29 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#ifndef MEDIAPIPE_TASKS_C_CORE_BASE_OPTIONS_CONVERTER_H_
+#define MEDIAPIPE_TASKS_C_CORE_BASE_OPTIONS_CONVERTER_H_
+
+#include "mediapipe/tasks/c/core/base_options.h"
+#include "mediapipe/tasks/cc/core/base_options.h"
+
+namespace mediapipe::tasks::c::core {
+
+void CppConvertToBaseOptions(const BaseOptions& in,
+                             mediapipe::tasks::core::BaseOptions* out);
+
+}  // namespace mediapipe::tasks::c::core
+
+#endif  // MEDIAPIPE_TASKS_C_CORE_BASE_OPTIONS_H_
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/text/language_detector/BUILD b/third_party/mediapipe/src/mediapipe/tasks/c/text/language_detector/BUILD
new file mode 100644
index 0000000..9a3ce21
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/text/language_detector/BUILD
@@ -0,0 +1,93 @@
+# Copyright 2023 The MediaPipe Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+package(default_visibility = ["//mediapipe/tasks:internal"])
+
+licenses(["notice"])
+
+cc_library(
+    name = "language_detector_lib",
+    srcs = ["language_detector.cc"],
+    hdrs = ["language_detector.h"],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//mediapipe/tasks/c/components/containers:language_detection_result_converter",
+        "//mediapipe/tasks/c/components/processors:classifier_options",
+        "//mediapipe/tasks/c/components/processors:classifier_options_converter",
+        "//mediapipe/tasks/c/core:base_options",
+        "//mediapipe/tasks/c/core:base_options_converter",
+        "//mediapipe/tasks/cc/text/language_detector",
+        "@com_google_absl//absl/log:absl_log",
+        "@com_google_absl//absl/status",
+    ],
+    alwayslink = 1,
+)
+
+# bazel build -c opt --linkopt -s --strip always --define MEDIAPIPE_DISABLE_GPU=1 \
+# //mediapipe/tasks/c/text/language_detector:liblanguage_detector.so
+cc_binary(
+    name = "liblanguage_detector.so",
+    linkopts = [
+        "-Wl,-soname=liblanguage_detector.so",
+        "-fvisibility=hidden",
+    ],
+    linkshared = True,
+    tags = [
+        "manual",
+        "nobuilder",
+        "notap",
+    ],
+    deps = [":language_detector_lib"],
+)
+
+# bazel build --config darwin_arm64 -c opt --strip always --define MEDIAPIPE_DISABLE_GPU=1 \
+# //mediapipe/tasks/c/text/language_detector:liblanguage_detector.dylib
+cc_binary(
+    name = "liblanguage_detector.dylib",
+    linkopts = [
+        "-Wl,-install_name,liblanguage_detector.dylib",
+        "-fvisibility=hidden",
+    ],
+    linkshared = True,
+    tags = [
+        "manual",
+        "nobuilder",
+        "notap",
+    ],
+    deps = [":language_detector_lib"],
+)
+
+cc_library(
+    name = "language_detector",
+    hdrs = ["language_detector.h"],
+    deps = [
+        "//mediapipe/tasks/c/components/processors:classifier_options",
+        "//mediapipe/tasks/c/core:base_options",
+    ],
+)
+
+cc_test(
+    name = "language_detector_test",
+    srcs = ["language_detector_test.cc"],
+    data = ["//mediapipe/tasks/testdata/text:language_detector"],
+    linkstatic = 1,
+    deps = [
+        ":language_detector_lib",
+        "//mediapipe/framework/deps:file_path",
+        "//mediapipe/framework/port:gtest",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/strings",
+        "@com_google_googletest//:gtest_main",
+    ],
+)
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/text/language_detector/language_detector.cc b/third_party/mediapipe/src/mediapipe/tasks/c/text/language_detector/language_detector.cc
new file mode 100644
index 0000000..c71433f
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/text/language_detector/language_detector.cc
@@ -0,0 +1,124 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "mediapipe/tasks/c/text/language_detector/language_detector.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/log/absl_log.h"
+#include "absl/status/status.h"
+#include "mediapipe/tasks/c/components/containers/language_detection_result_converter.h"
+#include "mediapipe/tasks/c/components/processors/classifier_options_converter.h"
+#include "mediapipe/tasks/c/core/base_options_converter.h"
+#include "mediapipe/tasks/cc/text/language_detector/language_detector.h"
+
+namespace mediapipe::tasks::c::text::language_detector {
+
+namespace {
+
+using ::mediapipe::tasks::c::components::containers::
+    CppCloseLanguageDetectionResult;
+using ::mediapipe::tasks::c::components::containers::
+    CppConvertToLanguageDetectionResult;
+using ::mediapipe::tasks::c::components::processors::
+    CppConvertToClassifierOptions;
+using ::mediapipe::tasks::c::core::CppConvertToBaseOptions;
+using ::mediapipe::tasks::text::language_detector::LanguageDetector;
+
+int CppProcessError(absl::Status status, char** error_msg) {
+  if (error_msg) {
+    *error_msg = strdup(status.ToString().c_str());
+  }
+  return status.raw_code();
+}
+
+}  // namespace
+
+LanguageDetector* CppLanguageDetectorCreate(
+    const LanguageDetectorOptions& options, char** error_msg) {
+  auto cpp_options = std::make_unique<
+      ::mediapipe::tasks::text::language_detector::LanguageDetectorOptions>();
+
+  CppConvertToBaseOptions(options.base_options, &cpp_options->base_options);
+  CppConvertToClassifierOptions(options.classifier_options,
+                                &cpp_options->classifier_options);
+
+  auto detector = LanguageDetector::Create(std::move(cpp_options));
+  if (!detector.ok()) {
+    ABSL_LOG(ERROR) << "Failed to create LanguageDetector: "
+                    << detector.status();
+    CppProcessError(detector.status(), error_msg);
+    return nullptr;
+  }
+  return detector->release();
+}
+
+int CppLanguageDetectorDetect(void* detector, const char* utf8_str,
+                              LanguageDetectorResult* result,
+                              char** error_msg) {
+  auto cpp_detector = static_cast<LanguageDetector*>(detector);
+  auto cpp_result = cpp_detector->Detect(utf8_str);
+  if (!cpp_result.ok()) {
+    ABSL_LOG(ERROR) << "Language Detection failed: " << cpp_result.status();
+    return CppProcessError(cpp_result.status(), error_msg);
+  }
+
+  CppConvertToLanguageDetectionResult(*cpp_result, result);
+  return 0;
+}
+
+void CppLanguageDetectorCloseResult(LanguageDetectorResult* result) {
+  CppCloseLanguageDetectionResult(result);
+}
+
+int CppLanguageDetectorClose(void* detector, char** error_msg) {
+  auto cpp_detector = static_cast<LanguageDetector*>(detector);
+  auto result = cpp_detector->Close();
+  if (!result.ok()) {
+    ABSL_LOG(ERROR) << "Failed to close LanguageDetector: " << result;
+    return CppProcessError(result, error_msg);
+  }
+  delete cpp_detector;
+  return 0;
+}
+
+}  // namespace mediapipe::tasks::c::text::language_detector
+
+extern "C" {
+
+void* language_detector_create(struct LanguageDetectorOptions* options,
+                               char** error_msg) {
+  return mediapipe::tasks::c::text::language_detector::
+      CppLanguageDetectorCreate(*options, error_msg);
+}
+
+int language_detector_detect(void* detector, const char* utf8_str,
+                             LanguageDetectorResult* result, char** error_msg) {
+  return mediapipe::tasks::c::text::language_detector::
+      CppLanguageDetectorDetect(detector, utf8_str, result, error_msg);
+}
+
+void language_detector_close_result(LanguageDetectorResult* result) {
+  mediapipe::tasks::c::text::language_detector::CppLanguageDetectorCloseResult(
+      result);
+}
+
+int language_detector_close(void* detector, char** error_ms) {
+  return mediapipe::tasks::c::text::language_detector::CppLanguageDetectorClose(
+      detector, error_ms);
+}
+
+}  // extern "C"
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/text/language_detector/language_detector.h b/third_party/mediapipe/src/mediapipe/tasks/c/text/language_detector/language_detector.h
new file mode 100644
index 0000000..f1c8506
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/text/language_detector/language_detector.h
@@ -0,0 +1,91 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#ifndef MEDIAPIPE_TASKS_C_TEXT_LANGUAGE_DETECTOR_LANGUAGE_DETECTOR_H_
+#define MEDIAPIPE_TASKS_C_TEXT_LANGUAGE_DETECTOR_LANGUAGE_DETECTOR_H_
+
+#include <cstdint>
+
+#include "mediapipe/tasks/c/components/processors/classifier_options.h"
+#include "mediapipe/tasks/c/core/base_options.h"
+
+#ifndef MP_EXPORT
+#define MP_EXPORT __attribute__((visibility("default")))
+#endif  // MP_EXPORT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// A language code and its probability.
+struct LanguageDetectorPrediction {
+  // An i18n language / locale code, e.g. "en" for English, "uz" for Uzbek,
+  // "ja"-Latn for Japanese (romaji).
+  char* language_code;
+
+  float probability;
+};
+
+// Task output.
+struct LanguageDetectorResult {
+  struct LanguageDetectorPrediction* predictions;
+
+  // The count of predictions.
+  uint32_t predictions_count;
+};
+
+// The options for configuring a MediaPipe language detector task.
+struct LanguageDetectorOptions {
+  // Base options for configuring MediaPipe Tasks, such as specifying the model
+  // file with metadata, accelerator options, op resolver, etc.
+  struct BaseOptions base_options;
+
+  // Options for configuring the detector behavior, such as score threshold,
+  // number of results, etc.
+  struct ClassifierOptions classifier_options;
+};
+
+// Creates a LanguageDetector from the provided `options`.
+// Returns a pointer to the language detector on success.
+// If an error occurs, returns `nullptr` and sets the error parameter to an
+// an error message (if `error_msg` is not nullptr). You must free the memory
+// allocated for the error message.
+MP_EXPORT void* language_detector_create(
+    struct LanguageDetectorOptions* options, char** error_msg = nullptr);
+
+// Performs language detection on the input `text`. Returns `0` on success.
+// If an error occurs, returns an error code and sets the error parameter to an
+// an error message (if `error_msg` is not nullptr). You must free the memory
+// allocated for the error message.
+MP_EXPORT int language_detector_detect(void* detector, const char* utf8_str,
+                                       LanguageDetectorResult* result,
+                                       char** error_msg = nullptr);
+
+// Frees the memory allocated inside a LanguageDetectorResult result. Does not
+// free the result pointer itself.
+MP_EXPORT void language_detector_close_result(LanguageDetectorResult* result);
+
+// Shuts down the LanguageDetector when all the work is done. Frees all memory.
+// If an error occurs, returns an error code and sets the error parameter to an
+// an error message (if `error_msg` is not nullptr). You must free the memory
+// allocated for the error message.
+MP_EXPORT int language_detector_close(void* detector,
+                                      char** error_msg = nullptr);
+
+#ifdef __cplusplus
+}  // extern C
+#endif
+
+#endif  // MEDIAPIPE_TASKS_C_TEXT_LANGUAGE_DETECTOR_LANGUAGE_DETECTOR_H_
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/text/text_classifier/BUILD b/third_party/mediapipe/src/mediapipe/tasks/c/text/text_classifier/BUILD
index ca69366..1d2924e 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/c/text/text_classifier/BUILD
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/text/text_classifier/BUILD
@@ -30,6 +30,7 @@
         "//mediapipe/tasks/c/core:base_options_converter",
         "//mediapipe/tasks/cc/text/text_classifier",
         "@com_google_absl//absl/log:absl_log",
+        "@com_google_absl//absl/status",
     ],
     alwayslink = 1,
 )
@@ -67,3 +68,19 @@
     ],
     deps = [":text_classifier_lib"],
 )
+
+cc_test(
+    name = "text_classifier_test",
+    srcs = ["text_classifier_test.cc"],
+    data = ["//mediapipe/tasks/testdata/text:bert_text_classifier_models"],
+    linkstatic = 1,
+    deps = [
+        ":text_classifier_lib",
+        "//mediapipe/framework/deps:file_path",
+        "//mediapipe/framework/port:gtest",
+        "//mediapipe/tasks/c/components/containers:category",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/strings",
+        "@com_google_googletest//:gtest_main",
+    ],
+)
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/text/text_classifier/text_classifier.cc b/third_party/mediapipe/src/mediapipe/tasks/c/text/text_classifier/text_classifier.cc
index 0de12396..f25c572 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/c/text/text_classifier/text_classifier.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/text/text_classifier/text_classifier.cc
@@ -19,6 +19,7 @@
 #include <utility>
 
 #include "absl/log/absl_log.h"
+#include "absl/status/status.h"
 #include "mediapipe/tasks/c/components/containers/classification_result_converter.h"
 #include "mediapipe/tasks/c/components/processors/classifier_options.h"
 #include "mediapipe/tasks/c/components/processors/classifier_options_converter.h"
@@ -30,15 +31,26 @@
 
 namespace {
 
-using ::mediapipe::tasks::c::components::containers::CppConvertToBaseOptions;
+using ::mediapipe::tasks::c::components::containers::
+    CppCloseClassificationResult;
 using ::mediapipe::tasks::c::components::containers::
     CppConvertToClassificationResult;
 using ::mediapipe::tasks::c::components::processors::
     CppConvertToClassifierOptions;
+using ::mediapipe::tasks::c::core::CppConvertToBaseOptions;
 using ::mediapipe::tasks::text::text_classifier::TextClassifier;
+
+int CppProcessError(absl::Status status, char** error_msg) {
+  if (error_msg) {
+    *error_msg = strdup(status.ToString().c_str());
+  }
+  return status.raw_code();
+}
+
 }  // namespace
 
-TextClassifier* CppTextClassifierCreate(const TextClassifierOptions& options) {
+TextClassifier* CppTextClassifierCreate(const TextClassifierOptions& options,
+                                        char** error_msg) {
   auto cpp_options = std::make_unique<
       ::mediapipe::tasks::text::text_classifier::TextClassifierOptions>();
 
@@ -50,50 +62,63 @@
   if (!classifier.ok()) {
     ABSL_LOG(ERROR) << "Failed to create TextClassifier: "
                     << classifier.status();
+    CppProcessError(classifier.status(), error_msg);
     return nullptr;
   }
   return classifier->release();
 }
 
-bool CppTextClassifierClassify(void* classifier, char* utf8_str,
-                               TextClassifierResult* result) {
+int CppTextClassifierClassify(void* classifier, const char* utf8_str,
+                              TextClassifierResult* result, char** error_msg) {
   auto cpp_classifier = static_cast<TextClassifier*>(classifier);
   auto cpp_result = cpp_classifier->Classify(utf8_str);
   if (!cpp_result.ok()) {
     ABSL_LOG(ERROR) << "Classification failed: " << cpp_result.status();
-    return false;
+    return CppProcessError(cpp_result.status(), error_msg);
   }
   CppConvertToClassificationResult(*cpp_result, result);
-  return true;
+  return 0;
 }
 
-void CppTextClassifierClose(void* classifier) {
+void CppTextClassifierCloseResult(TextClassifierResult* result) {
+  CppCloseClassificationResult(result);
+}
+
+int CppTextClassifierClose(void* classifier, char** error_msg) {
   auto cpp_classifier = static_cast<TextClassifier*>(classifier);
   auto result = cpp_classifier->Close();
   if (!result.ok()) {
     ABSL_LOG(ERROR) << "Failed to close TextClassifier: " << result;
+    return CppProcessError(result, error_msg);
   }
   delete cpp_classifier;
+  return 0;
 }
 
 }  // namespace mediapipe::tasks::c::text::text_classifier
 
 extern "C" {
 
-void* text_classifier_create(struct TextClassifierOptions* options) {
+void* text_classifier_create(struct TextClassifierOptions* options,
+                             char** error_msg) {
   return mediapipe::tasks::c::text::text_classifier::CppTextClassifierCreate(
-      *options);
+      *options, error_msg);
 }
 
-int text_classifier_classify(void* classifier, char* utf8_str,
-                             TextClassifierResult* result) {
+int text_classifier_classify(void* classifier, const char* utf8_str,
+                             TextClassifierResult* result, char** error_msg) {
   return mediapipe::tasks::c::text::text_classifier::CppTextClassifierClassify(
-      classifier, utf8_str, result);
+      classifier, utf8_str, result, error_msg);
 }
 
-void text_classifier_close(void* classifier) {
-  mediapipe::tasks::c::text::text_classifier::CppTextClassifierClose(
-      classifier);
+void text_classifier_close_result(TextClassifierResult* result) {
+  mediapipe::tasks::c::text::text_classifier::CppTextClassifierCloseResult(
+      result);
+}
+
+int text_classifier_close(void* classifier, char** error_ms) {
+  return mediapipe::tasks::c::text::text_classifier::CppTextClassifierClose(
+      classifier, error_ms);
 }
 
 }  // extern "C"
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/text/text_classifier/text_classifier.h b/third_party/mediapipe/src/mediapipe/tasks/c/text/text_classifier/text_classifier.h
index 1ba14088..057b00f 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/c/text/text_classifier/text_classifier.h
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/text/text_classifier/text_classifier.h
@@ -42,14 +42,31 @@
 };
 
 // Creates a TextClassifier from the provided `options`.
-MP_EXPORT void* text_classifier_create(struct TextClassifierOptions* options);
+// Returns a pointer to the text classifier on success.
+// If an error occurs, returns `nullptr` and sets the error parameter to an
+// an error message (if `error_msg` is not nullptr). You must free the memory
+// allocated for the error message.
+MP_EXPORT void* text_classifier_create(struct TextClassifierOptions* options,
+                                       char** error_msg = nullptr);
 
-// Performs classification on the input `text`.
-MP_EXPORT int text_classifier_classify(void* classifier, char* utf8_str,
-                                       TextClassifierResult* result);
+// Performs classification on the input `text`. Returns `0` on success.
+// If an error occurs, returns an error code and sets the error parameter to an
+// an error message (if `error_msg` is not nullptr). You must free the memory
+// allocated for the error message.
+MP_EXPORT int text_classifier_classify(void* classifier, const char* utf8_str,
+                                       TextClassifierResult* result,
+                                       char** error_msg = nullptr);
+
+// Frees the memory allocated inside a TextClassifierResult result. Does not
+// free the result pointer itself.
+MP_EXPORT void text_classifier_close_result(TextClassifierResult* result);
 
 // Shuts down the TextClassifier when all the work is done. Frees all memory.
-MP_EXPORT void text_classifier_close(void* classifier);
+// If an error occurs, returns an error code and sets the error parameter to an
+// an error message (if `error_msg` is not nullptr). You must free the memory
+// allocated for the error message.
+MP_EXPORT int text_classifier_close(void* classifier,
+                                    char** error_msg = nullptr);
 
 #ifdef __cplusplus
 }  // extern C
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/text/text_embedder/BUILD b/third_party/mediapipe/src/mediapipe/tasks/c/text/text_embedder/BUILD
new file mode 100644
index 0000000..28a743eb
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/text/text_embedder/BUILD
@@ -0,0 +1,85 @@
+# Copyright 2023 The MediaPipe Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+package(default_visibility = ["//mediapipe/tasks:internal"])
+
+licenses(["notice"])
+
+cc_library(
+    name = "text_embedder_lib",
+    srcs = ["text_embedder.cc"],
+    hdrs = ["text_embedder.h"],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//mediapipe/tasks/c/components/containers:embedding_result",
+        "//mediapipe/tasks/c/components/containers:embedding_result_converter",
+        "//mediapipe/tasks/c/components/processors:embedder_options",
+        "//mediapipe/tasks/c/components/processors:embedder_options_converter",
+        "//mediapipe/tasks/c/core:base_options",
+        "//mediapipe/tasks/c/core:base_options_converter",
+        "//mediapipe/tasks/cc/text/text_embedder",
+        "@com_google_absl//absl/log:absl_log",
+        "@com_google_absl//absl/status",
+    ],
+    alwayslink = 1,
+)
+
+# bazel build -c opt --linkopt -s --strip always --define MEDIAPIPE_DISABLE_GPU=1 \
+# //mediapipe/tasks/c/text/text_embedder:libtext_embedder.so
+cc_binary(
+    name = "libtext_embedder.so",
+    linkopts = [
+        "-Wl,-soname=libtext_embedder.so",
+        "-fvisibility=hidden",
+    ],
+    linkshared = True,
+    tags = [
+        "manual",
+        "nobuilder",
+        "notap",
+    ],
+    deps = [":text_embedder_lib"],
+)
+
+# bazel build --config darwin_arm64 -c opt --strip always --define MEDIAPIPE_DISABLE_GPU=1 \
+# //mediapipe/tasks/c/text/text_embedder:libtext_embedder.dylib
+cc_binary(
+    name = "libtext_embedder.dylib",
+    linkopts = [
+        "-Wl,-install_name,libtext_embedder.dylib",
+        "-fvisibility=hidden",
+    ],
+    linkshared = True,
+    tags = [
+        "manual",
+        "nobuilder",
+        "notap",
+    ],
+    deps = [":text_embedder_lib"],
+)
+
+cc_test(
+    name = "text_embedder_test",
+    srcs = ["text_embedder_test.cc"],
+    data = ["//mediapipe/tasks/testdata/text:mobilebert_embedding_model"],
+    linkstatic = 1,
+    deps = [
+        ":text_embedder_lib",
+        "//mediapipe/framework/deps:file_path",
+        "//mediapipe/framework/port:gtest",
+        "@com_google_absl//absl/flags:flag",
+        "@com_google_absl//absl/strings",
+        "@com_google_googletest//:gtest_main",
+    ],
+)
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/text/text_embedder/text_embedder.cc b/third_party/mediapipe/src/mediapipe/tasks/c/text/text_embedder/text_embedder.cc
new file mode 100644
index 0000000..c98b958f
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/text/text_embedder/text_embedder.cc
@@ -0,0 +1,119 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#include "mediapipe/tasks/c/text/text_embedder/text_embedder.h"
+
+#include <memory>
+#include <utility>
+
+#include "absl/log/absl_log.h"
+#include "absl/status/status.h"
+#include "mediapipe/tasks/c/components/containers/embedding_result_converter.h"
+#include "mediapipe/tasks/c/components/processors/embedder_options_converter.h"
+#include "mediapipe/tasks/c/core/base_options_converter.h"
+#include "mediapipe/tasks/cc/text/text_embedder/text_embedder.h"
+
+namespace mediapipe::tasks::c::text::text_embedder {
+
+namespace {
+
+using ::mediapipe::tasks::c::components::containers::CppCloseEmbeddingResult;
+using ::mediapipe::tasks::c::components::containers::
+    CppConvertToEmbeddingResult;
+using ::mediapipe::tasks::c::components::processors::
+    CppConvertToEmbedderOptions;
+using ::mediapipe::tasks::c::core::CppConvertToBaseOptions;
+using ::mediapipe::tasks::text::text_embedder::TextEmbedder;
+
+int CppProcessError(absl::Status status, char** error_msg) {
+  if (error_msg) {
+    *error_msg = strdup(status.ToString().c_str());
+  }
+  return status.raw_code();
+}
+
+}  // namespace
+
+TextEmbedder* CppTextEmbedderCreate(const TextEmbedderOptions& options,
+                                    char** error_msg) {
+  auto cpp_options = std::make_unique<
+      ::mediapipe::tasks::text::text_embedder::TextEmbedderOptions>();
+
+  CppConvertToBaseOptions(options.base_options, &cpp_options->base_options);
+  CppConvertToEmbedderOptions(options.embedder_options,
+                              &cpp_options->embedder_options);
+
+  auto embedder = TextEmbedder::Create(std::move(cpp_options));
+  if (!embedder.ok()) {
+    ABSL_LOG(ERROR) << "Failed to create TextEmbedder: " << embedder.status();
+    CppProcessError(embedder.status(), error_msg);
+    return nullptr;
+  }
+  return embedder->release();
+}
+
+int CppTextEmbedderEmbed(void* embedder, const char* utf8_str,
+                         TextEmbedderResult* result, char** error_msg) {
+  auto cpp_embedder = static_cast<TextEmbedder*>(embedder);
+  auto cpp_result = cpp_embedder->Embed(utf8_str);
+  if (!cpp_result.ok()) {
+    ABSL_LOG(ERROR) << "Embedding extraction failed: " << cpp_result.status();
+    return CppProcessError(cpp_result.status(), error_msg);
+  }
+  CppConvertToEmbeddingResult(*cpp_result, result);
+  return 0;
+}
+
+void CppTextEmbedderCloseResult(TextEmbedderResult* result) {
+  CppCloseEmbeddingResult(result);
+}
+
+int CppTextEmbedderClose(void* embedder, char** error_msg) {
+  auto cpp_embedder = static_cast<TextEmbedder*>(embedder);
+  auto result = cpp_embedder->Close();
+  if (!result.ok()) {
+    ABSL_LOG(ERROR) << "Failed to close TextEmbedder: " << result;
+    return CppProcessError(result, error_msg);
+  }
+  delete cpp_embedder;
+  return 0;
+}
+
+}  // namespace mediapipe::tasks::c::text::text_embedder
+
+extern "C" {
+
+void* text_embedder_create(struct TextEmbedderOptions* options,
+                           char** error_msg) {
+  return mediapipe::tasks::c::text::text_embedder::CppTextEmbedderCreate(
+      *options, error_msg);
+}
+
+int text_embedder_embed(void* embedder, const char* utf8_str,
+                        TextEmbedderResult* result, char** error_msg) {
+  return mediapipe::tasks::c::text::text_embedder::CppTextEmbedderEmbed(
+      embedder, utf8_str, result, error_msg);
+}
+
+void text_embedder_close_result(TextEmbedderResult* result) {
+  mediapipe::tasks::c::text::text_embedder::CppTextEmbedderCloseResult(result);
+}
+
+int text_embedder_close(void* embedder, char** error_ms) {
+  return mediapipe::tasks::c::text::text_embedder::CppTextEmbedderClose(
+      embedder, error_ms);
+}
+
+}  // extern "C"
diff --git a/third_party/mediapipe/src/mediapipe/tasks/c/text/text_embedder/text_embedder.h b/third_party/mediapipe/src/mediapipe/tasks/c/text/text_embedder/text_embedder.h
new file mode 100644
index 0000000..c9ccf81
--- /dev/null
+++ b/third_party/mediapipe/src/mediapipe/tasks/c/text/text_embedder/text_embedder.h
@@ -0,0 +1,74 @@
+/* Copyright 2023 The MediaPipe Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+
+#ifndef MEDIAPIPE_TASKS_C_TEXT_TEXT_EMBEDDER_TEXT_EMBEDDER_H_
+#define MEDIAPIPE_TASKS_C_TEXT_TEXT_EMBEDDER_TEXT_EMBEDDER_H_
+
+#include "mediapipe/tasks/c/components/containers/embedding_result.h"
+#include "mediapipe/tasks/c/components/processors/embedder_options.h"
+#include "mediapipe/tasks/c/core/base_options.h"
+
+#ifndef MP_EXPORT
+#define MP_EXPORT __attribute__((visibility("default")))
+#endif  // MP_EXPORT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbeddingResult TextEmbedderResult;
+
+// The options for configuring a MediaPipe text embedder task.
+struct TextEmbedderOptions {
+  // Base options for configuring MediaPipe Tasks, such as specifying the model
+  // file with metadata, accelerator options, op resolver, etc.
+  struct BaseOptions base_options;
+
+  // Options for configuring the embedder behavior, such as l2_normalize
+  // and quantize.
+  struct EmbedderOptions embedder_options;
+};
+
+// Creates a TextEmbedder from the provided `options`.
+// Returns a pointer to the text embedder on success.
+// If an error occurs, returns `nullptr` and sets the error parameter to an
+// an error message (if `error_msg` is not `nullptr`). You must free the memory
+// allocated for the error message.
+MP_EXPORT void* text_embedder_create(struct TextEmbedderOptions* options,
+                                     char** error_msg = nullptr);
+
+// Performs embedding extraction on the input `text`. Returns `0` on success.
+// If an error occurs, returns an error code and sets the error parameter to an
+// an error message (if `error_msg` is not `nullptr`). You must free the memory
+// allocated for the error message.
+MP_EXPORT int text_embedder_embed(void* embedder, const char* utf8_str,
+                                  TextEmbedderResult* result,
+                                  char** error_msg = nullptr);
+
+// Frees the memory allocated inside a TextEmbedderResult result. Does not
+// free the result pointer itself.
+MP_EXPORT void text_embedder_close_result(TextEmbedderResult* result);
+
+// Shuts down the TextEmbedder when all the work is done. Frees all memory.
+// If an error occurs, returns an error code and sets the error parameter to an
+// an error message (if `error_msg` is not `nullptr`). You must free the memory
+// allocated for the error message.
+MP_EXPORT int text_embedder_close(void* embedder, char** error_msg = nullptr);
+
+#ifdef __cplusplus
+}  // extern C
+#endif
+
+#endif  // MEDIAPIPE_TASKS_C_TEXT_TEXT_EMBEDDER_TEXT_EMBEDDER_H_
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/components/calculators/score_calibration_calculator.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/components/calculators/score_calibration_calculator.cc
index c689cc2..24f1db7 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/components/calculators/score_calibration_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/components/calculators/score_calibration_calculator.cc
@@ -178,9 +178,9 @@
     for (int i = 0; i < num_scores; ++i) {
       // Use the "safe" flavor as we need to check that the externally provided
       // indices are not out-of-bounds.
-      ASSIGN_OR_RETURN(raw_calibrated_scores[i],
-                       SafeComputeCalibratedScore(
-                           static_cast<int>(raw_indices[i]), raw_scores[i]));
+      MP_ASSIGN_OR_RETURN(raw_calibrated_scores[i],
+                          SafeComputeCalibratedScore(
+                              static_cast<int>(raw_indices[i]), raw_scores[i]));
     }
   } else {
     if (num_scores != options_.sigmoids_size()) {
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/BUILD b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/BUILD
index dc5aca48..1a1e75d 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/BUILD
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/BUILD
@@ -122,6 +122,7 @@
         "//mediapipe/tasks/cc/components/processors/proto:image_preprocessing_graph_options_cc_proto",
         "//mediapipe/tasks/cc/core:model_resources",
         "//mediapipe/tasks/cc/core/proto:acceleration_cc_proto",
+        "//mediapipe/tasks/cc/core/proto:base_options_cc_proto",
         "//mediapipe/tasks/cc/vision/utils:image_tensor_specs",
         "@com_google_absl//absl/status",
         "@com_google_absl//absl/status:statusor",
@@ -132,8 +133,6 @@
 
 # TODO: Enable this test
 
-# TODO: Investigate rewriting the build rule to only link
-# the Bert Preprocessor if it's needed.
 cc_library(
     name = "text_preprocessing_graph",
     srcs = ["text_preprocessing_graph.cc"],
@@ -169,6 +168,7 @@
     deps = [
         "//mediapipe/calculators/core:split_vector_calculator",
         "//mediapipe/calculators/core:split_vector_calculator_cc_proto",
+        "//mediapipe/calculators/tensor:tensors_dequantization_calculator",
         "//mediapipe/calculators/tensor:tensors_to_detections_calculator",
         "//mediapipe/calculators/tensor:tensors_to_detections_calculator_cc_proto",
         "//mediapipe/calculators/tflite:ssd_anchors_calculator",
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.cc
index 525b3d4..20d2924 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/classification_postprocessing_graph.cc
@@ -180,16 +180,17 @@
     LabelItems empty_label_items;
     return empty_label_items;
   }
-  ASSIGN_OR_RETURN(absl::string_view labels_file,
-                   metadata_extractor.GetAssociatedFile(labels_filename));
+  MP_ASSIGN_OR_RETURN(absl::string_view labels_file,
+                      metadata_extractor.GetAssociatedFile(labels_filename));
   const std::string display_names_filename =
       ModelMetadataExtractor::FindFirstAssociatedFileName(
           tensor_metadata, tflite::AssociatedFileType_TENSOR_AXIS_LABELS,
           locale);
   absl::string_view display_names_file;
   if (!display_names_filename.empty()) {
-    ASSIGN_OR_RETURN(display_names_file, metadata_extractor.GetAssociatedFile(
-                                             display_names_filename));
+    MP_ASSIGN_OR_RETURN(
+        display_names_file,
+        metadata_extractor.GetAssociatedFile(display_names_filename));
   }
   return mediapipe::BuildLabelMapFromFiles(labels_file, display_names_file);
 }
@@ -199,10 +200,10 @@
 absl::StatusOr<float> GetScoreThreshold(
     const ModelMetadataExtractor& metadata_extractor,
     const TensorMetadata& tensor_metadata) {
-  ASSIGN_OR_RETURN(const ProcessUnit* score_thresholding_process_unit,
-                   metadata_extractor.FindFirstProcessUnit(
-                       tensor_metadata,
-                       tflite::ProcessUnitOptions_ScoreThresholdingOptions));
+  MP_ASSIGN_OR_RETURN(const ProcessUnit* score_thresholding_process_unit,
+                      metadata_extractor.FindFirstProcessUnit(
+                          tensor_metadata,
+                          tflite::ProcessUnitOptions_ScoreThresholdingOptions));
   if (score_thresholding_process_unit == nullptr) {
     return kDefaultScoreThreshold;
   }
@@ -255,10 +256,10 @@
     return absl::OkStatus();
   }
   // Get ScoreCalibrationOptions, if any.
-  ASSIGN_OR_RETURN(const ProcessUnit* score_calibration_process_unit,
-                   metadata_extractor.FindFirstProcessUnit(
-                       *tensor_metadata,
-                       tflite::ProcessUnitOptions_ScoreCalibrationOptions));
+  MP_ASSIGN_OR_RETURN(const ProcessUnit* score_calibration_process_unit,
+                      metadata_extractor.FindFirstProcessUnit(
+                          *tensor_metadata,
+                          tflite::ProcessUnitOptions_ScoreCalibrationOptions));
   if (score_calibration_process_unit == nullptr) {
     return absl::OkStatus();
   }
@@ -276,7 +277,7 @@
         "parameters file with type TENSOR_AXIS_SCORE_CALIBRATION.",
         MediaPipeTasksStatus::kMetadataAssociatedFileNotFoundError);
   }
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       absl::string_view score_calibration_file,
       metadata_extractor.GetAssociatedFile(score_calibration_filename));
   ScoreCalibrationCalculatorOptions calculator_options;
@@ -317,15 +318,15 @@
   LabelItems label_items;
   float score_threshold = kDefaultScoreThreshold;
   if (tensor_metadata != nullptr) {
-    ASSIGN_OR_RETURN(label_items,
-                     GetLabelItemsIfAny(metadata_extractor, *tensor_metadata,
-                                        options.display_names_locale()));
-    ASSIGN_OR_RETURN(score_threshold,
-                     GetScoreThreshold(metadata_extractor, *tensor_metadata));
+    MP_ASSIGN_OR_RETURN(label_items,
+                        GetLabelItemsIfAny(metadata_extractor, *tensor_metadata,
+                                           options.display_names_locale()));
+    MP_ASSIGN_OR_RETURN(score_threshold, GetScoreThreshold(metadata_extractor,
+                                                           *tensor_metadata));
   }
   // Allowlist / denylist.
-  ASSIGN_OR_RETURN(auto allow_or_deny_categories,
-                   GetAllowOrDenyCategoryIndicesIfAny(options, label_items));
+  MP_ASSIGN_OR_RETURN(auto allow_or_deny_categories,
+                      GetAllowOrDenyCategoryIndicesIfAny(options, label_items));
   if (!allow_or_deny_categories.empty()) {
     if (options.category_allowlist_size()) {
       calculator_options->mutable_allow_classes()->Assign(
@@ -359,8 +360,8 @@
     const proto::ClassifierOptions& classifier_options,
     proto::ClassificationPostprocessingGraphOptions* options) {
   MP_RETURN_IF_ERROR(SanityCheckClassifierOptions(classifier_options));
-  ASSIGN_OR_RETURN(const auto heads_properties,
-                   GetClassificationHeadsProperties(model_resources));
+  MP_ASSIGN_OR_RETURN(const auto heads_properties,
+                      GetClassificationHeadsProperties(model_resources));
   for (int i = 0; i < heads_properties.num_heads; ++i) {
     MP_RETURN_IF_ERROR(ConfigureScoreCalibrationIfAny(
         *model_resources.GetMetadataExtractor(), i, options));
@@ -406,7 +407,7 @@
   absl::StatusOr<mediapipe::CalculatorGraphConfig> GetConfig(
       mediapipe::SubgraphContext* sc) override {
     Graph graph;
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         auto output_streams,
         BuildClassificationPostprocessing(
             sc->Options<proto::ClassificationPostprocessingGraphOptions>(),
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.cc
index 813a23ae..a320e2a 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/detection_postprocessing_graph.cc
@@ -221,15 +221,16 @@
     LabelItems empty_label_items;
     return empty_label_items;
   }
-  ASSIGN_OR_RETURN(absl::string_view labels_file,
-                   metadata_extractor.GetAssociatedFile(labels_filename));
+  MP_ASSIGN_OR_RETURN(absl::string_view labels_file,
+                      metadata_extractor.GetAssociatedFile(labels_filename));
   const std::string display_names_filename =
       ModelMetadataExtractor::FindFirstAssociatedFileName(
           tensor_metadata, associated_file_type, locale);
   absl::string_view display_names_file;
   if (!display_names_filename.empty()) {
-    ASSIGN_OR_RETURN(display_names_file, metadata_extractor.GetAssociatedFile(
-                                             display_names_filename));
+    MP_ASSIGN_OR_RETURN(
+        display_names_file,
+        metadata_extractor.GetAssociatedFile(display_names_filename));
   }
   return mediapipe::BuildLabelMapFromFiles(labels_file, display_names_file);
 }
@@ -237,7 +238,7 @@
 absl::StatusOr<float> GetScoreThreshold(
     const ModelMetadataExtractor& metadata_extractor,
     const TensorMetadata& tensor_metadata) {
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       const ProcessUnit* score_thresholding_process_unit,
       metadata_extractor.FindFirstProcessUnit(
           tensor_metadata, ProcessUnitOptions_ScoreThresholdingOptions));
@@ -288,7 +289,7 @@
     const ModelMetadataExtractor& metadata_extractor,
     const TensorMetadata& tensor_metadata) {
   // Get ScoreCalibrationOptions, if any.
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       const ProcessUnit* score_calibration_process_unit,
       metadata_extractor.FindFirstProcessUnit(
           tensor_metadata, tflite::ProcessUnitOptions_ScoreCalibrationOptions));
@@ -309,7 +310,7 @@
         "parameters file with type TENSOR_AXIS_SCORE_CALIBRATION.",
         MediaPipeTasksStatus::kMetadataAssociatedFileNotFoundError);
   }
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       absl::string_view score_calibration_file,
       metadata_extractor.GetAssociatedFile(score_calibration_filename));
   ScoreCalibrationCalculatorOptions score_calibration_calculator_options;
@@ -393,13 +394,13 @@
       metadata_extractor->GetOutputTensorMetadata();
   PostProcessingSpecs specs;
   specs.max_results = options.max_results();
-  ASSIGN_OR_RETURN(specs.output_tensor_indices,
-                   GetOutputTensorIndices(output_tensors_metadata));
+  MP_ASSIGN_OR_RETURN(specs.output_tensor_indices,
+                      GetOutputTensorIndices(output_tensors_metadata));
   // Extracts mandatory BoundingBoxProperties and performs sanity checks on the
   // fly.
-  ASSIGN_OR_RETURN(const BoundingBoxProperties* bounding_box_properties,
-                   GetBoundingBoxProperties(*output_tensors_metadata->Get(
-                       specs.output_tensor_indices[0])));
+  MP_ASSIGN_OR_RETURN(const BoundingBoxProperties* bounding_box_properties,
+                      GetBoundingBoxProperties(*output_tensors_metadata->Get(
+                          specs.output_tensor_indices[0])));
   if (bounding_box_properties->index() == nullptr) {
     specs.bounding_box_corners_order = {0, 1, 2, 3};
   } else {
@@ -415,7 +416,7 @@
   // For models with in-model-nms, the label map is stored in the Category
   // tensor which use TENSOR_VALUE_LABELS. For models with out-of-model-nms, the
   // label map is stored in the Score tensor which use TENSOR_AXIS_LABELS.
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       specs.label_items,
       GetLabelItemsIfAny(
           *metadata_extractor,
@@ -425,7 +426,7 @@
           options.display_names_locale()));
   // Obtains allow/deny categories.
   specs.is_allowlist = !options.category_allowlist().empty();
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       specs.allow_or_deny_categories,
       GetAllowOrDenyCategoryIndicesIfAny(options, specs.label_items));
 
@@ -433,7 +434,7 @@
   if (options.has_score_threshold()) {
     specs.score_threshold = options.score_threshold();
   } else {
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         specs.score_threshold,
         GetScoreThreshold(
             *metadata_extractor,
@@ -444,7 +445,7 @@
   }
   if (in_model_nms) {
     // Builds score calibration options (if available) from metadata.
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         specs.score_calibration_options,
         GetScoreCalibrationOptionsIfAny(
             *metadata_extractor,
@@ -709,6 +710,57 @@
   return model_output_tensors;
 }
 
+// Identifies whether or not the model has quantized outputs, and performs
+// sanity checks.
+absl::StatusOr<bool> HasQuantizedOutputs(
+    const core::ModelResources& model_resources) {
+  const tflite::Model& model = *model_resources.GetTfLiteModel();
+  // Model is checked to have single subgraph before.
+  const auto* primary_subgraph = (*model.subgraphs())[0];
+  int num_output_tensors = primary_subgraph->outputs()->size();
+  // Sanity check tensor types and check if model outputs are quantized or not.
+  int num_quantized_tensors = 0;
+  for (int i = 0; i < num_output_tensors; ++i) {
+    const auto* tensor =
+        primary_subgraph->tensors()->Get(primary_subgraph->outputs()->Get(i));
+    if (tensor->type() != tflite::TensorType_FLOAT32 &&
+        tensor->type() != tflite::TensorType_UINT8) {
+      return CreateStatusWithPayload(
+          absl::StatusCode::kInvalidArgument,
+          absl::StrFormat("Expected output tensor at index %d to have type "
+                          "UINT8 or FLOAT32, found %s instead.",
+                          i, tflite::EnumNameTensorType(tensor->type())),
+          MediaPipeTasksStatus::kInvalidOutputTensorTypeError);
+    }
+    if (tensor->type() == tflite::TensorType_UINT8) {
+      num_quantized_tensors++;
+    }
+  }
+  if (num_quantized_tensors != num_output_tensors &&
+      num_quantized_tensors != 0) {
+    return CreateStatusWithPayload(
+        absl::StatusCode::kInvalidArgument,
+        absl::StrFormat(
+            "Expected either all or none of the output tensors to be "
+            "quantized, but found %d quantized outputs for %d total outputs.",
+            num_quantized_tensors, num_output_tensors),
+        MediaPipeTasksStatus::kInvalidOutputTensorTypeError);
+  }
+  // Check if metadata is consistent with model topology.
+  const auto* output_tensors_metadata =
+      model_resources.GetMetadataExtractor()->GetOutputTensorMetadata();
+  if (output_tensors_metadata != nullptr &&
+      num_output_tensors != output_tensors_metadata->size()) {
+    return CreateStatusWithPayload(
+        absl::StatusCode::kInvalidArgument,
+        absl::StrFormat("Mismatch between number of output tensors (%d) and "
+                        "output tensors metadata (%d).",
+                        num_output_tensors, output_tensors_metadata->size()),
+        MediaPipeTasksStatus::kMetadataInconsistencyError);
+  }
+  return num_quantized_tensors > 0;
+}
+
 }  // namespace
 
 absl::Status ConfigureDetectionPostprocessingGraph(
@@ -737,13 +789,15 @@
             model.subgraphs()->Get(0)->outputs()->size()),
         MediaPipeTasksStatus::kInvalidArgumentError);
   }
-
+  MP_ASSIGN_OR_RETURN(bool has_quantized_outputs,
+                      HasQuantizedOutputs(model_resources));
+  options.set_has_quantized_outputs(has_quantized_outputs);
   const ModelMetadataExtractor* metadata_extractor =
       model_resources.GetMetadataExtractor();
   if (in_model_nms) {
-    ASSIGN_OR_RETURN(auto post_processing_specs,
-                     BuildInModelNmsPostProcessingSpecs(detector_options,
-                                                        metadata_extractor));
+    MP_ASSIGN_OR_RETURN(auto post_processing_specs,
+                        BuildInModelNmsPostProcessingSpecs(detector_options,
+                                                           metadata_extractor));
     ConfigureInModelNmsTensorsToDetectionsCalculator(
         post_processing_specs, options.mutable_tensors_to_detections_options());
     ConfigureDetectionLabelIdToTextCalculator(
@@ -754,9 +808,9 @@
           std::move(*post_processing_specs.score_calibration_options);
     }
   } else {
-    ASSIGN_OR_RETURN(auto post_processing_specs,
-                     BuildOutModelNmsPostProcessingSpecs(detector_options,
-                                                         metadata_extractor));
+    MP_ASSIGN_OR_RETURN(auto post_processing_specs,
+                        BuildOutModelNmsPostProcessingSpecs(
+                            detector_options, metadata_extractor));
     MP_RETURN_IF_ERROR(ConfigureOutModelNmsTensorsToDetectionsCalculator(
         metadata_extractor, post_processing_specs,
         options.mutable_tensors_to_detections_options()));
@@ -795,7 +849,7 @@
   absl::StatusOr<mediapipe::CalculatorGraphConfig> GetConfig(
       mediapipe::SubgraphContext* sc) override {
     Graph graph;
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         auto output_streams,
         BuildDetectionPostprocessing(
             *sc->MutableOptions<proto::DetectionPostprocessingGraphOptions>(),
@@ -819,12 +873,20 @@
   BuildDetectionPostprocessing(
       proto::DetectionPostprocessingGraphOptions& graph_options,
       Source<std::vector<Tensor>> tensors_in, Graph& graph) {
+    Source<std::vector<Tensor>> tensors = tensors_in;
+    if (graph_options.has_quantized_outputs()) {
+      auto& tensors_dequantization_node =
+          graph.AddNode("TensorsDequantizationCalculator");
+      tensors_in >> tensors_dequantization_node.In(kTensorsTag);
+      tensors = tensors_dequantization_node.Out(kTensorsTag)
+                    .Cast<std::vector<Tensor>>();
+    }
     std::optional<Source<std::vector<Detection>>> detections;
     if (!graph_options.has_non_max_suppression_options()) {
       // Calculators to perform score calibration, if specified in the options.
       if (graph_options.has_score_calibration_options()) {
-        ASSIGN_OR_RETURN(tensors_in,
-                         CalibrateScores(tensors_in, graph_options, graph));
+        MP_ASSIGN_OR_RETURN(tensors,
+                            CalibrateScores(tensors, graph_options, graph));
       }
       // Calculator to convert output tensors to a detection proto vector.
       auto& tensors_to_detections =
@@ -832,7 +894,7 @@
       tensors_to_detections
           .GetOptions<mediapipe::TensorsToDetectionsCalculatorOptions>()
           .Swap(graph_options.mutable_tensors_to_detections_options());
-      tensors_in >> tensors_to_detections.In(kTensorsTag);
+      tensors >> tensors_to_detections.In(kTensorsTag);
       detections = tensors_to_detections.Out(kDetectionsTag)
                        .Cast<std::vector<Detection>>();
     } else {
@@ -849,7 +911,7 @@
           .GetOptions<mediapipe::TensorsToDetectionsCalculatorOptions>()
           .Swap(graph_options.mutable_tensors_to_detections_options());
       anchors >> tensors_to_detections.SideIn(kAnchorsTag);
-      tensors_in >> tensors_to_detections.In(kTensorsTag);
+      tensors >> tensors_to_detections.In(kTensorsTag);
       detections = tensors_to_detections.Out(kDetectionsTag)
                        .Cast<std::vector<mediapipe::Detection>>();
       // Non maximum suppression removes redundant object detections.
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph.cc
index ec28d62..bfe253c 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/embedding_postprocessing_graph.cc
@@ -151,13 +151,13 @@
     const ModelResources& model_resources,
     const proto::EmbedderOptions& embedder_options,
     proto::EmbeddingPostprocessingGraphOptions* options) {
-  ASSIGN_OR_RETURN(bool has_quantized_outputs,
-                   HasQuantizedOutputs(model_resources));
+  MP_ASSIGN_OR_RETURN(bool has_quantized_outputs,
+                      HasQuantizedOutputs(model_resources));
   options->set_has_quantized_outputs(has_quantized_outputs);
   auto* tensors_to_embeddings_options =
       options->mutable_tensors_to_embeddings_options();
   *tensors_to_embeddings_options->mutable_embedder_options() = embedder_options;
-  ASSIGN_OR_RETURN(auto head_names, GetHeadNames(model_resources));
+  MP_ASSIGN_OR_RETURN(auto head_names, GetHeadNames(model_resources));
   if (!head_names.empty()) {
     *tensors_to_embeddings_options->mutable_head_names() = {head_names.begin(),
                                                             head_names.end()};
@@ -197,7 +197,7 @@
   absl::StatusOr<mediapipe::CalculatorGraphConfig> GetConfig(
       mediapipe::SubgraphContext* sc) override {
     Graph graph;
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         auto output_streams,
         BuildEmbeddingPostprocessing(
             sc->Options<proto::EmbeddingPostprocessingGraphOptions>(),
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.cc
index 1040701c..1604dfb 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.cc
@@ -36,6 +36,7 @@
 #include "mediapipe/tasks/cc/components/processors/proto/image_preprocessing_graph_options.pb.h"
 #include "mediapipe/tasks/cc/core/model_resources.h"
 #include "mediapipe/tasks/cc/core/proto/acceleration.pb.h"
+#include "mediapipe/tasks/cc/core/proto/base_options.pb.h"
 #include "mediapipe/tasks/cc/vision/utils/image_tensor_specs.h"
 #include "tensorflow/lite/schema/schema_generated.h"
 
@@ -73,7 +74,7 @@
 
 // Fills in the ImageToTensorCalculatorOptions based on the ImageTensorSpecs.
 absl::Status ConfigureImageToTensorCalculator(
-    const ImageTensorSpecs& image_tensor_specs,
+    const ImageTensorSpecs& image_tensor_specs, GpuOrigin::Mode gpu_origin,
     mediapipe::ImageToTensorCalculatorOptions* options) {
   options->set_output_tensor_width(image_tensor_specs.image_width);
   options->set_output_tensor_height(image_tensor_specs.image_height);
@@ -109,7 +110,7 @@
   }
   // TODO: need to support different GPU origin on different
   // platforms or applications.
-  options->set_gpu_origin(mediapipe::GpuOrigin::TOP_LEFT);
+  options->set_gpu_origin(gpu_origin);
   return absl::OkStatus();
 }
 
@@ -125,10 +126,19 @@
 absl::Status ConfigureImagePreprocessingGraph(
     const ModelResources& model_resources, bool use_gpu,
     proto::ImagePreprocessingGraphOptions* options) {
-  ASSIGN_OR_RETURN(auto image_tensor_specs,
-                   vision::BuildInputImageTensorSpecs(model_resources));
+  return ConfigureImagePreprocessingGraph(model_resources, use_gpu,
+                                          GpuOrigin::TOP_LEFT, options);
+}
+
+absl::Status ConfigureImagePreprocessingGraph(
+    const ModelResources& model_resources, bool use_gpu,
+    GpuOrigin::Mode gpu_origin,
+    proto::ImagePreprocessingGraphOptions* options) {
+  MP_ASSIGN_OR_RETURN(auto image_tensor_specs,
+                      vision::BuildInputImageTensorSpecs(model_resources));
   MP_RETURN_IF_ERROR(ConfigureImageToTensorCalculator(
-      image_tensor_specs, options->mutable_image_to_tensor_options()));
+      image_tensor_specs, gpu_origin,
+      options->mutable_image_to_tensor_options()));
   // The GPU backend isn't able to process int data. If the input tensor is
   // quantized, forces the image preprocessing graph to use CPU backend.
   if (use_gpu && image_tensor_specs.tensor_type != tflite::TensorType_UINT8) {
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.h b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.h
index 2f7473f..bcaef4ac 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.h
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/image_preprocessing_graph.h
@@ -17,6 +17,7 @@
 #define MEDIAPIPE_TASKS_CC_COMPONENTS_PROCESSORS_IMAGE_PREPROCESSING_GRAPH_H_
 
 #include "absl/status/status.h"
+#include "mediapipe/gpu/gpu_origin.pb.h"
 #include "mediapipe/tasks/cc/components/processors/proto/image_preprocessing_graph_options.pb.h"
 #include "mediapipe/tasks/cc/core/model_resources.h"
 #include "mediapipe/tasks/cc/core/proto/acceleration.pb.h"
@@ -64,6 +65,12 @@
 //     GPU).
 absl::Status ConfigureImagePreprocessingGraph(
     const core::ModelResources& model_resources, bool use_gpu,
+    ::mediapipe::GpuOrigin::Mode gpu_origin,
+    proto::ImagePreprocessingGraphOptions* options);
+
+// A convenient function of the above. gpu_origin is set to TOP_LEFT by default.
+absl::Status ConfigureImagePreprocessingGraph(
+    const core::ModelResources& model_resources, bool use_gpu,
     proto::ImagePreprocessingGraphOptions* options);
 
 // Determine if the image preprocessing graph should use GPU as the backend
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/proto/detection_postprocessing_graph_options.proto b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/proto/detection_postprocessing_graph_options.proto
index ec11df2b..ce0edd1 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/proto/detection_postprocessing_graph_options.proto
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/proto/detection_postprocessing_graph_options.proto
@@ -46,4 +46,7 @@
   // Optional detection label id to text calculator options.
   optional mediapipe.DetectionLabelIdToTextCalculatorOptions
       detection_label_ids_to_text_options = 5;
+
+  // Whether output tensors are quantized (kTfLiteUint8) or not (kFloat32).
+  optional bool has_quantized_outputs = 6;
 }
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/text_preprocessing_graph.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/text_preprocessing_graph.cc
index ecf59e2..2b5fce5 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/text_preprocessing_graph.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/components/processors/text_preprocessing_graph.cc
@@ -180,8 +180,8 @@
         MediaPipeTasksStatus::kInvalidArgumentError);
   }
 
-  ASSIGN_OR_RETURN(TextModelType::ModelType model_type,
-                   GetModelType(model_resources));
+  MP_ASSIGN_OR_RETURN(TextModelType::ModelType model_type,
+                      GetModelType(model_resources));
   const tflite::SubGraph& model_graph =
       *(*model_resources.GetTfLiteModel()->subgraphs())[0];
   options.set_model_type(model_type);
@@ -193,13 +193,13 @@
     }
     case TextModelType::BERT_MODEL:
     case TextModelType::REGEX_MODEL: {
-      ASSIGN_OR_RETURN(int max_seq_len, GetMaxSeqLen(model_graph));
+      MP_ASSIGN_OR_RETURN(int max_seq_len, GetMaxSeqLen(model_graph));
       options.set_max_seq_len(max_seq_len);
     }
   }
   if (model_type == TextModelType::BERT_MODEL) {
-    ASSIGN_OR_RETURN(bool has_dynamic_input_tensors,
-                     HasDynamicInputTensors(model_graph));
+    MP_ASSIGN_OR_RETURN(bool has_dynamic_input_tensors,
+                        HasDynamicInputTensors(model_graph));
     options.set_has_dynamic_input_tensors(has_dynamic_input_tensors);
   }
   return absl::OkStatus();
@@ -227,7 +227,7 @@
   absl::StatusOr<mediapipe::CalculatorGraphConfig> GetConfig(
       mediapipe::SubgraphContext* sc) override {
     Graph graph;
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         Source<std::vector<Tensor>> tensors_in,
         BuildTextPreprocessing(
             sc->Options<TextPreprocessingGraphOptions>(),
@@ -242,8 +242,8 @@
   absl::StatusOr<Source<std::vector<Tensor>>> BuildTextPreprocessing(
       const TextPreprocessingGraphOptions& options, Source<std::string> text_in,
       SideSource<ModelMetadataExtractor> metadata_extractor_in, Graph& graph) {
-    ASSIGN_OR_RETURN(std::string preprocessor_name,
-                     GetCalculatorNameFromModelType(options.model_type()));
+    MP_ASSIGN_OR_RETURN(std::string preprocessor_name,
+                        GetCalculatorNameFromModelType(options.model_type()));
     auto& text_preprocessor = graph.AddNode(preprocessor_name);
     switch (options.model_type()) {
       case TextModelType::UNSPECIFIED_MODEL:
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/core/BUILD b/third_party/mediapipe/src/mediapipe/tasks/cc/core/BUILD
index ce9181d5..fa61feb 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/core/BUILD
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/core/BUILD
@@ -261,6 +261,7 @@
     deps = [
         "//mediapipe/framework:calculator_cc_proto",
         "//mediapipe/framework:calculator_framework",
+        "//mediapipe/framework:executor",
         "//mediapipe/framework/port:status",
         "//mediapipe/framework/tool:name_util",
         "//mediapipe/tasks/cc:common",
@@ -319,6 +320,7 @@
         ":task_runner",
         ":utils",
         "//mediapipe/framework:calculator_cc_proto",
+        "//mediapipe/framework:executor",
         "//mediapipe/framework/port:requires",
         "//mediapipe/framework/port:status",
         "//mediapipe/tasks/cc:common",
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/core/external_file_handler.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/core/external_file_handler.cc
index af304c4..069b904e 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/core/external_file_handler.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/core/external_file_handler.cc
@@ -122,8 +122,8 @@
   // Obtain file descriptor, offset and size.
   int fd = -1;
   if (!external_file_.file_name().empty()) {
-    ASSIGN_OR_RETURN(std::string file_name,
-                     PathToResourceAsFile(external_file_.file_name()));
+    MP_ASSIGN_OR_RETURN(std::string file_name,
+                        PathToResourceAsFile(external_file_.file_name()));
     owned_fd_ = open(file_name.c_str(), O_RDONLY | O_BINARY);
     if (owned_fd_ < 0) {
       const std::string error_message = absl::StrFormat(
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.cc
index 04bc750..0121520 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/core/mediapipe_builtin_op_resolver.cc
@@ -30,7 +30,7 @@
 namespace mediapipe {
 namespace tasks {
 namespace core {
-// TODO: Use separate builtin op-resolvers.
+
 MediaPipeBuiltinOpResolver::MediaPipeBuiltinOpResolver() {
   AddCustom("MaxPoolingWithArgmax2D",
             mediapipe::tflite_operations::RegisterMaxPoolingWithArgmax2D());
@@ -60,6 +60,7 @@
   AddCustom("FusedBatchNormV3",
             mediapipe::tflite_operations::Register_FusedBatchNorm());
 }
+
 }  // namespace core
 }  // namespace tasks
 }  // namespace mediapipe
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_asset_bundle_resources.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_asset_bundle_resources.cc
index 58b30630..ae86463 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_asset_bundle_resources.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_asset_bundle_resources.cc
@@ -59,14 +59,14 @@
   if (model_asset_bundle_file_->has_file_name()) {
     // If the model asset bundle file name is a relative path, searches the file
     // in a platform-specific location and returns the absolute path on success.
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         std::string path_to_resource,
         mediapipe::PathToResourceAsFile(model_asset_bundle_file_->file_name()));
     model_asset_bundle_file_->set_file_name(path_to_resource);
   }
-  ASSIGN_OR_RETURN(model_asset_bundle_file_handler_,
-                   ExternalFileHandler::CreateFromExternalFile(
-                       model_asset_bundle_file_.get()));
+  MP_ASSIGN_OR_RETURN(model_asset_bundle_file_handler_,
+                      ExternalFileHandler::CreateFromExternalFile(
+                          model_asset_bundle_file_.get()));
   const char* buffer_data =
       model_asset_bundle_file_handler_->GetFileContent().data();
   size_t buffer_size =
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_resources.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_resources.cc
index 1a917f72..4f1a9bb7 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_resources.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_resources.cc
@@ -110,12 +110,12 @@
     } else {
       // If the model file name is a relative path, searches the file in a
       // platform-specific location and returns the absolute path on success.
-      ASSIGN_OR_RETURN(std::string path_to_resource,
-                       PathToResourceAsFile(model_file_->file_name()));
+      MP_ASSIGN_OR_RETURN(std::string path_to_resource,
+                          PathToResourceAsFile(model_file_->file_name()));
       model_file_->set_file_name(path_to_resource);
     }
   }
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       model_file_handler_,
       ExternalFileHandler::CreateFromExternalFile(model_file_.get()));
   const char* buffer_data = model_file_handler_->GetFileContent().data();
@@ -152,9 +152,9 @@
 
   model_packet_ = MakePacket<ModelPtr>(
       model.release(), [](tflite::FlatBufferModel* model) { delete model; });
-  ASSIGN_OR_RETURN(auto model_metadata_extractor,
-                   metadata::ModelMetadataExtractor::CreateFromModelBuffer(
-                       buffer_data, buffer_size));
+  MP_ASSIGN_OR_RETURN(auto model_metadata_extractor,
+                      metadata::ModelMetadataExtractor::CreateFromModelBuffer(
+                          buffer_data, buffer_size));
   metadata_extractor_packet_ = PacketAdopting<metadata::ModelMetadataExtractor>(
       std::move(model_metadata_extractor));
   return absl::OkStatus();
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_resources_calculator.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_resources_calculator.cc
index 8db3581..39daa3b 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_resources_calculator.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_resources_calculator.cc
@@ -109,7 +109,7 @@
             "ModelResourcesCacheService, and the CalculatorOptions has no "
             "'model_file' field to create a local ModelResources.");
       }
-      ASSIGN_OR_RETURN(
+      MP_ASSIGN_OR_RETURN(
           model_resources_,
           ModelResources::Create(
               "", std::make_unique<proto::ExternalFile>(options.model_file())));
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_task_graph.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_task_graph.cc
index a68d40a..b82a697 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_task_graph.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/core/model_task_graph.cc
@@ -92,8 +92,8 @@
   absl::StatusOr<CalculatorGraphConfig> GetConfig(
       SubgraphContext* sc) override {
     auto* subgraph_options = sc->MutableOptions<InferenceSubgraphOptions>();
-    ASSIGN_OR_RETURN(auto inference_delegate,
-                     DecideInferenceSettings(*subgraph_options));
+    MP_ASSIGN_OR_RETURN(auto inference_delegate,
+                        DecideInferenceSettings(*subgraph_options));
     Graph graph;
     auto& model_resources_node = graph.AddNode("ModelResourcesCalculator");
     auto& model_resources_opts =
@@ -163,8 +163,8 @@
     const std::string tag_suffix) {
   auto model_resources_cache_service = sc->Service(kModelResourcesCacheService);
   if (!model_resources_cache_service.IsAvailable()) {
-    ASSIGN_OR_RETURN(auto local_model_resource,
-                     ModelResources::Create("", std::move(external_file)));
+    MP_ASSIGN_OR_RETURN(auto local_model_resource,
+                        ModelResources::Create("", std::move(external_file)));
     ABSL_LOG(WARNING)
         << "A local ModelResources object is created. Please consider using "
            "ModelResourcesCacheService to cache the created ModelResources "
@@ -172,14 +172,14 @@
     local_model_resources_.push_back(std::move(local_model_resource));
     return local_model_resources_.back().get();
   }
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       auto op_resolver_packet,
       model_resources_cache_service.GetObject().GetGraphOpResolverPacket());
   const std::string tag =
       absl::StrCat(CreateModelResourcesTag(sc->OriginalNode()), tag_suffix);
-  ASSIGN_OR_RETURN(auto model_resources,
-                   ModelResources::Create(tag, std::move(external_file),
-                                          op_resolver_packet));
+  MP_ASSIGN_OR_RETURN(auto model_resources,
+                      ModelResources::Create(tag, std::move(external_file),
+                                             op_resolver_packet));
   MP_RETURN_IF_ERROR(
       model_resources_cache_service.GetObject().AddModelResources(
           std::move(model_resources)));
@@ -211,7 +211,7 @@
   // bundle resources into the model resources service since the memory is
   // not owned by this model asset bundle resources.
   if (!model_resources_cache_service.IsAvailable() || has_file_pointer_meta) {
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         auto local_model_asset_bundle_resource,
         ModelAssetBundleResources::Create("", std::move(external_file)));
     if (!has_file_pointer_meta) {
@@ -226,7 +226,7 @@
   }
   const std::string tag = absl::StrCat(
       CreateModelAssetBundleResourcesTag(sc->OriginalNode()), tag_suffix);
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       auto model_bundle_resources,
       ModelAssetBundleResources::Create(tag, std::move(external_file)));
   MP_RETURN_IF_ERROR(
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/core/proto/BUILD b/third_party/mediapipe/src/mediapipe/tasks/cc/core/proto/BUILD
index 72de1be8..fbc6575 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/core/proto/BUILD
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/core/proto/BUILD
@@ -46,6 +46,7 @@
     deps = [
         ":acceleration_proto",
         ":external_file_proto",
+        "//mediapipe/gpu:gpu_origin_proto",
     ],
 )
 
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/core/proto/base_options.proto b/third_party/mediapipe/src/mediapipe/tasks/cc/core/proto/base_options.proto
index 9c95719..ee7521dc0 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/core/proto/base_options.proto
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/core/proto/base_options.proto
@@ -17,6 +17,7 @@
 
 package mediapipe.tasks.core.proto;
 
+import "mediapipe/gpu/gpu_origin.proto";
 import "mediapipe/tasks/cc/core/proto/acceleration.proto";
 import "mediapipe/tasks/cc/core/proto/external_file.proto";
 
@@ -24,7 +25,7 @@
 option java_outer_classname = "BaseOptionsProto";
 
 // Base options for mediapipe tasks.
-// Next Id: 4
+// Next Id: 5
 message BaseOptions {
   // The external model asset, as a single standalone TFLite file. It could be
   // packed with TFLite Model Metadata[1] and associated files if exist. Fail to
@@ -40,4 +41,7 @@
 
   // Acceleration setting to use available delegate on the device.
   optional Acceleration acceleration = 3;
+
+  // Gpu origin for calculators with gpu supported.
+  optional mediapipe.GpuOrigin.Mode gpu_origin = 4 [default = TOP_LEFT];
 }
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/core/task_api_factory.h b/third_party/mediapipe/src/mediapipe/tasks/cc/core/task_api_factory.h
index 6f604dd..3f173818 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/core/task_api_factory.h
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/core/task_api_factory.h
@@ -17,6 +17,7 @@
 #define MEDIAPIPE_TASKS_CC_CORE_TASK_API_FACTORY_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <utility>
@@ -26,6 +27,7 @@
 #include "absl/strings/match.h"
 #include "absl/strings/str_cat.h"
 #include "mediapipe/framework/calculator.pb.h"
+#include "mediapipe/framework/executor.h"
 #include "mediapipe/framework/port/requires.h"
 #include "mediapipe/framework/port/status_macros.h"
 #include "mediapipe/tasks/cc/common.h"
@@ -56,7 +58,9 @@
   static absl::StatusOr<std::unique_ptr<T>> Create(
       CalculatorGraphConfig graph_config,
       std::unique_ptr<tflite::OpResolver> resolver,
-      PacketsCallback packets_callback = nullptr) {
+      PacketsCallback packets_callback = nullptr,
+      std::shared_ptr<Executor> default_executor = nullptr,
+      std::optional<PacketMap> input_side_packets = std::nullopt) {
     bool found_task_subgraph = false;
     // This for-loop ensures there's only one subgraph besides
     // FlowLimiterCalculator.
@@ -74,10 +78,12 @@
         found_task_subgraph = true;
       }
     }
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         auto runner,
         core::TaskRunner::Create(std::move(graph_config), std::move(resolver),
-                                 std::move(packets_callback)));
+                                 std::move(packets_callback),
+                                 std::move(default_executor),
+                                 std::move(input_side_packets)));
     return std::make_unique<T>(std::move(runner));
   }
 
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/core/task_runner.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/core/task_runner.cc
index d97c4e4..88c91bc 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/core/task_runner.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/core/task_runner.cc
@@ -21,6 +21,7 @@
 #include <iterator>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
@@ -33,6 +34,7 @@
 #include "absl/synchronization/mutex.h"
 #include "mediapipe/framework/calculator.pb.h"
 #include "mediapipe/framework/calculator_framework.h"
+#include "mediapipe/framework/executor.h"
 #include "mediapipe/framework/tool/name_util.h"
 #include "mediapipe/tasks/cc/common.h"
 #include "mediapipe/tasks/cc/core/model_resources_cache.h"
@@ -89,17 +91,22 @@
 absl::StatusOr<std::unique_ptr<TaskRunner>> TaskRunner::Create(
     CalculatorGraphConfig config,
     std::unique_ptr<tflite::OpResolver> op_resolver,
-    PacketsCallback packets_callback) {
+    PacketsCallback packets_callback,
+    std::shared_ptr<Executor> default_executor,
+    std::optional<PacketMap> input_side_packets) {
   auto task_runner = absl::WrapUnique(new TaskRunner(packets_callback));
-  MP_RETURN_IF_ERROR(
-      task_runner->Initialize(std::move(config), std::move(op_resolver)));
+  MP_RETURN_IF_ERROR(task_runner->Initialize(
+      std::move(config), std::move(op_resolver), std::move(default_executor),
+      std::move(input_side_packets)));
   MP_RETURN_IF_ERROR(task_runner->Start());
   return task_runner;
 }
 
 absl::Status TaskRunner::Initialize(
     CalculatorGraphConfig config,
-    std::unique_ptr<tflite::OpResolver> op_resolver) {
+    std::unique_ptr<tflite::OpResolver> op_resolver,
+    std::shared_ptr<Executor> default_executor,
+    std::optional<PacketMap> input_side_packets) {
   if (initialized_) {
     return CreateStatusWithPayload(
         absl::StatusCode::kInvalidArgument,
@@ -123,7 +130,9 @@
         MediaPipeTasksStatus::kRunnerInitializationError);
   }
   config.clear_output_stream();
-  PacketMap input_side_packets;
+  if (!input_side_packets) {
+    input_side_packets.emplace();
+  }
   if (packets_callback_) {
     tool::AddMultiStreamCallback(
         output_stream_names_,
@@ -132,7 +141,7 @@
               GenerateOutputPacketMap(packets, output_stream_names_));
           return;
         },
-        &config, &input_side_packets,
+        &config, &input_side_packets.value(),
         /*observe_timestamp_bounds=*/true);
   } else {
     mediapipe::tool::AddMultiStreamCallback(
@@ -142,8 +151,14 @@
               GenerateOutputPacketMap(packets, output_stream_names_);
           return;
         },
-        &config, &input_side_packets, /*observe_timestamp_bounds=*/true);
+        &config, &input_side_packets.value(),
+        /*observe_timestamp_bounds=*/true);
   }
+
+  if (default_executor) {
+    MP_RETURN_IF_ERROR(graph_.SetExecutor("", std::move(default_executor)));
+  }
+
   auto model_resources_cache =
       std::make_shared<ModelResourcesCache>(std::move(op_resolver));
   MP_RETURN_IF_ERROR(
@@ -152,7 +167,7 @@
                  "ModelResourcesCacheService is not set up successfully.",
                  MediaPipeTasksStatus::kRunnerModelResourcesCacheServiceError));
   MP_RETURN_IF_ERROR(
-      AddPayload(graph_.Initialize(std::move(config), input_side_packets),
+      AddPayload(graph_.Initialize(std::move(config), *input_side_packets),
                  "MediaPipe CalculatorGraph is not successfully initialized.",
                  MediaPipeTasksStatus::kRunnerInitializationError));
   initialized_ = true;
@@ -202,7 +217,8 @@
         "callback is provided.",
         MediaPipeTasksStatus::kRunnerApiCalledInWrongModeError);
   }
-  ASSIGN_OR_RETURN(auto input_timestamp, ValidateAndGetPacketTimestamp(inputs));
+  MP_ASSIGN_OR_RETURN(auto input_timestamp,
+                      ValidateAndGetPacketTimestamp(inputs));
   // MediaPipe reports runtime errors through CalculatorGraph::WaitUntilIdle or
   // WaitUntilDone without indicating the exact packet timestamp.
   // To ensure that the TaskRunner::Process reports errors per invocation,
@@ -264,7 +280,8 @@
         "callback is not provided.",
         MediaPipeTasksStatus::kRunnerApiCalledInWrongModeError);
   }
-  ASSIGN_OR_RETURN(auto input_timestamp, ValidateAndGetPacketTimestamp(inputs));
+  MP_ASSIGN_OR_RETURN(auto input_timestamp,
+                      ValidateAndGetPacketTimestamp(inputs));
   if (!input_timestamp.IsAllowedInStream()) {
     return CreateStatusWithPayload(
         absl::StatusCode::kInvalidArgument,
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/core/task_runner.h b/third_party/mediapipe/src/mediapipe/tasks/cc/core/task_runner.h
index cd77c055..810063d4 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/core/task_runner.h
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/core/task_runner.h
@@ -24,6 +24,7 @@
 #include <functional>
 #include <map>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -34,6 +35,7 @@
 #include "absl/synchronization/mutex.h"
 #include "mediapipe/framework/calculator.pb.h"
 #include "mediapipe/framework/calculator_framework.h"
+#include "mediapipe/framework/executor.h"
 #include "mediapipe/framework/port/status_macros.h"
 #include "mediapipe/tasks/cc/core/model_resources.h"
 #include "mediapipe/tasks/cc/core/model_resources_cache.h"
@@ -73,7 +75,9 @@
   static absl::StatusOr<std::unique_ptr<TaskRunner>> Create(
       CalculatorGraphConfig config,
       std::unique_ptr<tflite::OpResolver> op_resolver = nullptr,
-      PacketsCallback packets_callback = nullptr);
+      PacketsCallback packets_callback = nullptr,
+      std::shared_ptr<Executor> default_executor = nullptr,
+      std::optional<PacketMap> input_side_packets = std::nullopt);
 
   // TaskRunner is neither copyable nor movable.
   TaskRunner(const TaskRunner&) = delete;
@@ -125,7 +129,9 @@
   // be only initialized once.
   absl::Status Initialize(
       CalculatorGraphConfig config,
-      std::unique_ptr<tflite::OpResolver> op_resolver = nullptr);
+      std::unique_ptr<tflite::OpResolver> op_resolver = nullptr,
+      std::shared_ptr<Executor> default_executor = nullptr,
+      std::optional<PacketMap> input_side_packets = std::nullopt);
 
   // Starts the task runner. Returns an ok status to indicate that the
   // runner is ready to accept input data. Otherwise, returns an error status to
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/core/utils.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/core/utils.cc
index 168c4363c..d6db1d6 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/core/utils.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/core/utils.cc
@@ -32,6 +32,7 @@
 namespace {
 constexpr char kFinishedTag[] = "FINISHED";
 constexpr char kFlowLimiterCalculatorName[] = "FlowLimiterCalculator";
+constexpr char kPreviousLoopbackCalculatorName[] = "PreviousLoopbackCalculator";
 
 }  // namespace
 
@@ -89,6 +90,19 @@
   return config;
 }
 
+void FixGraphBackEdges(::mediapipe::CalculatorGraphConfig& graph_config) {
+  // TODO remove when support is fixed.
+  // As mediapipe GraphBuilder currently doesn't support configuring
+  // InputStreamInfo, modifying the CalculatorGraphConfig proto directly.
+  for (int i = 0; i < graph_config.node_size(); ++i) {
+    if (graph_config.node(i).calculator() == kPreviousLoopbackCalculatorName) {
+      auto* info = graph_config.mutable_node(i)->add_input_stream_info();
+      info->set_tag_index("LOOP");
+      info->set_back_edge(true);
+    }
+  }
+}
+
 }  // namespace core
 }  // namespace tasks
 }  // namespace mediapipe
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/core/utils.h b/third_party/mediapipe/src/mediapipe/tasks/cc/core/utils.h
index 54d6386..5b56c8f 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/core/utils.h
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/core/utils.h
@@ -84,6 +84,10 @@
     std::vector<std::string> input_stream_tags, std::string finished_stream_tag,
     int max_in_flight = 1, int max_in_queue = 1);
 
+// Fixs the graph config containing PreviousLoopbackCalculator where the edge
+// forming a loop needs to be tagged as back edge.
+void FixGraphBackEdges(::mediapipe::CalculatorGraphConfig& graph_config);
+
 }  // namespace core
 }  // namespace tasks
 }  // namespace mediapipe
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/metadata/utils/zip_utils.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/metadata/utils/zip_utils.cc
index b9dd784..f994d282 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/metadata/utils/zip_utils.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/metadata/utils/zip_utils.cc
@@ -141,7 +141,7 @@
   if (global_info.number_entry > 0) {
     int error = unzGoToFirstFile(zf);
     while (error == UNZ_OK) {
-      ASSIGN_OR_RETURN(auto zip_file_info, GetCurrentZipFileInfo(zf));
+      MP_ASSIGN_OR_RETURN(auto zip_file_info, GetCurrentZipFileInfo(zf));
       // Store result in map.
       (*files)[zip_file_info.name] = absl::string_view(
           buffer_data + zip_file_info.position, zip_file_info.size);
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/text/custom_ops/sentencepiece/BUILD b/third_party/mediapipe/src/mediapipe/tasks/cc/text/custom_ops/sentencepiece/BUILD
index 334ed74d..f412547 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/text/custom_ops/sentencepiece/BUILD
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/text/custom_ops/sentencepiece/BUILD
@@ -108,7 +108,7 @@
         ":sentencepiece_constants",
         "@com_google_absl//absl/status",
         "@com_google_absl//absl/status:statusor",
-        "@com_google_sentencepiece//src:sentencepiece_model_cc_proto",
+        "@com_google_sentencepiece//:sentencepiece_model_cc_proto",
     ],
 )
 
@@ -165,8 +165,8 @@
         "@com_google_absl//absl/flags:flag",
         "@com_google_absl//absl/status",
         "@com_google_absl//absl/strings:str_format",
-        "@com_google_sentencepiece//src:sentencepiece_cc_proto",
-        "@com_google_sentencepiece//src:sentencepiece_processor",
+        "@com_google_sentencepiece//:sentencepiece_cc_proto",
+        "@com_google_sentencepiece//:sentencepiece_processor",
         "@org_tensorflow//tensorflow/core:lib",
     ],
 )
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/text/language_detector/language_detector.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/text/language_detector/language_detector.cc
index 4764277..fc4abfc8 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/text/language_detector/language_detector.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/text/language_detector/language_detector.cc
@@ -112,7 +112,7 @@
 
 absl::StatusOr<LanguageDetectorResult> LanguageDetector::Detect(
     absl::string_view text) {
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       auto output_packets,
       runner_->Process(
           {{kTextStreamName, MakePacket<std::string>(std::string(text))}}));
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_classifier/BUILD b/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_classifier/BUILD
index 121b4f5..eafdc5c 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_classifier/BUILD
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_classifier/BUILD
@@ -88,7 +88,7 @@
         "@com_google_absl//absl/status",
         "@com_google_absl//absl/strings",
         "@com_google_absl//absl/strings:cord",
-        "@com_google_sentencepiece//src:sentencepiece_processor",  # fixdeps: keep
+        "@com_google_sentencepiece//:sentencepiece_processor",  # fixdeps: keep
         "@org_tensorflow//tensorflow/lite:test_util",
     ],
 )
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_classifier/text_classifier.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_classifier/text_classifier.cc
index 0ffd57c..bc1fb04 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_classifier/text_classifier.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_classifier/text_classifier.cc
@@ -91,7 +91,7 @@
 
 absl::StatusOr<TextClassifierResult> TextClassifier::Classify(
     absl::string_view text) {
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       auto output_packets,
       runner_->Process(
           {{kTextStreamName, MakePacket<std::string>(std::string(text))}}));
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_classifier/text_classifier_graph.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_classifier/text_classifier_graph.cc
index bd032cd..4dbe7ec 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_classifier/text_classifier_graph.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_classifier/text_classifier_graph.cc
@@ -85,11 +85,11 @@
  public:
   absl::StatusOr<CalculatorGraphConfig> GetConfig(
       SubgraphContext* sc) override {
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         const ModelResources* model_resources,
         CreateModelResources<proto::TextClassifierGraphOptions>(sc));
     Graph graph;
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         auto classifications,
         BuildTextClassifierTask(
             sc->Options<proto::TextClassifierGraphOptions>(), *model_resources,
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_embedder/BUILD b/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_embedder/BUILD
index c925abc..168bcc5 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_embedder/BUILD
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_embedder/BUILD
@@ -92,7 +92,7 @@
         "@com_google_absl//absl/flags:flag",
         "@com_google_absl//absl/status",
         "@com_google_absl//absl/status:statusor",
-        "@com_google_sentencepiece//src:sentencepiece_processor",
+        "@com_google_sentencepiece//:sentencepiece_processor",
         "@org_tensorflow//tensorflow/lite:test_util",
     ],
 )
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_embedder/text_embedder.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_embedder/text_embedder.cc
index aa98c1e..a4560d6 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_embedder/text_embedder.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_embedder/text_embedder.cc
@@ -87,7 +87,7 @@
 }
 
 absl::StatusOr<TextEmbedderResult> TextEmbedder::Embed(absl::string_view text) {
-  ASSIGN_OR_RETURN(
+  MP_ASSIGN_OR_RETURN(
       auto output_packets,
       runner_->Process(
           {{kTextInStreamName, MakePacket<std::string>(std::string(text))}}));
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_embedder/text_embedder_graph.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_embedder/text_embedder_graph.cc
index d5bdda4f..61cab6c9 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_embedder/text_embedder_graph.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/text/text_embedder/text_embedder_graph.cc
@@ -88,10 +88,11 @@
   absl::StatusOr<CalculatorGraphConfig> GetConfig(
       SubgraphContext* sc) override {
     ABSL_CHECK(sc != nullptr);
-    ASSIGN_OR_RETURN(const ModelResources* model_resources,
-                     CreateModelResources<proto::TextEmbedderGraphOptions>(sc));
+    MP_ASSIGN_OR_RETURN(
+        const ModelResources* model_resources,
+        CreateModelResources<proto::TextEmbedderGraphOptions>(sc));
     Graph graph;
-    ASSIGN_OR_RETURN(
+    MP_ASSIGN_OR_RETURN(
         Source<EmbeddingResult> embedding_result_out,
         BuildTextEmbedderTask(sc->Options<proto::TextEmbedderGraphOptions>(),
                               *model_resources,
@@ -142,8 +143,8 @@
 
     // The UniversalSentenceEncoder model has an extraneous output head.
     std::vector<absl::string_view> filtered_head_names;
-    ASSIGN_OR_RETURN(TextModelType::ModelType model_type,
-                     GetModelType(model_resources));
+    MP_ASSIGN_OR_RETURN(TextModelType::ModelType model_type,
+                        GetModelType(model_resources));
     if (model_type == TextModelType::USE_MODEL) {
       postprocessing_options->mutable_tensors_to_embeddings_options()
           ->add_ignored_head_names(kUSEQueryTensorName);
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/text/tokenizers/BUILD b/third_party/mediapipe/src/mediapipe/tasks/cc/text/tokenizers/BUILD
index b299f1c..3a5c21b7 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/text/tokenizers/BUILD
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/text/tokenizers/BUILD
@@ -73,7 +73,7 @@
         "//mediapipe/framework/port:logging",
         "@com_google_absl//absl/log:absl_check",
         "@com_google_absl//absl/strings",
-        "@com_google_sentencepiece//src:sentencepiece_processor",
+        "@com_google_sentencepiece//:sentencepiece_processor",
     ],
 )
 
@@ -88,7 +88,7 @@
         "//mediapipe/framework/port:gtest_main",
         "//mediapipe/tasks/cc/core:utils",
         "@com_google_absl//absl/log:absl_check",
-        "@com_google_sentencepiece//src:sentencepiece_processor",
+        "@com_google_sentencepiece//:sentencepiece_processor",
     ],
 )
 
@@ -140,7 +140,7 @@
         "@com_google_absl//absl/status:statusor",
         "@com_google_absl//absl/strings",
         "@com_google_absl//absl/strings:cord",
-        "@com_google_sentencepiece//src:sentencepiece_processor",
+        "@com_google_sentencepiece//:sentencepiece_processor",
     ],
 )
 
diff --git a/third_party/mediapipe/src/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils.cc b/third_party/mediapipe/src/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils.cc
index 1c2faa67..0637ee9 100644
--- a/third_party/mediapipe/src/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils.cc
+++ b/third_party/mediapipe/src/mediapipe/tasks/cc/text/tokenizers/tokenizer_utils.cc
@@ -51,9 +51,9 @@
         "Invalid vocab_file from input process unit.",
         MediaPipeTasksStatus::kMetadataInvalidTokenizerError);
   }
-  ASSIGN_OR_RETURN(absl::string_view vocab_buffer,
-                   metadata_extractor->GetAssociatedFile(
-                       associated_files->Get(0)->name()->str()));
+  MP_ASSIGN_OR_RETURN(absl::string_view vocab_buffer,
+                      metadata_extractor->GetAssociatedFile(
+                          associated_files->Get(0)->name()->str()));
   return vocab_buffer;
 }
 }  // namespace
@@ -61,9 +61,9 @@
 absl::StatusOr<std::unique_ptr<RegexTokenizer>> CreateRegexTokenizerFromOptions(
     const tflite::RegexTokenizerOptions* options,
     const metadata::ModelMetadataExtractor* metadata_extractor) {
-  ASSIGN_OR_RETURN(absl::string_view vocab_buffer,
-                   CheckAndLoadFirstAssociatedFile(options->vocab_file(),
-                                                   metadata_extractor));
+  MP_ASSIGN_OR_RETURN(absl::string_view vocab_buffer,
+                      CheckAndLoadFirstAssociatedFile(options->vocab_file(),
+                                                      metadata_extractor));
   if (options->delim_regex_pattern() == nullptr) {
     return CreateStatusWithPayload(
         absl::StatusCode::kInvalidArgument,
@@ -108,9 +108,9 @@
     case tflite::ProcessUnitOptions_BertTokenizerOptions: {
       const tflite::BertTokenizerOptions* options =
           tokenizer_process_unit->options_as<tflite::BertTokenizerOptions>();
-      ASSIGN_OR_RETURN(absl::string_view vocab_buffer,
-                       CheckAndLoadFirstAssociatedFile(options->vocab_file(),
-                                                       metadata_extractor));
+      MP_ASSIGN_OR_RETURN(absl::string_view vocab_buffer,
+                          CheckAndLoadFirstAssociatedFile(options->vocab_file(),
+                                                          metadata_extractor));
       return std::make_unique<BertTokenizer>(vocab_buffer.data(),
                                              vocab_buffer.size());
     }
@@ -118,9 +118,10 @@
       const tflite::SentencePieceTokenizerOptions* options =
           tokenizer_process_unit
               ->options_as<tflite::SentencePieceTokenizerOptions>();
-      ASSIGN_OR_RETURN(absl::string_view model_buffer,
-                       CheckAndLoadFirstAssociatedFile(
-                           options->sentencePiece_model(), metadata_extractor));
+      MP_ASSIGN_OR_RETURN(
+          absl::string_view model_buffer,
+          CheckAndLoadFirstAssociatedFile(options->sentencePiece_model(),
+                                          metadata_extractor));
       return std::make_unique<SentencePieceTokenizer>(model_buffer.data(),
                                                       model_buffer.size());
     }
diff --git a/third_party/mediapipe/src/mediapipe/util/frame_buffer/frame_buffer_util.cc b/third_party/mediapipe/src/mediapipe/util/frame_buffer/frame_buffer_util.cc
index fa0ea90..9e81d858 100644
--- a/third_party/mediapipe/src/mediapipe/util/frame_buffer/frame_buffer_util.cc
+++ b/third_party/mediapipe/src/mediapipe/util/frame_buffer/frame_buffer_util.cc
@@ -244,7 +244,7 @@
   if (shape.dims.size() != 4 || shape.dims[0] != 1) {
     return absl::InvalidArgumentError("Expected tensor with batch size of 1.");
   }
-  ASSIGN_OR_RETURN(int channels, NumberOfChannels(buffer));
+  MP_ASSIGN_OR_RETURN(int channels, NumberOfChannels(buffer));
   if (shape.dims[2] != buffer.dimension().width ||
       shape.dims[1] != buffer.dimension().height || shape.dims[3] != channels) {
     return absl::InvalidArgumentError(
@@ -260,8 +260,8 @@
 // output YuvBuffer is agnostic to the YUV format since the YUV buffers are
 // managed individually.
 absl::StatusOr<YuvBuffer> CreateYuvBuffer(const FrameBuffer& buffer) {
-  ASSIGN_OR_RETURN(FrameBuffer::YuvData yuv_data,
-                   FrameBuffer::GetYuvDataFromFrameBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(FrameBuffer::YuvData yuv_data,
+                      FrameBuffer::GetYuvDataFromFrameBuffer(buffer));
   return YuvBuffer(const_cast<uint8_t*>(yuv_data.y_buffer),
                    const_cast<uint8_t*>(yuv_data.u_buffer),
                    const_cast<uint8_t*>(yuv_data.v_buffer),
@@ -293,8 +293,8 @@
 
 absl::Status CropGrayscale(const FrameBuffer& buffer, int x0, int y0, int x1,
                            int y1, FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateGrayBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateGrayBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateGrayBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateGrayBuffer(*output_buffer));
   bool success_crop = input.Crop(x0, y0, x1, y1);
   if (!success_crop) {
     return absl::UnknownError("Halide grayscale crop operation failed.");
@@ -308,8 +308,8 @@
 
 absl::Status ResizeGrayscale(const FrameBuffer& buffer,
                              FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateGrayBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateGrayBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateGrayBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateGrayBuffer(*output_buffer));
   return input.Resize(&output)
              ? absl::OkStatus()
              : absl::UnknownError("Halide grayscale resize operation failed.");
@@ -317,8 +317,8 @@
 
 absl::Status RotateGrayscale(const FrameBuffer& buffer, int angle_deg,
                              FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateGrayBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateGrayBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateGrayBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateGrayBuffer(*output_buffer));
   return input.Rotate(angle_deg % 360, &output)
              ? absl::OkStatus()
              : absl::UnknownError("Halide grayscale rotate operation failed.");
@@ -326,8 +326,8 @@
 
 absl::Status FlipHorizontallyGrayscale(const FrameBuffer& buffer,
                                        FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateGrayBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateGrayBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateGrayBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateGrayBuffer(*output_buffer));
   return input.FlipHorizontally(&output)
              ? absl::OkStatus()
              : absl::UnknownError(
@@ -336,8 +336,8 @@
 
 absl::Status FlipVerticallyGrayscale(const FrameBuffer& buffer,
                                      FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateGrayBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateGrayBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateGrayBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateGrayBuffer(*output_buffer));
   return input.FlipVertically(&output)
              ? absl::OkStatus()
              : absl::UnknownError(
@@ -348,25 +348,25 @@
 //------------------------------------------------------------------------------
 
 absl::Status ResizeRgb(const FrameBuffer& buffer, FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateRgbBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateRgbBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateRgbBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateRgbBuffer(*output_buffer));
   return input.Resize(&output)
              ? absl::OkStatus()
              : absl::UnknownError("Halide rgb[a] resize operation failed.");
 }
 
 absl::Status ConvertRgb(const FrameBuffer& buffer, FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateRgbBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateRgbBuffer(buffer));
   bool result = false;
   if (output_buffer->format() == FrameBuffer::Format::kGRAY) {
-    ASSIGN_OR_RETURN(auto output, CreateGrayBuffer(*output_buffer));
+    MP_ASSIGN_OR_RETURN(auto output, CreateGrayBuffer(*output_buffer));
     result = input.Convert(&output);
   } else if (IsSupportedYuvBuffer(*output_buffer)) {
-    ASSIGN_OR_RETURN(auto output, CreateYuvBuffer(*output_buffer));
+    MP_ASSIGN_OR_RETURN(auto output, CreateYuvBuffer(*output_buffer));
     result = input.Convert(&output);
   } else if (output_buffer->format() == FrameBuffer::Format::kRGBA ||
              output_buffer->format() == FrameBuffer::Format::kRGB) {
-    ASSIGN_OR_RETURN(auto output, CreateRgbBuffer(*output_buffer));
+    MP_ASSIGN_OR_RETURN(auto output, CreateRgbBuffer(*output_buffer));
     result = input.Convert(&output);
   }
   return result ? absl::OkStatus()
@@ -375,8 +375,8 @@
 
 absl::Status CropRgb(const FrameBuffer& buffer, int x0, int y0, int x1, int y1,
                      FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateRgbBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateRgbBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateRgbBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateRgbBuffer(*output_buffer));
   bool success_crop = input.Crop(x0, y0, x1, y1);
   if (!success_crop) {
     return absl::UnknownError("Halide rgb[a] crop operation failed.");
@@ -390,8 +390,8 @@
 
 absl::Status FlipHorizontallyRgb(const FrameBuffer& buffer,
                                  FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateRgbBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateRgbBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateRgbBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateRgbBuffer(*output_buffer));
   return input.FlipHorizontally(&output)
              ? absl::OkStatus()
              : absl::UnknownError(
@@ -400,8 +400,8 @@
 
 absl::Status FlipVerticallyRgb(const FrameBuffer& buffer,
                                FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateRgbBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateRgbBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateRgbBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateRgbBuffer(*output_buffer));
   return input.FlipVertically(&output)
              ? absl::OkStatus()
              : absl::UnknownError(
@@ -410,8 +410,8 @@
 
 absl::Status RotateRgb(const FrameBuffer& buffer, int angle,
                        FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateRgbBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateRgbBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateRgbBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateRgbBuffer(*output_buffer));
   return input.Rotate(angle % 360, &output)
              ? absl::OkStatus()
              : absl::UnknownError("Halide rgb[a] rotate operation failed.");
@@ -419,8 +419,8 @@
 
 absl::Status ToFloatTensorRgb(const FrameBuffer& buffer, float scale,
                               float offset, Tensor& tensor) {
-  ASSIGN_OR_RETURN(auto input, CreateRgbBuffer(buffer));
-  ASSIGN_OR_RETURN(int channels, NumberOfChannels(buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateRgbBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(int channels, NumberOfChannels(buffer));
   auto view = tensor.GetCpuWriteView();
   float* data = view.buffer<float>();
   FloatBuffer output(data, buffer.dimension().width, buffer.dimension().height,
@@ -435,8 +435,8 @@
 
 absl::Status CropYuv(const FrameBuffer& buffer, int x0, int y0, int x1, int y1,
                      FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateYuvBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateYuvBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateYuvBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateYuvBuffer(*output_buffer));
   bool success_crop = input.Crop(x0, y0, x1, y1);
   if (!success_crop) {
     return absl::UnknownError("Halide YUV crop operation failed.");
@@ -449,8 +449,8 @@
 }
 
 absl::Status ResizeYuv(const FrameBuffer& buffer, FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateYuvBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateYuvBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateYuvBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateYuvBuffer(*output_buffer));
   return input.Resize(&output)
              ? absl::OkStatus()
              : absl::UnknownError("Halide YUV resize operation failed.");
@@ -458,8 +458,8 @@
 
 absl::Status RotateYuv(const FrameBuffer& buffer, int angle_deg,
                        FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateYuvBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateYuvBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateYuvBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateYuvBuffer(*output_buffer));
   return input.Rotate(angle_deg % 360, &output)
              ? absl::OkStatus()
              : absl::UnknownError("Halide YUV rotate operation failed.");
@@ -467,8 +467,8 @@
 
 absl::Status FlipHorizontallyYuv(const FrameBuffer& buffer,
                                  FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateYuvBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateYuvBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateYuvBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateYuvBuffer(*output_buffer));
   return input.FlipHorizontally(&output)
              ? absl::OkStatus()
              : absl::UnknownError(
@@ -477,8 +477,8 @@
 
 absl::Status FlipVerticallyYuv(const FrameBuffer& buffer,
                                FrameBuffer* output_buffer) {
-  ASSIGN_OR_RETURN(auto input, CreateYuvBuffer(buffer));
-  ASSIGN_OR_RETURN(auto output, CreateYuvBuffer(*output_buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateYuvBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto output, CreateYuvBuffer(*output_buffer));
   return input.FlipVertically(&output)
              ? absl::OkStatus()
              : absl::UnknownError("Halide YUV vertical flip operation failed.");
@@ -488,10 +488,10 @@
 // scale format.
 absl::Status ConvertYuv(const FrameBuffer& buffer, FrameBuffer* output_buffer) {
   bool success_convert = false;
-  ASSIGN_OR_RETURN(auto input, CreateYuvBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(auto input, CreateYuvBuffer(buffer));
   if (output_buffer->format() == FrameBuffer::Format::kRGBA ||
       output_buffer->format() == FrameBuffer::Format::kRGB) {
-    ASSIGN_OR_RETURN(auto output, CreateRgbBuffer(*output_buffer));
+    MP_ASSIGN_OR_RETURN(auto output, CreateRgbBuffer(*output_buffer));
     bool half_sampling = false;
     if (buffer.dimension().width / 2 == output_buffer->dimension().width &&
         buffer.dimension().height / 2 == output_buffer->dimension().height) {
@@ -517,7 +517,7 @@
     }
     success_convert = true;
   } else if (IsSupportedYuvBuffer(*output_buffer)) {
-    ASSIGN_OR_RETURN(auto output, CreateYuvBuffer(*output_buffer));
+    MP_ASSIGN_OR_RETURN(auto output, CreateYuvBuffer(*output_buffer));
     success_convert = input.Resize(&output);
   }
   return success_convert
@@ -607,8 +607,8 @@
       return std::make_shared<FrameBuffer>(planes, dimension, target_format);
     }
     case FrameBuffer::Format::kYV12: {
-      ASSIGN_OR_RETURN(const FrameBuffer::Dimension uv_dimension,
-                       GetUvPlaneDimension(dimension, target_format));
+      MP_ASSIGN_OR_RETURN(const FrameBuffer::Dimension uv_dimension,
+                          GetUvPlaneDimension(dimension, target_format));
       return CreateFromYuvRawBuffer(
           /*y_plane=*/buffer,
           /*u_plane=*/buffer + dimension.Size() + uv_dimension.Size(),
@@ -617,8 +617,8 @@
           /*pixel_stride_uv=*/1);
     }
     case FrameBuffer::Format::kYV21: {
-      ASSIGN_OR_RETURN(const FrameBuffer::Dimension uv_dimension,
-                       GetUvPlaneDimension(dimension, target_format));
+      MP_ASSIGN_OR_RETURN(const FrameBuffer::Dimension uv_dimension,
+                          GetUvPlaneDimension(dimension, target_format));
       return CreateFromYuvRawBuffer(
           /*y_plane=*/buffer, /*u_plane=*/buffer + dimension.Size(),
           /*v_plane=*/buffer + dimension.Size() + uv_dimension.Size(),
@@ -820,8 +820,8 @@
     return absl::InvalidArgumentError(
         "Only support getting biplanar UV buffer from NV12/NV21 frame buffer.");
   }
-  ASSIGN_OR_RETURN(FrameBuffer::YuvData yuv_data,
-                   FrameBuffer::GetYuvDataFromFrameBuffer(buffer));
+  MP_ASSIGN_OR_RETURN(FrameBuffer::YuvData yuv_data,
+                      FrameBuffer::GetYuvDataFromFrameBuffer(buffer));
   const uint8_t* uv_buffer = buffer.format() == FrameBuffer::Format::kNV12
                                  ? yuv_data.u_buffer
                                  : yuv_data.v_buffer;
diff --git a/third_party/mediapipe/src/mediapipe/util/rectangle_util.cc b/third_party/mediapipe/src/mediapipe/util/rectangle_util.cc
index 93850140..ab46a92 100644
--- a/third_party/mediapipe/src/mediapipe/util/rectangle_util.cc
+++ b/third_party/mediapipe/src/mediapipe/util/rectangle_util.cc
@@ -45,11 +45,11 @@
     const mediapipe::NormalizedRect& new_rect,
     absl::Span<const mediapipe::NormalizedRect> existing_rects,
     float min_similarity_threshold) {
-  ASSIGN_OR_RETURN(Rectangle_f new_rectangle, ToRectangle(new_rect));
+  MP_ASSIGN_OR_RETURN(Rectangle_f new_rectangle, ToRectangle(new_rect));
 
   for (const mediapipe::NormalizedRect& existing_rect : existing_rects) {
-    ASSIGN_OR_RETURN(Rectangle_f existing_rectangle,
-                     ToRectangle(existing_rect));
+    MP_ASSIGN_OR_RETURN(Rectangle_f existing_rectangle,
+                        ToRectangle(existing_rect));
     if (CalculateIou(existing_rectangle, new_rectangle) >
         min_similarity_threshold) {
       return true;
diff --git a/third_party/mediapipe/src/mediapipe/util/resource_util_apple.cc b/third_party/mediapipe/src/mediapipe/util/resource_util_apple.cc
index d6ca2c3..b78be35 100644
--- a/third_party/mediapipe/src/mediapipe/util/resource_util_apple.cc
+++ b/third_party/mediapipe/src/mediapipe/util/resource_util_apple.cc
@@ -50,7 +50,7 @@
     ABSL_LOG(WARNING)
         << "Setting \"read_as_binary\" to false is a no-op on ios.";
   }
-  ASSIGN_OR_RETURN(std::string full_path, PathToResourceAsFile(path));
+  MP_ASSIGN_OR_RETURN(std::string full_path, PathToResourceAsFile(path));
   return file::GetContents(full_path, output, read_as_binary);
 }
 }  // namespace internal
diff --git a/third_party/mediapipe/src/mediapipe/util/tflite/tflite_gpu_runner.cc b/third_party/mediapipe/src/mediapipe/util/tflite/tflite_gpu_runner.cc
index 6a132ac6..642fb71 100644
--- a/third_party/mediapipe/src/mediapipe/util/tflite/tflite_gpu_runner.cc
+++ b/third_party/mediapipe/src/mediapipe/util/tflite/tflite_gpu_runner.cc
@@ -237,7 +237,7 @@
 
   if (serialized_model_.empty() &&
       opencl_init_from_serialized_model_is_forced_) {
-    ASSIGN_OR_RETURN(serialized_model_, GetSerializedModel());
+    MP_ASSIGN_OR_RETURN(serialized_model_, GetSerializedModel());
   }
 
   // Try to initialize from serialized model first.
diff --git a/third_party/mediapipe/src/mediapipe/util/tflite/tflite_model_loader.cc b/third_party/mediapipe/src/mediapipe/util/tflite/tflite_model_loader.cc
index a2a3cc2b..766543f 100644
--- a/third_party/mediapipe/src/mediapipe/util/tflite/tflite_model_loader.cc
+++ b/third_party/mediapipe/src/mediapipe/util/tflite/tflite_model_loader.cc
@@ -31,8 +31,8 @@
   // TODO: get rid of manual resolving with PathToResourceAsFile
   // as soon as it's incorporated into GetResourceContents.
   if (!status_or_content.ok()) {
-    ASSIGN_OR_RETURN(auto resolved_path,
-                     mediapipe::PathToResourceAsFile(model_path));
+    MP_ASSIGN_OR_RETURN(auto resolved_path,
+                        mediapipe::PathToResourceAsFile(model_path));
     VLOG(2) << "Loading the model from " << resolved_path;
     MP_RETURN_IF_ERROR(
         mediapipe::GetResourceContents(resolved_path, &model_blob));
diff --git a/third_party/mediapipe/src/third_party/com_github_glog_glog_windows_patch.diff b/third_party/mediapipe/src/third_party/com_github_glog_glog_windows_patch.diff
new file mode 100644
index 0000000..250be11
--- /dev/null
+++ b/third_party/mediapipe/src/third_party/com_github_glog_glog_windows_patch.diff
@@ -0,0 +1,26 @@
+diff --git a/bazel/glog.bzl b/bazel/glog.bzl
+index dacd934..d7b3d78 100644
+--- a/bazel/glog.bzl
++++ b/bazel/glog.bzl
+@@ -53,7 +53,6 @@ def glog_library(namespace = "google", with_gflags = 1, **kwargs):
+     )
+ 
+     common_copts = [
+-        "-std=c++14",
+         "-DGLOG_BAZEL_BUILD",
+         # Inject a C++ namespace.
+         "-DGOOGLE_NAMESPACE='%s'" % namespace,
+@@ -145,7 +144,13 @@ def glog_library(namespace = "google", with_gflags = 1, **kwargs):
+         ],
+     })
+ 
++    c14_opts = ["-std=c++14"]
++    c17_opts = ["-std=c++17"]
++
+     final_lib_copts = select({
++        "@bazel_tools//src/conditions:windows": c17_opts,
++         "//conditions:default": c14_opts,
++    }) + select({
+         "@bazel_tools//src/conditions:windows": common_copts + windows_only_copts,
+         "@bazel_tools//src/conditions:darwin": common_copts + linux_or_darwin_copts + darwin_only_copts,
+         "@bazel_tools//src/conditions:freebsd": common_copts + linux_or_darwin_copts + freebsd_only_copts,
diff --git a/third_party/mediapipe/src/third_party/com_google_sentencepiece.diff b/third_party/mediapipe/src/third_party/com_google_sentencepiece.diff
new file mode 100644
index 0000000..4534397
--- /dev/null
+++ b/third_party/mediapipe/src/third_party/com_google_sentencepiece.diff
@@ -0,0 +1,808 @@
+diff --git a/src/bpe_model.cc b/src/bpe_model.cc
+index 22cd115..97e0bda 100644
+--- a/src/bpe_model.cc
++++ b/src/bpe_model.cc
+@@ -21,7 +21,7 @@
+ 
+ #include "bpe_model.h"
+ #include "freelist.h"
+-#include "third_party/absl/container/flat_hash_map.h"
++#include "absl/container/flat_hash_map.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/bpe_model_trainer.cc b/src/bpe_model_trainer.cc
+index 964d44e..ae8983c 100644
+--- a/src/bpe_model_trainer.cc
++++ b/src/bpe_model_trainer.cc
+@@ -18,7 +18,7 @@
+ #include <vector>
+ 
+ #include "bpe_model_trainer.h"
+-#include "third_party/absl/container/flat_hash_set.h"
++#include "absl/container/flat_hash_set.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/bpe_model_trainer.h b/src/bpe_model_trainer.h
+index e011a37..17f6e06 100644
+--- a/src/bpe_model_trainer.h
++++ b/src/bpe_model_trainer.h
+@@ -20,7 +20,7 @@
+ #include <vector>
+ 
+ #include "sentencepiece_model.pb.h"
+-#include "third_party/absl/container/flat_hash_map.h"
++#include "absl/container/flat_hash_map.h"
+ #include "trainer_interface.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/bpe_model_trainer_test.cc b/src/bpe_model_trainer_test.cc
+index 173eb9c..2a43c3a 100644
+--- a/src/bpe_model_trainer_test.cc
++++ b/src/bpe_model_trainer_test.cc
+@@ -20,8 +20,8 @@
+ #include "sentencepiece_processor.h"
+ #include "sentencepiece_trainer.h"
+ #include "testharness.h"
+-#include "third_party/absl/strings/str_cat.h"
+-#include "third_party/absl/strings/str_join.h"
++#include "absl/strings/str_cat.h"
++#include "absl/strings/str_join.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/builder.cc b/src/builder.cc
+index 378aaa0..1557a07 100644
+--- a/src/builder.cc
++++ b/src/builder.cc
+@@ -18,10 +18,10 @@
+ 
+ #include "builder.h"
+ #include "filesystem.h"
+-#include "third_party/absl/strings/str_join.h"
+-#include "third_party/absl/strings/str_replace.h"
+-#include "third_party/absl/strings/str_split.h"
+-#include "third_party/absl/strings/strip.h"
++#include "absl/strings/str_join.h"
++#include "absl/strings/str_replace.h"
++#include "absl/strings/str_split.h"
++#include "absl/strings/strip.h"
+ 
+ #ifdef ENABLE_NFKC_COMPILE
+ #include <unicode/errorcode.h>
+@@ -36,7 +36,7 @@
+ 
+ #include "normalization_rule.h"
+ #include "normalizer.h"
+-#include "third_party/darts_clone/darts.h"
++#include "include/darts.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/builder.h b/src/builder.h
+index 49d2884..289fab6 100644
+--- a/src/builder.h
++++ b/src/builder.h
+@@ -22,7 +22,7 @@
+ #include "common.h"
+ #include "sentencepiece_model.pb.h"
+ #include "sentencepiece_processor.h"
+-#include "third_party/absl/strings/string_view.h"
++#include "absl/strings/string_view.h"
+ 
+ namespace sentencepiece {
+ namespace normalizer {
+diff --git a/src/builder_test.cc b/src/builder_test.cc
+index 4acb7b3..1dee5c7 100644
+--- a/src/builder_test.cc
++++ b/src/builder_test.cc
+@@ -18,7 +18,7 @@
+ #include "normalizer.h"
+ #include "sentencepiece_trainer.h"
+ #include "testharness.h"
+-#include "third_party/absl/strings/str_cat.h"
++#include "absl/strings/str_cat.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/char_model_trainer_test.cc b/src/char_model_trainer_test.cc
+index 8c2e4b7..e8b4979 100644
+--- a/src/char_model_trainer_test.cc
++++ b/src/char_model_trainer_test.cc
+@@ -19,8 +19,8 @@
+ #include "filesystem.h"
+ #include "sentencepiece_processor.h"
+ #include "testharness.h"
+-#include "third_party/absl/strings/str_cat.h"
+-#include "third_party/absl/strings/str_join.h"
++#include "absl/strings/str_cat.h"
++#include "absl/strings/str_join.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/compile_charsmap_main.cc b/src/compile_charsmap_main.cc
+index c5a5188..931028b 100644
+--- a/src/compile_charsmap_main.cc
++++ b/src/compile_charsmap_main.cc
+@@ -22,8 +22,8 @@
+ #include "filesystem.h"
+ #include "init.h"
+ #include "sentencepiece_processor.h"
+-#include "third_party/absl/flags/flag.h"
+-#include "third_party/absl/strings/string_view.h"
++#include "absl/flags/flag.h"
++#include "absl/strings/string_view.h"
+ 
+ using sentencepiece::normalizer::Builder;
+ 
+diff --git a/src/error.cc b/src/error.cc
+index a226d98..ab4675d 100644
+--- a/src/error.cc
++++ b/src/error.cc
+@@ -20,8 +20,8 @@
+ #ifdef _USE_EXTERNAL_ABSL
+ // Naive workaround to define minloglevel on external absl package.
+ // We want to define them in other cc file.
+-#include "third_party/absl/flags/flag.h"
+-#include "third_party/absl/flags/parse.h"
++#include "absl/flags/flag.h"
++#include "absl/flags/parse.h"
+ ABSL_FLAG(int32, minloglevel, 0,
+           "Messages logged at a lower level than this don't actually.");
+ #endif
+diff --git a/src/filesystem.cc b/src/filesystem.cc
+index 833c8f7..6a169d9 100644
+--- a/src/filesystem.cc
++++ b/src/filesystem.cc
+@@ -15,7 +15,7 @@
+ #include <iostream>
+ 
+ #include "filesystem.h"
+-#include "third_party/absl/memory/memory.h"
++#include "absl/memory/memory.h"
+ #include "util.h"
+ 
+ #if defined(OS_WIN) && defined(UNICODE) && defined(_UNICODE)
+diff --git a/src/filesystem.h b/src/filesystem.h
+index e572b4b..dbcce48 100644
+--- a/src/filesystem.h
++++ b/src/filesystem.h
+@@ -23,7 +23,7 @@
+ 
+ #include "common.h"
+ #include "sentencepiece_processor.h"
+-#include "third_party/absl/strings/string_view.h"
++#include "absl/strings/string_view.h"
+ 
+ namespace sentencepiece {
+ namespace filesystem {
+diff --git a/src/filesystem_test.cc b/src/filesystem_test.cc
+index 790e756..39ece99 100644
+--- a/src/filesystem_test.cc
++++ b/src/filesystem_test.cc
+@@ -14,7 +14,7 @@
+ 
+ #include "filesystem.h"
+ #include "testharness.h"
+-#include "third_party/absl/strings/str_cat.h"
++#include "absl/strings/str_cat.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/init.h b/src/init.h
+index 090a2d9..acfda8a 100644
+--- a/src/init.h
++++ b/src/init.h
+@@ -16,8 +16,8 @@
+ #define INIT_H_
+ 
+ #include "common.h"
+-#include "third_party/absl/flags/flag.h"
+-#include "third_party/absl/flags/parse.h"
++#include "absl/flags/flag.h"
++#include "absl/flags/parse.h"
+ 
+ ABSL_DECLARE_FLAG(int32, minloglevel);
+ 
+diff --git a/src/model_factory.cc b/src/model_factory.cc
+index be99501..040c00c 100644
+--- a/src/model_factory.cc
++++ b/src/model_factory.cc
+@@ -15,7 +15,7 @@
+ #include "bpe_model.h"
+ #include "char_model.h"
+ #include "model_factory.h"
+-#include "third_party/absl/memory/memory.h"
++#include "absl/memory/memory.h"
+ #include "unigram_model.h"
+ #include "word_model.h"
+ 
+diff --git a/src/model_interface.cc b/src/model_interface.cc
+index c49be1e..22c6378 100644
+--- a/src/model_interface.cc
++++ b/src/model_interface.cc
+@@ -16,8 +16,8 @@
+ 
+ #include "model_interface.h"
+ #include "sentencepiece_model.pb.h"
+-#include "third_party/absl/memory/memory.h"
+-#include "third_party/absl/strings/str_format.h"
++#include "absl/memory/memory.h"
++#include "absl/strings/str_format.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/model_interface.h b/src/model_interface.h
+index aef5b53..fc14257 100644
+--- a/src/model_interface.h
++++ b/src/model_interface.h
+@@ -25,9 +25,9 @@
+ #include "normalizer.h"
+ #include "sentencepiece_model.pb.h"
+ #include "sentencepiece_processor.h"
+-#include "third_party/absl/container/flat_hash_map.h"
+-#include "third_party/absl/strings/string_view.h"
+-#include "third_party/darts_clone/darts.h"
++#include "absl/container/flat_hash_map.h"
++#include "absl/strings/string_view.h"
++#include "include/darts.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/model_interface_test.cc b/src/model_interface_test.cc
+index 69ee4e6..26a1e05 100644
+--- a/src/model_interface_test.cc
++++ b/src/model_interface_test.cc
+@@ -15,7 +15,7 @@
+ #include "model_factory.h"
+ #include "model_interface.h"
+ #include "testharness.h"
+-#include "third_party/absl/container/flat_hash_map.h"
++#include "absl/container/flat_hash_map.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/normalizer.cc b/src/normalizer.cc
+index 100b875..1791bd1 100644
+--- a/src/normalizer.cc
++++ b/src/normalizer.cc
+@@ -18,11 +18,11 @@
+ #include <vector>
+ 
+ #include "common.h"
+-#include "third_party/absl/memory/memory.h"
+-#include "third_party/absl/strings/match.h"
+-#include "third_party/absl/strings/string_view.h"
+-#include "third_party/absl/strings/strip.h"
+-#include "third_party/darts_clone/darts.h"
++#include "absl/memory/memory.h"
++#include "absl/strings/match.h"
++#include "absl/strings/string_view.h"
++#include "absl/strings/strip.h"
++#include "include/darts.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/normalizer.h b/src/normalizer.h
+index 622bbd2..1326102 100644
+--- a/src/normalizer.h
++++ b/src/normalizer.h
+@@ -24,8 +24,8 @@
+ #include "common.h"
+ #include "sentencepiece_model.pb.h"
+ #include "sentencepiece_processor.h"
+-#include "third_party/absl/strings/string_view.h"
+-#include "third_party/darts_clone/darts.h"
++#include "absl/strings/string_view.h"
++#include "include/darts.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/pretokenizer_for_training.cc b/src/pretokenizer_for_training.cc
+index 049658e..8021511 100644
+--- a/src/pretokenizer_for_training.cc
++++ b/src/pretokenizer_for_training.cc
+@@ -14,7 +14,7 @@
+ #include <string>
+ 
+ #include "pretokenizer_for_training.h"
+-#include "third_party/absl/strings/str_replace.h"
++#include "absl/strings/str_replace.h"
+ 
+ namespace sentencepiece {
+ namespace pretokenizer {
+diff --git a/src/pretokenizer_for_training.h b/src/pretokenizer_for_training.h
+index 2d3bc82..38beaa6 100644
+--- a/src/pretokenizer_for_training.h
++++ b/src/pretokenizer_for_training.h
+@@ -21,7 +21,7 @@
+ #include "common.h"
+ #include "sentencepiece.pb.h"
+ #include "sentencepiece_processor.h"
+-#include "third_party/absl/strings/string_view.h"
++#include "absl/strings/string_view.h"
+ 
+ namespace sentencepiece {
+ namespace pretokenizer {
+diff --git a/src/pretokenizer_for_training_test.cc b/src/pretokenizer_for_training_test.cc
+index 80f4787..c559eb8 100644
+--- a/src/pretokenizer_for_training_test.cc
++++ b/src/pretokenizer_for_training_test.cc
+@@ -13,7 +13,7 @@
+ // limitations under the License.!
+ #include "pretokenizer_for_training.h"
+ #include "testharness.h"
+-#include "third_party/absl/strings/str_cat.h"
++#include "absl/strings/str_cat.h"
+ #include "trainer_interface.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/sentencepiece_processor.cc b/src/sentencepiece_processor.cc
+index 1e4e7a0..1ff3990 100644
+--- a/src/sentencepiece_processor.cc
++++ b/src/sentencepiece_processor.cc
+@@ -23,14 +23,14 @@
+ #include "normalizer.h"
+ #include "sentencepiece.pb.h"
+ #include "sentencepiece_processor.h"
+-#include "third_party/absl/memory/memory.h"
+-#include "third_party/absl/strings/numbers.h"
+-#include "third_party/absl/strings/str_cat.h"
+-#include "third_party/absl/strings/str_join.h"
+-#include "third_party/absl/strings/str_replace.h"
+-#include "third_party/absl/strings/str_split.h"
+-#include "third_party/absl/strings/string_view.h"
+-#include "third_party/absl/strings/strip.h"
++#include "absl/memory/memory.h"
++#include "absl/strings/numbers.h"
++#include "absl/strings/str_cat.h"
++#include "absl/strings/str_join.h"
++#include "absl/strings/str_replace.h"
++#include "absl/strings/str_split.h"
++#include "absl/strings/string_view.h"
++#include "absl/strings/strip.h"
+ #include "unigram_model.h"
+ #include "util.h"
+ 
+diff --git a/src/sentencepiece_processor.h b/src/sentencepiece_processor.h
+index e8bd5f5..e81ebbf 100644
+--- a/src/sentencepiece_processor.h
++++ b/src/sentencepiece_processor.h
+@@ -22,7 +22,7 @@
+ #include <vector>
+ 
+ #if defined(_USE_INTERNAL_STRING_VIEW)
+-#include "third_party/absl/strings/string_view.h"
++#include "absl/strings/string_view.h"
+ #elif defined(_USE_TF_STRING_VIEW)
+ #include "absl/strings/string_view.h"
+ #else
+diff --git a/src/sentencepiece_processor_test.cc b/src/sentencepiece_processor_test.cc
+index 373e73e..829c3d4 100644
+--- a/src/sentencepiece_processor_test.cc
++++ b/src/sentencepiece_processor_test.cc
+@@ -23,10 +23,10 @@
+ #include "sentencepiece_processor.h"
+ #include "sentencepiece_trainer.h"
+ #include "testharness.h"
+-#include "third_party/absl/container/flat_hash_map.h"
+-#include "third_party/absl/memory/memory.h"
+-#include "third_party/absl/strings/str_cat.h"
+-#include "third_party/absl/strings/string_view.h"
++#include "absl/container/flat_hash_map.h"
++#include "absl/memory/memory.h"
++#include "absl/strings/str_cat.h"
++#include "absl/strings/string_view.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/sentencepiece_trainer.cc b/src/sentencepiece_trainer.cc
+index b9fe64f..47ef33c 100644
+--- a/src/sentencepiece_trainer.cc
++++ b/src/sentencepiece_trainer.cc
+@@ -22,12 +22,12 @@
+ #include "sentencepiece_model.pb.h"
+ #include "sentencepiece_trainer.h"
+ #include "spec_parser.h"
+-#include "third_party/absl/flags/flag.h"
+-#include "third_party/absl/strings/numbers.h"
+-#include "third_party/absl/strings/str_cat.h"
+-#include "third_party/absl/strings/str_split.h"
+-#include "third_party/absl/strings/string_view.h"
+-#include "third_party/absl/strings/strip.h"
++#include "absl/flags/flag.h"
++#include "absl/strings/numbers.h"
++#include "absl/strings/str_cat.h"
++#include "absl/strings/str_split.h"
++#include "absl/strings/string_view.h"
++#include "absl/strings/strip.h"
+ #include "trainer_factory.h"
+ #include "util.h"
+ 
+diff --git a/src/sentencepiece_trainer_test.cc b/src/sentencepiece_trainer_test.cc
+index e44e66b..fc73b1d 100644
+--- a/src/sentencepiece_trainer_test.cc
++++ b/src/sentencepiece_trainer_test.cc
+@@ -16,7 +16,7 @@
+ #include "sentencepiece_model.pb.h"
+ #include "sentencepiece_trainer.h"
+ #include "testharness.h"
+-#include "third_party/absl/strings/str_cat.h"
++#include "absl/strings/str_cat.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/spec_parser.h b/src/spec_parser.h
+index 2c5a95b..263f2bd 100644
+--- a/src/spec_parser.h
++++ b/src/spec_parser.h
+@@ -19,8 +19,8 @@
+ #include <vector>
+ 
+ #include "sentencepiece_processor.h"
+-#include "third_party/absl/strings/ascii.h"
+-#include "third_party/absl/strings/str_split.h"
++#include "absl/strings/ascii.h"
++#include "absl/strings/str_split.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/spm_decode_main.cc b/src/spm_decode_main.cc
+index 3382ddc..9dda65c 100644
+--- a/src/spm_decode_main.cc
++++ b/src/spm_decode_main.cc
+@@ -21,8 +21,8 @@
+ #include "init.h"
+ #include "sentencepiece.pb.h"
+ #include "sentencepiece_processor.h"
+-#include "third_party/absl/flags/flag.h"
+-#include "third_party/absl/strings/str_split.h"
++#include "absl/flags/flag.h"
++#include "absl/strings/str_split.h"
+ #include "util.h"
+ 
+ ABSL_FLAG(std::string, model, "", "model file name");
+diff --git a/src/spm_encode_main.cc b/src/spm_encode_main.cc
+index 4d12a38..29b7458 100644
+--- a/src/spm_encode_main.cc
++++ b/src/spm_encode_main.cc
+@@ -21,10 +21,10 @@
+ #include "init.h"
+ #include "sentencepiece.pb.h"
+ #include "sentencepiece_processor.h"
+-#include "third_party/absl/container/flat_hash_map.h"
+-#include "third_party/absl/flags/flag.h"
+-#include "third_party/absl/strings/str_cat.h"
+-#include "third_party/absl/strings/str_join.h"
++#include "absl/container/flat_hash_map.h"
++#include "absl/flags/flag.h"
++#include "absl/strings/str_cat.h"
++#include "absl/strings/str_join.h"
+ #include "trainer_interface.h"
+ 
+ ABSL_FLAG(std::string, model, "", "model file name");
+diff --git a/src/spm_export_vocab_main.cc b/src/spm_export_vocab_main.cc
+index b5d93cb..70a65c1 100644
+--- a/src/spm_export_vocab_main.cc
++++ b/src/spm_export_vocab_main.cc
+@@ -20,7 +20,7 @@
+ #include "init.h"
+ #include "sentencepiece_model.pb.h"
+ #include "sentencepiece_processor.h"
+-#include "third_party/absl/flags/flag.h"
++#include "absl/flags/flag.h"
+ 
+ ABSL_FLAG(std::string, output, "", "Output filename");
+ ABSL_FLAG(std::string, model, "", "input model file name");
+diff --git a/src/spm_normalize_main.cc b/src/spm_normalize_main.cc
+index 96da360..8c541b8 100644
+--- a/src/spm_normalize_main.cc
++++ b/src/spm_normalize_main.cc
+@@ -21,7 +21,7 @@
+ #include "sentencepiece_model.pb.h"
+ #include "sentencepiece_processor.h"
+ #include "sentencepiece_trainer.h"
+-#include "third_party/absl/flags/flag.h"
++#include "absl/flags/flag.h"
+ 
+ ABSL_FLAG(std::string, model, "", "Model file name");
+ ABSL_FLAG(bool, use_internal_normalization, false,
+diff --git a/src/spm_train_main.cc b/src/spm_train_main.cc
+index baf8dbf..ba1e811 100644
+--- a/src/spm_train_main.cc
++++ b/src/spm_train_main.cc
+@@ -18,10 +18,10 @@
+ #include "init.h"
+ #include "sentencepiece_model.pb.h"
+ #include "sentencepiece_trainer.h"
+-#include "third_party/absl/flags/flag.h"
+-#include "third_party/absl/strings/ascii.h"
+-#include "third_party/absl/strings/str_join.h"
+-#include "third_party/absl/strings/str_split.h"
++#include "absl/flags/flag.h"
++#include "absl/strings/ascii.h"
++#include "absl/strings/str_join.h"
++#include "absl/strings/str_split.h"
+ #include "util.h"
+ 
+ using sentencepiece::NormalizerSpec;
+diff --git a/src/testharness.cc b/src/testharness.cc
+index f6b1efe..daf2d14 100644
+--- a/src/testharness.cc
++++ b/src/testharness.cc
+@@ -26,7 +26,7 @@
+ #include <vector>
+ 
+ #include "common.h"
+-#include "third_party/absl/strings/str_cat.h"
++#include "absl/strings/str_cat.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/testharness.h b/src/testharness.h
+index 9879b06..98317ad 100644
+--- a/src/testharness.h
++++ b/src/testharness.h
+@@ -21,9 +21,9 @@
+ #include <string>
+ 
+ #include "common.h"
+-#include "third_party/absl/flags/flag.h"
+-#include "third_party/absl/flags/parse.h"
+-#include "third_party/absl/strings/string_view.h"
++#include "absl/flags/flag.h"
++#include "absl/flags/parse.h"
++#include "absl/strings/string_view.h"
+ 
+ ABSL_DECLARE_FLAG(std::string, test_tmpdir);
+ ABSL_DECLARE_FLAG(std::string, test_srcdir);
+diff --git a/src/trainer_factory.cc b/src/trainer_factory.cc
+index d1d2541..ff594d0 100644
+--- a/src/trainer_factory.cc
++++ b/src/trainer_factory.cc
+@@ -14,7 +14,7 @@
+ 
+ #include "bpe_model_trainer.h"
+ #include "char_model_trainer.h"
+-#include "third_party/absl/memory/memory.h"
++#include "absl/memory/memory.h"
+ #include "trainer_factory.h"
+ #include "unigram_model_trainer.h"
+ #include "word_model_trainer.h"
+diff --git a/src/trainer_interface.cc b/src/trainer_interface.cc
+index a3a4b74..70f2f72 100644
+--- a/src/trainer_interface.cc
++++ b/src/trainer_interface.cc
+@@ -26,13 +26,13 @@
+ #include "normalizer.h"
+ #include "sentencepiece_processor.h"
+ #include "sentencepiece_trainer.h"
+-#include "third_party/absl/container/flat_hash_map.h"
+-#include "third_party/absl/memory/memory.h"
+-#include "third_party/absl/strings/numbers.h"
+-#include "third_party/absl/strings/str_cat.h"
+-#include "third_party/absl/strings/str_format.h"
+-#include "third_party/absl/strings/str_join.h"
+-#include "third_party/absl/strings/str_split.h"
++#include "absl/container/flat_hash_map.h"
++#include "absl/memory/memory.h"
++#include "absl/strings/numbers.h"
++#include "absl/strings/str_cat.h"
++#include "absl/strings/str_format.h"
++#include "absl/strings/str_join.h"
++#include "absl/strings/str_split.h"
+ #include "trainer_interface.h"
+ #include "unicode_script.h"
+ #include "util.h"
+diff --git a/src/trainer_interface.h b/src/trainer_interface.h
+index f66d59a..8a654ec 100644
+--- a/src/trainer_interface.h
++++ b/src/trainer_interface.h
+@@ -27,7 +27,7 @@
+ #include "sentencepiece_model.pb.h"
+ #include "sentencepiece_processor.h"
+ #include "sentencepiece_trainer.h"
+-#include "third_party/absl/container/flat_hash_map.h"
++#include "absl/container/flat_hash_map.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/trainer_interface_test.cc b/src/trainer_interface_test.cc
+index 70a51ad..d7f3f0c 100644
+--- a/src/trainer_interface_test.cc
++++ b/src/trainer_interface_test.cc
+@@ -16,8 +16,8 @@
+ 
+ #include "filesystem.h"
+ #include "testharness.h"
+-#include "third_party/absl/strings/str_cat.h"
+-#include "third_party/absl/strings/str_format.h"
++#include "absl/strings/str_cat.h"
++#include "absl/strings/str_format.h"
+ #include "trainer_interface.h"
+ #include "util.h"
+ 
+diff --git a/src/unicode_script.cc b/src/unicode_script.cc
+index 583dc30..11b24dc 100644
+--- a/src/unicode_script.cc
++++ b/src/unicode_script.cc
+@@ -14,7 +14,7 @@
+ 
+ #include <unordered_map>
+ 
+-#include "third_party/absl/container/flat_hash_map.h"
++#include "absl/container/flat_hash_map.h"
+ #include "unicode_script.h"
+ #include "unicode_script_map.h"
+ #include "util.h"
+diff --git a/src/unicode_script_map.h b/src/unicode_script_map.h
+index f2e67e9..f1b8299 100644
+--- a/src/unicode_script_map.h
++++ b/src/unicode_script_map.h
+@@ -14,7 +14,7 @@
+ 
+ #ifndef UNICODE_SCRIPT_DATA_H_
+ #define UNICODE_SCRIPT_DATA_H_
+-#include "third_party/absl/container/flat_hash_map.h"
++#include "absl/container/flat_hash_map.h"
+ namespace sentencepiece {
+ namespace unicode_script {
+ namespace {
+diff --git a/src/unicode_script_test.cc b/src/unicode_script_test.cc
+index ab33565..e0b1c4d 100644
+--- a/src/unicode_script_test.cc
++++ b/src/unicode_script_test.cc
+@@ -14,7 +14,7 @@
+ 
+ #include "common.h"
+ #include "testharness.h"
+-#include "third_party/absl/strings/string_view.h"
++#include "absl/strings/string_view.h"
+ #include "unicode_script.h"
+ #include "util.h"
+ 
+diff --git a/src/unigram_model.cc b/src/unigram_model.cc
+index 3b99060..9c72fb9 100644
+--- a/src/unigram_model.cc
++++ b/src/unigram_model.cc
+@@ -22,9 +22,9 @@
+ #include <utility>
+ #include <vector>
+ 
+-#include "third_party/absl/memory/memory.h"
+-#include "third_party/absl/strings/str_split.h"
+-#include "third_party/absl/strings/string_view.h"
++#include "absl/memory/memory.h"
++#include "absl/strings/str_split.h"
++#include "absl/strings/string_view.h"
+ #include "unigram_model.h"
+ #include "util.h"
+ 
+diff --git a/src/unigram_model.h b/src/unigram_model.h
+index 448e489..9062f12 100644
+--- a/src/unigram_model.h
++++ b/src/unigram_model.h
+@@ -24,7 +24,7 @@
+ #include "freelist.h"
+ #include "model_interface.h"
+ #include "sentencepiece_model.pb.h"
+-#include "third_party/darts_clone/darts.h"
++#include "include/darts.h"
+ 
+ namespace sentencepiece {
+ namespace unigram {
+diff --git a/src/unigram_model_test.cc b/src/unigram_model_test.cc
+index f93b21c..808e907 100644
+--- a/src/unigram_model_test.cc
++++ b/src/unigram_model_test.cc
+@@ -22,8 +22,8 @@
+ #include "sentencepiece_model.pb.h"
+ #include "sentencepiece_processor.h"
+ #include "testharness.h"
+-#include "third_party/absl/strings/str_cat.h"
+-#include "third_party/absl/strings/str_join.h"
++#include "absl/strings/str_cat.h"
++#include "absl/strings/str_join.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/unigram_model_trainer.cc b/src/unigram_model_trainer.cc
+index 9615040..373ec95 100644
+--- a/src/unigram_model_trainer.cc
++++ b/src/unigram_model_trainer.cc
+@@ -25,8 +25,8 @@
+ #include "normalizer.h"
+ #include "pretokenizer_for_training.h"
+ #include "sentencepiece_trainer.h"
+-#include "third_party/absl/container/flat_hash_map.h"
+-#include "third_party/absl/memory/memory.h"
++#include "absl/container/flat_hash_map.h"
++#include "absl/memory/memory.h"
+ #include "third_party/esaxx/esa.hxx"  // Suffix array library.
+ #include "unicode_script.h"
+ #include "unigram_model_trainer.h"
+diff --git a/src/unigram_model_trainer.h b/src/unigram_model_trainer.h
+index 91fbeb4..f2d6b36 100644
+--- a/src/unigram_model_trainer.h
++++ b/src/unigram_model_trainer.h
+@@ -21,7 +21,7 @@
+ #include <vector>
+ 
+ #include "sentencepiece_model.pb.h"
+-#include "third_party/absl/strings/string_view.h"
++#include "absl/strings/string_view.h"
+ #include "trainer_interface.h"
+ #include "unigram_model.h"
+ #include "util.h"
+diff --git a/src/unigram_model_trainer_test.cc b/src/unigram_model_trainer_test.cc
+index ffe515e..fdb25f6 100644
+--- a/src/unigram_model_trainer_test.cc
++++ b/src/unigram_model_trainer_test.cc
+@@ -16,8 +16,8 @@
+ #include "sentencepiece_processor.h"
+ #include "sentencepiece_trainer.h"
+ #include "testharness.h"
+-#include "third_party/absl/strings/str_cat.h"
+-#include "third_party/absl/strings/str_join.h"
++#include "absl/strings/str_cat.h"
++#include "absl/strings/str_join.h"
+ #include "unigram_model_trainer.h"
+ #include "util.h"
+ 
+diff --git a/src/util.h b/src/util.h
+index 0d15863..d4a2d51 100644
+--- a/src/util.h
++++ b/src/util.h
+@@ -30,7 +30,7 @@
+ 
+ #include "common.h"
+ #include "sentencepiece_processor.h"
+-#include "third_party/absl/strings/string_view.h"
++#include "absl/strings/string_view.h"
+ 
+ #ifdef SPM_NO_THREADLOCAL
+ #include <pthread.h>
+diff --git a/src/util_test.cc b/src/util_test.cc
+index 71d006f..231fc96 100644
+--- a/src/util_test.cc
++++ b/src/util_test.cc
+@@ -16,7 +16,7 @@
+ 
+ #include "filesystem.h"
+ #include "testharness.h"
+-#include "third_party/absl/strings/str_cat.h"
++#include "absl/strings/str_cat.h"
+ #include "util.h"
+ 
+ namespace sentencepiece {
+diff --git a/src/word_model_trainer.cc b/src/word_model_trainer.cc
+index 0b8b062..b057843 100644
+--- a/src/word_model_trainer.cc
++++ b/src/word_model_trainer.cc
+@@ -15,8 +15,8 @@
+ #include <cmath>
+ #include <string>
+ 
+-#include "third_party/absl/container/flat_hash_map.h"
+-#include "third_party/absl/strings/string_view.h"
++#include "absl/container/flat_hash_map.h"
++#include "absl/strings/string_view.h"
+ #include "util.h"
+ #include "word_model.h"
+ #include "word_model_trainer.h"
+diff --git a/src/word_model_trainer_test.cc b/src/word_model_trainer_test.cc
+index c4a8bc6..366810f 100644
+--- a/src/word_model_trainer_test.cc
++++ b/src/word_model_trainer_test.cc
+@@ -18,8 +18,8 @@
+ #include "filesystem.h"
+ #include "sentencepiece_processor.h"
+ #include "testharness.h"
+-#include "third_party/absl/strings/str_cat.h"
+-#include "third_party/absl/strings/str_join.h"
++#include "absl/strings/str_cat.h"
++#include "absl/strings/str_join.h"
+ #include "util.h"
+ #include "word_model_trainer.h"
+ 
\ No newline at end of file
diff --git a/third_party/mediapipe/src/third_party/sentencepiece.BUILD b/third_party/mediapipe/src/third_party/sentencepiece.BUILD
new file mode 100644
index 0000000..19ec771
--- /dev/null
+++ b/third_party/mediapipe/src/third_party/sentencepiece.BUILD
@@ -0,0 +1,96 @@
+package(
+    default_visibility = ["//visibility:public"],
+    features = [
+        "layering_check",
+        "parse_headers",
+    ],
+)
+
+licenses(["notice"])  # Apache 2, BSD, MIT
+
+proto_library(
+    name = "sentencepiece_proto",
+    srcs = ["src/sentencepiece.proto"],
+)
+
+cc_proto_library(
+    name = "sentencepiece_cc_proto",
+    deps = [":sentencepiece_proto"],
+)
+
+proto_library(
+    name = "sentencepiece_model_proto",
+    srcs = ["src/sentencepiece_model.proto"],
+)
+
+cc_proto_library(
+    name = "sentencepiece_model_cc_proto",
+    deps = [":sentencepiece_model_proto"],
+)
+
+genrule(
+    name = "config_h",
+    srcs = ["config.h.in"],
+    outs = ["config.h"],
+    cmd = "cp $< $@",
+)
+
+cc_library(
+    name = "common",
+    hdrs = [
+        "config.h",
+        "src/common.h",
+    ],
+    deps = [
+        "@com_google_absl//absl/base",
+    ],
+)
+
+cc_library(
+    name = "sentencepiece_processor",
+    srcs = [
+        "src/bpe_model.cc",
+        "src/char_model.cc",
+        "src/error.cc",
+        "src/filesystem.cc",
+        "src/model_factory.cc",
+        "src/model_interface.cc",
+        "src/normalizer.cc",
+        "src/sentencepiece_processor.cc",
+        "src/unigram_model.cc",
+        "src/util.cc",
+        "src/word_model.cc",
+    ],
+    hdrs = [
+        "src/bpe_model.h",
+        "src/char_model.h",
+        "src/filesystem.h",
+        "src/freelist.h",
+        "src/model_factory.h",
+        "src/model_interface.h",
+        "src/normalizer.h",
+        "src/sentencepiece_processor.h",
+        "src/trainer_interface.h",
+        "src/unigram_model.h",
+        "src/util.h",
+        "src/word_model.h",
+    ],
+    defines = ["_USE_TF_STRING_VIEW"],
+    includes = [
+        ".",
+        "src",
+    ],
+    linkstatic = 1,
+    deps =
+        [
+            ":common",
+            ":sentencepiece_cc_proto",
+            ":sentencepiece_model_cc_proto",
+            "@com_google_absl//absl/container:flat_hash_map",
+            "@com_google_absl//absl/container:flat_hash_set",
+            "@com_google_absl//absl/memory",
+            "@com_google_absl//absl/strings",
+            "@com_google_absl//absl/strings:str_format",
+            "@darts_clone",
+        ],
+)
diff --git a/third_party/mediapipe/src/third_party/wasm_files.bzl b/third_party/mediapipe/src/third_party/wasm_files.bzl
index e92b4c6..f6256b91 100644
--- a/third_party/mediapipe/src/third_party/wasm_files.bzl
+++ b/third_party/mediapipe/src/third_party/wasm_files.bzl
@@ -12,72 +12,72 @@
 
     http_file(
         name = "com_google_mediapipe_wasm_audio_wasm_internal_js",
-        sha256 = "ac039c8da1744daf69204774a62ef2454c43f583079e4d6019c7d9d649a88296",
-        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.js?generation=1694462959229481"],
+        sha256 = "bb10ba65b0135f3d22c380bd87712f6a859ecdebdf1e3243407bc2f3ac5ccf71",
+        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.js?generation=1696624044559284"],
     )
 
     http_file(
         name = "com_google_mediapipe_wasm_audio_wasm_internal_wasm",
-        sha256 = "8350845781aa409282f9ee032954051c23a05f3924d5fab351c70ab8238ff178",
-        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.wasm?generation=1694462961688784"],
+        sha256 = "01079a05e1ce4963e3a78cd5fee8f33be9fda10f1c6c450d00cf71251d817e0c",
+        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_internal.wasm?generation=1696624047350232"],
     )
 
     http_file(
         name = "com_google_mediapipe_wasm_audio_wasm_nosimd_internal_js",
-        sha256 = "bc327080eef396f1eec0279aba39f4c8e2c62ce9bd2b1926250b653be3b40f75",
-        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.js?generation=1694462963880649"],
+        sha256 = "c9484189261601052357359edd4a8575b0d51d0ce12cf3343d12a933307303c6",
+        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.js?generation=1696624049287593"],
     )
 
     http_file(
         name = "com_google_mediapipe_wasm_audio_wasm_nosimd_internal_wasm",
-        sha256 = "fa78cd7e0739dad3ce32a29c3efabf7d726cab3fd3d502376718ccee2e636ee7",
-        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.wasm?generation=1694462966325219"],
+        sha256 = "c00c3455b9ca1f477879383dde7a5853e1bac06cad8c48088c53c6bd1bcd3890",
+        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/audio_wasm_nosimd_internal.wasm?generation=1696624051752560"],
     )
 
     http_file(
         name = "com_google_mediapipe_wasm_text_wasm_internal_js",
-        sha256 = "310cfddc2f4cd9b77ee5e52873b934cc4b36febb3eebf50179c32a945227181a",
-        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.js?generation=1694462968420889"],
+        sha256 = "b5a8b98ac3927c28b462f8a0f9523fb7b0b6ac720a0009ba2c4f211516cc5a5e",
+        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.js?generation=1696624053716124"],
     )
 
     http_file(
         name = "com_google_mediapipe_wasm_text_wasm_internal_wasm",
-        sha256 = "6cb3f9ffcb115d2194d5db7423892e1878f6a9f22c47be3d0ccbe7509f0f2451",
-        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.wasm?generation=1694462970962013"],
+        sha256 = "a5f28b7aa458f7e34c78cb90aac0fc3a228a5d0f3ae675fb7a5e2dca4299363c",
+        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_internal.wasm?generation=1696624056400203"],
     )
 
     http_file(
         name = "com_google_mediapipe_wasm_text_wasm_nosimd_internal_js",
-        sha256 = "9ba9de60d9f76fd7a757a76d91492b5452717ccde3fbf48c0e0fc772e13e9955",
-        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.js?generation=1694462973078901"],
+        sha256 = "0eb6417d62f860161b504a72c88659a6a866b36e477da600630bebaca01bf7c6",
+        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.js?generation=1696624058379631"],
     )
 
     http_file(
         name = "com_google_mediapipe_wasm_text_wasm_nosimd_internal_wasm",
-        sha256 = "84f75a001201c80101d7414c421ff394fae163a633859aded255c66ad5d43393",
-        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.wasm?generation=1694462975552723"],
+        sha256 = "af9e62a8e63ea38e3f984f2937cd856cb6a599cdda169bb1c29169a1a08f60f9",
+        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/text_wasm_nosimd_internal.wasm?generation=1696624060772680"],
     )
 
     http_file(
         name = "com_google_mediapipe_wasm_vision_wasm_internal_js",
-        sha256 = "83564c478f223b8f48f118ee1a44cb1e6ae0c6852a2d3f92578f1ee428d583a3",
-        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.js?generation=1694462977711637"],
+        sha256 = "addc64f89585eaa7322f649158d57ac70fd0e9ae0d37f4aeb4016b04d0e18d2a",
+        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.js?generation=1696624062874405"],
     )
 
     http_file(
         name = "com_google_mediapipe_wasm_vision_wasm_internal_wasm",
-        sha256 = "82ce4e58488ae07160f1cc9c1aeb09795b95401687845e370ddfab9b1d262051",
-        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.wasm?generation=1694462980930015"],
+        sha256 = "357a65e76313ceb65ffec453c47275abfc387b7b6e77823b6c4c016ab7a40cf5",
+        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_internal.wasm?generation=1696624065934602"],
     )
 
     http_file(
         name = "com_google_mediapipe_wasm_vision_wasm_nosimd_internal_js",
-        sha256 = "64cd4d0671a092c578a4e016653b217d8bf6294645f2e58bf1bdaab8a2c66b0c",
-        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.js?generation=1694462983062269"],
+        sha256 = "c41e7c4b00d2ab701d6e805917a26da7b563737fd12671f2f3496c036c94d633",
+        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.js?generation=1696624067936821"],
     )
 
     http_file(
         name = "com_google_mediapipe_wasm_vision_wasm_nosimd_internal_wasm",
-        sha256 = "1774eb27bdca99c316e56a04a060ac5deade518ae57a2259a76d0fa9e526bd1d",
-        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.wasm?generation=1694462985858237"],
+        sha256 = "620986d18baa69934579bbd701d72532cedc2a6b052932cb19e302bd748afcba",
+        urls = ["https://storage.googleapis.com/mediapipe-assets/wasm/vision_wasm_nosimd_internal.wasm?generation=1696624070556427"],
     )
diff --git a/third_party/pdfium b/third_party/pdfium
index f51bfc7..0bb4790 160000
--- a/third_party/pdfium
+++ b/third_party/pdfium
@@ -1 +1 @@
-Subproject commit f51bfc7f6b03b942534d9cab8fe4cb7c3b75420d
+Subproject commit 0bb4790a4455400532900b350d967260fa1ea552
diff --git a/third_party/perfetto b/third_party/perfetto
index 43f878ea..34f1b98 160000
--- a/third_party/perfetto
+++ b/third_party/perfetto
@@ -1 +1 @@
-Subproject commit 43f878eaee4f5cd96b7404f6830af679a283ebce
+Subproject commit 34f1b98dca5071866b2f0778605dcea0a3d1fbef
diff --git a/third_party/re2/src b/third_party/re2/src
index ece4cec..928a015 160000
--- a/third_party/re2/src
+++ b/third_party/re2/src
@@ -1 +1 @@
-Subproject commit ece4cecab5c8445d93abd98d88c899f370b4ea4a
+Subproject commit 928a015e6ecc02519abb5d4a8732099545c48346
diff --git a/third_party/robolectric/BUILD.gn b/third_party/robolectric/BUILD.gn
index 6cfa72e..e795e91 100644
--- a/third_party/robolectric/BUILD.gn
+++ b/third_party/robolectric/BUILD.gn
@@ -7,7 +7,6 @@
 group("robolectric_runtime_jars") {
   testonly = true
   data = [
-    "lib/android-all-instrumented-4.4_r1-robolectric-r2-i4.jar",
     "lib/android-all-instrumented-5.0.2_r3-robolectric-r0-i4.jar",
     "lib/android-all-instrumented-6.0.1_r3-robolectric-r1-i4.jar",
     "lib/android-all-instrumented-7.0.0_r1-robolectric-r1-i4.jar",
@@ -20,11 +19,12 @@
     "lib/android-all-instrumented-12-robolectric-7732740-i4.jar",
     "lib/android-all-instrumented-12.1-robolectric-8229987-i4.jar",
     "lib/android-all-instrumented-13-robolectric-9030017-i4.jar",
+    "lib/android-all-instrumented-14-robolectric-10818077-i4.jar",
   ]
 }
 
 # Robolectric tests compile against the robolectric sdk. This should be kept in
 # sync with the latest version in //third_party/android_sdk.
 android_system_java_prebuilt("robolectric_test_sdk_java") {
-  jar_path = "lib/android-all-13-robolectric-9030017.jar"
+  jar_path = "lib/android-all-14-robolectric-10818077.jar"
 }
diff --git a/third_party/robolectric/cipd.yaml b/third_party/robolectric/cipd.yaml
deleted file mode 100644
index 15641802..0000000
--- a/third_party/robolectric/cipd.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2017 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# To create CIPD package run the following command.
-# cipd create --pkg-def cipd.yaml
-package: chromium/third_party/robolectric
-description: robolectric modified Android SDKs
-data:
-  - file: lib/android-all-4.4_r1-robolectric-r2.jar
-  - file: lib/android-all-5.0.2_r3-robolectric-r0.jar
-  - file: lib/android-all-7.1.0_r7-robolectric-r1.jar
-  - file: lib/android-all-8.0.0_r4-robolectric-r1.jar
-  - file: lib/android-all-8.1.0-robolectric-4611349.jar
-  - file: lib/android-all-9-robolectric-4913185-2.jar
-  - file: lib/android-all-10-robolectric-5803371.jar
-
diff --git a/third_party/skia b/third_party/skia
index 8132e33..85971b25 160000
--- a/third_party/skia
+++ b/third_party/skia
@@ -1 +1 @@
-Subproject commit 8132e3356d63b576df1471f1e10d7ea2da4cd1bd
+Subproject commit 85971b25cf4b94a4843f6a4e9faa6412b3d56d92
diff --git a/third_party/vulkan-deps b/third_party/vulkan-deps
index 178effa9..07facff 160000
--- a/third_party/vulkan-deps
+++ b/third_party/vulkan-deps
@@ -1 +1 @@
-Subproject commit 178effa90318284c25994f6cf9216bc6346883f7
+Subproject commit 07facff77053becb70a23e07b60200ec6ddc8f36
diff --git a/third_party/webgpu-cts/src b/third_party/webgpu-cts/src
index 6696b0e..c78f0a43 160000
--- a/third_party/webgpu-cts/src
+++ b/third_party/webgpu-cts/src
@@ -1 +1 @@
-Subproject commit 6696b0e2df59ae2bb5a29a7b1dbb50e4109b6b55
+Subproject commit c78f0a43e79c2b0fa86dbd7775dfaed04d79b9f1
diff --git a/third_party/webrtc b/third_party/webrtc
index 1a22983..2bf3620 160000
--- a/third_party/webrtc
+++ b/third_party/webrtc
@@ -1 +1 @@
-Subproject commit 1a22983098e6ed36489bc762c945f55abfb9514e
+Subproject commit 2bf3620e13769857cdf6b28a17abe47918ccf2bd
diff --git a/tools/clang/scripts/dashboard.py b/tools/clang/scripts/dashboard.py
index 0353bcf..d11247f2 100755
--- a/tools/clang/scripts/dashboard.py
+++ b/tools/clang/scripts/dashboard.py
@@ -4,11 +4,13 @@
 # found in the LICENSE file.
 
 import argparse
+import json
 import os
 import re
 import subprocess
 import sys
 import time
+import urllib.request
 
 THIS_DIR = os.path.abspath(os.path.dirname(__file__))
 CHROMIUM_REPO = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..'))
@@ -45,13 +47,33 @@
   return int(m.group(1))
 
 
+svn2git_dict = None
+
+
+def svn2git(svn_rev):
+  global svn2git_dict
+  if not svn2git_dict:
+    # The JSON was generated with:
+    # $ ( echo '{' && git rev-list 40c47680eb2a1cb9bb7f8598c319335731bd5204 | while read commit ; do SVNREV=$(git log --format=%B -n 1 $commit | grep '^llvm-svn: [0-9]*$' | awk '{print $2 }') ; [[ ! -z '$SVNREV' ]] && echo "\"$SVNREV\": \"$commit\"," ; done && echo '}' ) | tee /tmp/llvm_svn2git.json
+    # and manually removing the trailing comma of the last entry.
+    with urllib.request.urlopen(
+        'https://commondatastorage.googleapis.com/chromium-browser-clang/llvm_svn2git.json'
+    ) as url:
+      svn2git_dict = json.load(url)
+    # For branch commits, use the most recent commit to main instead.
+    svn2git_dict['324578'] = '93505707b6d3ec117e555c5a48adc2cc56470e38'
+    svn2git_dict['149886'] = '60fc2425457f43f38edf5b310551f996f4f42df8'
+    svn2git_dict['145240'] = '12330650f843cf7613444e345a4ecfcf06923761'
+  return svn2git_dict[svn_rev]
+
+
 def clang_rolls():
   '''Return a dict from timestamp to clang revision rolled in at that time.'''
-  # The first roll using a git revision for the clang package version:
-  FIRST_GIT_ROLL = '9549a986740e03ca362144559d7d8b69644f8c5e'
+  FIRST_ROLL = 'd78457ce2895e5b98102412983a979f1896eca90'
   log = subprocess.check_output([
       'git', '-C', CHROMIUM_REPO, 'log', '--date=unix', '--pretty=fuller', '-p',
-      f'{FIRST_GIT_ROLL}..origin/main', '--', 'tools/clang/scripts/update.py'
+      f'{FIRST_ROLL}..origin/main', '--', 'tools/clang/scripts/update.py',
+      'tools/clang/scripts/update.sh'
   ]).decode('utf-8')
 
   # AuthorDate is when a commit was first authored; CommitDate (part of
@@ -61,6 +83,8 @@
   VERSION_RE = re.compile(
       r'^\+CLANG_REVISION = \'llvmorg-\d+-init-\d+-g([0-9a-f]+)\'$')
   VERSION_RE_OLD = re.compile(r'^\+CLANG_REVISION = \'([0-9a-f]{10,})\'$')
+  # +CLANG_REVISION=125186
+  VERSION_RE_SVN = re.compile(r'^\+CLANG_REVISION ?= ?\'?(\d{1,6})\'?$')
 
   rolls = {}
   date = None
@@ -68,13 +92,21 @@
     m = DATE_RE.match(line)
     if m:
       date = int(m.group(1))
-    m = VERSION_RE.match(line)
-    if not m:
-      m = VERSION_RE_OLD.match(line)
-    if m:
+      next
+
+    rev = None
+    if m := VERSION_RE.match(line):
+      rev = m.group(1)
+    elif m := VERSION_RE_OLD.match(line):
+      rev = m.group(1)
+    elif m := VERSION_RE_SVN.match(line):
+      rev = svn2git(m.group(1))
+
+    if rev:
       assert (date)
-      rolls[date] = m.group(1)
+      rolls[date] = rev
       date = None
+
   return rolls
 
 
diff --git a/tools/grit/grit/format/html_inline.py b/tools/grit/grit/format/html_inline.py
index b07b478..9ea5f2d 100755
--- a/tools/grit/grit/format/html_inline.py
+++ b/tools/grit/grit/format/html_inline.py
@@ -397,6 +397,13 @@
       return None
 
     filename = filename.replace('%DISTRIBUTION%', distribution)
+
+    if filename.startswith("%ROOT_GEN_DIR%"):
+      # Expand %ROOT_GEN_DIR%  placeholder to allow inlining generated files.
+      filename = filename.replace(
+          '%ROOT_GEN_DIR%', os.path.relpath(os.environ['root_gen_dir'],
+                                            base_path))
+
     if filename_expansion_function:
       filename = filename_expansion_function(filename)
     return os.path.normpath(os.path.join(base_path, filename))
@@ -516,6 +523,15 @@
                   lambda m: InlineCSSFile(m, '%s', filepath),
                   text)
 
+  if names_only:
+    relpath = os.path.relpath(input_filename, os.getcwd())
+    if relpath.startswith(os.path.join(os.environ['root_gen_dir'], '')):
+      # Don't attempt to read the file when `names_only` is true and the current
+      # file is a generated file, since the file is not guaranteed to exist yet,
+      # for example when invoked from grit_info.py. Inlined generated files are
+      # not supposed to rely on Grit's flattenhtml attribute anyway, therefore
+      # no more dependencies would be discovered anyway, so just return early.
+      return InlinedData(None, inlined_files)
 
   flat_text = util.ReadFile(input_filename, 'utf-8')
 
diff --git a/tools/grit/grit/format/html_inline_unittest.py b/tools/grit/grit/format/html_inline_unittest.py
index 0aa26c3f..d6c34fdc 100755
--- a/tools/grit/grit/format/html_inline_unittest.py
+++ b/tools/grit/grit/format/html_inline_unittest.py
@@ -26,6 +26,10 @@
 class HtmlInlineUnittest(unittest.TestCase):
   '''Unit tests for HtmlInline.'''
 
+  @classmethod
+  def setUpClass(cls):
+    os.environ["root_gen_dir"] = "gen"
+
   def testGetResourceFilenames(self):
     '''Tests that all included files are returned by GetResourceFilenames.'''
 
@@ -42,6 +46,7 @@
           <include src='test.html'>
           <include
               src="really-long-long-long-long-long-test-file-omg-so-long.html">
+          <script src="foo.js"></script>
         </body>
       </html>
       ''',
@@ -71,6 +76,10 @@
       ''',
 
       'test.png': 'PNG DATA',
+
+      'foo.js': '''
+      console.log('hello foo');
+      ''',
     }
 
     source_resources = set()
@@ -84,6 +93,42 @@
     self.assertEqual(resources, source_resources)
     tmp_dir.CleanUp()
 
+  def testGetResourceFilenamesWithGeneratedFile(self):
+    '''Tests that included files are returned by GetResourceFilenames, even when
+       generated files are inlined, and that no exception is thrown by
+       accidentally trying to read generated files which are not guaranteed to
+       exist yet (prod case is when this is invoked from grit_info.py).'''
+
+    # Create an HTML file that attempts to inline a generated JS file.
+    # Intentionally don't create the generated JS file to simulate he case where
+    # it does not exist yet, by the time GetResourceFilenames() is invoked.
+    files = {
+      'index.html': '''
+      <!DOCTYPE HTML>
+      <html>
+        <body>
+          <script src="%ROOT_GEN_DIR%/does_not_exist.js"></script>
+        </body>
+      </html>
+      ''',
+    }
+
+    source_resources = set()
+    tmp_dir = util.TempDir(files)
+    # `root_gen_dir` environment valiable must be specified relative to the
+    # current working directory.
+    os.environ["root_gen_dir"] = os.path.relpath(
+        os.path.join(tmp_dir.GetPath(), 'gen'))
+
+    source_resources.add(
+        tmp_dir.GetPath(os.path.join('gen', 'does_not_exist.js')))
+
+    resources = html_inline.GetResourceFilenames(tmp_dir.GetPath('index.html'),
+                                                 None)
+
+    self.assertEqual(resources, source_resources)
+    tmp_dir.CleanUp()
+
   def testUnmatchedEndIfBlock(self):
     '''Tests that an unmatched </if> raises an exception.'''
 
@@ -406,6 +451,42 @@
                          util.FixLineEnd(result.inlined_data, '\n'))
     tmp_dir.CleanUp()
 
+  def testFilenameRootGenDirExpansion(self):
+    '''Tests that %ROOT_GEN_DIR tokens in filenames are properly expanded'''
+
+    files = {
+      'index.html': '''
+      <html>
+      <body>
+      <script src="%ROOT_GEN_DIR%/foo/bar/generated.js"></script>
+      </body>
+      </html>
+      ''',
+    }
+    files[os.path.join('gen', 'foo', 'bar', 'generated.js')] = \
+        '''console.log('hello generated');'''
+
+    expected_inlined = '''
+      <html>
+      <body>
+      <script>console.log('hello generated');</script>
+      </body>
+      </html>
+      '''
+
+    source_resources = set()
+    tmp_dir = util.TempDir(files)
+    os.environ["root_gen_dir"] = os.path.relpath(
+        os.path.join(tmp_dir.GetPath(), 'gen'))
+    for filename in files:
+      source_resources.add(tmp_dir.GetPath(filename))
+
+    result = html_inline.DoInline(tmp_dir.GetPath('index.html'), None)
+    resources = result.inlined_files
+    resources.add(tmp_dir.GetPath('index.html'))
+    self.assertEqual(resources, source_resources)
+    self.assertMultiLineEqual(expected_inlined, result.inlined_data)
+
   def testFilenameVariableExpansion(self):
     '''Tests that variables are expanded in filenames before inlining.'''
 
diff --git a/tools/grit/grit/format/rc_unittest.py b/tools/grit/grit/format/rc_unittest.py
index 6200a86a..ad766e92 100755
--- a/tools/grit/grit/format/rc_unittest.py
+++ b/tools/grit/grit/format/rc_unittest.py
@@ -48,6 +48,10 @@
 
 
 class FormatRcUnittest(unittest.TestCase):
+  @classmethod
+  def setUpClass(cls):
+    os.environ["root_gen_dir"] = "gen"
+
   def testMessages(self):
     root = util.ParseGrdForUnittest("""
       <messages>
diff --git a/tools/grit/grit/gather/chrome_html_unittest.py b/tools/grit/grit/gather/chrome_html_unittest.py
index 954a2cf..b5ae72b9 100755
--- a/tools/grit/grit/gather/chrome_html_unittest.py
+++ b/tools/grit/grit/gather/chrome_html_unittest.py
@@ -31,6 +31,10 @@
 class ChromeHtmlUnittest(unittest.TestCase):
   '''Unit tests for ChromeHtml.'''
 
+  @classmethod
+  def setUpClass(cls):
+    os.environ["root_gen_dir"] = "gen"
+
   def testFileResources(self):
     '''Tests inlined image file resources with available high DPI assets.'''
 
diff --git a/tools/grit/grit/node/misc_unittest.py b/tools/grit/grit/node/misc_unittest.py
index 258a7b2..83232d1 100755
--- a/tools/grit/grit/node/misc_unittest.py
+++ b/tools/grit/grit/node/misc_unittest.py
@@ -49,6 +49,10 @@
 
 
 class GritNodeUnittest(unittest.TestCase):
+  @classmethod
+  def setUpClass(cls):
+    os.environ["root_gen_dir"] = "gen"
+
   def testUniqueNameAttribute(self):
     try:
       restree = grd_reader.Parse(
diff --git a/tools/grit/grit/node/structure_unittest.py b/tools/grit/grit/node/structure_unittest.py
index 2bc12eb..3aab4c73 100755
--- a/tools/grit/grit/node/structure_unittest.py
+++ b/tools/grit/grit/node/structure_unittest.py
@@ -44,6 +44,10 @@
 
 
 class StructureUnittest(unittest.TestCase):
+  @classmethod
+  def setUpClass(cls):
+    os.environ["root_gen_dir"] = "gen"
+
   def testSkeleton(self):
     grd = util.ParseGrdForUnittest('''
         <structures>
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
index 3892209..2d30ff7e 100644
--- a/tools/gritsettings/resource_ids.spec
+++ b/tools/gritsettings/resource_ids.spec
@@ -151,6 +151,10 @@
     "META": {"sizes": {"includes": [10],}},
     "includes": [2480],
   },
+  "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/chromeos/edu_coexistence/resources.grd": {
+    "META": {"sizes": {"includes": [20],}},
+    "includes": [2490],
+  },
   "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/chromeos/gaia_action_buttons/resources.grd": {
     "META": {"sizes": {"includes": [10],}},
     "includes": [2500],
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index a5a1326..c1c402c 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -39760,6 +39760,8 @@
   <suffix name="TabPinnedFeature" label="For tab pinned overflow hint."/>
   <suffix name="TabSearch" label="For the tab search feature."/>
   <suffix name="TabSwitcherButton" label="For tab switcher button."/>
+  <suffix name="TrackingProtectionOffboarding"
+      label="for tracking protection offboarding notice"/>
   <suffix name="TrackingProtectionOnboarding"
       label="for tracking protection onboarding notice"/>
   <suffix name="TranslateMenuButton" label="For translate menu button."/>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index e295274..d4044294 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -27237,8 +27237,15 @@
 </enum>
 
 <enum name="DeviceSettingsStaticShortcutAction">
-  <int value="0" label="Copy"/>
-  <int value="1" label="Paste"/>
+  <int value="0" label="Disable"/>
+  <int value="1" label="Copy"/>
+  <int value="2" label="Paste"/>
+  <int value="3" label="Undo"/>
+  <int value="4" label="Redo"/>
+  <int value="5" label="Zoom In"/>
+  <int value="6" label="Zoom Out"/>
+  <int value="7" label="Previous page"/>
+  <int value="8" label="Next Page"/>
 </enum>
 
 <enum name="DeviceSettingsStatus">
@@ -30119,23 +30126,26 @@
 </enum>
 
 <enum name="DownloadCommand">
-  <int value="1" label="Show in folder"/>
-  <int value="2" label="Open when complete"/>
-  <int value="3" label="Always open type"/>
-  <int value="4" label="Platform open"/>
-  <int value="5" label="Cancel"/>
-  <int value="6" label="Pause"/>
-  <int value="7" label="Resume"/>
-  <int value="8" label="Discard"/>
-  <int value="9" label="Keep"/>
-  <int value="10" label="Learn more scanning"/>
-  <int value="11" label="Learn more interrupted"/>
-  <int value="12" label="Learn more mixed content"/>
-  <int value="13" label="Copy to clipboard"/>
-  <int value="14" label="Deep scan"/>
-  <int value="15" label="Bypass deep scanning"/>
-  <int value="16" label="Review"/>
-  <int value="17" label="Retry"/>
+  <int value="0" label="Show in folder"/>
+  <int value="1" label="Open when complete"/>
+  <int value="2" label="Always open type"/>
+  <int value="3" label="Platform open"/>
+  <int value="4" label="Cancel"/>
+  <int value="5" label="Pause"/>
+  <int value="6" label="Resume"/>
+  <int value="7" label="Discard"/>
+  <int value="8" label="Keep"/>
+  <int value="9" label="Learn more scanning"/>
+  <int value="10" label="Learn more interrupted"/>
+  <int value="11" label="Learn more insecure download"/>
+  <int value="12" label="Learn more download blocked"/>
+  <int value="13" label="Open Safe Browsing setting"/>
+  <int value="14" label="Copy to clipboard"/>
+  <int value="15" label="Deep scan"/>
+  <int value="16" label="Bypass deep scanning"/>
+  <int value="17" label="Review"/>
+  <int value="18" label="Retry"/>
+  <int value="19" label="Cancel deep scan"/>
 </enum>
 
 <enum name="DownloadConnectionSecurity">
@@ -34026,7 +34036,6 @@
   <int value="1171" label="ZstdContentEncodingEnabled"/>
   <int value="1172" label="IPv6ReachabilityOverrideEnabled"/>
   <int value="1173" label="UserFeedbackWithLowLevelDebugDataAllowed"/>
-  <int value="1174" label="DeviceFlexHwDataForProductImprovementEnabled"/>
 </enum>
 
 <enum name="EnterprisePoliciesSources">
@@ -62259,6 +62268,7 @@
       label="ResamplingScrollEventsExperimentalPrediction:disabled"/>
   <int value="-1493620195"
       label="kFileSystemAccessPersistentPermissions:enabled"/>
+  <int value="-1493308731" label="WebIdentityDigitalCredentials:disabled"/>
   <int value="-1492934655" label="TabSwitcherOnReturn:enabled"/>
   <int value="-1492609320"
       label="TurnOffStreamingMediaCachingOnBattery:disabled"/>
@@ -65203,6 +65213,7 @@
   <int value="-67616014" label="PDFAnnotations:enabled"/>
   <int value="-67604092" label="LanguagePacksInSettings:enabled"/>
   <int value="-67297229" label="OfflinePagesDescriptivePendingStatus:disabled"/>
+  <int value="-67176255" label="PeripheralNotification:disabled"/>
   <int value="-66834375" label="SharesheetCopyToClipboard:enabled"/>
   <int value="-66535194" label="DesktopMinimalUI:enabled"/>
   <int value="-64839201" label="SyncUSSAutofillWalletData:disabled"/>
@@ -67233,6 +67244,7 @@
   <int value="928900043" label="OmniboxLooseMaxLimitOnDedicatedRows:disabled"/>
   <int value="928991555" label="DefaultViewportIsDeviceWidth:disabled"/>
   <int value="929462705" label="disable-link-disambiguation-popup"/>
+  <int value="929599043" label="PeripheralNotification:enabled"/>
   <int value="930187600" label="WebAssemblyExperimentalJSPI:enabled"/>
   <int value="931603226" label="ArcTouchscreenEmulation:enabled"/>
   <int value="932468127" label="LauncherPulsingBlocksRefresh:enabled"/>
@@ -69130,6 +69142,7 @@
   <int value="1841993231"
       label="AutofillRemoveCardExpirationAndTypeTitles:enabled"/>
   <int value="1842219851" label="enable-incognito-window-counter"/>
+  <int value="1842518765" label="WebIdentityDigitalCredentials:enabled"/>
   <int value="1843088575" label="OutOfBlinkCors:enabled"/>
   <int value="1843847665" label="SyncPromoAfterSigninIntercept:disabled"/>
   <int value="1844110073" label="enable-app-view"/>
@@ -73064,6 +73077,15 @@
   <int value="9" label="Exceeded allocated time for background task"/>
 </enum>
 
+<enum name="MetricState">
+  <int value="0" label="Correctly not logged"/>
+  <int value="1" label="Correctly logged"/>
+  <int value="2" label="Incorrectly not logged"/>
+  <int value="3" label="Incorrectly logged"/>
+  <int value="4" label="Incorrectly logged multiple times"/>
+  <int value="5" label="Wrong value logged"/>
+</enum>
+
 <enum name="MhtmlGenerationFinalSaveStatus">
   <int value="0" label="Success"/>
   <int value="1" label="File closing error"/>
@@ -80396,6 +80418,17 @@
   </int>
 </enum>
 
+<enum name="OnboardingStartupState">
+  <int value="0" label="kIneligible"/>
+  <int value="1" label="kEligibleWaitingToOnboard"/>
+  <int value="2" label="kOnboardedWaitingToAck"/>
+  <int value="3" label="kAckedGotIt"/>
+  <int value="4" label="kAckedSettings"/>
+  <int value="5" label="kAckedClosed"/>
+  <int value="6" label="kAckedLearnMore"/>
+  <int value="7" label="kAckedOther"/>
+</enum>
+
 <enum name="OnboardingUserActionMetric">
   <int value="0" label="Unknown"/>
   <int value="1" label="Onboarding is started by user action"/>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index 2efec70..8ee7661 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -6285,6 +6285,15 @@
   </summary>
 </histogram>
 
+<histogram name="Ash.ShortcutCustomization.CustomizationsLoadedOnStartup"
+    units="count" expires_after="2024-08-17">
+  <owner>jimmyxgong@chromium.org</owner>
+  <owner>cros-peripherals@google.com</owner>
+  <summary>
+    Record the number of customized accelerator modifications on startup.
+  </summary>
+</histogram>
+
 <histogram
     name="Ash.ShortcutCustomization.RemoveDefaultAccelerator.{ActionName}"
     units="Shortcuts" expires_after="2024-08-17">
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml
index 863356958..2f9298d 100644
--- a/tools/metrics/histograms/metadata/blink/histograms.xml
+++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -1447,7 +1447,7 @@
 </histogram>
 
 <histogram name="Blink.FedCm.LoginHint" enum="FedCmNumAccounts"
-    expires_after="2023-11-30">
+    expires_after="2024-05-18">
   <owner>npm@chromium.org</owner>
   <owner>web-identity-eng@google.com</owner>
   <summary>
@@ -1491,7 +1491,7 @@
 </histogram>
 
 <histogram name="Blink.FedCm.RpContext" enum="FedCmRpContext"
-    expires_after="2023-11-30">
+    expires_after="2024-05-18">
   <owner>npm@chromium.org</owner>
   <owner>web-identity-eng@google.com</owner>
   <summary>
@@ -1718,7 +1718,7 @@
 </histogram>
 
 <histogram name="Blink.FedCm.UserInfo.NumAccounts" enum="FedCmNumAccounts"
-    expires_after="2023-11-30">
+    expires_after="2024-05-18">
   <owner>npm@chromium.org</owner>
   <owner>web-identity-eng@google.com</owner>
   <summary>
@@ -1729,7 +1729,7 @@
 </histogram>
 
 <histogram name="Blink.FedCm.UserInfo.Status" enum="FedCmUserInfoStatus"
-    expires_after="2023-11-30">
+    expires_after="2024-05-18">
   <owner>npm@chromium.org</owner>
   <owner>web-identity-eng@google.com</owner>
   <summary>
@@ -1739,7 +1739,7 @@
 </histogram>
 
 <histogram name="Blink.FedCm.UserInfo.TimeToRequestCompleted" units="ms"
-    expires_after="2023-11-30">
+    expires_after="2024-05-18">
   <owner>npm@chromium.org</owner>
   <owner>web-identity-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/browser/histograms.xml b/tools/metrics/histograms/metadata/browser/histograms.xml
index c3b709c8..4b2aa26 100644
--- a/tools/metrics/histograms/metadata/browser/histograms.xml
+++ b/tools/metrics/histograms/metadata/browser/histograms.xml
@@ -153,6 +153,17 @@
   </summary>
 </histogram>
 
+<histogram name="Browser.ERP.ConfigFileSignatureVerificationError"
+    enum="EnterpriseCloudReportingStatusCode" expires_after="2024-06-01">
+  <owner>albertojuarez@google.com</owner>
+  <owner>src/components/reporting/OWNERS</owner>
+  <summary>
+    Recorded when ConfigurationFileController encounters an error while trying
+    to verify the signature and the signed message received from the reporting
+    server.
+  </summary>
+</histogram>
+
 <histogram name="Browser.ERP.EventEnqueueResult"
     enum="EnterpriseCloudReportingStatusCode" expires_after="2024-03-24">
   <owner>lbaraz@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/download/histograms.xml b/tools/metrics/histograms/metadata/download/histograms.xml
index 16e538e8..0a836ed 100644
--- a/tools/metrics/histograms/metadata/download/histograms.xml
+++ b/tools/metrics/histograms/metadata/download/histograms.xml
@@ -138,15 +138,17 @@
   </summary>
 </histogram>
 
-<histogram name="Download.Bubble.ProcessedCommand" enum="DownloadCommand"
-    expires_after="2024-03-17">
-  <owner>xinghuilu@chromium.org</owner>
+<histogram name="Download.Bubble.ProcessedCommand2" enum="DownloadCommand"
+    expires_after="2024-10-20">
+  <owner>chlily@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
     Records each time a download command is executed on download bubble. It is
-    logged when a quick action is clicked on the primary view or a button is
-    clicked on the subpage. Actions on context menu are excluded. Clicking the
-    trasparent button is also excluded.
+    logged when a quick action is clicked on the primary view or a button or
+    link is clicked on the security subpage. Actions on context menu are
+    excluded. Clicking the trasparent button is also excluded. This histogram
+    replaced Download.Bubble.ProcessedCommand in M120 due to the enum being
+    incorrectly numbered.
   </summary>
 </histogram>
 
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml
index 12c96d50..1e687aa 100644
--- a/tools/metrics/histograms/metadata/extensions/histograms.xml
+++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -4220,7 +4220,7 @@
 
 <histogram
     name="Extensions.ServiceWorkerBackground.FinishedExternalRequest_Result"
-    enum="ServiceWorkerStatusCode" expires_after="never">
+    enum="ServiceWorkerExternalRequestResult" expires_after="never">
 <!-- expires-never: Monitors core extension system health. -->
 
   <owner>jlulejian@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
index cabbec6..e3e097a 100644
--- a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
+++ b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
@@ -420,6 +420,8 @@
       summary="tab switcher cards with multiple tab thumbnails"/>
   <variant name="IPH_TabSearch" summary="tab search discovery"/>
   <variant name="IPH_TabSwitcherButton" summary="tab switcher button"/>
+  <variant name="IPH_TrackingProtectionOffboarding"
+      summary="tracking protection offboarding notice"/>
   <variant name="IPH_TrackingProtectionOnboarding"
       summary="tracking protection onboarding notice"/>
   <variant name="IPH_TranslateMenuButton" summary="translate menu button"/>
diff --git a/tools/metrics/histograms/metadata/file/histograms.xml b/tools/metrics/histograms/metadata/file/histograms.xml
index 64e3240a..3f99793 100644
--- a/tools/metrics/histograms/metadata/file/histograms.xml
+++ b/tools/metrics/histograms/metadata/file/histograms.xml
@@ -986,6 +986,16 @@
   </summary>
 </histogram>
 
+<histogram name="FileBrowser.OfficeFiles.Errors.{CloudProvider}.MetricState"
+    enum="MetricState" expires_after="M124">
+  <owner>simmonsjosh@google.com</owner>
+  <owner>src/ui/file_manager/OWNERS</owner>
+  <summary>
+    The state of the FileBrowser.OfficeFiles.Errors.{CloudProvider} metric.
+  </summary>
+  <token key="CloudProvider" variants="CloudProvider"/>
+</histogram>
+
 <histogram
     name="FileBrowser.OfficeFiles.FileHandler.{RootType}.{ConnectionStatus}"
     enum="OfficeFileHandler" expires_after="M124">
@@ -1235,6 +1245,24 @@
   </token>
 </histogram>
 
+<histogram
+    name="FileBrowser.OfficeFiles.Open.IOTaskError.{CloudProvider}.{Transfer}.MetricState"
+    enum="MetricState" expires_after="M124">
+  <owner>simmonsjosh@google.com</owner>
+  <owner>src/ui/file_manager/OWNERS</owner>
+  <summary>
+    The state of the
+    FileBrowser.OfficeFiles.Open.IOTaskError.{CloudProvider}.{Transfer} metric.
+  </summary>
+  <token key="CloudProvider" variants="CloudProvider"/>
+  <token key="Transfer">
+    <variant name="Copy"
+        summary="The files have been copied to {CloudProvider}"/>
+    <variant name="Move"
+        summary="The files have been moved to {CloudProvider}"/>
+  </token>
+</histogram>
+
 <histogram name="FileBrowser.OfficeFiles.Open.SourceVolume.{CloudProvider}"
     enum="OfficeFilesSourceVolume" expires_after="M124">
   <owner>austinct@chromium.org</owner>
@@ -1256,6 +1284,18 @@
   </token>
 </histogram>
 
+<histogram
+    name="FileBrowser.OfficeFiles.Open.SourceVolume.{CloudProvider}.MetricState"
+    enum="MetricState" expires_after="M124">
+  <owner>simmonsjosh@google.com</owner>
+  <owner>src/ui/file_manager/OWNERS</owner>
+  <summary>
+    The state of the FileBrowser.OfficeFiles.Open.SourceVolume.{CloudProvider}
+    metric.
+  </summary>
+  <token key="CloudProvider" variants="CloudProvider"/>
+</histogram>
+
 <histogram name="FileBrowser.OfficeFiles.Open.TransferRequired.{CloudProvider}"
     enum="OfficeFilesTransferRequired" expires_after="M124">
   <owner>simmonsjosh@google.com</owner>
@@ -1267,6 +1307,18 @@
   <token key="CloudProvider" variants="CloudProvider"/>
 </histogram>
 
+<histogram
+    name="FileBrowser.OfficeFiles.Open.TransferRequired.{CloudProvider}.MetricState"
+    enum="MetricState" expires_after="M124">
+  <owner>simmonsjosh@google.com</owner>
+  <owner>src/ui/file_manager/OWNERS</owner>
+  <summary>
+    The state of the
+    FileBrowser.OfficeFiles.Open.TransferRequired.{CloudProvider} metric.
+  </summary>
+  <token key="CloudProvider" variants="CloudProvider"/>
+</histogram>
+
 <histogram name="FileBrowser.OfficeFiles.Open.UploadResult.{CloudProvider}"
     enum="OfficeFilesUploadResult" expires_after="M124">
   <owner>simmonsjosh@google.com</owner>
@@ -1278,6 +1330,18 @@
   <token key="CloudProvider" variants="CloudProvider"/>
 </histogram>
 
+<histogram
+    name="FileBrowser.OfficeFiles.Open.UploadResult.{CloudProvider}.MetricState"
+    enum="MetricState" expires_after="M124">
+  <owner>simmonsjosh@google.com</owner>
+  <owner>src/ui/file_manager/OWNERS</owner>
+  <summary>
+    The state of the FileBrowser.OfficeFiles.Open.UploadResult.{CloudProvider}
+    metric.
+  </summary>
+  <token key="CloudProvider" variants="CloudProvider"/>
+</histogram>
+
 <histogram name="FileBrowser.OfficeFiles.Setup.CancelPage"
     enum="OfficeSetupPage" expires_after="M124">
   <owner>austinct@chromium.org</owner>
@@ -1338,6 +1402,17 @@
   </token>
 </histogram>
 
+<histogram
+    name="FileBrowser.OfficeFiles.TaskResult.{CloudProvider}.MetricState"
+    enum="MetricState" expires_after="M124">
+  <owner>simmonsjosh@google.com</owner>
+  <owner>src/ui/file_manager/OWNERS</owner>
+  <summary>
+    The state of the FileBrowser.OfficeFiles.TaskResult.{CloudProvider} metric.
+  </summary>
+  <token key="CloudProvider" variants="CloudProvider"/>
+</histogram>
+
 <histogram name="FileBrowser.OfficeFiles.UseOutsideDrive"
     enum="OfficeFilesUseOutsideDriveHook" expires_after="2024-02-25">
   <owner>cassycc@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml
index baebf82a..ecbd1a9 100644
--- a/tools/metrics/histograms/metadata/ios/histograms.xml
+++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -2409,36 +2409,6 @@
   </summary>
 </histogram>
 
-<histogram
-    name="IOS.PushNotification.NotificationAutorizationStatusChangedToAuthorized"
-    enum="PushNotificationSettingsAuthorizationStatus"
-    expires_after="2024-10-16">
-  <owner>danieltwhite@google.com</owner>
-  <owner>ajuma@google.com</owner>
-  <summary>
-    Logs the push notification iOS settings permission status the user's device
-    was previously in before the user updated their push notifications
-    permission status to enable push notifications. This histogram is logged
-    only when push notification permission status has changed and Chrome makes
-    an APNS device token request.
-  </summary>
-</histogram>
-
-<histogram
-    name="IOS.PushNotification.NotificationAutorizationStatusChangedToDenied"
-    enum="PushNotificationSettingsAuthorizationStatus"
-    expires_after="2024-10-16">
-  <owner>danieltwhite@google.com</owner>
-  <owner>ajuma@google.com</owner>
-  <summary>
-    Logs the push notification iOS settings permission status the user's device
-    was previously in before the user updated their push notifications
-    permission status to disable push notifications. This histogram is logged
-    only when push notification permission status has changed and Chrome makes
-    an APNS device token request.
-  </summary>
-</histogram>
-
 <histogram name="IOS.PushNotification.NotificationSettingsAuthorizationStatus"
     enum="PushNotificationSettingsAuthorizationStatus"
     expires_after="2024-10-11">
diff --git a/tools/metrics/histograms/metadata/payment/histograms.xml b/tools/metrics/histograms/metadata/payment/histograms.xml
index b49c0b7..378ef01 100644
--- a/tools/metrics/histograms/metadata/payment/histograms.xml
+++ b/tools/metrics/histograms/metadata/payment/histograms.xml
@@ -35,13 +35,6 @@
   </summary>
 </histogram>
 
-<histogram name="PaymentRequest.CheckoutFunnel.Aborted"
-    enum="PaymentRequestAbortReason" expires_after="2022-11-22">
-  <owner>rouslan@chromium.org</owner>
-  <owner>web-payments-team@google.com</owner>
-  <summary>The reason that lead to an abort of the Payment Request.</summary>
-</histogram>
-
 <histogram name="PaymentRequest.CheckoutFunnel.NoShow"
     enum="PaymentRequestNoShowReason" expires_after="2022-11-22">
   <owner>rouslan@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/print/histograms.xml b/tools/metrics/histograms/metadata/print/histograms.xml
index 0caa94b..87394f4 100644
--- a/tools/metrics/histograms/metadata/print/histograms.xml
+++ b/tools/metrics/histograms/metadata/print/histograms.xml
@@ -35,6 +35,21 @@
   </summary>
 </histogram>
 
+<histogram name="PrintPreview.GetPrintersTime.{PrinterType}" units="ms"
+    expires_after="2024-10-16">
+  <owner>gavinwill@chromium.org</owner>
+  <owner>cros-peripherals@google.com</owner>
+  <summary>
+    The amount of time it takes to fetch {PrinterType} printers. Recorded
+    whenever Print Preview is opened and {PrinterType} printers are requested.
+  </summary>
+  <token key="PrinterType">
+    <variant name="Extension"/>
+    <variant name="Local"/>
+    <variant name="PDF"/>
+  </token>
+</histogram>
+
 <histogram name="PrintPreview.InitialDisplayTime" units="ms"
     expires_after="2024-03-10">
   <owner>thestig@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/privacy/histograms.xml b/tools/metrics/histograms/metadata/privacy/histograms.xml
index d495bcf..a4a4ea62 100644
--- a/tools/metrics/histograms/metadata/privacy/histograms.xml
+++ b/tools/metrics/histograms/metadata/privacy/histograms.xml
@@ -897,6 +897,28 @@
 </histogram>
 
 <histogram
+    name="PrivacySandbox.TrackingProtection.Onboarding.EligibleToOnboardedDuration"
+    units="ms" expires_after="2024-09-30">
+  <owner>jacobstanley@google.com</owner>
+  <owner>koilos@google.com</owner>
+  <summary>
+    Records the duration it takes while being eligible up till onboarding to
+    3PCD. This occurs once during the process of onboarding.
+  </summary>
+</histogram>
+
+<histogram
+    name="PrivacySandbox.TrackingProtection.Onboarding.LastShownToAckedDuration"
+    units="ms" expires_after="2024-09-30">
+  <owner>jacobstanley@google.com</owner>
+  <owner>koilos@google.com</owner>
+  <summary>
+    Records the duration it takes to acknowledge the notice from the last time
+    it was shown. This occurs once during the process of onboarding.
+  </summary>
+</histogram>
+
+<histogram
     name="PrivacySandbox.TrackingProtection.Onboarding.NoticeControllerEvent"
     enum="TrackingProtectionNoticeControllerEvent" expires_after="2024-09-01">
   <owner>tommasin@chromium.org</owner>
@@ -910,6 +932,60 @@
   </summary>
 </histogram>
 
+<histogram
+    name="PrivacySandbox.TrackingProtection.Onboarding.OnboardedToAckedDuration"
+    units="ms" expires_after="2024-09-30">
+  <owner>jacobstanley@google.com</owner>
+  <owner>koilos@google.com</owner>
+  <summary>
+    Records the time it takes to acknowledge the notice for 3PCD after being
+    onboarded. This occurs once during the process of onboarding.
+  </summary>
+</histogram>
+
+<histogram
+    name="PrivacySandbox.TrackingProtection.OnboardingStartup.EligibleToOnboardedDuration"
+    units="ms" expires_after="2024-09-30">
+  <owner>jacobstanley@google.com</owner>
+  <owner>koilos@google.com</owner>
+  <summary>
+    Records the duration it takes while being eligible up till onboarding to
+    3PCD. This occurs once per profile during the startup of onboarding.
+  </summary>
+</histogram>
+
+<histogram name="PrivacySandbox.TrackingProtection.OnboardingStartup.State"
+    enum="OnboardingStartupState" expires_after="2024-09-30">
+  <owner>jacobstanley@google.com</owner>
+  <owner>koilos@google.com</owner>
+  <summary>
+    Records the state on startup of being onboarded to 3PCD. This occurs once
+    per profile during the startup of onboarding.
+  </summary>
+</histogram>
+
+<histogram
+    name="PrivacySandbox.TrackingProtection.OnboardingStartup.WaitingToAckSince"
+    units="ms" expires_after="2024-09-30">
+  <owner>jacobstanley@google.com</owner>
+  <owner>koilos@google.com</owner>
+  <summary>
+    Records the time it takes to acknowledge the notice for 3PCD after being
+    onboarded. This occurs once per profile during the startup of onboarding.
+  </summary>
+</histogram>
+
+<histogram
+    name="PrivacySandbox.TrackingProtection.OnboardingStartup.WaitingToOnboardSince"
+    units="ms" expires_after="2024-09-30">
+  <owner>jacobstanley@google.com</owner>
+  <owner>koilos@google.com</owner>
+  <summary>
+    Records the time it takes while waiting to be onboarded to 3PCD. This occurs
+    once per profile during the startup of onboarding.
+  </summary>
+</histogram>
+
 <histogram name="PrivacySandbox.{ApiType}" enum="PrivacySandboxApiAllowed"
     expires_after="M122">
   <owner>linnan@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml
index f03311a7..d16ea8e4 100644
--- a/tools/metrics/histograms/metadata/tab/histograms.xml
+++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -1064,6 +1064,20 @@
   <summary>[Android and iOS] The number of tabs opened at cold launch.</summary>
 </histogram>
 
+<histogram name="Tabs.DroppedDuplicatesCountOnSessionRestore" units="tabs"
+    expires_after="2024-10-16">
+  <owner>lpromero@google.com</owner>
+  <owner>chromeleon@google.com</owner>
+  <summary>
+    [iOS] The number of invalid duplicated tabs dropped during restoration.
+
+    Note: This tracks invalid web states that share the same identifier. These
+    web states are dropped on all session restores. This metric is not to be
+    confused with Tabs.DuplicatesCountAtStartup which counts valid duplicates
+    (i.e. different web states, with different identifiers, but the same URL).
+  </summary>
+</histogram>
+
 <histogram name="Tabs.DuplicatesCountAtStartup" units="tabs"
     expires_after="2024-03-17">
   <owner>pakzhygitov@google.com</owner>
diff --git a/tools/perf/benchmarks/jetstream2.py b/tools/perf/benchmarks/jetstream2.py
index 24255dc0..b9e2e34 100644
--- a/tools/perf/benchmarks/jetstream2.py
+++ b/tools/perf/benchmarks/jetstream2.py
@@ -85,10 +85,10 @@
     emails=['omerkatz@chromium.org'],
     component='Blink>JavaScript>GarbageCollection',
     documentation_url='https://browserbench.org/JetStream2.0/in-depth.html')
-class JetStream2MinorMC(JetStream2):
-  """Latest JetStream2 with the MinorMC flag.
+class JetStream2NoMinorMS(JetStream2):
+  """Latest JetStream2 without the MinorMS flag.
 
-  Shows the performance of upcoming MinorMC young generation GC in V8.
+  Shows the performance with Scavenger young generation GC in V8.
   """
   @classmethod
   def Name(cls):
diff --git a/tools/perf/benchmarks/octane.py b/tools/perf/benchmarks/octane.py
index f8806332..73f69e6 100644
--- a/tools/perf/benchmarks/octane.py
+++ b/tools/perf/benchmarks/octane.py
@@ -33,10 +33,10 @@
 
 @benchmark.Info(emails=['omerkatz@chromium.org'],
                 component='Blink>JavaScript>GarbageCollection')
-class OctaneMinorMC(press._PressBenchmark):  # pylint: disable=protected-access
-  """Google's Octane JavaScript benchmark with the MinorMC flag.
+class OctaneNoMinorMS(press._PressBenchmark):  # pylint: disable=protected-access
+  """Google's Octane JavaScript benchmark without the MinorMS flag.
 
-  Shows the performance of upcoming MinorMC young generation GC in V8.
+  Shows the performance of Scavenger young generation GC in V8.
 
   http://chromium.github.io/octane/index.html?auto=1
   """
diff --git a/tools/perf/benchmarks/speedometer2.py b/tools/perf/benchmarks/speedometer2.py
index 15fa8a21..24258379 100644
--- a/tools/perf/benchmarks/speedometer2.py
+++ b/tools/perf/benchmarks/speedometer2.py
@@ -194,10 +194,10 @@
 @benchmark.Info(emails=['omerkatz@chromium.org'],
                 component='Blink>JavaScript>GarbageCollection',
                 documentation_url='https://browserbench.org/Speedometer2.1')
-class Speedometer2MinorMC(Speedometer2):
-  """The latest Speedometer2 benchmark with the MinorMC flag.
+class Speedometer2NoMinorMS(Speedometer2):
+  """The latest Speedometer2 benchmark without the MinorMS flag.
 
-  Shows the performance of upcoming MinorMC young generation GC in V8.
+  Shows the performance of Scavenger young generation GC in V8.
   """
 
   @classmethod
diff --git a/tools/perf/benchmarks/speedometer3.py b/tools/perf/benchmarks/speedometer3.py
index 997385e..09e5859 100644
--- a/tools/perf/benchmarks/speedometer3.py
+++ b/tools/perf/benchmarks/speedometer3.py
@@ -174,10 +174,10 @@
 @benchmark.Info(emails=['omerkatz@chromium.org'],
                 component='Blink>JavaScript>GarbageCollection',
                 documentation_url='https://github.com/WebKit/Speedometer')
-class Speedometer3MinorMC(Speedometer3):
-  """The latest Speedometer3 benchmark with the MinorMC flag.
+class Speedometer3NoMinorMS(Speedometer3):
+  """The latest Speedometer3 benchmark without the MinorMS flag.
 
-  Shows the performance of upcoming MinorMC young generation GC in V8.
+  Shows the performance of Scavenger young generation GC in V8.
   """
   @classmethod
   def Name(cls):
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index b09e154..6f11567 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,8 +5,8 @@
             "full_remote_path": "perfetto-luci-artifacts/v38.0/linux-arm64/trace_processor_shell"
         },
         "win": {
-            "hash": "5f18e3f7449ec68c1e92da52942063394b2b691c",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/2b538edb675527611fdd503210e5b9943627844c/trace_processor_shell.exe"
+            "hash": "3499cb0a5b536fe5c7d88e9d8db4de4f11059ce0",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/34f1b98dca5071866b2f0778605dcea0a3d1fbef/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "bb52a6e014d9272dc4784b1678eee77075df1a86",
@@ -21,8 +21,8 @@
             "full_remote_path": "perfetto-luci-artifacts/v35.0/mac-arm64/trace_processor_shell"
         },
         "linux": {
-            "hash": "d44e3b075f617e0c3345dd6535cb79358134f15d",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/2b538edb675527611fdd503210e5b9943627844c/trace_processor_shell"
+            "hash": "cf7db8bd19fcfbc4af5be9ceae22cd7d59852034",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/34f1b98dca5071866b2f0778605dcea0a3d1fbef/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/remove_duplicate_includes.py b/tools/remove_duplicate_includes.py
deleted file mode 100755
index 9e5daab..0000000
--- a/tools/remove_duplicate_includes.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2016 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""This script will search through the target folder specified and try to find
-duplicate includes from h and cc files, and remove them from the cc files. The
-current/working directory needs to be chromium_checkout/src/ when this tool is
-run.
-
-Usage: remove_duplicate_includes.py --dry-run components/foo components/bar
-"""
-
-from __future__ import print_function
-
-import argparse
-import collections
-import logging
-import os
-import re
-import sys
-
-# This could be generalized if desired, and moved to command line arguments.
-H_FILE_SUFFIX = '.h'
-CC_FILE_SUFFIX = '.cc'
-
-# The \s should allow us to ignore any whitespace and only focus on the group
-# captured when comparing between files.
-INCLUDE_REGEX = re.compile('^\s*(#include\s+[\"<](.*?)[\">])\s*$')
-
-def HasSuffix(file_name, suffix):
-  return os.path.splitext(file_name)[1] == suffix
-
-def IsEmpty(line):
-  return not line.strip()
-
-def FindIncludeSet(input_lines, h_path_to_include_set, cc_file_name):
-  """Finds and returns the corresponding include set for the given .cc file.
-
-  This is done by finding the first include in the file and then trying to look
-  up an .h file in the passed in map. If not present, then None is returned
-  immediately.
-  """
-  for line in input_lines:
-    match = INCLUDE_REGEX.search(line)
-    # The first include match should be the corresponding .h file, else skip.
-    if match:
-      h_file_path = os.path.join(os.getcwd(), match.group(2))
-      if h_file_path not in h_path_to_include_set:
-        print('First include did not match to a known .h file, skipping ' + \
-          cc_file_name + ', line: ' + match.group(1))
-        return None
-      return h_path_to_include_set[h_file_path]
-
-def WithoutDuplicates(input_lines, include_set, cc_file_name):
-  """Checks every input line and sees if we can remove it based on the contents
-  of the given include set.
-
-  Returns what the new contents of the file should be.
-  """
-  output_lines = []
-  # When a section of includes are completely removed, we want to remove the
-  # trailing empty as well.
-  lastCopiedLineWasEmpty = False
-  lastLineWasOmitted = False
-  for line in input_lines:
-      match = INCLUDE_REGEX.search(line)
-      if match and match.group(2) in include_set:
-        print('Removed ' + match.group(1) + ' from ' + cc_file_name)
-        lastLineWasOmitted = True
-      elif lastCopiedLineWasEmpty and lastLineWasOmitted and IsEmpty(line):
-        print('Removed empty line from ' + cc_file_name)
-        lastLineWasOmitted = True
-      else:
-        lastCopiedLineWasEmpty = IsEmpty(line)
-        lastLineWasOmitted = False
-        output_lines.append(line)
-  return output_lines
-
-def main():
-  parser = argparse.ArgumentParser()
-  parser.add_argument('--dry-run', action='store_true',
-    help='Does not actually remove lines when specified.')
-  parser.add_argument('targets', nargs='+',
-    help='Relative path to folders to search for duplicate includes in.')
-  args = parser.parse_args()
-
-  # A map of header file paths to the includes they contain.
-  h_path_to_include_set = {}
-
-  # Simply collects the path of all cc files present.
-  cc_file_path_set = set()
-
-  for relative_root in args.targets:
-    absolute_root = os.path.join(os.getcwd(), relative_root)
-    for dir_path, dir_name_list, file_name_list in os.walk(absolute_root):
-      for file_name in file_name_list:
-        file_path = os.path.join(dir_path, file_name)
-        if HasSuffix(file_name, H_FILE_SUFFIX):
-          # By manually adding the set instead of using defaultdict we can avoid
-          # warning about missing .h files when the .h file has no includes.
-          h_path_to_include_set[file_path] = set()
-          with open(file_path) as fh:
-            for line in fh:
-              match = INCLUDE_REGEX.search(line)
-              if match:
-                h_path_to_include_set[file_path].add(match.group(2))
-        elif HasSuffix(file_name, CC_FILE_SUFFIX):
-          cc_file_path_set.add(file_path)
-
-  for cc_file_path in cc_file_path_set:
-    cc_file_name = os.path.basename(cc_file_path)
-    with open(cc_file_path, 'r' if args.dry_run else 'r+') as fh:
-      # Read out all lines and reset file position to allow overwriting.
-      input_lines = fh.readlines()
-      fh.seek(0)
-      include_set = FindIncludeSet(input_lines, h_path_to_include_set,
-                                   cc_file_name)
-      if include_set:
-        output_lines = WithoutDuplicates(input_lines, include_set, cc_file_name)
-        if not args.dry_run:
-          fh.writelines(output_lines)
-          fh.truncate()
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/tools/typescript/definitions/webview_tag.d.ts b/tools/typescript/definitions/webview_tag.d.ts
index b6b4f21..99c24905 100644
--- a/tools/typescript/definitions/webview_tag.d.ts
+++ b/tools/typescript/definitions/webview_tag.d.ts
@@ -262,7 +262,7 @@
       // Manually added to match the webview_tag.js Closure externs file.
       export interface WebView extends HTMLIFrameElement {
         request: WebRequestEventInterface;
-        back(): void;
+        back(callback?: (success: boolean) => void): void;
         reload(): void;
         addContentScripts(contentScriptList: ContentScriptDetails[]): void;
         removeContentScripts(scriptNameList?: string[]): void;
diff --git a/ui/base/template_expressions.cc b/ui/base/template_expressions.cc
index 71c0b92..d219df1 100644
--- a/ui/base/template_expressions.cc
+++ b/ui/base/template_expressions.cc
@@ -9,6 +9,7 @@
 #include <ostream>
 
 #include "base/check_op.h"
+#include "base/no_destructor.h"
 #include "base/strings/escape.h"
 #include "base/strings/string_piece.h"
 #include "base/values.h"
@@ -126,7 +127,8 @@
   if (key == "displayResolutionText")
     return false;
 #endif
-  return re2::RE2::PartialMatch(replacement, re2::RE2(R"(\$\d)"));
+  static const base::NoDestructor<re2::RE2> placeholder_regex(R"(\$\d)");
+  return re2::RE2::PartialMatch(replacement, *placeholder_regex.get());
 }
 #endif  // DCHECK_IS_ON()
 
diff --git a/ui/base/ui_base_features.cc b/ui/base/ui_base_features.cc
index 08304d99..4e33406 100644
--- a/ui/base/ui_base_features.cc
+++ b/ui/base/ui_base_features.cc
@@ -104,7 +104,7 @@
 // "Customize keyboard keys" page.
 BASE_FEATURE(kSupportF11AndF12KeyShortcuts,
              "SupportF11AndF12KeyShortcuts",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 bool AreF11AndF12ShortcutsEnabled() {
   // TODO(crbug/1264581): Remove this once kDeviceI18nShortcutsEnabled policy is
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index 765ccf5..42c27a6f 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -43,7 +43,6 @@
 #include "components/viz/common/frame_sinks/begin_frame_args.h"
 #include "components/viz/common/frame_sinks/begin_frame_source.h"
 #include "components/viz/common/gpu/context_provider.h"
-#include "components/viz/common/resources/resource_settings.h"
 #include "components/viz/common/switches.h"
 #include "components/viz/host/host_frame_sink_manager.h"
 #include "components/viz/host/renderer_settings_creation.h"
@@ -192,23 +191,21 @@
 #if BUILDFLAG(IS_APPLE)
   // Using CoreAnimation to composite requires using GpuMemoryBuffers, which
   // require zero copy.
-  settings.resource_settings.use_gpu_memory_buffer_resources =
-      settings.use_zero_copy;
+  settings.use_gpu_memory_buffer_resources = settings.use_zero_copy;
   settings.enable_elastic_overscroll = true;
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   // Rasterized tiles must be overlay candidates to be forwarded.
   // This is very similar to the line above for Apple.
-  settings.resource_settings.use_gpu_memory_buffer_resources =
+  settings.use_gpu_memory_buffer_resources =
       features::IsDelegatedCompositingEnabled();
 #endif
 
   // Set use_gpu_memory_buffer_resources to false to disable delegated
   // compositing, if RawDraw is enabled.
-  if (settings.resource_settings.use_gpu_memory_buffer_resources &&
-      features::IsUsingRawDraw()) {
-    settings.resource_settings.use_gpu_memory_buffer_resources = false;
+  if (settings.use_gpu_memory_buffer_resources && features::IsUsingRawDraw()) {
+    settings.use_gpu_memory_buffer_resources = false;
   }
 
   settings.memory_policy.bytes_limit_when_visible =
diff --git a/ui/events/ozone/evdev/event_device_info.cc b/ui/events/ozone/evdev/event_device_info.cc
index 44115c18..6b542a01 100644
--- a/ui/events/ozone/evdev/event_device_info.cc
+++ b/ui/events/ozone/evdev/event_device_info.cc
@@ -302,6 +302,10 @@
     {0x413c, 0x81d5},  // Dell Active Pen PN579X
 };
 
+constexpr DeviceId kHeatmapSupportedDevices[] = {
+    {0x04f3, 0x4222},  // Rex
+};
+
 // Certain devices need to be forced to use libinput in place of
 // evdev/libgestures
 constexpr DeviceId kForceLibinputlist[] = {
@@ -644,6 +648,16 @@
   return EvdevBitIsSet(prop_bits_.data(), code);
 }
 
+bool EventDeviceInfo::SupportsHeatmap() const {
+  for (const auto& device_id : kHeatmapSupportedDevices) {
+    if (input_id_.vendor == device_id.vendor &&
+        input_id_.product == device_id.product_id) {
+      return true;
+    }
+  }
+  return false;
+}
+
 int32_t EventDeviceInfo::GetAbsMinimum(unsigned int code) const {
   return abs_info_[code].minimum;
 }
diff --git a/ui/events/ozone/evdev/event_device_info.h b/ui/events/ozone/evdev/event_device_info.h
index 8ecefe9..dbef2a2 100644
--- a/ui/events/ozone/evdev/event_device_info.h
+++ b/ui/events/ozone/evdev/event_device_info.h
@@ -187,6 +187,9 @@
   // device.
   bool HasValidMTAbsXY() const;
 
+  // Determine whether this device supports heatmap.
+  bool SupportsHeatmap() const;
+
   // Determine whether the device supports rumble.
   bool SupportsRumble() const;
 
diff --git a/ui/events/ozone/evdev/event_device_info_unittest.cc b/ui/events/ozone/evdev/event_device_info_unittest.cc
index 1465fb6..e2bba9e7 100644
--- a/ui/events/ozone/evdev/event_device_info_unittest.cc
+++ b/ui/events/ozone/evdev/event_device_info_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
+#include "event_device_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/ozone/evdev/event_device_test_util.h"
 #include "ui/events/ozone/evdev/event_device_util.h"
@@ -561,4 +562,21 @@
             fmt(static_cast<ui::KeyboardType>(2345)));
 }
 
+TEST(EventDeviceInfoTest, RexHeatmapTouchScreen) {
+  EventDeviceInfo devinfo;
+  EXPECT_TRUE(CapabilitiesToDeviceInfo(kRexHeatmapTouchScreen, &devinfo));
+
+  EXPECT_FALSE(devinfo.HasKeyboard());
+  EXPECT_FALSE(devinfo.HasMouse());
+  EXPECT_FALSE(devinfo.HasPointingStick());
+  EXPECT_FALSE(devinfo.HasTouchpad());
+  EXPECT_FALSE(devinfo.HasHapticTouchpad());
+  EXPECT_TRUE(devinfo.HasTouchscreen());
+  EXPECT_FALSE(devinfo.HasTablet());
+  EXPECT_FALSE(devinfo.HasGamepad());
+  EXPECT_FALSE(devinfo.IsStylusButtonDevice());
+  EXPECT_FALSE(devinfo.HasStylusSwitch());
+  EXPECT_TRUE(devinfo.SupportsHeatmap());
+}
+
 }  // namespace ui
diff --git a/ui/events/ozone/evdev/event_device_test_util.cc b/ui/events/ozone/evdev/event_device_test_util.cc
index 121c39c..34cbc36 100644
--- a/ui/events/ozone/evdev/event_device_test_util.cc
+++ b/ui/events/ozone/evdev/event_device_test_util.cc
@@ -1492,6 +1492,45 @@
     /* kbd_top_row_layout */ "",
 };
 
+const DeviceAbsoluteAxis kRexHeatmapTouchScreenAbsAxes[] = {
+    {ABS_X, {0, 0, 3600, 0, 0, 12}},
+    {ABS_Y, {0, 0, 2256, 0, 0, 12}},
+    {ABS_PRESSURE, {0, 0, 255, 0, 0, 0}},
+    {ABS_MT_SLOT, {0, 0, 9, 0, 0, 0}},
+    {ABS_MT_TOUCH_MAJOR, {0, 0, 255, 0, 0, 1}},
+    {ABS_MT_TOUCH_MINOR, {0, 0, 255, 0, 0, 1}},
+    {ABS_MT_ORIENTATION, {0, 0, 1, 0, 0, 0}},
+    {ABS_MT_POSITION_X, {0, 0, 3600, 0, 0, 12}},
+    {ABS_MT_POSITION_Y, {0, 0, 2256, 0, 0, 12}},
+    {ABS_MT_TOOL_TYPE, {0, 0, 2, 0, 0, 0}},
+    {ABS_MT_TRACKING_ID, {0, 0, 65535, 0, 0, 0}},
+    {ABS_MT_PRESSURE, {0, 0, 255, 0, 0, 0}},
+};
+
+const DeviceCapabilities kRexHeatmapTouchScreen = {
+    /* path */
+    "/sys/devices/pci0000:00/0000:00:1e.2/pxa2xx-spi.6/spi_master/spi0/"
+    "spi-ELAN9006:00/001C:04F3:4222.0001/input/input6/event5",
+    /* name */ "spi 04F3:4222",
+    /* phys */ "spi-ELAN9006:00",
+    /* uniq */ "",
+    /* bustype */ "001c",
+    /* vendor */ "04f3",
+    /* product */ "4222",
+    /* version */ "0300",
+    /* prop */ "2",
+    /* ev */ "1b",
+    /* key */ "400 0 0 0 0 0",
+    /* rel */ "0",
+    /* abs */ "6f3800001000003",
+    /* msc */ "20",
+    /* sw */ "0",
+    /* led */ "0",
+    /* ff */ "0",
+    kRexHeatmapTouchScreenAbsAxes,
+    std::size(kRexHeatmapTouchScreenAbsAxes),
+};
+
 // NB: Please use the capture_device_capabilities.py script to add more
 // test data here. This will help ensure the data matches what the kernel
 // reports for a real device and is entered correctly.
diff --git a/ui/events/ozone/evdev/event_device_test_util.h b/ui/events/ozone/evdev/event_device_test_util.h
index b6ab142..a97b1a9a 100644
--- a/ui/events/ozone/evdev/event_device_test_util.h
+++ b/ui/events/ozone/evdev/event_device_test_util.h
@@ -120,6 +120,7 @@
 extern const DeviceCapabilities kHPProBook6560bTouchpad;
 extern const DeviceCapabilities kJinlonKeyboard;
 extern const DeviceCapabilities kSymbolTechBarcodeScanner;
+extern const DeviceCapabilities kRexHeatmapTouchScreen;
 }  // namespace ui
 
 #endif  // UI_EVENTS_OZONE_EVDEV_EVENT_DEVICE_TEST_UTIL_H_
diff --git a/ui/file_manager/file_manager/common/js/files_app_entry_types.js b/ui/file_manager/file_manager/common/js/files_app_entry_types.js
index 59889b7..85c1d14 100644
--- a/ui/file_manager/file_manager/common/js/files_app_entry_types.js
+++ b/ui/file_manager/file_manager/common/js/files_app_entry_types.js
@@ -195,6 +195,10 @@
     return this.label_;
   }
 
+  get devicePath() {
+    return this.devicePath_;
+  }
+
   get isNativeType() {
     return false;
   }
diff --git a/ui/file_manager/file_manager/containers/search_container.ts b/ui/file_manager/file_manager/containers/search_container.ts
index 376b7cb9..ec5b65a 100644
--- a/ui/file_manager/file_manager/containers/search_container.ts
+++ b/ui/file_manager/file_manager/containers/search_container.ts
@@ -6,13 +6,14 @@
 
 import {queryRequiredElement} from '../common/js/dom_utils.js';
 import {recordUserAction} from '../common/js/metrics.js';
-import {str} from '../common/js/util.js';
+import {str, strf} from '../common/js/util.js';
 import {VolumeManagerCommon} from '../common/js/volume_manager_types.js';
 import {CurrentDirectory, PropStatus, SearchData, SearchLocation, SearchOptions, SearchRecency, State} from '../externs/ts/state.js';
 import {VolumeManager} from '../externs/volume_manager.js';
 import {PathComponent} from '../foreground/js/path_component.js';
+import {A11yAnnounce} from '../foreground/js/ui/a11y_announce.js';
 import {changeDirectory} from '../state/ducks/current_directory.js';
-import {clearSearch, getDefaultSearchOptions, updateSearch} from '../state/ducks/search.js';
+import {clearSearch, getDefaultSearchOptions, isSearchEmpty, updateSearch} from '../state/ducks/search.js';
 import type {FileKey} from '../state/file_key.js';
 import {getStore, type Store} from '../state/store.js';
 import {type BreadcrumbClickedEvent, XfBreadcrumb} from '../widgets/xf_breadcrumb.js';
@@ -190,6 +191,9 @@
   private pathComponents_: FileKey[] = [];
   // Volume manager, used by us to resolve paths of selected entries.
   private volumeManager_: VolumeManager;
+  // The accessibility interface that is used to announce the outcomes of file
+  // searches.
+  private a11y_: A11yAnnounce;
 
 
   /**
@@ -204,7 +208,8 @@
    */
   constructor(
       volumeManager: VolumeManager, searchWrapper: HTMLElement,
-      optionsContainer: HTMLElement, pathContainer: HTMLElement) {
+      optionsContainer: HTMLElement, pathContainer: HTMLElement,
+      a11y: A11yAnnounce) {
     super();
     this.volumeManager_ = volumeManager;
     // The "box" around the search button, query input, and clear button.
@@ -231,6 +236,7 @@
 
     this.optionsContainer_ = optionsContainer;
     this.pathContainer_ = pathContainer;
+    this.a11y_ = a11y;
     this.store_ = getStore();
     this.store_.subscribe(this);
 
@@ -265,20 +271,11 @@
   }
 
   /**
-   * Sets the new query. This method does not post events, even if the query
-   * changed as a result.
-   */
-  setQuery(query: string) {
-    this.inputElement_.value = query;
-    this.openSearch();
-  }
-
-  /**
    * Returns the user entered search query. This method trims white spaces from
    * the left side of the query.
    */
   getQuery(): string {
-    return this.inputElement_.value.trimLeft();
+    return this.inputElement_.value.trimStart();
   }
 
   /**
@@ -301,19 +298,33 @@
       return;
     }
     // Cache the last received search state for future comparisons.
-    this.searchState_ = search;
-    if (!search) {
+    const lastSearch = this.searchState_;
+    this.searchState_ = state.search;
+
+    if (lastSearch?.query && search && search.query === undefined) {
+      this.a11y_.speakA11yMessage(str('SEARCH_A11Y_CLEAR_SEARCH'));
+    }
+    if (!search || isSearchEmpty(search)) {
       this.closeSearch();
       return;
     }
+
     const query = search.query;
     if (query !== undefined && query !== this.getQuery()) {
-      this.setQuery(query);
+      this.inputElement_.value = query;
+      this.openSearch();
     }
     if (search.status === PropStatus.STARTED && query) {
       this.showOptionsElement_(state);
       this.showBreadcrumbElement_();
     }
+    if (search.status === PropStatus.SUCCESS && query) {
+      const content = state.currentDirectory?.content;
+      const count = content ? content.keys.length : 0;
+      const messageId =
+          count === 0 ? 'SEARCH_A11Y_NO_RESULT' : 'SEARCH_A11Y_RESULT';
+      this.a11y_.speakA11yMessage(strf(messageId, query));
+    }
   }
 
   /**
@@ -577,6 +588,14 @@
   }
 
   /**
+   * Returns whether the search container is open. In the open state the user
+   * may enter a search query, interact with options, etc.
+   */
+  isOpen() {
+    return this.inputState_ === SearchInputState.OPEN;
+  }
+
+  /**
    * Starts the process of opening the search widget. We use CSS transitions to
    * open the widget and thus the widget it not fully opened until the CSS
    * transition finishes.
@@ -585,6 +604,7 @@
     // Do not initiate open transition if we are not closed. This would leave us
     // in the OPENING state, without ever getting to OPEN state.
     if (this.inputState_ === SearchInputState.CLOSED) {
+      this.inputState_ = SearchInputState.OPEN;
       this.inputElement_.addEventListener('transitionend', () => {
         this.searchWrapper_.removeAttribute('collapsed');
       }, {once: true, passive: true, capture: true});
@@ -595,7 +615,6 @@
       this.searchBox_.classList.add('has-cursor', 'has-text');
       this.searchButton_.tabIndex = -1;
       this.updateClearButton_(this.getQuery());
-      this.inputState_ = SearchInputState.OPEN;
     }
   }
 
@@ -608,6 +627,7 @@
     // Do not initiate close transition if we are not open. This would leave us
     // in the CLOSING state, without ever getting to CLOSED state.
     if (this.inputState_ === SearchInputState.OPEN) {
+      this.inputState_ = SearchInputState.CLOSED;
       this.inputElement_.addEventListener('transitionend', () => {
         this.searchWrapper_.setAttribute('collapsed', '');
       }, {once: true, passive: true, capture: true});
@@ -622,7 +642,6 @@
       this.searchBox_.classList.remove('has-cursor', 'has-text');
       this.searchButton_.tabIndex = 0;
       this.currentOptions_ = getDefaultSearchOptions();
-      this.inputState_ = SearchInputState.CLOSED;
     }
   }
 
@@ -642,8 +661,8 @@
     this.updateClearButton_(query);
     this.store_.dispatch(updateSearch({
       query: query,
-      status: undefined,   // do not change
-      options: undefined,  // do not change
+      status: undefined,  // do not change
+      options: this.currentOptions_,
     }));
   }
 }
diff --git a/ui/file_manager/file_manager/containers/search_container_unittest.ts b/ui/file_manager/file_manager/containers/search_container_unittest.ts
index 5973d9c..5bba64c 100644
--- a/ui/file_manager/file_manager/containers/search_container_unittest.ts
+++ b/ui/file_manager/file_manager/containers/search_container_unittest.ts
@@ -2,27 +2,57 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js';
 import {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.js';
 import {getTrustedHTML} from 'chrome://resources/js/static_types.js';
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js';
 
 import {EntryLocation} from '../externs/entry_location.js';
-import {State} from '../externs/ts/state.js';
+import {PropStatus, State} from '../externs/ts/state.js';
 import {VolumeManager} from '../externs/volume_manager.js';
+import {A11yAnnounce} from '../foreground/js/ui/a11y_announce.js';
+import {clearSearch, getDefaultSearchOptions, updateSearch} from '../state/ducks/search.js';
 import {waitDeepEquals} from '../state/for_tests.js';
 import {getEmptyState, getStore, type Store} from '../state/store.js';
 
 import {SearchContainer} from './search_container.js';
 
+class TestA11yAnnouncer extends A11yAnnounce {
+  messages: string[] = [];
 
-let searchWrapper: HTMLElement|undefined;
+  override speakA11yMessage(message: string) {
+    this.messages.push(message);
+  }
+}
+
 let store: Store|undefined;
 let searchContainer: SearchContainer|undefined;
+const a11y: TestA11yAnnouncer = new TestA11yAnnouncer();
 
-function setupStore(): Store {
-  const store = getStore();
+/**
+ * Creates a store if necessary. Initializes it to an empty state.
+ */
+function setupStore(): void {
+  if (store === undefined) {
+    store = getStore();
+  }
   store.init(getEmptyState());
-  return store;
+}
+
+/**
+ * Creates a search container if necessary.
+ */
+function setupSearchContainer(): void {
+  if (searchContainer === undefined) {
+    const volumeManager: VolumeManager = {
+      getLocationInfo: (_entry: Entry): EntryLocation => {
+        return new EntryLocation();
+      },
+    } as unknown as VolumeManager;
+    searchContainer = new SearchContainer(
+        volumeManager, document.querySelector('#search-wrapper') as HTMLElement,
+        document.querySelector('#options-container') as HTMLElement,
+        document.querySelector('#path-container') as HTMLElement, a11y);
+  }
 }
 
 /**
@@ -44,35 +74,27 @@
         <div id="path-container"></div>
       </div>
     </div>`;
-  searchWrapper = document.querySelector('#search-wrapper') as HTMLElement;
 
-  store = setupStore();
-  const volumeManager: VolumeManager = {
-    getLocationInfo: (_entry: Entry): EntryLocation => {
-      return new EntryLocation();
-    },
-  } as unknown as VolumeManager;
+  setupStore();
+  setupSearchContainer();
+}
 
-  searchContainer = new SearchContainer(
-      volumeManager, searchWrapper,
-      document.querySelector('#options-container') as HTMLElement,
-      document.querySelector('#path-container') as HTMLElement);
+export function tearDown() {
+  // Clears accessibility message from the previous test.
+  a11y.messages = [];
 }
 
 /**
- * Resets flags state.
+ * Checks that manually entering a query (simulated here by setting value and
+ * posint an input event) correctly propagates the state to the store.
  */
-export function tearDown() {
-  loadTimeData.resetForTesting();
-}
-
 export async function testQueryUpdated() {
   // Manually open the search container; without this the container is in the
   // closed state and does not clean up query or option values on close.
   searchContainer!.openSearch();
 
   // Test 1: Enter a query.
-  const input = searchWrapper!.querySelector('cr-input') as CrInputElement;
+  const input = document.querySelector('cr-input') as CrInputElement;
   input.value = 'hello';
   input.dispatchEvent(new Event('input', {
     bubbles: true,
@@ -81,7 +103,7 @@
   const want1 = {
     query: 'hello',
     status: undefined,
-    options: undefined,
+    options: getDefaultSearchOptions(),
   };
   await waitDeepEquals(store!, want1, (state: State) => {
     return state.search;
@@ -99,4 +121,56 @@
   });
 }
 
-// TODO(b:241868453): Add test for V2
+/**
+ * Checks that store changes correctly result in opening and closing of the
+ * search box.
+ */
+export async function testOpenAndClose() {
+  assertFalse(searchContainer!.isOpen());
+  store!.dispatch(updateSearch({
+    query: 'hello',
+    status: undefined,
+    options: getDefaultSearchOptions(),
+  }));
+  assertTrue(searchContainer!.isOpen());
+  store!.dispatch(clearSearch());
+  assertFalse(searchContainer!.isOpen());
+  // No results appeared so expect just one message about search being closed.
+  assertEquals(1, a11y.messages.length);
+  assertEquals(
+      'Search text cleared, showing all files and folders.', a11y.messages[0]);
+}
+
+export async function testNoResultFoundAnnouncement() {
+  // Start a file search with the query 'hello'.
+  store!.dispatch(updateSearch({
+    query: 'hello',
+    status: undefined,
+    options: getDefaultSearchOptions(),
+  }));
+  // Wait for the store to update its state.
+  const want1 = {
+    query: 'hello',
+    status: undefined,
+    options: getDefaultSearchOptions(),
+  };
+  await waitDeepEquals(store!, want1, (state: State) => {
+    return state.search;
+  });
+  // Fake a successful search.
+  store!.dispatch(updateSearch({
+    query: 'hello',
+    status: PropStatus.SUCCESS,
+    options: getDefaultSearchOptions(),
+  }));
+  const want2 = {
+    query: 'hello',
+    status: PropStatus.SUCCESS,
+    options: getDefaultSearchOptions(),
+  };
+  await waitDeepEquals(store!, want2, (state: State) => {
+    return state.search;
+  });
+  assertEquals(1, a11y.messages.length);
+  assertEquals('There are no results for hello.', a11y.messages[0]);
+}
diff --git a/ui/file_manager/file_manager/externs/polymer_elements/files_format_dialog.js b/ui/file_manager/file_manager/externs/polymer_elements/files_format_dialog.js
new file mode 100644
index 0000000..018a166
--- /dev/null
+++ b/ui/file_manager/file_manager/externs/polymer_elements/files_format_dialog.js
@@ -0,0 +1,7 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+class FilesFormatDialog extends HTMLElement {
+  showEraseModal(root) {}
+}
diff --git a/ui/file_manager/file_manager/foreground/elements/BUILD.gn b/ui/file_manager/file_manager/foreground/elements/BUILD.gn
index 247d8e5..81e0fdb 100644
--- a/ui/file_manager/file_manager/foreground/elements/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/elements/BUILD.gn
@@ -35,7 +35,6 @@
                     "browser_resolver_prefix_replacements=\"chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp/=./image_loader/\"",
                   ]
   deps = [
-    ":files_format_dialog",
     ":files_spinner",
     ":xf_button",
     ":xf_circular_progress",
@@ -47,7 +46,6 @@
 html_to_js("web_components") {
   visibility += [ "//ui/file_manager/*" ]
   js_files = [
-    "files_format_dialog.js",
     "files_spinner.js",
     "icons.js",
     "xf_button.js",
@@ -57,30 +55,13 @@
   ]
 }
 
-js_library("files_format_dialog") {
-  deps = [
-    "//ash/webui/common/resources:i18n_behavior",
-    "//third_party/polymer/v3_0/components-chromium/iron-icon:iron-icon",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/file_manager/file_manager/common/js:files_app_entry_types",
-    "//ui/file_manager/file_manager/common/js:util",
-    "//ui/file_manager/file_manager/common/js:volume_manager_types",
-    "//ui/file_manager/file_manager/externs:volume_info",
-    "//ui/file_manager/file_manager/foreground/js:file_rename",
-  ]
-  externs_list = [
-    "//ui/webui/resources/cr_elements/cr_button/cr_button_externs.js",
-    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
-    "//ui/webui/resources/cr_elements/cr_input/cr_input_externs.js",
-  ]
-}
-
 js_library("files_spinner") {
 }
 
 html_to_wrapper("polymer_elements") {
   visibility += [ "//ui/file_manager/*" ]
   in_files = [
+    "files_format_dialog.html",
     "files_metadata_box.html",
     "files_toast.html",
     "files_tooltip.html",
diff --git a/ui/file_manager/file_manager/foreground/elements/files_format_dialog.html b/ui/file_manager/file_manager/foreground/elements/files_format_dialog.html
index 51c1804..03c8a1b7 100644
--- a/ui/file_manager/file_manager/foreground/elements/files_format_dialog.html
+++ b/ui/file_manager/file_manager/foreground/elements/files_format_dialog.html
@@ -129,25 +129,25 @@
   }
 </style>
 
-<cr-dialog id="dialog" close-text="[[i18n('CLOSE_LABEL')]]"
+<cr-dialog id="dialog" close-text="$i18n{CLOSE_LABEL}"
            single-partition-format$="[[getSinglePartitionFormat()]]">
   <div slot="title">
-    [[i18n('FORMAT_DIALOG_TITLE', title)]]
+    [[getStrf('FORMAT_DIALOG_TITLE', title)]]
   </div>
   <div slot="body">
-    <div>[[getDialogMessage_(isErase_)]]</div>
-    <div id="warning-container" hidden="[[!space_used_]]" role="alert">
+    <div>[[getDialogMessage(isErase_)]]</div>
+    <div id="warning-container" hidden="[[!spaceUsed_]]" role="alert">
       <iron-icon id="warning-icon" icon="cr:warning"></iron-icon>
       <div id="warning-message">
-        [[i18n('FORMAT_DIALOG_DELETE_WARNING', space_used_)]]
+        [[getStrf('FORMAT_DIALOG_DELETE_WARNING', spaceUsed_)]]
       </div>
     </div>
-    <cr-input label="[[i18n('FORMAT_DIALOG_DRIVE_NAME_LABEL')]]"
+    <cr-input label="$i18n{FORMAT_DIALOG_DRIVE_NAME_LABEL}"
         id="label" value="{{label_}}" auto-validate="true">
     </cr-input>
     <div id="disk-format">
       <label id="format-type-label" class="cr-form-field-label">
-        [[i18n('FORMAT_DIALOG_FORMAT_LABEL')]]
+        $i18n{FORMAT_DIALOG_FORMAT_LABEL}
       </label>
       <select class="md-select" aria-labelledby="format-type-label"
           value="{{formatType_::change}}">
@@ -158,12 +158,12 @@
     </div>
   </div>
   <div slot="button-container">
-    <cr-button class="cancel-button" on-click="cancel_" id="cancel">
-      [[i18n('CANCEL_LABEL')]]
+    <cr-button class="cancel-button" on-click="cancel" id="cancel">
+      $i18n{CANCEL_LABEL}
     </cr-button>
-    <cr-button class="action-button" on-click="format_"
+    <cr-button class="action-button" on-click="format"
         id="format-button">
-      [[getConfirmLabel_(isErase_)]]
+      [[getConfirmLabel(isErase_)]]
     </cr-button>
   </div>
 </cr-dialog>
diff --git a/ui/file_manager/file_manager/foreground/elements/files_format_dialog.js b/ui/file_manager/file_manager/foreground/elements/files_format_dialog.js
deleted file mode 100644
index 860fe06..0000000
--- a/ui/file_manager/file_manager/foreground/elements/files_format_dialog.js
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright 2019 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'chrome://resources/cr_elements/cr_button/cr_button.js';
-import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
-import 'chrome://resources/cr_elements/cr_input/cr_input.js';
-import 'chrome://resources/cr_elements/icons.html.js';
-import 'chrome://resources/cr_elements/md_select.css.js';
-import 'chrome://resources/cr_elements/cr_shared_style.css.js';
-import 'chrome://resources/cr_elements/cr_shared_vars.css.js';
-import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
-
-import {I18nBehavior} from 'chrome://resources/ash/common/i18n_behavior.js';
-import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {EntryList, VolumeEntry} from '../../common/js/files_app_entry_types.js';
-import {util} from '../../common/js/util.js';
-import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js';
-import {VolumeInfo} from '../../externs/volume_info.js';
-import {validateExternalDriveName} from '../js/file_rename.js';
-
-Polymer({
-  _template: html`{__html_template__}`,
-
-  is: 'files-format-dialog',
-
-  behaviors: [I18nBehavior],
-
-  properties: {
-    label_: {
-      type: String,
-      value: '',
-    },
-
-    /** @type {chrome.fileManagerPrivate.FormatFileSystemType} */
-    formatType_: {
-      type: String,
-      value: chrome.fileManagerPrivate.FormatFileSystemType.VFAT,
-    },
-
-    space_used_: {
-      type: String,
-      value: '',
-    },
-
-    isErase_: {
-      type: Boolean,
-      value: false,
-    },
-  },
-
-  ready: function() {
-    this.$.dialog.consumeKeydownEvent = true;
-  },
-
-  /** @private */
-  cancel_: function() {
-    this.$.dialog.cancel();
-  },
-
-  /** @private */
-  format_: function() {
-    try {
-      validateExternalDriveName(
-          this.label_,
-          /** @type {!VolumeManagerCommon.FileSystemType} */
-          (this.formatType_));
-    } catch (error) {
-      this.$.label.setAttribute('error-message', error.message);
-      this.$.label.invalid = true;
-      return;
-    }
-
-    if (this.isErase_) {
-      chrome.fileManagerPrivate.singlePartitionFormat(
-          this.root_.devicePath_, this.formatType_, this.label_);
-    } else {
-      chrome.fileManagerPrivate.formatVolume(
-          this.volumeInfo_.volumeId, this.formatType_, this.label_);
-    }
-    this.$.dialog.close();
-  },
-
-  /**
-   * Used to set "single-partition-format" attribute on element.
-   * It is used to check flag status in the tests.
-   * @return {string}
-   *
-   * @private
-   */
-  getSinglePartitionFormat() {
-    if (util.isSinglePartitionFormatEnabled()) {
-      return 'single-partition-format';
-    }
-    return '';
-  },
-
-  /**
-   * @param {!boolean} is_erase
-   * @return {string}
-   *
-   * @private
-   */
-  getConfirmLabel_: function(is_erase) {
-    if (util.isSinglePartitionFormatEnabled()) {
-      if (is_erase) {
-        return this.i18n('REPARTITION_DIALOG_CONFIRM_LABEL');
-      } else {
-        return this.i18n('FORMAT_DIALOG_CONFIRM_SHORT_LABEL');
-      }
-    } else {
-      return this.i18n('FORMAT_DIALOG_CONFIRM_LABEL');
-    }
-  },
-
-  /**
-   * @param {!boolean} is_erase
-   * @return {string}
-   *
-   * @private
-   */
-  getDialogMessage_: function(is_erase) {
-    if (util.isSinglePartitionFormatEnabled()) {
-      if (is_erase) {
-        return this.i18n('REPARTITION_DIALOG_MESSAGE');
-      } else {
-        return this.i18n('FORMAT_PARTITION_DIALOG_MESSAGE');
-      }
-    } else {
-      return this.i18n('FORMAT_DIALOG_MESSAGE');
-    }
-  },
-
-  /**
-   * Shows the dialog for drive represented by |volumeInfo|.
-   * @param {!VolumeInfo} volumeInfo
-   */
-  showModal: function(volumeInfo) {
-    this.isErase_ = false;
-    this.label_ = '';
-    this.formatType_ = chrome.fileManagerPrivate.FormatFileSystemType.VFAT;
-    this.space_used_ = '';
-
-    this.volumeInfo_ = volumeInfo;
-    this.title = this.volumeInfo_.label;
-    if (volumeInfo.displayRoot) {
-      chrome.fileManagerPrivate.getDirectorySize(
-          volumeInfo.displayRoot, space_used_ => {
-            if (space_used_ > 0 && volumeInfo === this.volumeInfo_) {
-              this.space_used_ = util.bytesToString(space_used_);
-            }
-            if (window.IN_TEST) {
-              this.$['warning-container'].setAttribute('fully-initialized', '');
-            }
-          });
-    }
-
-    this.$.dialog.showModal();
-  },
-
-  /**
-   * Shows the dialog for erasing device.
-   * @param {!EntryList} root
-   */
-  showEraseModal: function(root) {
-    this.isErase_ = true;
-    this.label_ = '';
-    this.formatType_ = chrome.fileManagerPrivate.FormatFileSystemType.VFAT;
-    this.space_used_ = '';
-
-    this.root_ = root;
-    this.title = root.label;
-    const childVolumes =
-        /** @type {Array<VolumeEntry>} */ (this.root_.getUIChildren());
-    let totalSpaceUsed = 0;
-
-    const getSpaceUsedRequests = childVolumes.map((childVolume) => {
-      return new Promise((resolve) => {
-        const volumeInfo = childVolume.volumeInfo;
-        if (volumeInfo.displayRoot) {
-          chrome.fileManagerPrivate.getDirectorySize(
-              volumeInfo.displayRoot, space_used_ => {
-                totalSpaceUsed += space_used_;
-                if (totalSpaceUsed > 0) {
-                  this.space_used_ = util.bytesToString(totalSpaceUsed);
-                }
-                resolve();
-              });
-        }
-      });
-    });
-
-    Promise.all(getSpaceUsedRequests).then(() => {
-      if (window.IN_TEST) {
-        this.$['warning-container'].setAttribute('fully-initialized', '');
-      }
-    });
-    this.$.dialog.showModal();
-  },
-});
-
-//# sourceURL=//ui/file_manager/file_manager/foreground/elements/files_format_dialog.js
diff --git a/ui/file_manager/file_manager/foreground/elements/files_format_dialog.ts b/ui/file_manager/file_manager/foreground/elements/files_format_dialog.ts
new file mode 100644
index 0000000..2f6f423
--- /dev/null
+++ b/ui/file_manager/file_manager/foreground/elements/files_format_dialog.ts
@@ -0,0 +1,228 @@
+// Copyright 2019 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview
+ * This file is checked via TS, so we suppress Closure checks.
+ * @suppress {checkTypes}
+ */
+
+import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
+import 'chrome://resources/cr_elements/cr_input/cr_input.js';
+import 'chrome://resources/cr_elements/icons.html.js';
+import 'chrome://resources/cr_elements/md_select.css.js';
+import 'chrome://resources/cr_elements/cr_shared_style.css.js';
+import 'chrome://resources/cr_elements/cr_shared_vars.css.js';
+import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
+
+import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.js';
+import {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {EntryList} from '../../common/js/files_app_entry_types.js';
+import {str, strf, util} from '../../common/js/util.js';
+import {FilesAppEntry} from '../../externs/files_app_entry_interfaces.js';
+import {VolumeInfo} from '../../externs/volume_info.js';
+import {validateExternalDriveName} from '../js/file_rename.js';
+
+import {getTemplate} from './files_format_dialog.html.js';
+
+export interface FilesFormatDialog {
+  $: {
+    dialog: CrDialogElement,
+    label: CrInputElement,
+    'warning-container': HTMLDivElement,
+  };
+  label_: string;
+  formatType_: chrome.fileManagerPrivate.FormatFileSystemType;
+  spaceUsed_: string;
+  isErase_: boolean;
+}
+
+function getVolumeInfoDisplayRoot(entry: Entry|FilesAppEntry): DirectoryEntry|
+    null {
+  if ('volumeInfo' in entry) {
+    return (entry.volumeInfo as VolumeInfo).displayRoot || null;
+  }
+  return null;
+}
+
+export class FilesFormatDialog extends PolymerElement {
+  static get is() {
+    return 'files-format-dialog' as const;
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  static get properties() {
+    return {
+      label_: {
+        type: String,
+        value: '',
+      },
+
+      formatType_: {
+        type: String,
+        value: chrome.fileManagerPrivate.FormatFileSystemType.VFAT,
+      },
+
+      spaceUsed_: {
+        type: String,
+        value: '',
+      },
+
+      isErase_: {
+        type: Boolean,
+        value: false,
+      },
+    };
+  }
+
+  private volumeInfo_: VolumeInfo|null = null;
+  private root_: EntryList|null = null;
+
+  override ready() {
+    super.ready();
+
+    this.$.dialog.consumeKeydownEvent = true;
+  }
+
+  cancel() {
+    this.$.dialog.cancel();
+  }
+
+  format() {
+    try {
+      validateExternalDriveName(this.label_, this.formatType_);
+    } catch (error: any) {
+      this.$.label.setAttribute('error-message', error.message);
+      this.$.label.invalid = true;
+      return;
+    }
+
+    if (this.isErase_) {
+      chrome.fileManagerPrivate.singlePartitionFormat(
+          this.root_?.devicePath || '', this.formatType_, this.label_);
+    } else {
+      chrome.fileManagerPrivate.formatVolume(
+          this.volumeInfo_?.volumeId || '', this.formatType_, this.label_);
+    }
+    this.$.dialog.close();
+  }
+
+
+  /**
+   * Used to set "single-partition-format" attribute on element.
+   * It is used to check flag status in the tests.
+   */
+  getSinglePartitionFormat() {
+    if (util.isSinglePartitionFormatEnabled()) {
+      return 'single-partition-format';
+    }
+    return '';
+  }
+
+  getConfirmLabel(isErase: boolean) {
+    if (util.isSinglePartitionFormatEnabled()) {
+      if (isErase) {
+        return str('REPARTITION_DIALOG_CONFIRM_LABEL');
+      } else {
+        return str('FORMAT_DIALOG_CONFIRM_SHORT_LABEL');
+      }
+    } else {
+      return str('FORMAT_DIALOG_CONFIRM_LABEL');
+    }
+  }
+
+  getDialogMessage(isErase: boolean) {
+    if (util.isSinglePartitionFormatEnabled()) {
+      if (isErase) {
+        return str('REPARTITION_DIALOG_MESSAGE');
+      } else {
+        return str('FORMAT_PARTITION_DIALOG_MESSAGE');
+      }
+    } else {
+      return str('FORMAT_DIALOG_MESSAGE');
+    }
+  }
+
+  getStrf(token: string, value: string): string {
+    return strf(token, value);
+  }
+
+  /**
+   * Shows the dialog for drive represented by |volumeInfo|.
+   */
+  showModal(volumeInfo: VolumeInfo) {
+    this.isErase_ = false;
+    this.label_ = '';
+    this.formatType_ = chrome.fileManagerPrivate.FormatFileSystemType.VFAT;
+    this.spaceUsed_ = '';
+
+    this.volumeInfo_ = volumeInfo;
+    this.title = this.volumeInfo_.label;
+    if (volumeInfo.displayRoot) {
+      chrome.fileManagerPrivate.getDirectorySize(
+          volumeInfo.displayRoot, (spaceUsed: number) => {
+            if (spaceUsed > 0 && volumeInfo === this.volumeInfo_) {
+              this.spaceUsed_ = util.bytesToString(spaceUsed);
+            }
+            if (window.IN_TEST) {
+              this.$['warning-container'].setAttribute('fully-initialized', '');
+            }
+          });
+    }
+
+    this.$.dialog.showModal();
+  }
+
+  /**
+   * Shows the dialog for erasing device.
+   */
+  showEraseModal(root: EntryList) {
+    this.isErase_ = true;
+    this.label_ = '';
+    this.formatType_ = chrome.fileManagerPrivate.FormatFileSystemType.VFAT;
+    this.spaceUsed_ = '';
+
+    this.root_ = root;
+    this.title = root.label;
+    const childVolumes = this.root_.getUIChildren();
+    let totalSpaceUsed = 0;
+
+    const getSpaceUsedRequests = childVolumes.map((childVolume) => {
+      return new Promise((resolve: (value: void) => void) => {
+        const displayRoot = getVolumeInfoDisplayRoot(childVolume);
+        if (displayRoot) {
+          chrome.fileManagerPrivate.getDirectorySize(
+              displayRoot, (spaceUsed: number) => {
+                totalSpaceUsed += spaceUsed;
+                if (totalSpaceUsed > 0) {
+                  this.spaceUsed_ = util.bytesToString(totalSpaceUsed);
+                }
+                resolve();
+              });
+        }
+      });
+    });
+
+    Promise.all(getSpaceUsedRequests).then(() => {
+      if (window.IN_TEST) {
+        this.$['warning-container'].setAttribute('fully-initialized', '');
+      }
+    });
+    this.$.dialog.showModal();
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    [FilesFormatDialog.is]: FilesFormatDialog;
+  }
+}
+
+customElements.define(FilesFormatDialog.is, FilesFormatDialog);
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn
index f5d6f9e..f4c4cad 100644
--- a/ui/file_manager/file_manager/foreground/js/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -65,7 +65,6 @@
     ":path_component",
     ":providers_model",
     ":scan_controller",
-    ":search_controller",
     ":selection_menu_controller",
     ":sort_menu_controller",
     ":spinner_controller",
@@ -130,7 +129,6 @@
     ":path_component",
     ":providers_model",
     ":scan_controller",
-    ":search_controller",
     ":selection_menu_controller",
     ":sort_menu_controller",
     ":spinner_controller",
@@ -434,7 +432,6 @@
 js_library("deferred_elements") {
   visibility += [ "//ui/file_manager:*" ]
   deps = [
-    "//ui/file_manager/file_manager/foreground/elements:files_format_dialog",
     "//ui/file_manager/file_manager/foreground/elements:files_spinner",
     "//ui/file_manager/file_manager/foreground/elements:xf_button",
     "//ui/file_manager/file_manager/foreground/elements:xf_circular_progress",
@@ -493,7 +490,6 @@
     ":navigation_uma",
     ":providers_model",
     ":scan_controller",
-    ":search_controller",
     ":selection_menu_controller",
     ":sort_menu_controller",
     ":spinner_controller",
@@ -557,6 +553,7 @@
     "ui:files_confirm_dialog",
     "ui:list",
     "//ash/webui/common/resources:assert",
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/file_manager/file_manager/common/js:dialog_type",
     "//ui/file_manager/file_manager/common/js:file_type",
     "//ui/file_manager/file_manager/common/js:files_app_entry_types",
@@ -567,7 +564,10 @@
     "//ui/file_manager/file_manager/externs:files_app_entry_interfaces",
     "//ui/file_manager/file_manager/externs:volume_info",
     "//ui/file_manager/file_manager/externs:volume_manager",
-    "//ui/file_manager/file_manager/foreground/elements:files_format_dialog",
+  ]
+  externs_list = [
+    "//ui/file_manager/file_manager/externs/polymer_elements/files_format_dialog.js",
+    "//ui/webui/resources/cr_elements/cr_dialog/cr_dialog_externs.js",
   ]
 }
 
@@ -852,17 +852,6 @@
   ]
 }
 
-js_library("search_controller") {
-  deps = [
-    ":directory_model",
-    "ui:file_manager_ui",
-    "//ui/file_manager/file_manager/common/js:util",
-    "//ui/file_manager/file_manager/common/js:volume_manager_types",
-    "//ui/file_manager/file_manager/externs:entry_location",
-    "//ui/file_manager/file_manager/externs:volume_manager",
-  ]
-}
-
 js_library("selection_menu_controller") {
   deps = [
     "ui:menu",
diff --git a/ui/file_manager/file_manager/foreground/js/directory_model.js b/ui/file_manager/file_manager/foreground/js/directory_model.js
index ca633ce..1295f9d 100644
--- a/ui/file_manager/file_manager/foreground/js/directory_model.js
+++ b/ui/file_manager/file_manager/foreground/js/directory_model.js
@@ -20,7 +20,7 @@
 import {VolumeManager} from '../../externs/volume_manager.js';
 import {getMyFiles} from '../../state/ducks/all_entries.js';
 import {changeDirectory} from '../../state/ducks/current_directory.js';
-import {getDefaultSearchOptions, updateSearch} from '../../state/ducks/search.js';
+import {clearSearch, getDefaultSearchOptions, updateSearch} from '../../state/ducks/search.js';
 import {getFileData, getStore, getVolume} from '../../state/store.js';
 
 import {constants} from './constants.js';
@@ -110,6 +110,7 @@
     this.rescanTime_ = null;
     this.scanFailures_ = 0;
     this.changeDirectorySequence_ = 0;
+    this.cachedSearch_ = {};
 
     /** @private @type {?function(Event): void} */
     this.onSearchCompleted_ = null;
@@ -183,6 +184,16 @@
 
   /** @param {!State} state latest state from the store. */
   onStateChanged(state) {
+    this.handleDirectoryState_(state);
+    this.handleSearchState_(state);
+  }
+
+  /**
+   * Handles the current directory slice of the store's state.
+   * @param {!State} state latest state from the store.
+   * @private
+   */
+  handleDirectoryState_(state) {
     const currentEntry = this.getCurrentDirEntry();
     const currentURL = currentEntry ? currentEntry.toURL() : null;
     let newURL = state.currentDirectory ? state.currentDirectory.key : null;
@@ -224,6 +235,42 @@
   }
 
   /**
+   * Reacts to changes in the search state of the store. If the search changed
+   * and the query is not empty, this method triggers a new directory search.
+   * @param {!State} state
+   * @private
+   */
+  handleSearchState_(state) {
+    const currentEntry = this.getCurrentDirEntry();
+    // Do not handle any search state until we have the current directory set.
+    // Requests to handle current search state may be triggered by the files app
+    // before it is fully started.
+    if (!currentEntry) {
+      return;
+    }
+    const search = state.search;
+    if (this.cachedSearch_ === search) {
+      // Bail out early if the search part of the state has not changed.
+      return;
+    }
+
+    // Cache the last received search state for future comparisons.
+    const lastSearch = this.cachedSearch_;
+    this.cachedSearch_ = search;
+
+    // We change the search state (STARTED, SUCCESS, etc.) so only trigger
+    // a new search if the query or the options have changed.
+    if (!search) {
+      return;
+    }
+    if (!lastSearch || lastSearch.query !== search.query ||
+        lastSearch.options !== search.options) {
+      this.search_(
+          search.query || '', search.options || getDefaultSearchOptions());
+    }
+  }
+
+  /**
    * Disposes the directory model by removing file watchers.
    */
   dispose() {
@@ -1210,7 +1257,7 @@
    *
    * @param {!DirectoryEntry|!FilesAppDirEntry} dirEntry The entry of the new
    *     directory to be opened.
-   * @param {function()=} opt_callback Executed if the directory loads
+   * @param {function(boolean)=} opt_callback Executed if the directory loads
    *     successfully.
    */
   changeDirectoryEntry(dirEntry, opt_callback) {
@@ -1249,11 +1296,11 @@
 
       const previousDirEntry = this.currentDirContents_.getDirectoryEntry();
       this.clearAndScan_(newDirectoryContents, result => {
-        // Calls the callback of the method when successful.
-        if (result && opt_callback) {
-          opt_callback();
+        // Calls the callback of the method and inform it about success or lack
+        // of thereof.
+        if (opt_callback) {
+          opt_callback(result);
         }
-
         // Notify that the current task of this.directoryChangeQueue_
         // is completed.
         setTimeout(queueTaskCallback, 0);
@@ -1272,6 +1319,15 @@
       event.newDirEntry = dirEntry;
       event.volumeChanged = previousVolumeInfo !== currentVolumeInfo;
       this.dispatchEvent(event);
+      if (previousDirEntry) {
+        // If we changed from a directory to another directory always clear
+        // search and search query on directory change. When the Files app is
+        // started previousDirEntry is undefined. For that case we must not
+        // clear the search query as it may be part of the starting parameters.
+        this.cachedSearch_ = {};
+        this.store_.dispatch(clearSearch());
+        this.clearLastSearchQuery();
+      }
       // Notify the Store that the new directory has successfully changed.
       this.store_.dispatch(
           changeDirectory({to: dirEntry, status: PropStatus.SUCCESS}));
@@ -1661,10 +1717,9 @@
    * @param {string} query Query that will be searched for.
    * @param {!SearchOptions} options Search options, such as file
    *     type, etc.
-   * @param {function(Event)} onSearchRescan Function that will be called when
-   *     the search directory is rescanned (i.e. search results are displayed).
+   * @private
    */
-  search(query, options, onSearchRescan) {
+  search_(query, options) {
     this.lastSearchQuery_ = query;
     this.stopActiveSearch_();
     const currentDirEntry = this.getCurrentDirEntry();
@@ -1702,9 +1757,6 @@
       this.store_.dispatch(
           updateSearch({query: query, status: PropStatus.STARTED}));
       this.onSearchCompleted_ = (...args) => {
-        // Notify the caller via callback, for non-store based callers.
-        onSearchRescan(...args);
-
         // Notify the store-aware parts.
         this.store_.dispatch(updateSearch({status: PropStatus.SUCCESS}));
       };
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js
index e6abb6e..228089a 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -83,7 +83,6 @@
 import {QuickViewModel} from './quick_view_model.js';
 import {QuickViewUma} from './quick_view_uma.js';
 import {ScanController} from './scan_controller.js';
-import {SearchController} from './search_controller.js';
 import {SelectionMenuController} from './selection_menu_controller.js';
 import {SortMenuController} from './sort_menu_controller.js';
 import {SpinnerController} from './spinner_controller.js';
@@ -243,12 +242,6 @@
     this.directoryTreeNamingController_ = null;
 
     /**
-     * Controller for search UI.
-     * @private @type {?SearchController}
-     */
-    this.searchController_ = null;
-
-    /**
      * Controller for directory scan.
      * @private @type {?ScanController}
      */
@@ -1189,13 +1182,6 @@
         this.metadataUpdateController_, assert(this.crostini_),
         this.progressCenter);
 
-    // Create search controller.
-    this.searchController_ = new SearchController(
-        this.ui_.searchContainer,
-        this.directoryModel_,
-        assert(this.ui_),
-    );
-
     // Create directory tree naming controller.
     this.directoryTreeNamingController_ = new DirectoryTreeNamingController(
         this.directoryModel_, assert(this.ui_.directoryTree),
@@ -1450,7 +1436,7 @@
       this.store_.dispatch(updateSearch({
         query: searchQuery,
         status: PropStatus.STARTED,
-        options: undefined,
+        options: getDefaultSearchOptions(),
       }));
       // Show a spinner, as the crossover search function call could be slow.
       const hideSpinnerCallback = this.spinnerController_.show();
@@ -1612,8 +1598,8 @@
           this.directoryModel_.selectEntry(opt_selectionEntry);
         }
         if (this.launchParams_.searchQuery) {
-          this.searchController_.setSearchQuery(
-              this.launchParams_.searchQuery, getDefaultSearchOptions());
+          this.store_.dispatch(
+              updateSearch({query: this.launchParams_.searchQuery}));
         }
       } else {
         console.warn('No entry for finishSetupCurrentDirectory_');
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
index 8faf230..a536f0d 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -941,7 +941,7 @@
     const root = CommandUtil.getEventEntry(event, fileManager);
 
     if (root && root instanceof EntryList) {
-      /** @type {FilesFormatDialogElement} */ (fileManager.ui.formatDialog)
+      /** @type {FilesFormatDialog} */ (fileManager.ui.formatDialog)
           .showEraseModal(root);
     }
   }
diff --git a/ui/file_manager/file_manager/foreground/js/search_controller.js b/ui/file_manager/file_manager/foreground/js/search_controller.js
deleted file mode 100644
index 9c0c4d0..0000000
--- a/ui/file_manager/file_manager/foreground/js/search_controller.js
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {str, strf} from '../../common/js/util.js';
-import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js';
-import {SearchContainer} from '../../containers/search_container.js';
-import {SearchOptions, State} from '../../externs/ts/state.js';
-import {getDefaultSearchOptions} from '../../state/ducks/search.js';
-import {getStore} from '../../state/store.js';
-
-import {DirectoryModel} from './directory_model.js';
-import {FileManagerUI} from './ui/file_manager_ui.js';
-
-/**
- * Controller for searching.
- */
-export class SearchController {
-  /**
-   * @param {!SearchContainer} searchContainer The controller of search
-   *     elements.
-   * @param {!DirectoryModel} directoryModel Directory model.
-   * @param {!FileManagerUI} a11y FileManagerUI to be able to announce a11y
-   *     messages.
-   */
-  constructor(searchContainer, directoryModel, a11y) {
-    /** @const @private @type {!SearchContainer} */
-    this.searchContainer_ = searchContainer;
-
-    /** @const @private @type {!DirectoryModel} */
-    this.directoryModel_ = directoryModel;
-
-    /** @const @private @type {!FileManagerUI} */
-    this.a11y_ = a11y;
-
-    directoryModel.addEventListener('directory-changed', this.clear.bind(this));
-
-    this.cachedSearchState_ = {};
-    this.store_ = getStore();
-    this.store_.subscribe(this);
-  }
-
-  /**
-   * Reacts to state change in the store. This method checks if the search
-   * component of the search state changed. If so, it triggers a new search.
-   * @param {State} state
-   */
-  onStateChanged(state) {
-    const searchState = state.search;
-    if (!searchState) {
-      return;
-    }
-    if (searchState.query === this.cachedSearchState_.query &&
-        searchState.options === this.cachedSearchState_.options) {
-      return;
-    }
-    this.cachedSearchState_ = searchState;
-    this.onSearchChange_(
-        searchState.query || '',
-        searchState.options || getDefaultSearchOptions());
-  }
-
-  /**
-   * Clears the search state.
-   * @param {Event=} opt_event when called from "directory-changed" event.
-   */
-  clear(opt_event) {
-    this.directoryModel_.clearLastSearchQuery();
-    // If the call to clear was caused by the startup code we do not clear
-    // the search container. This is to prevent the search container from
-    // hiding launch parameter search query. We detect the app start up
-    // condition by checking that the previous directory entry was not set.
-    if (opt_event && opt_event.previousDirEntry !== null) {
-      this.searchContainer_.clear();
-    }
-    // Only update visibility if |clear| is called from "directory-changed"
-    // event.
-    if (opt_event) {
-      // My Files currently doesn't implement search so let's hide it.
-      const isMyFiles =
-          (opt_event.newDirEntry &&
-           opt_event.newDirEntry.rootType ===
-               VolumeManagerCommon.RootType.MY_FILES);
-      this.searchContainer_.setHidden(isMyFiles);
-    }
-  }
-
-  /**
-   * Sets search query on the search box and performs a search.
-   * @param {string} searchQuery Search query string to be searched with.
-   * @param {!SearchOptions} options Options to be used when searching.
-   */
-  setSearchQuery(searchQuery, options) {
-    this.searchContainer_.setQuery(searchQuery);
-    this.onSearchChange_(searchQuery, options);
-  }
-
-  /**
-   * Handles text change event.
-   * @param {string} query
-   * @param {!SearchOptions} options Search options, such as type,
-   *    location, etc.
-   * @private
-   */
-  onSearchChange_(query, options) {
-    if (!query) {
-      const msg = str('SEARCH_A11Y_CLEAR_SEARCH');
-      this.a11y_.speakA11yMessage(msg);
-    }
-    const onSearchRescan = function() {
-      const fileList = this.directoryModel_.getFileList();
-      const count = fileList.getFileCount() + fileList.getFolderCount();
-      const msgId =
-          count === 0 ? 'SEARCH_A11Y_NO_RESULT' : 'SEARCH_A11Y_RESULT';
-      const msg = strf(msgId, query);
-      this.a11y_.speakA11yMessage(msg);
-    };
-
-    this.directoryModel_.search(query, options, onSearchRescan.bind(this));
-  }
-}
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
index ec17388..603ba2bf 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_manager_ui.js
@@ -526,7 +526,8 @@
     this.searchContainer = new SearchContainer(
         volumeManager, queryRequiredElement('#search-wrapper', this.element),
         queryRequiredElement('#search-options-container', this.element),
-        queryRequiredElement('#path-display-container', this.element));
+        queryRequiredElement('#path-display-container', this.element),
+        /*a11y=*/ this);
 
     if (util.isDriveFsBulkPinningEnabled()) {
       /**
diff --git a/ui/file_manager/file_manager/state/ducks/all_entries.ts b/ui/file_manager/file_manager/state/ducks/all_entries.ts
index 4505b8ad..d4efae0 100644
--- a/ui/file_manager/file_manager/state/ducks/all_entries.ts
+++ b/ui/file_manager/file_manager/state/ducks/all_entries.ts
@@ -613,6 +613,11 @@
     }
   }
 
+  state.allEntries[volumeRootKey].isEjectable =
+      (volumeInfo.source === VolumeManagerCommon.Source.DEVICE &&
+       volumeInfo.volumeType !== VolumeManagerCommon.VolumeType.MTP) ||
+      volumeInfo.source === VolumeManagerCommon.Source.FILE;
+
   if (volumeInfo.volumeType === VolumeType.REMOVABLE) {
     // It should be nested/grouped when there is more than 1 partition in the
     // same device.
@@ -666,12 +671,6 @@
         icon: constants.ICON_TYPES.UNKNOWN_REMOVABLE,
         isEjectable: false,
       };
-    } else {
-      // Update the isEjectable only if the removable device is not grouped.
-      state.allEntries[volumeRootKey].isEjectable =
-          (volumeInfo.source === VolumeManagerCommon.Source.DEVICE &&
-           volumeInfo.volumeType !== VolumeManagerCommon.VolumeType.MTP) ||
-          volumeInfo.source === VolumeManagerCommon.Source.FILE;
     }
   }
 
diff --git a/ui/file_manager/file_manager/state/ducks/search.ts b/ui/file_manager/file_manager/state/ducks/search.ts
index 1a6da08..6546cc7 100644
--- a/ui/file_manager/file_manager/state/ducks/search.ts
+++ b/ui/file_manager/file_manager/state/ducks/search.ts
@@ -14,6 +14,13 @@
 export {slice as searchSlice};
 
 /**
+ * Returns if the given search data represents empty (cleared) search.
+ */
+export function isSearchEmpty(search: SearchData): boolean {
+  return Object.values(search).every(f => f === undefined);
+}
+
+/**
  * Helper function that does a deep comparison between two SearchOptions.
  */
 function optionsChanged(
@@ -41,11 +48,15 @@
   };
   // Special case: if none of the fields are set, the action clears the search
   // state in the store.
-  if (Object.values(payload).every(field => field === undefined)) {
-    return {
-      ...state,
-      search: blankSearch,
-    };
+  if (isSearchEmpty(payload)) {
+    // Only change the state if the stored value has some defined values.
+    if (state.search && !isSearchEmpty(state.search)) {
+      return {
+        ...state,
+        search: blankSearch,
+      };
+    }
+    return state;
   }
 
   const currentSearch = state.search || blankSearch;
diff --git a/ui/file_manager/file_manager/state/ducks/volumes_unittest.ts b/ui/file_manager/file_manager/state/ducks/volumes_unittest.ts
index 64be3bf5..d2db1cc1 100644
--- a/ui/file_manager/file_manager/state/ducks/volumes_unittest.ts
+++ b/ui/file_manager/file_manager/state/ducks/volumes_unittest.ts
@@ -403,6 +403,50 @@
   done();
 }
 
+/** Tests that archive volume can be added correctly. */
+export async function testAddArchiveVolume(done: () => void) {
+  const initialState = getEmptyState();
+  const store = setupStore(initialState);
+
+  const {volumeManager} = window.fileManager;
+  const volumeInfo = MockVolumeManager.createMockVolumeInfo(
+      VolumeManagerCommon.VolumeType.ARCHIVE, 'test', 'test.zip');
+  // Archive's source should be File.
+  // @ts-ignore: access private variable to customize the source.
+  volumeInfo.source_ = VolumeManagerCommon.Source.FILE;
+  volumeManager.volumeInfoList.add(volumeInfo);
+  const volumeEntry = new VolumeEntry(volumeInfo);
+  const volumeMetadata = createFakeVolumeMetadata(volumeInfo);
+
+  // Dispatch an action to add the archive volume.
+  store.dispatch(addVolume({volumeInfo, volumeMetadata}));
+
+  // Expect the volume will be added from the store.
+  const myFilesFileData = createMyFilesDataWithEntryList();
+  const want: Partial<State> = {
+    allEntries: {
+      // My Files entry list.
+      [myFilesFileData.entry.toURL()]: myFilesFileData,
+      // Archive.
+      [volumeEntry.toURL()]: {
+        ...convertEntryToFileData(volumeEntry),
+        isEjectable: true,
+      },
+    },
+    volumes: {
+      [volumeInfo.volumeId]: {
+        ...convertVolumeInfoAndMetadataToVolume(volumeInfo, volumeMetadata),
+      },
+    },
+  };
+  await waitDeepEquals(store, want, (state) => ({
+                                      allEntries: state.allEntries,
+                                      volumes: state.volumes,
+                                    }));
+
+  done();
+}
+
 /** Tests that volume can be removed correctly. */
 export async function testRemoveVolume(done: () => void) {
   const initialState = getEmptyState();
diff --git a/ui/file_manager/file_names.gni b/ui/file_manager/file_names.gni
index 5b0b2e89..d5745b8 100644
--- a/ui/file_manager/file_names.gni
+++ b/ui/file_manager/file_names.gni
@@ -122,7 +122,6 @@
   "file_manager/foreground/js/path_component.js",
   "file_manager/foreground/js/providers_model.js",
   "file_manager/foreground/js/scan_controller.js",
-  "file_manager/foreground/js/search_controller.js",
   "file_manager/foreground/js/selection_menu_controller.js",
   "file_manager/foreground/js/sort_menu_controller.js",
   "file_manager/foreground/js/spinner_controller.js",
@@ -330,6 +329,7 @@
 # Closure is failing to recognize the generated JS from the TS.
 # JS targets should rely on externs to type check the Polymer elements from TS.
 ts_polymer = [
+  "file_manager/foreground/elements/files_format_dialog.ts",
   "file_manager/foreground/elements/files_quick_view.ts",
   "file_manager/foreground/elements/files_metadata_box.ts",
   "file_manager/foreground/elements/files_safe_media.ts",
@@ -443,6 +443,7 @@
 
 # Generated in foregorund/elements folder.
 ts_generated_templates += [
+  "file_manager/foreground/elements/files_format_dialog.html.ts",
   "file_manager/foreground/elements/files_metadata_box.html.ts",
   "file_manager/foreground/elements/files_metadata_entry.html.ts",
   "file_manager/foreground/elements/files_quick_view.html.ts",
@@ -479,7 +480,6 @@
   "file_manager/common/js/file_types_data.js",
 
   # Elements:
-  "file_manager/foreground/elements/files_format_dialog.js",
   "file_manager/foreground/elements/files_spinner.js",
   "file_manager/foreground/elements/icons.js",
   "file_manager/foreground/elements/xf_button.js",
diff --git a/ui/file_manager/integration_tests/file_manager/search.js b/ui/file_manager/integration_tests/file_manager/search.js
index 104d9d18..6c3f0ac 100644
--- a/ui/file_manager/integration_tests/file_manager/search.js
+++ b/ui/file_manager/integration_tests/file_manager/search.js
@@ -1118,3 +1118,17 @@
       appId, TestEntryInfo.getExpectedRows([ENTRIES.image3]),
       {ignoreLastModifiedTime: true});
 };
+
+/**
+ * Checks that any search, regardless if it has results or not, is closed if we
+ * navigate to another directory.
+ */
+testcase.changingDirectoryClosesSearch = async () => {
+  const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS);
+  await remoteCall.typeSearchText(appId, 'hello');
+  await remoteCall.waitForFiles(
+      appId, TestEntryInfo.getExpectedRows([ENTRIES.hello]));
+  const directoryTree = await DirectoryTreePageObject.create(appId, remoteCall);
+  await directoryTree.navigateToPath('/My files/Downloads/photos');
+  await remoteCall.waitForElement(appId, '#search-wrapper[collapsed]');
+};
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
index 729f6c4..9161edb 100644
--- a/ui/gfx/BUILD.gn
+++ b/ui/gfx/BUILD.gn
@@ -489,10 +489,14 @@
     sources += [
       "hdr_metadata_mac.h",
       "hdr_metadata_mac.mm",
+      "mac/color_space_util.h",
+      "mac/color_space_util.mm",
     ]
     frameworks = [
       "CoreFoundation.framework",
       "CoreGraphics.framework",
+      "CoreMedia.framework",
+      "CoreVideo.framework",
     ]
     if (is_mac) {
       sources += [
diff --git a/ui/gfx/mac/color_space_util.h b/ui/gfx/mac/color_space_util.h
new file mode 100644
index 0000000..cb71023fc
--- /dev/null
+++ b/ui/gfx/mac/color_space_util.h
@@ -0,0 +1,36 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_MAC_COLOR_SPACE_UTIL_H_
+#define UI_GFX_MAC_COLOR_SPACE_UTIL_H_
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "base/apple/scoped_cftyperef.h"
+#include "ui/gfx/color_space_export.h"
+
+namespace gfx {
+
+class ColorSpace;
+
+// Converts a gfx::ColorSpace to individual kCVImageBuffer keys. If
+// `prefer_srgb_trfn` is true then return the sRGB transfer function for all
+// Rec709-like content.
+COLOR_SPACE_EXPORT bool ColorSpaceToCVImageBufferKeys(
+    const gfx::ColorSpace& color_space,
+    bool prefer_srgb_trfn,
+    CFStringRef* out_primaries,
+    CFStringRef* out_transfer,
+    CFStringRef* out_matrix);
+
+// Converts individual kCVImageBuffer keys to a gfx::ColorSpace.
+COLOR_SPACE_EXPORT gfx::ColorSpace ColorSpaceFromCVImageBufferKeys(
+    CFTypeRef primaries,
+    CFTypeRef transfer,
+    CFTypeRef gamma,
+    CFTypeRef matrix);
+
+}  // namespace gfx
+
+#endif  // UI_GFX_MAC_COLOR_SPACE_UTIL_H_
diff --git a/ui/gfx/mac/color_space_util.mm b/ui/gfx/mac/color_space_util.mm
new file mode 100644
index 0000000..c31cb93a
--- /dev/null
+++ b/ui/gfx/mac/color_space_util.mm
@@ -0,0 +1,319 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gfx/mac/color_space_util.h"
+
+#include <CoreMedia/CoreMedia.h>
+#include <CoreVideo/CoreVideo.h>
+
+#include "base/apple/foundation_util.h"
+#include "base/apple/scoped_cftyperef.h"
+#include "base/memory/scoped_policy.h"
+#include "base/no_destructor.h"
+#include "third_party/skia/modules/skcms/skcms.h"
+#include "ui/gfx/color_space.h"
+
+namespace gfx {
+
+namespace {
+
+// Read the value for the key in |key| to CFString and convert it to IdType.
+// Use the list of pairs in |cfstr_id_pairs| to do the conversion (by doing a
+// linear lookup).
+template <typename IdType, typename StringIdPair>
+bool GetImageBufferProperty(CFTypeRef value_untyped,
+                            const std::vector<StringIdPair>& cfstr_id_pairs,
+                            IdType* value_as_id) {
+  CFStringRef value_as_string = base::apple::CFCast<CFStringRef>(value_untyped);
+  if (!value_as_string) {
+    return false;
+  }
+
+  for (const auto& p : cfstr_id_pairs) {
+    if (p.cfstr_cm) {
+      DCHECK(!CFStringCompare(p.cfstr_cv, p.cfstr_cm, 0));
+    }
+    if (!CFStringCompare(value_as_string, p.cfstr_cv, 0)) {
+      *value_as_id = p.id;
+      return true;
+    }
+  }
+
+  return false;
+}
+
+struct CVImagePrimary {
+  const CFStringRef cfstr_cv;
+  const CFStringRef cfstr_cm;
+  const gfx::ColorSpace::PrimaryID id;
+};
+const std::vector<CVImagePrimary>& GetSupportedImagePrimaries() {
+  static const base::NoDestructor<std::vector<CVImagePrimary>>
+      kSupportedPrimaries([] {
+        std::vector<CVImagePrimary> supported_primaries;
+        supported_primaries.push_back(
+            {kCVImageBufferColorPrimaries_ITU_R_709_2,
+             kCMFormatDescriptionColorPrimaries_ITU_R_709_2,
+             gfx::ColorSpace::PrimaryID::BT709});
+        supported_primaries.push_back(
+            {kCVImageBufferColorPrimaries_EBU_3213,
+             kCMFormatDescriptionColorPrimaries_EBU_3213,
+             gfx::ColorSpace::PrimaryID::BT470BG});
+        supported_primaries.push_back(
+            {kCVImageBufferColorPrimaries_SMPTE_C,
+             kCMFormatDescriptionColorPrimaries_SMPTE_C,
+             gfx::ColorSpace::PrimaryID::SMPTE170M});
+        supported_primaries.push_back(
+            {kCVImageBufferColorPrimaries_ITU_R_2020,
+             kCMFormatDescriptionColorPrimaries_ITU_R_2020,
+             gfx::ColorSpace::PrimaryID::BT2020});
+        supported_primaries.push_back(
+            {kCVImageBufferColorPrimaries_DCI_P3,
+             kCMFormatDescriptionColorPrimaries_DCI_P3,
+             gfx::ColorSpace::PrimaryID::SMPTEST431_2});
+        supported_primaries.push_back(
+            {kCVImageBufferColorPrimaries_P3_D65,
+             kCMFormatDescriptionColorPrimaries_P3_D65,
+             gfx::ColorSpace::PrimaryID::P3});
+        return supported_primaries;
+      }());
+  return *kSupportedPrimaries;
+}
+
+gfx::ColorSpace::PrimaryID GetCoreVideoPrimary(CFTypeRef primaries_untyped) {
+  auto primary_id = gfx::ColorSpace::PrimaryID::INVALID;
+  if (!GetImageBufferProperty(primaries_untyped, GetSupportedImagePrimaries(),
+                              &primary_id)) {
+    DLOG(ERROR) << "Failed to find CVImageBufferRef primaries: "
+                << primaries_untyped;
+  }
+  return primary_id;
+}
+
+struct CVImageTransferFn {
+  const CFStringRef cfstr_cv;
+  const CFStringRef cfstr_cm;
+  const gfx::ColorSpace::TransferID id;
+};
+const std::vector<CVImageTransferFn>& GetSupportedImageTransferFn() {
+  static const base::NoDestructor<std::vector<CVImageTransferFn>>
+      kSupportedTransferFuncs([] {
+        std::vector<CVImageTransferFn> supported_transfer_funcs;
+        supported_transfer_funcs.push_back(
+            {kCVImageBufferTransferFunction_ITU_R_709_2,
+             kCMFormatDescriptionTransferFunction_ITU_R_709_2,
+             gfx::ColorSpace::TransferID::BT709_APPLE});
+        supported_transfer_funcs.push_back(
+            {kCVImageBufferTransferFunction_ITU_R_709_2,
+             kCMFormatDescriptionTransferFunction_ITU_R_709_2,
+             gfx::ColorSpace::TransferID::BT709});
+        supported_transfer_funcs.push_back(
+            {kCVImageBufferTransferFunction_ITU_R_709_2,
+             kCMFormatDescriptionTransferFunction_ITU_R_709_2,
+             gfx::ColorSpace::TransferID::SMPTE170M});
+        supported_transfer_funcs.push_back(
+            {kCVImageBufferTransferFunction_SMPTE_240M_1995,
+             kCMFormatDescriptionTransferFunction_SMPTE_240M_1995,
+             gfx::ColorSpace::TransferID::SMPTE240M});
+        supported_transfer_funcs.push_back(
+            {kCVImageBufferTransferFunction_UseGamma,
+             kCMFormatDescriptionTransferFunction_UseGamma,
+             gfx::ColorSpace::TransferID::CUSTOM});
+        supported_transfer_funcs.push_back(
+            {kCVImageBufferTransferFunction_ITU_R_2020,
+             kCMFormatDescriptionTransferFunction_ITU_R_2020,
+             gfx::ColorSpace::TransferID::BT2020_10});
+        supported_transfer_funcs.push_back(
+            {kCVImageBufferTransferFunction_SMPTE_ST_428_1,
+             kCMFormatDescriptionTransferFunction_SMPTE_ST_428_1,
+             gfx::ColorSpace::TransferID::SMPTEST428_1});
+        supported_transfer_funcs.push_back(
+            {kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ,
+             kCMFormatDescriptionTransferFunction_SMPTE_ST_2084_PQ,
+             gfx::ColorSpace::TransferID::PQ});
+        supported_transfer_funcs.push_back(
+            {kCVImageBufferTransferFunction_ITU_R_2100_HLG,
+             kCMFormatDescriptionTransferFunction_ITU_R_2100_HLG,
+             gfx::ColorSpace::TransferID::HLG});
+        supported_transfer_funcs.push_back({kCVImageBufferTransferFunction_sRGB,
+                                            nullptr,
+                                            gfx::ColorSpace::TransferID::SRGB});
+        supported_transfer_funcs.push_back(
+            {kCVImageBufferTransferFunction_Linear,
+             kCMFormatDescriptionTransferFunction_Linear,
+             gfx::ColorSpace::TransferID::LINEAR});
+        supported_transfer_funcs.push_back(
+            {kCVImageBufferTransferFunction_sRGB,
+             kCMFormatDescriptionTransferFunction_sRGB,
+             gfx::ColorSpace::TransferID::SRGB});
+
+        return supported_transfer_funcs;
+      }());
+  return *kSupportedTransferFuncs;
+}
+
+gfx::ColorSpace::TransferID GetCoreVideoTransferFn(CFTypeRef transfer_untyped,
+                                                   CFTypeRef gamma_untyped,
+                                                   double* gamma) {
+  // The named transfer function.
+  auto transfer_id = gfx::ColorSpace::TransferID::INVALID;
+  if (!GetImageBufferProperty(transfer_untyped, GetSupportedImageTransferFn(),
+                              &transfer_id)) {
+    DLOG(ERROR) << "Failed to find CVImageBufferRef transfer: "
+                << transfer_untyped;
+  }
+
+  if (transfer_id != gfx::ColorSpace::TransferID::CUSTOM) {
+    return transfer_id;
+  }
+
+  CFNumberRef gamma_number = base::apple::CFCast<CFNumberRef>(gamma_untyped);
+  if (!gamma_number) {
+    DLOG(ERROR) << "Failed to get gamma level.";
+    return gfx::ColorSpace::TransferID::INVALID;
+  }
+
+  // CGFloat is a double on 64-bit systems.
+  CGFloat gamma_double = 0;
+  if (!CFNumberGetValue(gamma_number, kCFNumberCGFloatType, &gamma_double)) {
+    DLOG(ERROR) << "Failed to get CVImageBufferRef gamma level as float.";
+    return gfx::ColorSpace::TransferID::INVALID;
+  }
+
+  if (gamma_double == 2.2) {
+    return gfx::ColorSpace::TransferID::GAMMA22;
+  }
+  if (gamma_double == 2.8) {
+    return gfx::ColorSpace::TransferID::GAMMA28;
+  }
+
+  *gamma = gamma_double;
+  return transfer_id;
+}
+
+struct CVImageMatrix {
+  const CFStringRef cfstr_cv;
+  const CFStringRef cfstr_cm;
+  gfx::ColorSpace::MatrixID id;
+};
+const std::vector<CVImageMatrix>& GetSupportedImageMatrix() {
+  static const base::NoDestructor<std::vector<CVImageMatrix>>
+      kSupportedMatrices([] {
+        std::vector<CVImageMatrix> supported_matrices;
+        supported_matrices.push_back(
+            {kCVImageBufferYCbCrMatrix_ITU_R_709_2,
+             kCMFormatDescriptionYCbCrMatrix_ITU_R_709_2,
+             gfx::ColorSpace::MatrixID::BT709});
+        supported_matrices.push_back(
+            {kCVImageBufferYCbCrMatrix_ITU_R_601_4,
+             kCMFormatDescriptionYCbCrMatrix_ITU_R_601_4,
+             gfx::ColorSpace::MatrixID::SMPTE170M});
+        supported_matrices.push_back(
+            {kCVImageBufferYCbCrMatrix_SMPTE_240M_1995,
+             kCMFormatDescriptionYCbCrMatrix_SMPTE_240M_1995,
+             gfx::ColorSpace::MatrixID::SMPTE240M});
+        supported_matrices.push_back(
+            {kCVImageBufferYCbCrMatrix_ITU_R_2020,
+             kCMFormatDescriptionYCbCrMatrix_ITU_R_2020,
+             gfx::ColorSpace::MatrixID::BT2020_NCL});
+        return supported_matrices;
+      }());
+  return *kSupportedMatrices;
+}
+
+gfx::ColorSpace::MatrixID GetCoreVideoMatrix(CFTypeRef matrix_untyped) {
+  auto matrix_id = gfx::ColorSpace::MatrixID::INVALID;
+  if (!GetImageBufferProperty(matrix_untyped, GetSupportedImageMatrix(),
+                              &matrix_id)) {
+    DLOG(ERROR) << "Failed to find CVImageBufferRef YUV matrix: "
+                << matrix_untyped;
+  }
+  return matrix_id;
+}
+
+}  // anonymous namespace
+
+gfx::ColorSpace ColorSpaceFromCVImageBufferKeys(CFTypeRef primaries_untyped,
+                                                CFTypeRef transfer_untyped,
+                                                CFTypeRef gamma_untyped,
+                                                CFTypeRef matrix_untyped) {
+  double gamma;
+  auto primary_id = GetCoreVideoPrimary(primaries_untyped);
+  auto matrix_id = GetCoreVideoMatrix(matrix_untyped);
+  auto transfer_id =
+      GetCoreVideoTransferFn(transfer_untyped, gamma_untyped, &gamma);
+
+  if (primary_id == gfx::ColorSpace::PrimaryID::INVALID ||
+      matrix_id == gfx::ColorSpace::MatrixID::INVALID ||
+      transfer_id == gfx::ColorSpace::TransferID::INVALID) {
+    return gfx::ColorSpace();
+  }
+
+  // It is specified to the decoder to use luma=[16,235] chroma=[16,240] via
+  // the kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange.
+  //
+  // TODO(crbug.com/1103432): We'll probably need support for more than limited
+  // range content if we want this to be used for more than video sites.
+  auto range_id = gfx::ColorSpace::RangeID::LIMITED;
+
+  if (transfer_id == gfx::ColorSpace::TransferID::CUSTOM) {
+    // Transfer functions can also be specified as a gamma value.
+    skcms_TransferFunction custom_tr_fn = {2.2f, 1, 0, 1, 0, 0, 0};
+    if (transfer_id == gfx::ColorSpace::TransferID::CUSTOM) {
+      custom_tr_fn.g = gamma;
+    }
+
+    return gfx::ColorSpace(primary_id, gfx::ColorSpace::TransferID::CUSTOM,
+                           matrix_id, range_id, nullptr, &custom_tr_fn);
+  }
+
+  return gfx::ColorSpace(primary_id, transfer_id, matrix_id, range_id);
+}
+
+// Converts a gfx::ColorSpace to individual kCVImageBuffer* keys.
+bool ColorSpaceToCVImageBufferKeys(const gfx::ColorSpace& color_space,
+                                   bool prefer_srgb_trfn,
+                                   CFStringRef* out_primaries,
+                                   CFStringRef* out_transfer,
+                                   CFStringRef* out_matrix) {
+  DCHECK(out_primaries);
+  DCHECK(out_transfer);
+  DCHECK(out_matrix);
+
+  bool found_primary = false;
+  for (const auto& primaries : GetSupportedImagePrimaries()) {
+    if (primaries.id == color_space.GetPrimaryID()) {
+      *out_primaries = primaries.cfstr_cv;
+      found_primary = true;
+      break;
+    }
+  }
+
+  bool found_transfer = false;
+  for (const auto& transfer : GetSupportedImageTransferFn()) {
+    if (transfer.id == color_space.GetTransferID()) {
+      *out_transfer = transfer.cfstr_cv;
+      found_transfer = true;
+      break;
+    }
+  }
+  if (found_transfer && prefer_srgb_trfn) {
+    if (*out_transfer == kCVImageBufferTransferFunction_ITU_R_709_2) {
+      *out_transfer = kCVImageBufferTransferFunction_sRGB;
+    }
+  }
+
+  bool found_matrix = false;
+  for (const auto& matrix : GetSupportedImageMatrix()) {
+    if (matrix.id == color_space.GetMatrixID()) {
+      *out_matrix = matrix.cfstr_cv;
+      found_matrix = true;
+      break;
+    }
+  }
+
+  return found_primary && found_transfer && found_matrix;
+}
+
+}  // namespace gfx
diff --git a/ui/gfx/mac/io_surface.cc b/ui/gfx/mac/io_surface.cc
index af19d04e..2426817 100644
--- a/ui/gfx/mac/io_surface.cc
+++ b/ui/gfx/mac/io_surface.cc
@@ -20,6 +20,7 @@
 #include "ui/gfx/buffer_format_util.h"
 #include "ui/gfx/color_space.h"
 #include "ui/gfx/icc_profile.h"
+#include "ui/gfx/mac/color_space_util.h"
 
 namespace gfx {
 
@@ -150,11 +151,13 @@
   if (!color_space.IsValid())
     return true;
 
+  static const bool prefer_srgb_trfn =
+      base::FeatureList::IsEnabled(kIOSurfaceUseNamedSRGBForREC709);
+
   // Prefer using named spaces.
   CFStringRef color_space_name = nullptr;
   if (color_space == ColorSpace::CreateSRGB() ||
-      (base::FeatureList::IsEnabled(kIOSurfaceUseNamedSRGBForREC709) &&
-       color_space == ColorSpace::CreateREC709())) {
+      (prefer_srgb_trfn && color_space == ColorSpace::CreateREC709())) {
     color_space_name = kCGColorSpaceSRGB;
   } else if (color_space == ColorSpace::CreateDisplayP3D65()) {
     color_space_name = kCGColorSpaceDisplayP3;
@@ -191,6 +194,24 @@
       return true;
     }
   }
+
+  // https://crbug.com/1488397: Set parameters that will be rendering YUV
+  // content.
+  // TODO(b/304442486): Add gamma support here.
+  {
+    CFStringRef primaries = nullptr;
+    CFStringRef transfer = nullptr;
+    CFStringRef matrix = nullptr;
+    if (ColorSpaceToCVImageBufferKeys(color_space, prefer_srgb_trfn, &primaries,
+                                      &transfer, &matrix)) {
+      IOSurfaceSetValue(io_surface, CFSTR("IOSurfaceColorPrimaries"),
+                        primaries);
+      IOSurfaceSetValue(io_surface, CFSTR("IOSurfaceTransferFunction"),
+                        transfer);
+      IOSurfaceSetValue(io_surface, CFSTR("IOSurfaceYCbCrMatrix"), matrix);
+    }
+  }
+
   if (color_space_name) {
     if (io_surface) {
       IOSurfaceSetValue(io_surface, CFSTR("IOSurfaceColorSpace"),
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc
index 1ab6299b..aab22bc 100644
--- a/ui/gfx/render_text_unittest.cc
+++ b/ui/gfx/render_text_unittest.cc
@@ -7093,8 +7093,8 @@
 // falling back to other fonts.
 TEST_F(RenderTextTest, HarfBuzz_FontListFallback) {
   // Double-check that the requested fonts are present.
-  std::string format = std::string(kTestFontName) + ", %s, 12px";
-  FontList font_list(base::StringPrintf(format.c_str(), kSymbolFontName));
+  FontList font_list(
+      base::StringPrintf("%s, %s, 12px", kTestFontName, kSymbolFontName));
   const std::vector<Font>& fonts = font_list.GetFonts();
   ASSERT_EQ(2u, fonts.size());
   ASSERT_EQ(base::ToLowerASCII(kTestFontName),
diff --git a/ui/message_center/views/notification_control_buttons_unittest.cc b/ui/message_center/views/notification_control_buttons_unittest.cc
index 3841eb4f..1a82421 100644
--- a/ui/message_center/views/notification_control_buttons_unittest.cc
+++ b/ui/message_center/views/notification_control_buttons_unittest.cc
@@ -5,17 +5,17 @@
 #include "ui/message_center/views/notification_control_buttons_view.h"
 
 #include "base/memory/raw_ptr.h"
-#include "base/strings/utf_string_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/color_palette.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_unittest_util.h"
 #include "ui/gfx/paint_vector_icon.h"
+#include "ui/gfx/vector_icon_types.h"
 #include "ui/message_center/public/cpp/notification.h"
 #include "ui/message_center/vector_icons.h"
 #include "ui/message_center/views/message_view.h"
 #include "ui/views/controls/button/image_button.h"
+#include "ui/views/layout/box_layout.h"
 #include "ui/views/test/views_test_base.h"
 #include "ui/views/widget/widget.h"
 
@@ -154,4 +154,70 @@
       color_utils::BlendForMinContrast(SK_ColorBLACK, SK_ColorBLACK).color);
 }
 
+// Tests default and custom control button icons.
+TEST_F(NotificationControlButtonsTest, SetIcons) {
+  // Show the default control buttons.
+  buttons_view()->ShowCloseButton(true);
+  buttons_view()->ShowSettingsButton(true);
+  buttons_view()->ShowSnoozeButton(true);
+
+  // Verify that the default control buttons are using their default icons.
+  const SkColor default_icon_color =
+      buttons_view()->GetColorProvider()->GetColor(ui::kColorIcon);
+  EXPECT_TRUE(MatchesIcon(buttons_view()->close_button(),
+                          NotificationControlButtonsView::kDefaultCloseIcon,
+                          default_icon_color));
+  EXPECT_TRUE(MatchesIcon(buttons_view()->settings_button(),
+                          NotificationControlButtonsView::kDefaultSettingsIcon,
+                          default_icon_color));
+  EXPECT_TRUE(MatchesIcon(buttons_view()->snooze_button(),
+                          NotificationControlButtonsView::kDefaultSnoozeIcon,
+                          default_icon_color));
+
+  // Set the control buttons to have custom, non-default icons.
+  buttons_view()->ShowCloseButton(false);
+  buttons_view()->ShowSettingsButton(false);
+  buttons_view()->ShowSnoozeButton(false);
+  const gfx::VectorIcon& test_icon = kProductIcon;
+  buttons_view()->SetCloseButtonIcon(test_icon);
+  buttons_view()->SetSettingsButtonIcon(test_icon);
+  buttons_view()->SetSnoozeButtonIcon(test_icon);
+  buttons_view()->ShowCloseButton(true);
+  buttons_view()->ShowSettingsButton(true);
+  buttons_view()->ShowSnoozeButton(true);
+
+  // Verify that the control buttons are now using the custom icons.
+  EXPECT_TRUE(MatchesIcon(buttons_view()->close_button(), test_icon,
+                          default_icon_color));
+  EXPECT_TRUE(MatchesIcon(buttons_view()->settings_button(), test_icon,
+                          default_icon_color));
+  EXPECT_TRUE(MatchesIcon(buttons_view()->snooze_button(), test_icon,
+                          default_icon_color));
+}
+
+// Tests spacing between control buttons.
+TEST_F(NotificationControlButtonsTest, BetweenButtonsSpacing) {
+  // Show all the control buttons with default horizontal spacing.
+  buttons_view()->ShowCloseButton(true);
+  buttons_view()->ShowSettingsButton(true);
+  buttons_view()->ShowSnoozeButton(true);
+
+  // Verify that the control buttons use the default horizontal spacing.
+  EXPECT_EQ(static_cast<views::BoxLayout*>(buttons_view()->GetLayoutManager())
+                ->between_child_spacing(),
+            NotificationControlButtonsView::kDefaultBetweenButtonSpacing);
+
+  // Use a non-default amount of horizontal spacing.
+  const int new_spacing =
+      NotificationControlButtonsView::kDefaultBetweenButtonSpacing + 1;
+  buttons_view()->SetBetweenButtonSpacing(new_spacing);
+
+  // Verify that the control buttons use the new horizontal spacing, and that
+  // the layout has been invalidated.
+  EXPECT_EQ(static_cast<views::BoxLayout*>(buttons_view()->GetLayoutManager())
+                ->between_child_spacing(),
+            new_spacing);
+  EXPECT_TRUE(buttons_view()->needs_layout());
+}
+
 }  // namespace message_center
diff --git a/ui/message_center/views/notification_control_buttons_view.cc b/ui/message_center/views/notification_control_buttons_view.cc
index 193c0059..10ec325 100644
--- a/ui/message_center/views/notification_control_buttons_view.cc
+++ b/ui/message_center/views/notification_control_buttons_view.cc
@@ -11,11 +11,9 @@
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/color/color_provider.h"
 #include "ui/compositor/layer.h"
-#include "ui/events/event.h"
-#include "ui/gfx/color_palette.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/gfx/paint_vector_icon.h"
-#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/gfx/vector_icon_types.h"
 #include "ui/message_center/vector_icons.h"
 #include "ui/message_center/views/message_view.h"
 #include "ui/message_center/views/notification_control_button_factory.h"
@@ -28,11 +26,7 @@
 NotificationControlButtonsView::NotificationControlButtonsView(
     MessageView* message_view)
     : message_view_(message_view) {
-  auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
-      views::BoxLayout::Orientation::kHorizontal));
-  // Do not stretch buttons as that would stretch their focus indicator.
-  layout->set_cross_axis_alignment(
-      views::BoxLayout::CrossAxisAlignment::kStart);
+  UpdateLayoutManager();
 
   // Use layer to change the opacity.
   SetPaintToLayer();
@@ -59,7 +53,7 @@
     if (GetWidget()) {
       close_button_->SetImageModel(
           views::Button::STATE_NORMAL,
-          ui::ImageModel::FromVectorIcon(kNotificationCloseButtonIcon,
+          ui::ImageModel::FromVectorIcon(GetCloseButtonIcon(),
                                          DetermineButtonIconColor()));
     }
     close_button_->SetAccessibleName(l10n_util::GetStringUTF16(
@@ -88,7 +82,7 @@
     if (GetWidget()) {
       settings_button_->SetImageModel(
           views::Button::STATE_NORMAL,
-          ui::ImageModel::FromVectorIcon(kNotificationSettingsButtonIcon,
+          ui::ImageModel::FromVectorIcon(GetSettingsButtonIcon(),
                                          DetermineButtonIconColor()));
     }
     settings_button_->SetAccessibleName(l10n_util::GetStringUTF16(
@@ -116,7 +110,7 @@
     if (GetWidget()) {
       snooze_button_->SetImageModel(
           views::Button::STATE_NORMAL,
-          ui::ImageModel::FromVectorIcon(kNotificationSnoozeButtonIcon,
+          ui::ImageModel::FromVectorIcon(GetSnoozeButtonIcon(),
                                          DetermineButtonIconColor()));
     }
     snooze_button_->SetAccessibleName(l10n_util::GetStringUTF16(
@@ -147,6 +141,21 @@
          (snooze_button_ && snooze_button_->HasFocus());
 }
 
+void NotificationControlButtonsView::SetCloseButtonIcon(
+    const gfx::VectorIcon& icon) {
+  close_button_icon_ = &icon;
+}
+
+void NotificationControlButtonsView::SetSettingsButtonIcon(
+    const gfx::VectorIcon& icon) {
+  settings_button_icon_ = &icon;
+}
+
+void NotificationControlButtonsView::SetSnoozeButtonIcon(
+    const gfx::VectorIcon& icon) {
+  snooze_button_icon_ = &icon;
+}
+
 void NotificationControlButtonsView::SetButtonIconColors(SkColor color) {
   if (color == icon_color_)
     return;
@@ -162,6 +171,11 @@
   UpdateButtonIconColors();
 }
 
+void NotificationControlButtonsView::SetBetweenButtonSpacing(int spacing) {
+  between_button_spacing_ = spacing;
+  UpdateLayoutManager();
+}
+
 void NotificationControlButtonsView::SetMessageView(MessageView* message_view) {
   message_view_ = message_view;
 }
@@ -173,24 +187,33 @@
       std::move(notification_control_button_factory);
 }
 
+void NotificationControlButtonsView::UpdateLayoutManager() {
+  auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
+      views::BoxLayout::Orientation::kHorizontal));
+  layout->set_between_child_spacing(between_button_spacing_);
+
+  // Do not stretch buttons as that would stretch their focus indicator.
+  layout->set_cross_axis_alignment(
+      views::BoxLayout::CrossAxisAlignment::kStart);
+  InvalidateLayout();
+}
+
 void NotificationControlButtonsView::UpdateButtonIconColors() {
   SkColor icon_color = DetermineButtonIconColor();
   if (close_button_) {
-    close_button_->SetImageModel(views::Button::STATE_NORMAL,
-                                 ui::ImageModel::FromVectorIcon(
-                                     kNotificationCloseButtonIcon, icon_color));
+    close_button_->SetImageModel(
+        views::Button::STATE_NORMAL,
+        ui::ImageModel::FromVectorIcon(GetCloseButtonIcon(), icon_color));
   }
   if (settings_button_) {
     settings_button_->SetImageModel(
         views::Button::STATE_NORMAL,
-        ui::ImageModel::FromVectorIcon(kNotificationSettingsButtonIcon,
-                                       icon_color));
+        ui::ImageModel::FromVectorIcon(GetSettingsButtonIcon(), icon_color));
   }
   if (snooze_button_) {
     snooze_button_->SetImageModel(
         views::Button::STATE_NORMAL,
-        ui::ImageModel::FromVectorIcon(kNotificationSnoozeButtonIcon,
-                                       icon_color));
+        ui::ImageModel::FromVectorIcon(GetSnoozeButtonIcon(), icon_color));
   }
 }
 
@@ -203,6 +226,21 @@
   return color_utils::BlendForMinContrast(icon_color, background_color_).color;
 }
 
+const gfx::VectorIcon& NotificationControlButtonsView::GetCloseButtonIcon()
+    const {
+  return close_button_icon_ ? *close_button_icon_ : kDefaultCloseIcon;
+}
+
+const gfx::VectorIcon& NotificationControlButtonsView::GetSettingsButtonIcon()
+    const {
+  return settings_button_icon_ ? *settings_button_icon_ : kDefaultSettingsIcon;
+}
+
+const gfx::VectorIcon& NotificationControlButtonsView::GetSnoozeButtonIcon()
+    const {
+  return snooze_button_icon_ ? *snooze_button_icon_ : kDefaultSnoozeIcon;
+}
+
 BEGIN_METADATA(NotificationControlButtonsView, views::View)
 END_METADATA
 
diff --git a/ui/message_center/views/notification_control_buttons_view.h b/ui/message_center/views/notification_control_buttons_view.h
index 68e7b02..7c1206b 100644
--- a/ui/message_center/views/notification_control_buttons_view.h
+++ b/ui/message_center/views/notification_control_buttons_view.h
@@ -10,9 +10,11 @@
 #include "base/memory/raw_ptr.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/message_center/message_center_export.h"
+#include "ui/message_center/vector_icons.h"
 #include "ui/message_center/views/message_view.h"
 #include "ui/message_center/views/notification_control_button_factory.h"
 #include "ui/views/controls/button/image_button.h"
+#include "ui/views/metadata/view_factory.h"
 #include "ui/views/view.h"
 
 namespace message_center {
@@ -31,6 +33,17 @@
       const NotificationControlButtonsView&) = delete;
   ~NotificationControlButtonsView() override;
 
+  // Default control button icons.
+  inline static const gfx::VectorIcon& kDefaultCloseIcon =
+      kNotificationCloseButtonIcon;
+  inline static const gfx::VectorIcon& kDefaultSettingsIcon =
+      kNotificationSettingsButtonIcon;
+  inline static const gfx::VectorIcon& kDefaultSnoozeIcon =
+      kNotificationSnoozeButtonIcon;
+
+  // Default horizontal spacing between control buttons.
+  constexpr static int kDefaultBetweenButtonSpacing = 0;
+
   void OnThemeChanged() override;
 
   // Change the visibility of the close button. True to show, false to hide.
@@ -47,12 +60,26 @@
   // false otherwise.
   bool IsAnyButtonFocused() const;
 
+  // Sets the icon for the close, settings, and snooze buttons. Note that this
+  // will only have an effect the next time the buttons are shown. That is, if
+  // the XYZ button is currently visible when this method is called, then
+  // `SetXYZButtonIcon(false)` followed (eventually) by `SetXYZButtonIcon(true)`
+  // will need to occur before the new icon will be used. Of course, if the XYZ
+  // button is currently not visible when this method is called, then the new
+  // icon will be used the next time `SetXYZButtonIcon(true)` occurs.
+  void SetCloseButtonIcon(const gfx::VectorIcon& icon);
+  void SetSettingsButtonIcon(const gfx::VectorIcon& icon);
+  void SetSnoozeButtonIcon(const gfx::VectorIcon& icon);
+
   // Sets the icon color for the close, settings, and snooze buttons.
   void SetButtonIconColors(SkColor color);
 
   // Sets the background color to ensure proper readability.
   void SetBackgroundColor(SkColor color);
 
+  // Sets the horizontal spacing between buttons. Invalidates the layout.
+  void SetBetweenButtonSpacing(int spacing);
+
   void SetMessageView(MessageView* message_view);
 
   void SetNotificationControlButtonFactory(
@@ -65,6 +92,10 @@
   views::ImageButton* snooze_button() { return snooze_button_; }
 
  private:
+  // Updates the `views::LayoutManager` used to lay out this `views::View`'s
+  // children.
+  void UpdateLayoutManager();
+
   // Updates the button icon colors to the value of DetermineButtonIconColor().
   void UpdateButtonIconColors();
 
@@ -72,25 +103,48 @@
   // |background_color_| ensuring readability.
   SkColor DetermineButtonIconColor() const;
 
-  raw_ptr<MessageView> message_view_;
-  std::unique_ptr<NotificationControlButtonFactory>
-      notification_control_button_factory_;
+  // Returns the icon for the close, settings, and snooze buttons.
+  const gfx::VectorIcon& GetCloseButtonIcon() const;
+  const gfx::VectorIcon& GetSettingsButtonIcon() const;
+  const gfx::VectorIcon& GetSnoozeButtonIcon() const;
 
+  raw_ptr<MessageView> message_view_;
+  raw_ptr<const gfx::VectorIcon> close_button_icon_ = nullptr;
+  raw_ptr<const gfx::VectorIcon> settings_button_icon_ = nullptr;
+  raw_ptr<const gfx::VectorIcon> snooze_button_icon_ = nullptr;
   raw_ptr<views::ImageButton, DanglingUntriaged> close_button_ = nullptr;
   raw_ptr<views::ImageButton, DanglingUntriaged> settings_button_ = nullptr;
   raw_ptr<views::ImageButton, DanglingUntriaged> snooze_button_ = nullptr;
 
   // The color used for the close, settings, and snooze icons.
   absl::optional<SkColor> icon_color_;
+
   // The background color for readability of the icons.
   SkColor background_color_ = SK_ColorTRANSPARENT;
+
+  // The horizontal spacing between buttons.
+  int between_button_spacing_ = kDefaultBetweenButtonSpacing;
+
+  // Owned by this `views::View`:
+  std::unique_ptr<NotificationControlButtonFactory>
+      notification_control_button_factory_;
 };
 
 BEGIN_VIEW_BUILDER(MESSAGE_CENTER_EXPORT,
                    NotificationControlButtonsView,
                    views::View)
 VIEW_BUILDER_PROPERTY(MessageView*, MessageView)
+VIEW_BUILDER_PROPERTY(const gfx::VectorIcon&,
+                      CloseButtonIcon,
+                      const gfx::VectorIcon&)
+VIEW_BUILDER_PROPERTY(const gfx::VectorIcon&,
+                      SettingsButtonIcon,
+                      const gfx::VectorIcon&)
+VIEW_BUILDER_PROPERTY(const gfx::VectorIcon&,
+                      SnoozeButtonIcon,
+                      const gfx::VectorIcon&)
 VIEW_BUILDER_PROPERTY(SkColor, ButtonIconColors)
+VIEW_BUILDER_PROPERTY(int, BetweenButtonSpacing)
 VIEW_BUILDER_PROPERTY(std::unique_ptr<NotificationControlButtonFactory>,
                       NotificationControlButtonFactory)
 END_VIEW_BUILDER
diff --git a/ui/native_theme/native_theme.h b/ui/native_theme/native_theme.h
index ddfd9e4..e924f7f 100644
--- a/ui/native_theme/native_theme.h
+++ b/ui/native_theme/native_theme.h
@@ -261,6 +261,7 @@
   struct ScrollbarArrowExtraParams {
     bool is_hovering = false;
     float zoom = 0;
+    bool needs_rounded_corner = false;
     bool right_to_left = false;
     // These allow clients to directly override the color values to support
     // element-specific web platform CSS.
diff --git a/ui/native_theme/native_theme_aura.cc b/ui/native_theme/native_theme_aura.cc
index 46ab03ab..a5d40869 100644
--- a/ui/native_theme/native_theme_aura.cc
+++ b/ui/native_theme/native_theme_aura.cc
@@ -38,6 +38,7 @@
 namespace ui {
 
 namespace {
+
 // Constants for painting overlay scrollbars. Other properties needed outside
 // this painting code are defined in overlay_scrollbar_constants_aura.h.
 constexpr int kOverlayScrollbarMinimumLength = 32;
@@ -46,8 +47,17 @@
 // color. This prevents color interpolation between the patches.
 constexpr int kOverlayScrollbarBorderPatchWidth = 2;
 constexpr int kOverlayScrollbarCenterPatchSize = 1;
-const SkScalar kScrollRadius =
-    1;  // select[multiple] radius+width are set in css
+
+// This radius let scrollbar arrows fit in the default rounded border of some
+// form controls. TODO(crbug.com/1493088): We should probably let blink pass
+// the actual border radii.
+const SkScalar kScrollbarArrowRadius = 1;
+// Killswitch for the changed behavior (only drawing rounded corner for form
+// controls). Should remove after M120 ships.
+BASE_FEATURE(kNewScrollbarArrowRadius,
+             "NewScrollbarArrowRadius",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -219,26 +229,33 @@
   cc::PaintFlags flags;
   flags.setColor(bg_color);
 
-  SkScalar upper_left_radius = 0;
-  SkScalar lower_left_radius = 0;
-  SkScalar upper_right_radius = 0;
-  SkScalar lower_right_radius = 0;
-  float zoom = arrow.zoom ? arrow.zoom : 1.0;
-  if (direction == kScrollbarUpArrow) {
-    if (arrow.right_to_left) {
-      upper_left_radius = kScrollRadius * zoom;
-    } else {
-      upper_right_radius = kScrollRadius * zoom;
+  if (base::FeatureList::IsEnabled(kNewScrollbarArrowRadius) &&
+      !arrow.needs_rounded_corner) {
+    canvas->drawIRect(gfx::RectToSkIRect(rect), flags);
+  } else {
+    // TODO(crbug.com/1493088): Also draw rounded corner for left and right
+    // buttons when needed.
+    SkScalar upper_left_radius = 0;
+    SkScalar lower_left_radius = 0;
+    SkScalar upper_right_radius = 0;
+    SkScalar lower_right_radius = 0;
+    float zoom = arrow.zoom ? arrow.zoom : 1.0;
+    if (direction == kScrollbarUpArrow) {
+      if (arrow.right_to_left) {
+        upper_left_radius = kScrollbarArrowRadius * zoom;
+      } else {
+        upper_right_radius = kScrollbarArrowRadius * zoom;
+      }
+    } else if (direction == kScrollbarDownArrow) {
+      if (arrow.right_to_left) {
+        lower_left_radius = kScrollbarArrowRadius * zoom;
+      } else {
+        lower_right_radius = kScrollbarArrowRadius * zoom;
+      }
     }
-  } else if (direction == kScrollbarDownArrow) {
-    if (arrow.right_to_left) {
-      lower_left_radius = kScrollRadius * zoom;
-    } else {
-      lower_right_radius = kScrollRadius * zoom;
-    }
+    DrawPartiallyRoundRect(canvas, rect, upper_left_radius, upper_right_radius,
+                           lower_right_radius, lower_left_radius, flags);
   }
-  DrawPartiallyRoundRect(canvas, rect, upper_left_radius, upper_right_radius,
-                         lower_right_radius, lower_left_radius, flags);
 
   PaintArrow(canvas, rect, direction, arrow_color);
 }
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc
index 8d35bbc0..1d82507 100644
--- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc
+++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc
@@ -440,11 +440,13 @@
                       : ZAURA_TOPLEVEL_ROTATE_HANDLED_STATE_NOT_HANDLED);
 }
 
+void WaylandToplevelWindow::OnOverviewChange(uint32_t in_overview_as_int) {
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
-void WaylandToplevelWindow::OnOverviewModeChanged(bool in_overview) {
+  const bool in_overview =
+      in_overview_as_int == ZAURA_TOPLEVEL_IN_OVERVIEW_IN_OVERVIEW;
   delegate()->OnOverviewModeChanged(in_overview);
-}
 #endif
+}
 
 void WaylandToplevelWindow::LockFrame() {
   OnFrameLockingChanged(true);
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.h b/ui/ozone/platform/wayland/host/wayland_toplevel_window.h
index f39a9a89..cad41afc 100644
--- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.h
+++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.h
@@ -96,10 +96,7 @@
   void HideTooltip() override;
   void PropagateBufferScale(float new_scale) override;
   void OnRotateFocus(uint32_t serial, uint32_t direction, bool restart);
-
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-  void OnOverviewModeChanged(bool in_overview);
-#endif
+  void OnOverviewChange(uint32_t in_overview_as_int);
 
   // WmDragHandler:
   bool ShouldReleaseCaptureForDrag(ui::OSExchangeData* data) const override;
diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
index cc5cf617..9f05f0b 100644
--- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
@@ -4938,21 +4938,20 @@
     GTEST_SKIP();
   }
 
-  testing::NiceMock<MockWaylandPlatformWindowDelegate> delegate;
-  std::unique_ptr<WaylandWindow> toplevel_window =
-      CreateWaylandWindowWithParams(PlatformWindowType::kWindow,
-                                    gfx::Rect(300, 300), &delegate);
-
-  EXPECT_CALL(delegate, OnOverviewModeChanged(Eq(true))).Times(1);
-  PostToServerAndWait([](wl::TestWaylandServerThread* server) {
-    auto* const zaura_shell = server->zaura_shell()->resource();
-    zaura_shell_send_set_overview_mode(zaura_shell);
+  EXPECT_CALL(delegate_, OnOverviewModeChanged(Eq(true))).Times(1);
+  PostToServerAndWait([&](wl::TestWaylandServerThread* server) {
+    auto* surface = server->GetObject<wl::MockSurface>(surface_id_);
+    auto* toplevel = surface->xdg_surface()->xdg_toplevel()->zaura_toplevel();
+    zaura_toplevel_send_overview_change(toplevel->resource(),
+                                        ZAURA_TOPLEVEL_IN_OVERVIEW_IN_OVERVIEW);
   });
 
-  EXPECT_CALL(delegate, OnOverviewModeChanged(Eq(false))).Times(1);
-  PostToServerAndWait([](wl::TestWaylandServerThread* server) {
-    auto* const zaura_shell = server->zaura_shell()->resource();
-    zaura_shell_send_unset_overview_mode(zaura_shell);
+  EXPECT_CALL(delegate_, OnOverviewModeChanged(Eq(false))).Times(1);
+  PostToServerAndWait([&](wl::TestWaylandServerThread* server) {
+    auto* surface = server->GetObject<wl::MockSurface>(surface_id_);
+    auto* toplevel = surface->xdg_surface()->xdg_toplevel()->zaura_toplevel();
+    zaura_toplevel_send_overview_change(
+        toplevel->resource(), ZAURA_TOPLEVEL_IN_OVERVIEW_NOT_IN_OVERVIEW);
   });
 }
 #endif
diff --git a/ui/ozone/platform/wayland/host/wayland_zaura_shell.cc b/ui/ozone/platform/wayland/host/wayland_zaura_shell.cc
index 802f989..ee6d05f 100644
--- a/ui/ozone/platform/wayland/host/wayland_zaura_shell.cc
+++ b/ui/ozone/platform/wayland/host/wayland_zaura_shell.cc
@@ -24,7 +24,7 @@
 namespace {
 
 constexpr uint32_t kMinVersion = 1;
-constexpr uint32_t kMaxVersion = 60;
+constexpr uint32_t kMaxVersion = ZAURA_TOPLEVEL_OVERVIEW_CHANGE_SINCE_VERSION;
 
 }  // namespace
 
@@ -197,27 +197,11 @@
 // static
 void WaylandZAuraShell::OnSetOverviewMode(void* data,
                                           struct zaura_shell* zaura_shell) {
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-  auto* self = static_cast<WaylandZAuraShell*>(data);
-  for (auto* window : self->connection_->window_manager()->GetAllWindows()) {
-    if (auto* toplevel_window = window->AsWaylandToplevelWindow()) {
-      toplevel_window->OnOverviewModeChanged(true);
-    }
-  }
-#endif
 }
 
 // static
 void WaylandZAuraShell::OnUnsetOverviewMode(void* data,
                                             struct zaura_shell* zaura_shell) {
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-  auto* self = static_cast<WaylandZAuraShell*>(data);
-  for (auto* window : self->connection_->window_manager()->GetAllWindows()) {
-    if (auto* toplevel_window = window->AsWaylandToplevelWindow()) {
-      toplevel_window->OnOverviewModeChanged(false);
-    }
-  }
-#endif
 }
 
 // static
diff --git a/ui/ozone/platform/wayland/host/wayland_zaura_shell.h b/ui/ozone/platform/wayland/host/wayland_zaura_shell.h
index 4e1831ef..cdeae0b 100644
--- a/ui/ozone/platform/wayland/host/wayland_zaura_shell.h
+++ b/ui/ozone/platform/wayland/host/wayland_zaura_shell.h
@@ -89,8 +89,11 @@
                           struct zaura_shell* zaura_shell,
                           struct wl_surface* gained_active,
                           struct wl_surface* lost_active);
+
+  // TODO(sammiequon): Remove these two deprecated functions.
   static void OnSetOverviewMode(void* data, struct zaura_shell* zaura_shell);
   static void OnUnsetOverviewMode(void* data, struct zaura_shell* zaura_shell);
+
   static void OnCompositorVersion(void* data,
                                   struct zaura_shell* zaura_shell,
                                   const char* version_label);
diff --git a/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.cc
index bd3f0ce..c881aca 100644
--- a/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.cc
+++ b/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.cc
@@ -430,6 +430,16 @@
   toplevel_window->OnRotateFocus(serial, direction, restart);
 }
 
+// static
+void XDGToplevelWrapperImpl::OnOverviewChange(void* data,
+                                              zaura_toplevel* aura_toplevel,
+                                              uint32_t in_overview_as_uint) {
+  auto* self = static_cast<XDGToplevelWrapperImpl*>(data);
+  CHECK(self);
+  self->wayland_window_->AsWaylandToplevelWindow()->OnOverviewChange(
+      in_overview_as_uint);
+}
+
 void XDGToplevelWrapperImpl::SetTopLevelDecorationMode(
     DecorationMode requested_mode) {
   if (!zxdg_toplevel_decoration_ || requested_mode == decoration_mode_)
@@ -565,7 +575,8 @@
       .configure = &OnAuraToplevelConfigure,
       .origin_change = &OnOriginChange,
       .configure_raster_scale = &OnConfigureRasterScale,
-      .rotate_focus = &OnRotateFocus};
+      .rotate_focus = &OnRotateFocus,
+      .overview_change = &OnOverviewChange};
   zaura_toplevel_add_listener(aura_toplevel_.get(), &kAuraToplevelListener,
                               this);
 }
diff --git a/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.h b/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.h
index fd3ae89..e269593a 100644
--- a/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.h
+++ b/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.h
@@ -124,6 +124,9 @@
                             uint32_t serial,
                             uint32_t direction,
                             uint32_t restart);
+  static void OnOverviewChange(void* data,
+                               zaura_toplevel* aura_toplevel,
+                               uint32_t in_overview_as_uint);
 
   // Send request to wayland compositor to enable a requested decoration mode.
   void SetTopLevelDecorationMode(DecorationMode requested_mode);
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn
index 0437abb..4faabff 100644
--- a/ui/webui/resources/cr_elements/BUILD.gn
+++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -35,6 +35,7 @@
       "cr_icon_button/cr_icon_button.ts",
       "cr_input/cr_input.ts",
       "cr_link_row/cr_link_row.ts",
+      "cr_loading_gradient/cr_loading_gradient.ts",
       "cr_lottie/cr_lottie.ts",
       "cr_textarea/cr_textarea.ts",
       "cr_profile_avatar_selector/cr_profile_avatar_selector_grid.ts",
diff --git a/ui/webui/resources/cr_elements/cr_loading_gradient/cr_loading_gradient.html b/ui/webui/resources/cr_elements/cr_loading_gradient/cr_loading_gradient.html
new file mode 100644
index 0000000..bc425ef
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_loading_gradient/cr_loading_gradient.html
@@ -0,0 +1,41 @@
+<style>
+  :host {
+    --cr-loading-gradient-color1: transparent;
+    --cr-loading-gradient-color2: var(--cr-fallback-color-primary-container);
+    --cr-loading-gradient-color3: rgb(231, 248, 237);
+
+    display: flex;
+    width: 100%;
+    height: fit-content;
+    position: relative;
+  }
+
+  @media (prefers-color-scheme: dark) {
+    :host {
+      --cr-loading-gradient-color3: rgb(15, 82, 35);
+    }
+  }
+
+  #gradient {
+    position: absolute;
+    inset: 0;
+    background: linear-gradient(
+        130deg,
+        var(--cr-loading-gradient-color1) 0%,
+        var(--cr-loading-gradient-color2) 20%,
+        var(--cr-loading-gradient-color3) 40%,
+        var(--cr-loading-gradient-color1) 60%,
+        var(--cr-loading-gradient-color2) 80%,
+        var(--cr-loading-gradient-color3) 100%);
+    background-position: 0% 0%;
+    background-size: 250% 250%;
+    animation: gradient 5s infinite linear;
+  }
+
+  @keyframes gradient {
+    0% { background-position: 0 0; }
+    100% { background-position: 100% 100%; }
+  }
+</style>
+<div id="gradient"></div>
+<slot on-slotchange="onSlotchange_"></slot>
diff --git a/ui/webui/resources/cr_elements/cr_loading_gradient/cr_loading_gradient.ts b/ui/webui/resources/cr_elements/cr_loading_gradient/cr_loading_gradient.ts
new file mode 100644
index 0000000..cf211919
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_loading_gradient/cr_loading_gradient.ts
@@ -0,0 +1,39 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {assert} from 'chrome://resources/js/assert.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {getTemplate} from './cr_loading_gradient.html.js';
+
+/* Count of cr-loading-gradient elements created. Used to assign unique IDs.
+ * Unique IDs are necessary since clipPaths are slotted in from the light DOM,
+ * so there can be leakages across multiple <cr-loading-gradient> instances. */
+let count = 0;
+
+export class CrLoadingGradientElement extends PolymerElement {
+  static get is() {
+    return 'cr-loading-gradient';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  private onSlotchange_() {
+    const clipPath = this.querySelector('svg clipPath');
+    assert(clipPath);
+    const generatedId = `crLoadingGradient${count++}`;
+    clipPath.id = generatedId;
+    this.style.clipPath = `url(#${generatedId})`;
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    'cr-loading-gradient': CrLoadingGradientElement;
+  }
+}
+
+customElements.define(CrLoadingGradientElement.is, CrLoadingGradientElement);
diff --git a/ui/webui/resources/cr_elements/cr_textarea/cr_textarea.html b/ui/webui/resources/cr_elements/cr_textarea/cr_textarea.html
index 387b1a7..3df3a6d17 100644
--- a/ui/webui/resources/cr_elements/cr_textarea/cr_textarea.html
+++ b/ui/webui/resources/cr_elements/cr_textarea/cr_textarea.html
@@ -114,7 +114,7 @@
       on-focus="onInputFocusChange_" on-blur="onInputFocusChange_"
       on-change="onInputChange_" disabled="[[disabled]]"
       maxlength$="[[maxlength]]" readonly$="[[readonly]]"
-      required$="[[required]]"></textarea>
+      required$="[[required]]" placeholder$="[[placeholder]]"></textarea>
   <div id="underline-base"></div>
   <div id="underline"></div>
 </div>
diff --git a/ui/webui/resources/cr_elements/cr_textarea/cr_textarea.ts b/ui/webui/resources/cr_elements/cr_textarea/cr_textarea.ts
index 23ed829..608ed20 100644
--- a/ui/webui/resources/cr_elements/cr_textarea/cr_textarea.ts
+++ b/ui/webui/resources/cr_elements/cr_textarea/cr_textarea.ts
@@ -100,6 +100,14 @@
         notify: true,
       },
 
+      /**
+       * Placeholder text that is shown when no value is present.
+       */
+      placeholder: {
+        type: String,
+        value: '',
+      },
+
       /** Whether the textarea can auto-grow vertically or not. */
       autogrow: {
         type: Boolean,
@@ -151,6 +159,7 @@
   rows: number;
   label: string;
   value: string;
+  placeholder: string;
   autogrow: boolean;
   hasMaxHeight: boolean;
   invalid: boolean;
diff --git a/ui/webui/resources/tools/bundle_js.py b/ui/webui/resources/tools/bundle_js.py
index 4370434c..2beae2f7 100755
--- a/ui/webui/resources/tools/bundle_js.py
+++ b/ui/webui/resources/tools/bundle_js.py
@@ -83,15 +83,16 @@
 # out_dir: The root directory for the output (i.e. corresponding to
 #          host_url at runtime).
 # in_path: Root directory for the input files.
-# bundle_path: Path to the output files from the root output directory.
-#              E.g. if bundle is chrome://foo/bundle.js, this is |foo|.
+# bundle_dir_path: Path to the directory holding the bundled output files
+#                  relative to the root output directory. E.g. if bundle is
+#                  chrome://<blah>/foo/bundle.js, this is |foo|.
 # host_url: URL of the host. Usually something like "chrome://settings".
 # excludes: Imports to exclude from the bundle.
 # external_paths: Path mappings for import paths that are outside of
 #                 |in_path|. For example:
 #                 chrome://resources/|gen/ui/webui/resources/tsc
-def _generate_rollup_config(out_dir, in_path, bundle_path, host_url, excludes,
-                            external_paths):
+def _generate_rollup_config(out_dir, in_path, bundle_dir_path, host_url,
+                            excludes, external_paths):
   rollup_config_file = os.path.join(out_dir, 'rollup.config.mjs')
   path_to_plugin = os.path.join(
       os.path.relpath(_HERE_PATH, out_dir), 'rollup_plugin.mjs')
@@ -99,13 +100,13 @@
     import plugin from '{plugin_path}';
     export default ({{
       plugins: [
-        plugin('{in_path}', '{bundle_path}', '{host_url}', {exclude_list},
+        plugin('{in_path}', '{bundle_dir_path}', '{host_url}', {exclude_list},
                {external_path_list}) ]
     }});
     '''.format(
       plugin_path=path_to_plugin.replace('\\', '/'),
       in_path=in_path.replace('\\', '/'),
-      bundle_path=bundle_path.replace('\\', '/'),
+      bundle_dir_path=bundle_dir_path.replace('\\', '/'),
       host_url=host_url,
       exclude_list=json.dumps(excludes),
       external_path_list=json.dumps(external_paths))
@@ -116,12 +117,11 @@
 
 # Create the manifest file from the sourcemap generated by rollup and return the
 # list of bundles.
-def _generate_manifest_file(out_dir, in_path, bundle_path, manifest_out_path):
-  generated_sourcemaps = glob.glob('%s/*.map' %
-                                   os.path.join(out_dir, bundle_path))
+def _generate_manifest_file(out_dir, bundled_paths, bundle_dir_path,
+                            manifest_out_path):
   manifest = {}
-  output_filenames = []
-  for sourcemap_file in generated_sourcemaps:
+  for bundled_path in bundled_paths:
+    sourcemap_file = bundled_path + '.map'
     with open(sourcemap_file, 'r', encoding='utf-8') as f:
       sourcemap = json.loads(f.read())
       if not 'sources' in sourcemap:
@@ -131,35 +131,32 @@
       # Normalize everything to be relative to the output directory. This is
       # where the conversion to a dependency file expects it to be.
       bundle_to_output = os.path.relpath(out_dir,
-                                         os.path.join(out_dir, bundle_path))
+                                         os.path.join(out_dir, bundle_dir_path))
       for source in sources:
         if bundle_to_output != ".":
           replaced_sources.append(source.replace(bundle_to_output + "/", "", 1))
         else:
           replaced_sources.append(source)
-      filename = sourcemap_file[:-len('.map')]
-      filepath = os.path.join(bundle_path, os.path.basename(filename)). \
-              replace('\\', '/')
+      filepath = os.path.join(bundle_dir_path,
+                              os.path.basename(bundled_path)).replace(
+                                  '\\', '/')
       manifest[filepath] = replaced_sources
-      output_filenames.append(filename)
 
   with open(manifest_out_path, 'w', newline='', encoding='utf-8') as f:
     f.write(json.dumps(manifest))
 
-  return output_filenames
-
 
 def _bundle(out_folder, in_path, manifest_out_path, args, excludes,
             external_paths):
-  bundle_path = os.path.dirname(args.js_module_in_files[0])
-  out_dir = out_folder if not bundle_path else os.path.join(
-      out_folder, bundle_path)
+  bundle_dir_path = os.path.dirname(args.js_module_in_files[0])
+  out_dir = out_folder if not bundle_dir_path else os.path.join(
+      out_folder, bundle_dir_path)
   if not os.path.exists(out_dir):
     os.makedirs(out_dir)
 
-  rollup_config_file = _generate_rollup_config(out_folder, in_path, bundle_path,
-                                               args.host_url, excludes,
-                                               external_paths)
+  rollup_config_file = _generate_rollup_config(out_folder, in_path,
+                                               bundle_dir_path, args.host_url,
+                                               excludes, external_paths)
   rollup_args = [os.path.join(in_path, f) for f in args.js_module_in_files]
 
   # Confirm names are as expected. This is necessary to avoid having to replace
@@ -173,7 +170,7 @@
 
   for index, js_file in enumerate(args.js_module_in_files):
     bundle_name = '%s.rollup.js' % js_file[:-len('.js')]
-    assert os.path.dirname(js_file) == bundle_path, \
+    assert os.path.dirname(js_file) == bundle_dir_path, \
            'All input files must be in the same directory.'
     bundled_paths.append(os.path.join(out_folder, bundle_name))
     bundle_names.append(bundle_name)
@@ -186,7 +183,7 @@
     shared_file_name = 'shared.rollup.js'
     rollup_args += ['--chunkFileNames', shared_file_name]
     bundled_paths.append(os.path.join(out_dir, shared_file_name))
-    bundle_names.append(os.path.join(bundle_path, shared_file_name))
+    bundle_names.append(os.path.join(bundle_dir_path, shared_file_name))
 
   node.RunNode([node_modules.PathToRollup()] + rollup_args + [
       '--format',
@@ -202,11 +199,8 @@
   ])
 
   # Create the manifest file from the sourcemaps generated by rollup.
-  generated_paths = _generate_manifest_file(out_folder, in_path, bundle_path,
-                                            manifest_out_path)
-  assert len(generated_paths) == len(bundled_paths), \
-         'unexpected number of bundles - %s - generated by rollup' % \
-         (len(generated_paths))
+  _generate_manifest_file(out_folder, bundled_paths, bundle_dir_path,
+                          manifest_out_path)
 
   for bundled_file in bundled_paths:
     with open(bundled_file, 'r', encoding='utf-8') as f:
diff --git a/v8 b/v8
index bf7fbd2..bc56daf 160000
--- a/v8
+++ b/v8
@@ -1 +1 @@
-Subproject commit bf7fbd2548b2e6dd2d9ca12ede93e52d28e7baab
+Subproject commit bc56dafb2ce1ddfbca6861bb92038b40da83db54